2
* @file title_block_shape.cpp
3
* @brief description of graphic items and texts to build a title block
7
* This program source code file is part of KiCad, a free EDA CAD application.
9
* Copyright (C) 1992-2013 Jean-Pierre Charras <jp.charras at wanadoo.fr>.
10
* Copyright (C) 1992-2013 KiCad Developers, see change_log.txt for contributors.
13
* This program is free software; you can redistribute it and/or
14
* modify it under the terms of the GNU General Public License
15
* as published by the Free Software Foundation; either version 2
16
* of the License, or (at your option) any later version.
18
* This program is distributed in the hope that it will be useful,
19
* but WITHOUT ANY WARRANTY; without even the implied warranty of
20
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21
* GNU General Public License for more details.
23
* You should have received a copy of the GNU General Public License
24
* along with this program; if not, you may find one here:
25
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
26
* or you may search the http://www.gnu.org website for the version 2 license,
27
* or you may write to the Free Software Foundation, Inc.,
28
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
33
* the class WORKSHEET_DATAITEM (and WORKSHEET_DATAITEM_TEXT) defines
34
* a basic shape of a page layout ( frame references and title block )
35
* Basic shapes are line, rect and texts
36
* the WORKSHEET_DATAITEM coordinates units is the mm, and are relative to
37
* one of 4 page corners.
39
* These items cannot be drawn or plot "as this". they should be converted
40
* to a "draw list" (WS_DRAW_ITEM_BASE and derived items)
42
* The list of these items is stored in a WORKSHEET_LAYOUT instance.
44
* When building the draw list:
45
* the WORKSHEET_LAYOUT is used to create a WS_DRAW_ITEM_LIST
46
* coordinates are converted to draw/plot coordinates.
47
* texts are expanded if they contain format symbols.
48
* Items with m_RepeatCount > 1 are created m_RepeatCount times
50
* the WORKSHEET_LAYOUT is created only once.
51
* the WS_DRAW_ITEM_LIST is created each time the page layout is plot/drawn
53
* the WORKSHEET_LAYOUT instance is created from a S expression which
54
* describes the page layout (can be the default page layout or a custom file).
59
#include <worksheet.h>
60
#include <class_title_block.h>
61
#include <worksheet_shape_builder.h>
63
WORKSHEET_DATAITEM_POLYPOLYGON::WORKSHEET_DATAITEM_POLYPOLYGON() :
64
WORKSHEET_DATAITEM( WS_POLYPOLYGON )
69
const DPOINT WORKSHEET_DATAITEM_POLYPOLYGON::GetCornerPosition( unsigned aIdx,
72
DPOINT pos = m_Corners[aIdx];
75
RotatePoint( &pos.x, &pos.y, m_Orient * 10 );
76
pos += GetStartPos( aRepeat );
80
void WORKSHEET_DATAITEM_POLYPOLYGON::SetBoundingBox()
82
if( m_Corners.size() == 0 )
84
m_minCoord.x = m_maxCoord.x = 0.0;
85
m_minCoord.y = m_maxCoord.y = 0.0;
91
RotatePoint( &pos.x, &pos.y, m_Orient * 10 );
92
m_minCoord = m_maxCoord = pos;
94
for( unsigned ii = 1; ii < m_Corners.size(); ii++ )
97
RotatePoint( &pos.x, &pos.y, m_Orient * 10 );
99
if( m_minCoord.x > pos.x )
100
m_minCoord.x = pos.x;
102
if( m_minCoord.y > pos.y )
103
m_minCoord.y = pos.y;
105
if( m_maxCoord.x < pos.x )
106
m_maxCoord.x = pos.x;
108
if( m_maxCoord.y < pos.y )
109
m_maxCoord.y = pos.y;
113
bool WORKSHEET_DATAITEM_POLYPOLYGON::IsInsidePage( int ii ) const
115
DPOINT pos = GetStartPos( ii );
116
pos += m_minCoord; // left top pos of bounding box
118
if( m_LT_Corner.x > pos.x || m_LT_Corner.y > pos.y )
121
pos = GetStartPos( ii );
122
pos += m_maxCoord; // rignt bottom pos of bounding box
124
if( m_RB_Corner.x < pos.x || m_RB_Corner.y < pos.y )
130
const wxPoint WORKSHEET_DATAITEM_POLYPOLYGON::GetCornerPositionUi( unsigned aIdx,
133
DPOINT pos = GetCornerPosition( aIdx, aRepeat );
134
pos = pos * m_WSunits2Iu;
135
return wxPoint( int(pos.x), int(pos.y) );
138
WORKSHEET_DATAITEM_TEXT::WORKSHEET_DATAITEM_TEXT( const wxChar* aTextBase ) :
139
WORKSHEET_DATAITEM( WS_TEXT )
141
m_TextBase = aTextBase;
142
m_IncrementLabel = 1;
143
m_Hjustify = GR_TEXT_HJUSTIFY_LEFT;
144
m_Vjustify = GR_TEXT_VJUSTIFY_CENTER;
146
m_TextSize.x = m_TextSize.y = TB_DEFAULT_TEXTSIZE;
149
void WORKSHEET_DATAITEM_TEXT::TransfertSetupToGraphicText( WS_DRAW_ITEM_TEXT* aGText )
151
aGText->SetHorizJustify( m_Hjustify ) ;
152
aGText->SetVertJustify( m_Vjustify );
153
aGText->SetOrientation( m_Orient * 10 ); // graphic text orient unit = 0.1 degree
156
void WORKSHEET_DATAITEM_TEXT::IncrementLabel( int aIncr )
158
wxChar lbchar = m_TextBase[0];
159
if( lbchar >= '0' && lbchar <= '9' )
160
// A number is expected:
161
m_FullText.Printf( wxT("%d"), aIncr + lbchar - '0' );
163
m_FullText.Printf( wxT("%c"), aIncr + lbchar );
166
void WORKSHEET_DATAITEM_TEXT::SetConstrainedTextSize()
168
m_ConstrainedTextSize = m_TextSize;
170
if( m_BoundingBoxSize.x )
172
bool italic = (m_Flags & USE_ITALIC) != 0;
174
int lenMsg = ReturnGraphicTextWidth( m_FullText, m_TextSize.x, italic, linewidth );
175
if( lenMsg > m_BoundingBoxSize.x )
176
m_ConstrainedTextSize.x = m_TextSize.x * m_BoundingBoxSize.x / lenMsg;
179
if( m_BoundingBoxSize.y )
181
if( m_ConstrainedTextSize.y > m_BoundingBoxSize.y )
182
m_ConstrainedTextSize.y = m_BoundingBoxSize.y;
186
const DPOINT WORKSHEET_DATAITEM::GetStartPos( int ii ) const
189
pos.x = m_Pos.m_Pos.x + ( m_IncrementVector.x * ii );
190
pos.y = m_Pos.m_Pos.y + ( m_IncrementVector.y * ii );
192
switch( m_Pos.m_Anchor )
194
case RB_CORNER: // right bottom corner
195
pos = m_RB_Corner - pos;
198
case RT_CORNER: // right top corner
199
pos.x = m_RB_Corner.x - pos.x;
200
pos.y = m_LT_Corner.y + pos.y;
203
case LB_CORNER: // left bottom corner
204
pos.x = m_LT_Corner.x + pos.x;
205
pos.y = m_RB_Corner.y - pos.y;
208
case LT_CORNER: // left top corner
209
pos = m_LT_Corner + pos;
216
const wxPoint WORKSHEET_DATAITEM::GetStartPosUi( int ii ) const
218
DPOINT pos = GetStartPos( ii );
219
pos = pos * m_WSunits2Iu;
220
return wxPoint( int(pos.x), int(pos.y) );
223
const DPOINT WORKSHEET_DATAITEM::GetEndPos( int ii ) const
226
pos.x = m_End.m_Pos.x + ( m_IncrementVector.x * ii );
227
pos.y = m_End.m_Pos.y + ( m_IncrementVector.y * ii );
228
switch( m_End.m_Anchor )
230
case RB_CORNER: // right bottom corner
231
pos = m_RB_Corner - pos;
234
case RT_CORNER: // right top corner
235
pos.x = m_RB_Corner.x - pos.x;
236
pos.y = m_LT_Corner.y + pos.y;
239
case LB_CORNER: // left bottom corner
240
pos.x = m_LT_Corner.x + pos.x;
241
pos.y = m_RB_Corner.y - pos.y;
244
case LT_CORNER: // left top corner
245
pos = m_LT_Corner + pos;
252
const wxPoint WORKSHEET_DATAITEM::GetEndPosUi( int ii ) const
254
DPOINT pos = GetEndPos( ii );
255
pos = pos * m_WSunits2Iu;
256
return wxPoint( int(pos.x), int(pos.y) );
260
bool WORKSHEET_DATAITEM::IsInsidePage( int ii ) const
262
DPOINT pos = GetStartPos( ii );
264
if( m_RB_Corner.x < pos.x || m_LT_Corner.x > pos.x )
267
if( m_RB_Corner.y < pos.y || m_LT_Corner.y > pos.y )
270
pos = GetEndPos( ii );
272
if( m_RB_Corner.x < pos.x || m_LT_Corner.x > pos.x )
275
if( m_RB_Corner.y < pos.y || m_LT_Corner.y > pos.y )
281
double WORKSHEET_DATAITEM::m_WSunits2Iu = 1.0;
282
DPOINT WORKSHEET_DATAITEM::m_RB_Corner;
283
DPOINT WORKSHEET_DATAITEM::m_LT_Corner;
285
WORKSHEET_LAYOUT dataList; // The layout shape
287
void WS_DRAW_ITEM_LIST::BuildWorkSheetGraphicList(
288
const wxString& aPaperFormat,
289
const wxString& aFileName,
290
const wxString& aSheetPathHumanReadable,
291
const TITLE_BLOCK& aTitleBlock,
292
EDA_COLOR_T aLineColor, EDA_COLOR_T aTextColor )
294
#define milsTomm (25.4/1000)
296
m_titleBlock = &aTitleBlock,
297
m_paperFormat = &aPaperFormat,
298
m_fileName = &aFileName,
299
m_sheetFullName = &aSheetPathHumanReadable;
301
// Build the basic layout shape, if the layout list is empty
302
if( dataList.GetCount() == 0 )
303
dataList.SetLayout();
305
WORKSHEET_DATAITEM::m_WSunits2Iu = m_milsToIu / milsTomm;
307
// Left top corner position
309
lt_corner.x = m_LTmargin.x;
310
lt_corner.y = m_LTmargin.y;
311
WORKSHEET_DATAITEM::m_LT_Corner = lt_corner * milsTomm;
313
// Right bottom corner position
315
rb_corner.x = m_pageSize.x - m_RBmargin.x;
316
rb_corner.y = m_pageSize.y - m_RBmargin.y;
317
WORKSHEET_DATAITEM::m_RB_Corner = rb_corner * milsTomm;
319
WS_DRAW_ITEM_TEXT* gtext;
323
for( unsigned ii = 0; ; ii++ )
325
WORKSHEET_DATAITEM* wsItem = dataList.GetItem( ii );
330
pensize = wsItem->GetPenSizeUi();
332
switch( wsItem->m_Type )
334
case WORKSHEET_DATAITEM::WS_TEXT:
336
WORKSHEET_DATAITEM_TEXT * wsText = (WORKSHEET_DATAITEM_TEXT*)wsItem;
337
wsText->m_FullText = BuildFullText( wsText->m_TextBase );
338
if( wsText->m_FullText.IsEmpty() )
346
if( wsText->m_Flags & USE_TEXT_COLOR )
349
wsText->SetConstrainedTextSize();
352
textsize.x = KiROUND( wsText->m_ConstrainedTextSize.x
353
* WORKSHEET_DATAITEM::m_WSunits2Iu );
354
textsize.y = KiROUND( wsText->m_ConstrainedTextSize.y
355
* WORKSHEET_DATAITEM::m_WSunits2Iu );
357
if( wsText->IsBold())
358
pensize = GetPenSizeForBold( std::min( textsize.x, textsize.y ) );
360
for( int jj = 0; jj < wsText->m_RepeatCount; jj++)
362
if( ! wsText->IsInsidePage( jj ) )
365
Append( gtext = new WS_DRAW_ITEM_TEXT( wsText->m_FullText,
366
wsText->GetStartPosUi( jj ),
370
wsText->IsBold() ) );
371
wsText->TransfertSetupToGraphicText( gtext );
373
// Increment label for the next text
374
if( wsText->m_RepeatCount > 1 )
375
wsText->IncrementLabel( jj+1 );
380
case WORKSHEET_DATAITEM::WS_SEGMENT:
384
for( int jj = 0; jj < wsItem->m_RepeatCount; jj++ )
386
if( ! wsItem->IsInsidePage( jj ) )
388
Append( new WS_DRAW_ITEM_LINE( wsItem->GetStartPosUi( jj ),
389
wsItem->GetEndPosUi( jj ),
390
pensize, aLineColor ) );
394
case WORKSHEET_DATAITEM::WS_RECT:
398
for( int jj = 0; jj < wsItem->m_RepeatCount; jj++ )
400
if( ! wsItem->IsInsidePage( jj ) )
403
Append( new WS_DRAW_ITEM_RECT( wsItem->GetStartPosUi( jj ),
404
wsItem->GetEndPosUi( jj ),
405
pensize, aLineColor ) );
409
case WORKSHEET_DATAITEM::WS_POLYPOLYGON:
411
WORKSHEET_DATAITEM_POLYPOLYGON * wspoly =
412
(WORKSHEET_DATAITEM_POLYPOLYGON*) wsItem;
413
for( int jj = 0; jj < wsItem->m_RepeatCount; jj++ )
415
if( ! wsItem->IsInsidePage( jj ) )
418
for( int kk = 0; kk < wspoly->GetPolyCount(); kk++ )
420
const bool fill = true;
421
WS_DRAW_ITEM_POLYGON* poly = new WS_DRAW_ITEM_POLYGON( fill,
422
pensize, aLineColor );
425
// Create polygon outline
426
unsigned ist = wspoly->GetPolyIndexStart( kk );
427
unsigned iend = wspoly->GetPolyIndexEnd( kk );
429
poly->m_Corners.push_back(
430
wspoly->GetCornerPositionUi( ist++, jj ) );