33#include <wx/filename.h>
34#include <wx/mstream.h>
35#include <wx/zstream.h>
57 bool is_ascii7 =
true;
59 for(
size_t ii = 0; ii < aText.Len(); ii++ )
61 if( aText[ii] >= 0x7F )
72 for(
unsigned ii = 0; ii < aText.Len(); ii++ )
74 unsigned int code = aText[ii];
98 for(
size_t ii = 0; ii < aText.Len(); ii++ )
100 unsigned int code = aText[ii];
102 std::snprintf( buffer,
sizeof( buffer ),
"%4.4X", code );
131 double aScale,
bool aMirror )
158 wxASSERT_MSG( aWidth > 0,
"Plotter called to set negative pen width" );
175 r = ( r * a ) + ( 1 - a );
176 g = ( g * a ) + ( 1 - a );
177 b = ( b * a ) + ( 1 - a );
180 fprintf(
m_workFile,
"%g %g %g rg %g %g %g RG\n", r, g, b, r, g, b );
190 case PLOT_DASH_TYPE::DASH:
195 case PLOT_DASH_TYPE::DOT:
200 case PLOT_DASH_TYPE::DASHDOT:
206 case PLOT_DASH_TYPE::DASHDOTDOT:
207 fprintf(
m_workFile,
"[%d %d %d %d %d %d] 0 d\n",
226 fprintf(
m_workFile,
"%g %g %g %g re %c\n", p1_dev.
x, p1_dev.
y,
227 p2_dev.
x - p1_dev.
x, p2_dev.
y - p1_dev.
y, fill == FILL_T::NO_FILL ?
'S' :
'B' );
246 if( aFill == FILL_T::NO_FILL && diametre < width )
248 aFill = FILL_T::FILLED_SHAPE;
254 double magic = radius * 0.551784;
259 "%g %g %g %g %g %g c "
260 "%g %g %g %g %g %g c "
261 "%g %g %g %g %g %g c "
262 "%g %g %g %g %g %g c %c\n",
263 pos_dev.
x - radius, pos_dev.
y,
265 pos_dev.
x - radius, pos_dev.
y + magic,
266 pos_dev.
x - magic, pos_dev.
y + radius,
267 pos_dev.
x, pos_dev.
y + radius,
269 pos_dev.
x + magic, pos_dev.
y + radius,
270 pos_dev.
x + radius, pos_dev.
y + magic,
271 pos_dev.
x + radius, pos_dev.
y,
273 pos_dev.
x + radius, pos_dev.
y - magic,
274 pos_dev.
x + magic, pos_dev.
y - radius,
275 pos_dev.
x, pos_dev.
y - radius,
277 pos_dev.
x - magic, pos_dev.
y - radius,
278 pos_dev.
x - radius, pos_dev.
y - magic,
279 pos_dev.
x - radius, pos_dev.
y,
281 aFill == FILL_T::NO_FILL ?
's' :
'b' );
286 FILL_T aFill,
int aWidth,
int aMaxError )
294 EDA_ANGLE startAngle( aStart - aCenter );
303 if( startAngle > endAngle )
313 fprintf(
m_workFile,
"%g %g m ", pos_dev.
x, pos_dev.
y );
321 fprintf(
m_workFile,
"%g %g l ", pos_dev.
x, pos_dev.
y );
325 fprintf(
m_workFile,
"%g %g l ", pos_dev.
x, pos_dev.
y );
329 if( aFill == FILL_T::NO_FILL )
336 fprintf(
m_workFile,
"%g %g l b\n", pos_dev.
x, pos_dev.
y );
348 Circle( aCenter, aWidth, FILL_T::FILLED_SHAPE, 0 );
362 if( startAngle > endAngle )
364 std::swap( startAngle, endAngle );
365 std::swap( start, end );
371 start.
x = aCenter.
x +
KiROUND( aRadius * (-startAngle).Cos() );
372 start.
y = aCenter.
y +
KiROUND( aRadius * (-startAngle).Sin() );
374 fprintf(
m_workFile,
"%g %g m ", pos_dev.
x, pos_dev.
y );
378 end.
x = aCenter.
x +
KiROUND( aRadius * (-ii).Cos() );
379 end.
y = aCenter.
y +
KiROUND( aRadius * (-ii).Sin() );
381 fprintf(
m_workFile,
"%g %g l ", pos_dev.
x, pos_dev.
y );
384 end.
x = aCenter.
x +
KiROUND( aRadius * (-endAngle).Cos() );
385 end.
y = aCenter.
y +
KiROUND( aRadius * (-endAngle).Sin() );
387 fprintf(
m_workFile,
"%g %g l ", pos_dev.
x, pos_dev.
y );
391 if( aFill == FILL_T::NO_FILL )
398 fprintf(
m_workFile,
"%g %g l b\n", pos_dev.
x, pos_dev.
y );
408 if( aCornerList.size() <= 1 )
416 for(
unsigned ii = 1; ii < aCornerList.size(); ii++ )
423 if( aFill == FILL_T::NO_FILL )
425 else if( aWidth == 0 )
453 pos_dev.
x, pos_dev.
y,
454 ( plume==
'D' ) ?
'l' :
'm' );
465 VECTOR2I pix_size( aImage.GetWidth(), aImage.GetHeight() );
468 VECTOR2D drawsize( aScaleFactor * pix_size.
x, aScaleFactor * pix_size.
y );
471 VECTOR2I start( aPos.
x - drawsize.
x / 2, aPos.
y + drawsize.
y / 2 );
484 fprintf(
m_workFile,
"q %g 0 0 %g %g %g cm\n",
487 dev_start.
x, dev_start.
y );
499 "ID\n",
m_colorMode ?
"/RGB" :
"/G", pix_size.
x, pix_size.
y );
503 for(
int y = 0; y < pix_size.
y; y++ )
505 for(
int x = 0; x < pix_size.
x; x++ )
507 unsigned char r = aImage.GetRed( x, y ) & 0xFF;
508 unsigned char g = aImage.GetGreen( x, y ) & 0xFF;
509 unsigned char b = aImage.GetBlue( x, y ) & 0xFF;
512 if( aImage.HasAlpha() )
514 unsigned char alpha = aImage.GetAlpha( x, y ) & 0xFF;
518 float d = alpha / 255.0;
520 r = std::min(
KiROUND( r * d + ( a * 0xFF ) ), 0xFF );
521 g = std::min(
KiROUND( g * d + ( a * 0xFF ) ), 0xFF );
522 b = std::min(
KiROUND( b * d + ( a * 0xFF ) ), 0xFF );
526 if( aImage.HasMask() )
528 if( r == aImage.GetMaskRed() && g == aImage.GetMaskGreen()
529 && b == aImage.GetMaskBlue() )
547 unsigned char grey =
KiROUND( r * 0.2126 + g * 0.7152 + b * 0.0722 );
599 "<< /Length %d 0 R >>\n"
600 "stream\n", handle + 1 );
605 "<< /Length %d 0 R /Filter /FlateDecode >>\n"
606 "stream\n", handle + 1 );
631 unsigned char *inbuf =
new unsigned char[stream_len];
633 int rc = fread( inbuf, 1, stream_len,
m_workFile );
634 wxASSERT( rc == stream_len );
646 out_count = stream_len;
652 wxMemoryOutputStream memos(
nullptr, std::max( 2000l, stream_len ) ) ;
662 wxZlibOutputStream zos( memos, wxZ_BEST_COMPRESSION, wxZLIB_ZLIB );
664 zos.Write( inbuf, stream_len );
667 wxStreamBuffer* sb = memos.GetOutputStreamBuffer();
669 out_count = sb->Tell();
670 fwrite( sb->GetBufferStart(), 1, out_count,
m_outputFile );
705 "%g 0 0 %g 0 0 cm 1 J 1 j 0 0 0 rg 0 0 0 RG %g w\n",
721 const double PTsPERMIL = 0.072;
724 auto iuToPdfUserSpace =
729 retval.
y = psPaperSize.
y - retval.
y;
734 std::vector<int> hyperlinkHandles;
740 const BOX2I& box = linkPair.first;
741 const wxString& url = linkPair.second;
748 userSpaceBox.
SetEnd( topRight );
757 const BOX2I& box = menuPair.first;
758 const std::vector<wxString>& urls = menuPair.second;
765 userSpaceBox.
SetEnd( topRight );
772 int hyperLinkArrayHandle = -1;
775 if( hyperlinkHandles.size() > 0 )
782 for(
int handle : hyperlinkHandles )
805 " /ProcSet [/PDF /Text /ImageC /ImageB]\n"
807 "/MediaBox [0 0 %g %g]\n"
808 "/Contents %d 0 R\n",
815 if( hyperlinkHandles.size() > 0 )
816 fprintf(
m_outputFile,
"/Annots %d 0 R", hyperLinkArrayHandle );
825 wxString pageOutlineName = wxEmptyString;
829 pageOutlineName = wxString::Format(
_(
"Page %s" ),
m_pageNumbers.back() );
847 for(
const std::pair<BOX2I, wxString>& bookmarkPair : groupVector )
849 const BOX2I& box = bookmarkPair.first;
850 const wxString& ref = bookmarkPair.second;
855 actionHandle =
emitGoToAction( pageHandle, bottomLeft, topRight );
860 std::sort( groupOutlineNode->
children.begin(), groupOutlineNode->
children.end(),
863 return a->title < b->title;
876 return StartPlot( aPageNumber, wxEmptyString );
923 "<</S /GoTo /D [%d 0 R /FitR %d %d %d %d]\n"
925 aPageHandle, aBottomLeft.
x, aBottomLeft.
y, aTopRight.
x, aTopRight.
y );
939 "<</S /GoTo /D [%d 0 R /Fit]\n"
956 for( std::vector<OUTLINE_NODE*>::iterator it = node->
children.begin();
959 if( it >= node->
children.end() - 1 )
965 nextHandle = ( *( it + 1 ) )->entryHandle;
970 prevHandle = ( *it )->entryHandle;
974 if( parentHandle != -1 )
1013 const wxString& aTitle )
1034 "<< /Type /Outlines\n"
1068 {
"/Helvetica",
"/KicadFont", 0 },
1069 {
"/Helvetica-Oblique",
"/KicadFontI", 0 },
1070 {
"/Helvetica-Bold",
"/KicadFontB", 0 },
1071 {
"/Helvetica-BoldOblique",
"/KicadFontBI", 0 }
1077 for(
int i = 0; i < 4; i++ )
1083 " /Subtype /Type1\n"
1086 " /Encoding /WinAnsiEncoding\n"
1088 fontdefs[i].psname );
1096 for(
int i = 0; i < 4; i++ )
1099 fontdefs[i].rsname, fontdefs[i].font_handle );
1107 const BOX2D& box = linkPair.first;
1108 const wxString& url = linkPair.second;
1115 " /Rect [%g %g %g %g]\n"
1116 " /Border [16 16 0]\n",
1119 wxString pageNumber;
1120 bool pageFound =
false;
1129 " /Dest [%d 0 R /FitB]\n"
1142 " /A << /Type /Action /S /NOP >>\n"
1149 " /A << /Type /Action /S /URI /URI %s >>\n"
1159 const BOX2D& box = menuPair.first;
1160 const std::vector<wxString>& urls = menuPair.second;
1161 wxString js = wxT(
"var aParams = [ " );
1163 for(
const wxString& url : urls )
1165 if( url.StartsWith(
"!" ) )
1167 wxString
property = url.AfterFirst(
'!' );
1169 if( property.Find(
"http:" ) >= 0 )
1171 wxString href =
property.substr( property.Find(
"http:" ) );
1173 js += wxString::Format( wxT(
"{ cName: '%s', cReturn: '%s' }, " ),
1177 else if( property.Find(
"https:" ) >= 0 )
1179 wxString href =
property.substr( property.Find(
"https:" ) );
1181 js += wxString::Format( wxT(
"{ cName: '%s', cReturn: '%s' }, " ),
1187 js += wxString::Format( wxT(
"{ cName: '%s', cReturn: null }, " ),
1191 else if( url.StartsWith(
"#" ) )
1193 wxString pageNumber = url.AfterFirst(
'#' );
1199 wxString menuText = wxString::Format(
_(
"Show Page %s" ), pageNumber );
1201 js += wxString::Format( wxT(
"{ cName: '%s', cReturn: '#%d' }, " ),
1203 static_cast<int>( ii ) );
1208 else if( url.StartsWith(
"http:" ) || url.StartsWith(
"https:" ) )
1210 wxString menuText = wxString::Format(
_(
"Open %s" ), url );
1212 js += wxString::Format( wxT(
"{ cName: '%s', cReturn: '%s' }, " ),
1220 js += wxT(
"var cChoice = app.popUpMenuEx.apply\\( app, aParams \\); " );
1221 js += wxT(
"if\\( cChoice != null && cChoice.substring\\( 0, 1 \\) == '#' \\)"
1222 " this.pageNum = cChoice.slice\\( 1 \\); " );
1223 js += wxT(
"else if\\( cChoice != null && cChoice.substring\\( 0, 4 \\) == 'http' \\)"
1224 " app.launchURL\\( cChoice \\);" );
1231 " /Rect [%g %g %g %g]\n"
1232 " /Border [16 16 0]\n",
1236 " /A << /Type /Action /S /JavaScript /JS (%s) >>\n"
1238 js.ToStdString().c_str() );
1264 time_t ltime = time(
nullptr );
1265 strftime( date_buf, 250,
"D:%Y%m%d%H%M%S", localtime( <ime ) );
1276 "/Producer (KiCad PDF)\n"
1277 "/CreationDate (%s)\n"
1293 if( outlineHandle > 0 )
1300 "/PageMode /UseOutlines\n"
1301 "/Outlines %d 0 R\n"
1302 "/PageLayout /SinglePage\n"
1314 "/PageMode /UseNone\n"
1315 "/PageLayout /SinglePage\n"
1329 "0000000000 65535 f \n", (
long)
m_xrefTable.size() );
1331 for(
unsigned i = 1; i <
m_xrefTable.size(); i++ )
1339 "<< /Size %lu /Root %d 0 R /Info %d 0 R >>\n"
1343 (
unsigned long)
m_xrefTable.size(), catalogHandle, infoDictHandle, xref_start );
1354 const wxString& aText,
1362 bool aMultilineAllowed,
1367 if( aSize.
x == 0 || aSize.
y == 0 )
1375 const char *fontname = aItalic ? ( aBold ?
"/KicadFontBI" :
"/KicadFontI" )
1376 : ( aBold ?
"/KicadFontB" :
"/KicadFont" );
1379 double ctm_a, ctm_b, ctm_c, ctm_d, ctm_e, ctm_f;
1380 double wideningFactor, heightFactor;
1385 aV_justify, aWidth, aItalic, aBold, &wideningFactor, &ctm_a,
1386 &ctm_b, &ctm_c, &ctm_d, &ctm_e, &ctm_f, &heightFactor );
1391 wxStringTokenizer str_tok( aText,
" ", wxTOKEN_RET_DELIMS );
1414 while( str_tok.HasMoreTokens() )
1416 wxString word = str_tok.GetNextToken();
1420 &ctm_b, &ctm_c, &ctm_d, &ctm_e, &ctm_f, &heightFactor );
1429 if( word.Trim(
false ).Trim(
true ).empty() )
1436 fprintf(
m_workFile,
"q %f %f %f %f %g %g cm BT %s %g Tf %d Tr %g Tz ",
1437 ctm_a, ctm_b, ctm_c, ctm_d, ctm_e, ctm_f,
1438 fontname, heightFactor,
render_mode, wideningFactor * 100 );
1441 fprintf(
m_workFile,
"%s Tj ET\n", txt_pdf.c_str() );
1447 PLOTTER::Text( aPos, aColor, aText, aOrient, aSize, aH_justify, aV_justify, aWidth, aItalic,
1448 aBold, aMultilineAllowed, aFont );
1453 const wxString& aText,
1461 if( size.
x == 0 || size.
y == 0 )
1489 const wxString &aGroupName )
1492 m_bookmarksInPage[aGroupName].push_back( std::make_pair( aLocation, aSymbolReference ) );
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
void SetOrigin(const Vec &pos)
const Vec & GetPosition() const
coord_type GetTop() const
coord_type GetRight() const
coord_type GetLeft() const
coord_type GetBottom() const
void SetEnd(coord_type x, coord_type y)
static bool IsGotoPageHref(const wxString &aHref, wxString *aDestination=nullptr)
Check if aHref is a valid internal hyperlink.
FONT is an abstract base class for both outline and stroke fonts.
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false)
VECTOR2I StringBoundaryLimits(const wxString &aText, const VECTOR2I &aSize, int aThickness, bool aBold, bool aItalic) const
Compute the boundary limits of aText (the bounding box of all shapes).
A color representation with 4 components: red, green, blue, alpha.
int GetDefaultPenWidth() const
const VECTOR2I & GetSizeMils() const
std::vector< int > m_pageHandles
Handles to the page objects.
FILE * m_workFile
Temporary file to construct the stream before zipping.
virtual void StartPage(const wxString &aPageNumber, const wxString &aPageName=wxEmptyString)
Start a new page in the PDF document.
virtual void PlotText(const VECTOR2I &aPos, const COLOR4D &aColor, const wxString &aText, const TEXT_ATTRIBUTES &aAttributes, KIFONT::FONT *aFont, void *aData=nullptr) override
virtual void ClosePage()
Close the current page in the PDF document (and emit its compressed stream).
void emitOutlineNode(OUTLINE_NODE *aNode, int aParentHandle, int aNextNode, int aPrevNode)
Emits a outline item object and recurses into any children.
int emitOutline()
Starts emitting the outline object.
virtual bool EndPlot() override
virtual void PlotPoly(const std::vector< VECTOR2I > &aCornerList, FILL_T aFill, int aWidth=USE_DEFAULT_LINE_WIDTH, void *aData=nullptr) override
Polygon plotting for PDF.
virtual void SetCurrentLineWidth(int width, void *aData=nullptr) override
Pen width setting for PDF.
virtual void Text(const VECTOR2I &aPos, const COLOR4D &aColor, const wxString &aText, const EDA_ANGLE &aOrient, const VECTOR2I &aSize, enum GR_TEXT_H_ALIGN_T aH_justify, enum GR_TEXT_V_ALIGN_T aV_justify, int aWidth, bool aItalic, bool aBold, bool aMultilineAllowed=false, KIFONT::FONT *aFont=nullptr, void *aData=nullptr) override
Draw text with the plotter.
int m_streamLengthHandle
Handle to the deferred stream length.
void PlotImage(const wxImage &aImage, const VECTOR2I &aPos, double aScaleFactor) override
PDF images are handles as inline, not XObject streams...
void HyperlinkMenu(const BOX2I &aBox, const std::vector< wxString > &aDestURLs) override
Create a clickable hyperlink menu with a rectangular click area.
virtual bool OpenFile(const wxString &aFullFilename) override
Open or create the plot file aFullFilename.
int m_fontResDictHandle
Font resource dictionary.
virtual void emitSetRGBColor(double r, double g, double b, double a) override
PDF supports colors fully.
virtual void Arc(const VECTOR2I &aCenter, const VECTOR2I &aStart, const VECTOR2I &aEnd, FILL_T aFill, int aWidth, int aMaxError) override
The PDF engine can't directly plot arcs so we use polygonization.
int startPdfStream(int handle=-1)
Starts a PDF stream (for the page).
virtual void Rect(const VECTOR2I &p1, const VECTOR2I &p2, FILL_T fill, int width=USE_DEFAULT_LINE_WIDTH) override
Rectangles in PDF.
std::map< int, std::pair< BOX2D, wxString > > m_hyperlinkHandles
int m_pageTreeHandle
Handle to the root of the page tree object.
int emitGoToAction(int aPageHandle, const VECTOR2I &aBottomLeft, const VECTOR2I &aTopRight)
Emits an action object that instructs a goto coordinates on a page.
void closePdfStream()
Finish the current PDF stream (writes the deferred length, too)
void Bookmark(const BOX2I &aBox, const wxString &aName, const wxString &aGroupName=wxEmptyString) override
Create a bookmark to a symbol.
std::vector< long > m_xrefTable
The PDF xref offset table.
void HyperlinkBox(const BOX2I &aBox, const wxString &aDestinationURL) override
Create a clickable hyperlink with a rectangular click area.
virtual void Circle(const VECTOR2I &pos, int diametre, FILL_T fill, int width=USE_DEFAULT_LINE_WIDTH) override
Circle drawing for PDF.
virtual void PenTo(const VECTOR2I &pos, char plume) override
Moveto/lineto primitive, moves the 'pen' to the specified direction.
std::map< wxString, std::vector< std::pair< BOX2I, wxString > > > m_bookmarksInPage
virtual bool StartPlot(const wxString &aPageNumber) override
The PDF engine supports multiple pages; the first one is opened 'for free' the following are to be cl...
int startPdfObject(int handle=-1)
Open a new PDF object and returns the handle if the parameter is -1.
OUTLINE_NODE * addOutlineNode(OUTLINE_NODE *aParent, int aActionHandle, const wxString &aTitle)
Adds a new outline node entry.
std::string encodeStringForPlotter(const wxString &aUnicode) override
convert a wxString unicode string to a char string compatible with the accepted string PDF format (co...
std::vector< wxString > m_pageNumbers
List of loaded hyperlinks in current page.
virtual void SetDash(int aLineWidth, PLOT_DASH_TYPE aLineStyle) override
PDF supports dashed lines.
int allocPdfObject()
Allocate a new handle in the table of the PDF object.
virtual void SetViewport(const VECTOR2I &aOffset, double aIusPerDecimil, double aScale, bool aMirror) override
PDF can have multiple pages, so SetPageSettings can be called with the outputFile open (but not insid...
std::map< int, std::pair< BOX2D, std::vector< wxString > > > m_hyperlinkMenuHandles
int m_pageStreamHandle
Handle of the page content object.
std::vector< std::pair< BOX2I, wxString > > m_hyperlinksInPage
std::unique_ptr< OUTLINE_NODE > m_outlineRoot
Root outline node.
std::vector< std::pair< BOX2I, std::vector< wxString > > > m_hyperlinkMenusInPage
Handles for all the hyperlink objects that will be deferred.
void closePdfObject()
Close the current PDF object.
int m_totalOutlineNodes
Total number of outline nodes.
double GetDotMarkLenIU(int aLineWidth) const
double GetDashGapLenIU(int aLineWidth) const
static const int USE_DEFAULT_LINE_WIDTH
virtual VECTOR2D userToDeviceCoordinates(const VECTOR2I &aCoordinate)
Modify coordinates according to the orientation, scale factor, and offsets trace.
virtual void Text(const VECTOR2I &aPos, const COLOR4D &aColor, const wxString &aText, const EDA_ANGLE &aOrient, const VECTOR2I &aSize, enum GR_TEXT_H_ALIGN_T aH_justify, enum GR_TEXT_V_ALIGN_T aV_justify, int aPenWidth, bool aItalic, bool aBold, bool aMultilineAllowed, KIFONT::FONT *aFont, void *aData=nullptr)
Draw text with the plotter.
virtual VECTOR2D userToDeviceSize(const VECTOR2I &size)
Modify size according to the plotter scale factors (VECTOR2I version, returns a VECTOR2D).
double m_plotScale
Plot scale - chosen by the user (even implicitly with 'fit in a4')
FILE * m_outputFile
Output file.
static const int DO_NOT_SET_LINE_WIDTH
RENDER_SETTINGS * m_renderSettings
double GetDashMarkLenIU(int aLineWidth) const
virtual void SetColor(const COLOR4D &color) override
The SetColor implementation is split with the subclasses: The PSLIKE computes the rgb values,...
double plotScaleAdjX
Fine user scale adjust ( = 1.0 if no correction)
void computeTextParameters(const VECTOR2I &aPos, const wxString &aText, const EDA_ANGLE &aOrient, const VECTOR2I &aSize, bool aMirror, enum GR_TEXT_H_ALIGN_T aH_justify, enum GR_TEXT_V_ALIGN_T aV_justify, int aWidth, bool aItalic, bool aBold, double *wideningFactor, double *ctm_a, double *ctm_b, double *ctm_c, double *ctm_d, double *ctm_e, double *ctm_f, double *heightFactor)
This is the core for postscript/PDF text alignment.
GR_TEXT_H_ALIGN_T m_Halign
GR_TEXT_V_ALIGN_T m_Valign
static constexpr EDA_ANGLE & ANGLE_360
static constexpr EDA_ANGLE & FULL_CIRCLE
static constexpr EDA_ANGLE & ANGLE_0
int GetArcToSegmentCount(int aRadius, int aErrorMax, const EDA_ANGLE &aArcAngle)
void ignore_unused(const T &)
This file contains miscellaneous commonly used macros and functions.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Plotting engines similar to ps (PostScript, Gerber, svg)
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
PLOT_DASH_TYPE
Dashed line types.
wxString title
Title of outline node.
std::vector< OUTLINE_NODE * > children
Ordered list of children.
int entryHandle
Allocated handle for this outline entry.
OUTLINE_NODE * AddChild(int aActionHandle, const wxString &aTitle, int aEntryHandle)
int actionHandle
Handle to action.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
double EuclideanNorm(const VECTOR2I &vector)
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
VECTOR2< double > VECTOR2D