75 constexpr int MAX_PNG_DIMENSION = 32767;
94 if( cairo_surface_status(
m_surface ) != CAIRO_STATUS_SUCCESS )
103 if( cairo_status(
m_context ) != CAIRO_STATUS_SUCCESS )
121 cairo_set_line_cap(
m_context, CAIRO_LINE_CAP_ROUND );
122 cairo_set_line_join(
m_context, CAIRO_LINE_JOIN_ROUND );
158 cairo_status_t status = cairo_surface_write_to_png(
m_surface, aPath.ToUTF8().data() );
160 return status == CAIRO_STATUS_SUCCESS;
179 cairo_set_line_width(
m_context, deviceWidth > 0 ? deviceWidth : 1.0 );
194 effective.
r = 1.0 - effective.
r;
195 effective.
g = 1.0 - effective.
g;
196 effective.
b = 1.0 - effective.
b;
206 effective =
COLOR4D( k, k, k, 1.0 );
215 cairo_set_source_rgba(
m_context, effective.
r, effective.
g, effective.
b, effective.
a );
222 cairo_set_operator(
m_context, aClear ? CAIRO_OPERATOR_CLEAR : CAIRO_OPERATOR_OVER );
233 cairo_set_dash(
m_context,
nullptr, 0, 0 );
238 double base = std::max( 1.0,
userToDeviceSize(
static_cast<double>( aLineWidth ) ) );
245 dash[0] = 4.0 * base;
246 dash[1] = 2.0 * base;
251 dash[0] = 1.0 * base;
252 dash[1] = 2.0 * base;
257 dash[0] = 4.0 * base;
258 dash[1] = 2.0 * base;
259 dash[2] = 1.0 * base;
260 dash[3] = 2.0 * base;
265 dash[0] = 4.0 * base;
266 dash[1] = 2.0 * base;
267 dash[2] = 1.0 * base;
268 dash[3] = 2.0 * base;
269 dash[4] = 1.0 * base;
270 dash[5] = 2.0 * base;
275 cairo_set_dash(
m_context,
nullptr, 0, 0 );
279 cairo_set_dash(
m_context, dash, num_dashes, 0 );
300 if( aCornerRadius > 0 )
313 double x = std::min( start.
x,
end.x );
314 double y = std::min( start.
y,
end.y );
351 FILL_T aFill,
int aWidth )
359 double startRad = aStartAngle.
AsRadians();
360 double endRad = ( aStartAngle + aAngle ).AsRadians();
419 if( !
m_context || aCornerList.size() < 2 )
425 for(
size_t i = 1; i < aCornerList.size(); i++ )
449 int imgW = aImage.GetWidth();
450 int imgH = aImage.GetHeight();
452 if( imgW == 0 || imgH == 0 )
456 cairo_surface_t* imgSurface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, imgW, imgH );
458 if( cairo_surface_status( imgSurface ) != CAIRO_STATUS_SUCCESS )
460 cairo_surface_destroy( imgSurface );
464 const unsigned char* srcData = aImage.GetData();
465 const unsigned char* alphaData = aImage.HasAlpha() ? aImage.GetAlpha() :
nullptr;
466 unsigned char* dstBytes = cairo_image_surface_get_data( imgSurface );
467 int dstStride = cairo_image_surface_get_stride( imgSurface );
469 for(
int y = 0; y < imgH; y++ )
471 const unsigned char* srcRow = srcData + y * imgW * 3;
472 const unsigned char* alphaRow = alphaData ? alphaData + y * imgW :
nullptr;
473 uint32_t* dstRow =
reinterpret_cast<uint32_t*
>( dstBytes + y * dstStride );
477 for(
int x = 0; x < imgW; x++ )
479 uint32_t r = srcRow[x * 3 + 0];
480 uint32_t g = srcRow[x * 3 + 1];
481 uint32_t b = srcRow[x * 3 + 2];
482 dstRow[x] = ( 0xFFu << 24 ) | ( r << 16 ) | ( g << 8 ) | b;
487 for(
int x = 0; x < imgW; x++ )
489 uint32_t r = srcRow[x * 3 + 0];
490 uint32_t g = srcRow[x * 3 + 1];
491 uint32_t b = srcRow[x * 3 + 2];
492 uint32_t a = alphaRow[x];
496 r = ( r * a + 127 ) / 255;
497 g = ( g * a + 127 ) / 255;
498 b = ( b * a + 127 ) / 255;
501 dstRow[x] = ( a << 24 ) | ( r << 16 ) | ( g << 8 ) | b;
506 cairo_surface_mark_dirty( imgSurface );
509 double drawW =
userToDeviceSize(
static_cast<double>( imgW ) * aScaleFactor );
510 double drawH =
userToDeviceSize(
static_cast<double>( imgH ) * aScaleFactor );
513 pos.
x -= drawW / 2.0;
514 pos.
y -= drawH / 2.0;
518 cairo_scale(
m_context, drawW / imgW, drawH / imgH );
519 cairo_set_source_surface(
m_context, imgSurface, 0, 0 );
523 cairo_surface_destroy( imgSurface );
537 int width = std::min( aSize.
x, aSize.
y );
538 int len = std::max( aSize.
x, aSize.
y ) - width;
548 if( aSize.
x > aSize.
y )
571 std::vector<VECTOR2I> corners;
573 int dx = aSize.
x / 2;
574 int dy = aSize.
y / 2;
576 corners.push_back(
VECTOR2I( -dx, -dy ) );
577 corners.push_back(
VECTOR2I( -dx, dy ) );
578 corners.push_back(
VECTOR2I( dx, dy ) );
579 corners.push_back(
VECTOR2I( dx, -dy ) );
601 std::vector<VECTOR2I> corners;
604 corners.push_back( poly.
CPoint( i ) );
620 std::vector<VECTOR2I> corners;
622 for(
int j = 0; j < outline.
PointCount(); j++ )
623 corners.push_back( outline.
CPoint( j ) );
633 std::vector<VECTOR2I> corners;
635 for(
int i = 0; i < 4; i++ )
640 corners.push_back( corner );
650 std::vector<VECTOR2I> corners;
651 double radius = aDiameter / 2.0;
654 for(
int i = 0; i < aCornerCount; i++ )
659 corners.push_back( corner );
705 cairo_rectangle(
m_context, aX, aY, aWidth, aHeight );
715 cairo_rectangle(
m_context, aX, aY, aWidth, aHeight );
constexpr BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
static const COLOR4D WHITE
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
A color representation with 4 components: red, green, blue, alpha.
static const int USE_DEFAULT_LINE_WIDTH
int GetPlotterArcHighDef() const
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
virtual void ThickSegment(const VECTOR2I &start, const VECTOR2I &end, int width, void *aData)
virtual void PlotPoly(const std::vector< VECTOR2I > &aCornerList, FILL_T aFill, int aWidth, void *aData)=0
Draw a polygon ( filled or not ).
RENDER_SETTINGS * m_renderSettings
virtual void SetCurrentLineWidth(int aWidth, void *aData=nullptr) override
Set the line width for the next drawing.
void fillCircle(double aCx, double aCy, double aRadius)
virtual void FlashPadRect(const VECTOR2I &aPadPos, const VECTOR2I &aSize, const EDA_ANGLE &aPadOrient, void *aData) override
cairo_surface_t * m_surface
virtual void PenTo(const VECTOR2I &aPos, char aPlume) override
Moveto/lineto primitive, moves the 'pen' to the specified direction.
virtual void FlashRegularPolygon(const VECTOR2I &aShapePos, int aDiameter, int aCornerCount, const EDA_ANGLE &aOrient, void *aData) override
Flash a regular polygon.
virtual void SetDash(int aLineWidth, LINE_STYLE aLineStyle) override
virtual void Circle(const VECTOR2I &aCenter, int aDiameter, FILL_T aFill, int aWidth) override
virtual void Rect(const VECTOR2I &p1, const VECTOR2I &p2, FILL_T aFill, int aWidth, int aCornerRadius=0) override
virtual void Arc(const VECTOR2D &aCenter, const EDA_ANGLE &aStartAngle, const EDA_ANGLE &aAngle, double aRadius, FILL_T aFill, int aWidth) override
bool SaveFile(const wxString &aPath)
Save the rendered image to a PNG file.
virtual void FlashPadOval(const VECTOR2I &aPadPos, const VECTOR2I &aSize, const EDA_ANGLE &aPadOrient, void *aData) override
virtual bool EndPlot() override
COLOR4D m_backgroundColor
virtual VECTOR2D userToDeviceCoordinates(const VECTOR2I &aCoordinate) override
Transform coordinates from user space (IU) to device space (pixels).
void fillRect(double aX, double aY, double aWidth, double aHeight)
void strokeCircle(double aCx, double aCy, double aRadius)
virtual void FlashPadCircle(const VECTOR2I &aPadPos, int aDiameter, void *aData) override
virtual void SetColor(const COLOR4D &aColor) override
virtual void FlashPadTrapez(const VECTOR2I &aPadPos, const VECTOR2I *aCorners, const EDA_ANGLE &aPadOrient, void *aData) override
Flash a trapezoidal pad.
virtual void FlashPadRoundRect(const VECTOR2I &aPadPos, const VECTOR2I &aSize, int aCornerRadius, const EDA_ANGLE &aOrient, void *aData) override
virtual VECTOR2D userToDeviceSize(const VECTOR2I &aSize) override
Transform a size from user space to device space.
virtual void FlashPadCustom(const VECTOR2I &aPadPos, const VECTOR2I &aSize, const EDA_ANGLE &aPadOrient, SHAPE_POLY_SET *aPolygons, void *aData) override
virtual bool OpenFile(const wxString &aFullFilename) override
Open or create the plot file aFullFilename.
void strokeRect(double aX, double aY, double aWidth, double aHeight)
virtual void PlotPoly(const std::vector< VECTOR2I > &aCornerList, FILL_T aFill, int aWidth, void *aData=nullptr) override
Draw a polygon ( filled or not ).
void SetClearCompositing(bool aClear)
Switch the Cairo compositing operator between CLEAR and OVER.
virtual void PlotImage(const wxImage &aImage, const VECTOR2I &aPos, double aScaleFactor) override
Only PostScript plotters can plot bitmaps.
virtual void SetViewport(const VECTOR2I &aOffset, double aIusPerDecimil, double aScale, bool aMirror) override
Set the plot offset and scaling for the current plot.
virtual bool StartPlot(const wxString &aPageNumber) override
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
int PointCount() const
Return the number of points (vertices) in this line chain.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
Represent a set of closed polygons.
int OutlineCount() const
Return the number of outlines in the set.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
const SHAPE_LINE_CHAIN Outline() const
void SetRadius(int aRadius)
void TransformRoundChamferedRectToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aPosition, const VECTOR2I &aSize, const EDA_ANGLE &aRotation, int aCornerRadius, double aChamferRatio, int aChamferCorners, int aInflate, int aError, ERROR_LOC aErrorLoc)
Convert a rectangle with rounded corners and/or chamfered corners to a polygon.
static constexpr EDA_ANGLE ANGLE_360
@ FILLED_SHAPE
Fill with object color.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
constexpr int DEFAULT_PNG_DPI
LINE_STYLE
Dashed line types.
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D