Commit a287f893 authored by jean-pierre charras's avatar jean-pierre charras

Custom page layout: add support for poly-polygons (useful for logos)

parent 98eb5e75
......@@ -46,6 +46,8 @@
* pos
* start
* end
* pts
* xy
* maxlen
* maxheight
* font
......@@ -123,6 +125,29 @@
* example:
* (tbtext \"Size: %Z\" ...) displays "Size A4" or Size USLetter"
*
* Poly Polygons
* Set of filled polygons are supported.
*
* The main purpose is to allow logos, or complex shapes
* They support the repeat and rotation options
* They are defined by
* (polygon (position ..) <rotation> <linewidth>
* the parameter linewidth defines the pen size used to draw/plot
* the polygon outlines (default = 0)
* example:
* (polygon (pos 134 18 rbcorner) (rotate 20) (linewidth 0.00254)
*
* and a list of corners like
* (pts (xy 20.574 8.382) (xy 19.9009 8.382) (xy 19.9009 6.26364) (xy 19.7485 5.98932)
* .... )
*
* each sequence like
* (pts (xy 20.574 8.382) (xy 19.9009 8.382) (xy 19.9009 6.26364) (xy 19.7485 5.98932)
* .... )
* defines a polygon.
* Each coordinate is relative to the polygon position.
* Therefore a "polygon" is in fact a set of polygons, of a poly polygon
*
*/
#include <worksheet.h> // defaultPageLayout
......@@ -135,39 +160,39 @@
// frame ref pitch 50 mm
// export defaultPageLayout:
extern const char defaultPageLayout[];
extern const char defaultPageLayout[];
// Default page layout (sizes are in mm)
const char defaultPageLayout[] = "( page_layout\n"
"(setup (textsize 1.5 1.5) (linewidth 0.15) (textlinewidth 0.15) )"
"(rect (comment rect around the title block) (linewidth 0.15) (start 110 34) (end 2 2) )\n"
"(rect (start 0 0 ltcorner) (end 0 0 rbcorner) (repeat 2) (incrx 2) (incry 2) )\n"
"(line (start 50 2 ltcorner) (end 50 0 ltcorner) (repeat 30) (incrx 50) )\n"
"(tbtext \"1\" (pos 25 1 ltcorner) (font (size 1.3 1.3))(repeat 100) (incrx 50) )\n"
"(line (start 50 2 lbcorner) (end 50 0 lbcorner) (repeat 30) (incrx 50) )\n"
"(tbtext \"1\" (pos 25 1 lbcorner) (font (size 1.3 1.3)) (repeat 100) (incrx 50) )\n"
"(line (start 0 50 ltcorner) (end 2 50 ltcorner) (repeat 30) (incry 50) )\n"
"(tbtext \"A\" (pos 1 25 ltcorner) (font (size 1.3 1.3)) (justify center)(repeat 100) (incry 50) )\n"
"(line (start 0 50 rtcorner) (end 2 50 rtcorner) (repeat 30) (incry 50) )\n"
"(tbtext \"A\" (pos 1 25 rtcorner) (font (size 1.3 1.3)) (justify center) (repeat 100) (incry 50) )\n"
"(tbtext \"Date: %D\" (pos 87 6.9) )\n"
"(line (start 110 5.5) end 2 5.5) )\n"
"(tbtext \"%K\" (pos 109 4.1) (comment Kicad version ) )\n"
"(line (start 110 8.5) end 2 8.5) )\n"
"(tbtext \"Rev: %R\" (pos 24 6.9)(font bold)(justify left) )\n"
"(tbtext \"Size: %Z\" (comment Paper format name)(pos 109 6.9) )\n"
"(tbtext \"Id: %S/%N\" (comment Sheet id)(pos 24 4.1) )\n"
"(line (start 110 12.5) end 2 12.5) )\n"
"(tbtext \"Title: %T\" (pos 109 10.7)(font bold italic (size 2 2)) )\n"
"(tbtext \"File: %F\" (pos 109 14.3) )\n"
"(line (start 110 18.5) end 2 18.5) )\n"
"(tbtext \"Sheet: %P\" (pos 109 17) )\n"
"(tbtext \"%Y\" (comment Company name) (pos 109 20)(font bold) )\n"
"(tbtext \"%C0\" (comment Comment 0) (pos 109 23) )\n"
"(tbtext \"%C1\" (comment Comment 0) (pos 109 26) )\n"
"(tbtext \"%C2\" (comment Comment 0) (pos 109 29) )\n"
"(tbtext \"%C3\" (comment Comment 0) (pos 109 32) )\n"
"(line (start 90 8.5) end 90 5.5) )\n"
"(line (start 26 8.5) end 26 2) )\n"
")\n"
const char defaultPageLayout[] = "( page_layout\n"
"(setup (textsize 1.5 1.5) (linewidth 0.15) (textlinewidth 0.15) )"
"(rect (comment rect around the title block) (linewidth 0.15) (start 110 34) (end 2 2) )\n"
"(rect (start 0 0 ltcorner) (end 0 0 rbcorner) (repeat 2) (incrx 2) (incry 2) )\n"
"(line (start 50 2 ltcorner) (end 50 0 ltcorner) (repeat 30) (incrx 50) )\n"
"(tbtext \"1\" (pos 25 1 ltcorner) (font (size 1.3 1.3))(repeat 100) (incrx 50) )\n"
"(line (start 50 2 lbcorner) (end 50 0 lbcorner) (repeat 30) (incrx 50) )\n"
"(tbtext \"1\" (pos 25 1 lbcorner) (font (size 1.3 1.3)) (repeat 100) (incrx 50) )\n"
"(line (start 0 50 ltcorner) (end 2 50 ltcorner) (repeat 30) (incry 50) )\n"
"(tbtext \"A\" (pos 1 25 ltcorner) (font (size 1.3 1.3)) (justify center)(repeat 100) (incry 50) )\n"
"(line (start 0 50 rtcorner) (end 2 50 rtcorner) (repeat 30) (incry 50) )\n"
"(tbtext \"A\" (pos 1 25 rtcorner) (font (size 1.3 1.3)) (justify center) (repeat 100) (incry 50) )\n"
"(tbtext \"Date: %D\" (pos 87 6.9) )\n"
"(line (start 110 5.5) end 2 5.5) )\n"
"(tbtext \"%K\" (pos 109 4.1) (comment Kicad version ) )\n"
"(line (start 110 8.5) end 2 8.5) )\n"
"(tbtext \"Rev: %R\" (pos 24 6.9)(font bold)(justify left) )\n"
"(tbtext \"Size: %Z\" (comment Paper format name)(pos 109 6.9) )\n"
"(tbtext \"Id: %S/%N\" (comment Sheet id)(pos 24 4.1) )\n"
"(line (start 110 12.5) end 2 12.5) )\n"
"(tbtext \"Title: %T\" (pos 109 10.7)(font bold italic (size 2 2)) )\n"
"(tbtext \"File: %F\" (pos 109 14.3) )\n"
"(line (start 110 18.5) end 2 18.5) )\n"
"(tbtext \"Sheet: %P\" (pos 109 17) )\n"
"(tbtext \"%Y\" (comment Company name) (pos 109 20)(font bold) )\n"
"(tbtext \"%C0\" (comment Comment 0) (pos 109 23) )\n"
"(tbtext \"%C1\" (comment Comment 0) (pos 109 26) )\n"
"(tbtext \"%C2\" (comment Comment 0) (pos 109 29) )\n"
"(tbtext \"%C3\" (comment Comment 0) (pos 109 32) )\n"
"(line (start 90 8.5) end 90 5.5) )\n"
"(line (start 26 8.5) end 26 2) )\n"
")\n"
;
......@@ -76,6 +76,10 @@ private:
void parseSetup() throw( IO_ERROR, PARSE_ERROR );
void parseGraphic( WORKSHEET_DATAITEM * aItem ) throw( IO_ERROR, PARSE_ERROR );
void parseText( WORKSHEET_DATAITEM_TEXT * aItem ) throw( IO_ERROR, PARSE_ERROR );
void parsePolygon( WORKSHEET_DATAITEM_POLYPOLYGON * aItem )
throw( IO_ERROR, PARSE_ERROR );
void parsePolyOutline( WORKSHEET_DATAITEM_POLYPOLYGON * aItem )
throw( IO_ERROR, PARSE_ERROR );
void parseCoordinate( POINT_COORD& aCoord) throw( IO_ERROR, PARSE_ERROR );
};
......@@ -127,6 +131,12 @@ void PAGE_LAYOUT_READER_PARSER::Parse( WORKSHEET_LAYOUT* aLayout )
aLayout->Append( item );
break;
case T_polygon:
item = new WORKSHEET_DATAITEM_POLYPOLYGON();
parsePolygon( (WORKSHEET_DATAITEM_POLYPOLYGON*) item );
aLayout->Append( item );
break;
case T_tbtext:
NeedSYMBOLorNUMBER();
item = new WORKSHEET_DATAITEM_TEXT( FromUTF8() );
......@@ -177,6 +187,100 @@ void PAGE_LAYOUT_READER_PARSER::parseSetup() throw( IO_ERROR, PARSE_ERROR )
}
}
void PAGE_LAYOUT_READER_PARSER::parsePolygon( WORKSHEET_DATAITEM_POLYPOLYGON * aItem )
throw( IO_ERROR, PARSE_ERROR )
{
aItem->m_LineWidth = 0;
T token;
while( ( token = NextTok() ) != T_RIGHT )
{
if( token == T_EOF)
break;
if( token == T_LEFT )
token = NextTok();
switch( token )
{
case T_comment: // Comment, search the closing ')'
while( ( token = NextTok() ) != T_RIGHT && token != T_EOF );
break;
case T_pos:
parseCoordinate( aItem->m_Pos );
break;
case T_pts:
parsePolyOutline( aItem );
aItem->CloseContour();
break;
case T_rotate:
aItem->m_Orient = parseDouble();
NeedRIGHT();
break;
case T_repeat:
aItem->m_RepeatCount = parseInt( -1, 100 );
NeedRIGHT();
break;
case T_incrx:
aItem->m_IncrementVector.x = parseDouble();
NeedRIGHT();
break;
case T_incry:
aItem->m_IncrementVector.y = parseDouble();
NeedRIGHT();
break;
case T_linewidth:
aItem->m_LineWidth = parseDouble();
NeedRIGHT();
break;
default:
Unexpected( CurText() );
break;
}
}
aItem->SetBoundingBox();
}
void PAGE_LAYOUT_READER_PARSER::parsePolyOutline( WORKSHEET_DATAITEM_POLYPOLYGON * aItem )
throw( IO_ERROR, PARSE_ERROR )
{
DPOINT corner;
T token;
while( ( token = NextTok() ) != T_RIGHT )
{
if( token == T_EOF)
break;
if( token == T_LEFT )
token = NextTok();
switch( token )
{
case T_xy:
corner.x = parseDouble();
corner.y = parseDouble();
aItem->AppendCorner( corner );
NeedRIGHT();
break;
default:
Unexpected( CurText() );
break;
}
}
}
void PAGE_LAYOUT_READER_PARSER::parseGraphic( WORKSHEET_DATAITEM * aItem )
throw( IO_ERROR, PARSE_ERROR )
{
......
......@@ -16,6 +16,8 @@ name
pos
start
end
pts
xy
maxlen
maxheight
font
......
......@@ -60,6 +60,80 @@
#include <class_title_block.h>
#include <worksheet_shape_builder.h>
WORKSHEET_DATAITEM_POLYPOLYGON::WORKSHEET_DATAITEM_POLYPOLYGON() :
WORKSHEET_DATAITEM( WS_POLYPOLYGON )
{
m_Orient = 0.0;
}
const DPOINT WORKSHEET_DATAITEM_POLYPOLYGON::GetCornerPosition( unsigned aIdx,
int aRepeat ) const
{
DPOINT pos = m_Corners[aIdx];
// Rotation:
RotatePoint( &pos.x, &pos.y, m_Orient * 10 );
pos += GetStartPos( aRepeat );
return pos;
}
void WORKSHEET_DATAITEM_POLYPOLYGON::SetBoundingBox()
{
if( m_Corners.size() == 0 )
{
m_minCoord.x = m_maxCoord.x = 0.0;
m_minCoord.y = m_maxCoord.y = 0.0;
return;
}
DPOINT pos;
pos = m_Corners[0];
RotatePoint( &pos.x, &pos.y, m_Orient * 10 );
m_minCoord = m_maxCoord = pos;
for( unsigned ii = 1; ii < m_Corners.size(); ii++ )
{
pos = m_Corners[ii];
RotatePoint( &pos.x, &pos.y, m_Orient * 10 );
if( m_minCoord.x > pos.x )
m_minCoord.x = pos.x;
if( m_minCoord.y > pos.y )
m_minCoord.y = pos.y;
if( m_maxCoord.x < pos.x )
m_maxCoord.x = pos.x;
if( m_maxCoord.y < pos.y )
m_maxCoord.y = pos.y;
}
}
bool WORKSHEET_DATAITEM_POLYPOLYGON::IsInsidePage( int ii ) const
{
DPOINT pos = GetStartPos( ii );
pos += m_minCoord; // left top pos of bounding box
if( m_LT_Corner.x > pos.x || m_LT_Corner.y > pos.y )
return false;
pos = GetStartPos( ii );
pos += m_maxCoord; // rignt bottom pos of bounding box
if( m_RB_Corner.x < pos.x || m_RB_Corner.y < pos.y )
return false;
return true;
}
const wxPoint WORKSHEET_DATAITEM_POLYPOLYGON::GetCornerPositionUi( unsigned aIdx,
int aRepeat ) const
{
DPOINT pos = GetCornerPosition( aIdx, aRepeat );
pos = pos * m_WSunits2Iu;
return wxPoint( int(pos.x), int(pos.y) );
}
WORKSHEET_DATAITEM_TEXT::WORKSHEET_DATAITEM_TEXT( const wxChar* aTextBase ) :
WORKSHEET_DATAITEM( WS_TEXT )
......@@ -253,6 +327,8 @@ void WS_DRAW_ITEM_LIST::BuildWorkSheetGraphicList(
if( wsItem == NULL )
break;
pensize = wsItem->GetPenSizeUi();
switch( wsItem->m_Type )
{
case WORKSHEET_DATAITEM::WS_TEXT:
......@@ -262,8 +338,6 @@ void WS_DRAW_ITEM_LIST::BuildWorkSheetGraphicList(
if( wsText->m_FullText.IsEmpty() )
break;
pensize = wsText->GetPenSizeUi();
if( pensize == 0 )
pensize = m_penSize;
......@@ -283,10 +357,11 @@ void WS_DRAW_ITEM_LIST::BuildWorkSheetGraphicList(
if( wsText->IsBold())
pensize = GetPenSizeForBold( std::min( textsize.x, textsize.y ) );
for( int jj = 0; jj < wsText->m_RepeatCount; )
for( int jj = 0; jj < wsText->m_RepeatCount; jj++)
{
if( ! wsText->IsInsidePage( jj ) )
break;
continue;
Append( gtext = new WS_DRAW_ITEM_TEXT( wsText->m_FullText,
wsText->GetStartPosUi( jj ),
textsize,
......@@ -295,23 +370,21 @@ void WS_DRAW_ITEM_LIST::BuildWorkSheetGraphicList(
wsText->IsBold() ) );
wsText->TransfertSetupToGraphicText( gtext );
jj++;
if( wsText->m_RepeatCount > 1 ) // Try to increment label
wsText->IncrementLabel( jj );
// Increment label for the next text
if( wsText->m_RepeatCount > 1 )
wsText->IncrementLabel( jj+1 );
}
}
break;
case WORKSHEET_DATAITEM::WS_SEGMENT:
pensize = wsItem->GetPenSizeUi();
if( pensize == 0 )
pensize = m_penSize;
for( int jj = 0; jj < wsItem->m_RepeatCount; jj++ )
{
if( ! wsItem->IsInsidePage( jj ) )
break;
continue;
Append( new WS_DRAW_ITEM_LINE( wsItem->GetStartPosUi( jj ),
wsItem->GetEndPosUi( jj ),
pensize, aLineColor ) );
......@@ -319,8 +392,6 @@ void WS_DRAW_ITEM_LIST::BuildWorkSheetGraphicList(
break;
case WORKSHEET_DATAITEM::WS_RECT:
pensize = wsItem->GetPenSizeUi();
if( pensize == 0 )
pensize = m_penSize;
......@@ -334,6 +405,34 @@ void WS_DRAW_ITEM_LIST::BuildWorkSheetGraphicList(
pensize, aLineColor ) );
}
break;
case WORKSHEET_DATAITEM::WS_POLYPOLYGON:
{
WORKSHEET_DATAITEM_POLYPOLYGON * wspoly =
(WORKSHEET_DATAITEM_POLYPOLYGON*) wsItem;
for( int jj = 0; jj < wsItem->m_RepeatCount; jj++ )
{
if( ! wsItem->IsInsidePage( jj ) )
continue;
for( int kk = 0; kk < wspoly->GetPolyCount(); kk++ )
{
const bool fill = true;
WS_DRAW_ITEM_POLYGON* poly = new WS_DRAW_ITEM_POLYGON( fill,
pensize, aLineColor );
Append( poly );
// Create polygon outline
unsigned ist = wspoly->GetPolyIndexStart( kk );
unsigned iend = wspoly->GetPolyIndexEnd( kk );
while( ist <= iend )
poly->m_Corners.push_back(
wspoly->GetCornerPositionUi( ist++, jj ) );
}
}
}
break;
}
}
}
......@@ -52,13 +52,20 @@ public:
// Work sheet structure type definitions.
// Basic items are:
// * segment and rect (defined by 2 points)
// * text (defined by a coordinate), the text and its justifications
// * poly polygon defined by a coordinate, and a set of list of corners
// ( because we use it for logos, there are more than one polygon
// in this description
class WORKSHEET_DATAITEM
{
public:
enum WS_ItemType {
WS_TEXT,
WS_SEGMENT,
WS_RECT
WS_RECT,
WS_POLYPOLYGON
};
WS_ItemType m_Type;
POINT_COORD m_Pos;
......@@ -87,6 +94,8 @@ public:
m_LineWidth = 0.0;
}
virtual ~WORKSHEET_DATAITEM() {}
void SetStart( double aPosx, double aPosy, enum corner_anchor aAnchor = RB_CORNER )
{
m_Pos.m_Pos.x = aPosx;
......@@ -105,8 +114,92 @@ public:
const wxPoint GetEndPosUi( int ii = 0 ) const;
const DPOINT GetStartPos( int ii = 0 ) const;
const DPOINT GetEndPos( int ii = 0 ) const;
bool IsInsidePage( int ii ) const;
int GetPenSizeUi() {return KiROUND( m_LineWidth * m_WSunits2Iu ); }
/**
* @return true if the item is inside the rectangle defined by the
* 4 corners, false otherwise.
*/
virtual bool IsInsidePage( int ii ) const;
};
class WORKSHEET_DATAITEM_POLYPOLYGON : public WORKSHEET_DATAITEM
{
public:
double m_Orient; // Orientation in degrees
std::vector<DPOINT> m_Corners; // corner list
private:
std::vector<unsigned> m_polyIndexEnd; // index of the last point of each polygon
DPOINT m_minCoord; // min coord of corners, relative to m_Pos
DPOINT m_maxCoord; // max coord of corners, relative to m_Pos
public:
WORKSHEET_DATAITEM_POLYPOLYGON( );
/**
* add a corner in corner list
* @param aCorner: the item to append
*/
void AppendCorner( const DPOINT& aCorner )
{
m_Corners.push_back( aCorner );
}
/**
* Closes the current contour, by storing the index of the last corner
* of the current polygon in m_polyIndexEnd.
*/
void CloseContour()
{
m_polyIndexEnd.push_back( m_Corners.size() -1 );
}
/**
* @return the count of contours in the poly polygon
*/
int GetPolyCount() const { return (int) m_polyIndexEnd.size(); }
/**
* @return the index of the first corner of the contour aCountour
* @param aContour = the index of the contour
*/
unsigned GetPolyIndexStart( unsigned aContour) const
{
if( aContour == 0 )
return 0;
else
return m_polyIndexEnd[aContour-1] + 1;
}
/**
* @return the index of the last corner of the contour aCountour
* @param aContour = the index of the contour
*/
unsigned GetPolyIndexEnd( unsigned aContour) const
{
return m_polyIndexEnd[aContour];
}
/**
* @return the coordinate (in mm) of the corner aIdx,
* for the repeated item aRepeat
*/
const DPOINT GetCornerPosition( unsigned aIdx, int aRepeat = 0 ) const;
/**
* @return the coordinate (in draw/plot units) of the corner aIdx,
* for the repeated item aRepeat
*/
const wxPoint GetCornerPositionUi( unsigned aIdx, int aRepeat = 0 ) const;
/**
* calculate the bounding box of the set polygons
*/
void SetBoundingBox();
bool IsInsidePage( int ii ) const;
};
class WORKSHEET_DATAITEM_TEXT : public WORKSHEET_DATAITEM
......@@ -233,6 +326,7 @@ class WS_DRAW_ITEM_POLYGON : public WS_DRAW_ITEM_BASE
public:
std::vector <wxPoint> m_Corners;
public:
WS_DRAW_ITEM_POLYGON( bool aFill, int aPenWidth, EDA_COLOR_T aColor ) :
WS_DRAW_ITEM_BASE( wsg_poly, aColor )
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment