47void renderShapes( PLOTTER& aPlotter,
const std::vector<SCENE_SHAPE>& aShapes )
53 if( !s.polygons.empty() )
84 explicit PLOTTER_GEOMETRY_SINK( PLOTTER& aPlotter ) : m_plotter( aPlotter ) {}
86 void FillPolygon(
const DOCUMENT_POLYGON& aPoly )
override
88 if( aPoly.outline.size() < 3 )
91 m_plotter.SetColor( aPoly.color );
93 std::vector<VECTOR2I> pts( aPoly.outline.begin(), aPoly.outline.end() );
98 void StrokePolygon(
const DOCUMENT_POLYGON& )
override {}
100 void DrawSegment(
const DOCUMENT_SEGMENT& aSegment )
override
102 m_plotter.SetColor( aSegment.color );
103 m_plotter.ThickSegment( aSegment.start, aSegment.end,
EffectivePlotWidth( aSegment.width ),
107 void DrawCircle(
const DOCUMENT_CIRCLE& aCircle )
override
109 m_plotter.SetColor( aCircle.color );
110 m_plotter.Circle( aCircle.center, aCircle.radius * 2,
120void renderDocumentGeometry( PLOTTER& aPlotter,
const DOCUMENT_GEOMETRY& aGeometry )
122 PLOTTER_GEOMETRY_SINK sink( aPlotter );
135 double plotScale = 0.0;
137 double iuPerDecimil = 0.0;
141PIXEL_VIEWPORT computeViewport(
const BOX2I& aBBox,
const EDA_IU_SCALE& aIuScale,
int aDpi,
142 int aRequestedW,
int aRequestedH )
147 constexpr double MARGIN = 0.05;
149 BOX2I padded = aBBox;
150 int padX =
static_cast<int>( aBBox.
GetWidth() * MARGIN );
151 int padY =
static_cast<int>( aBBox.
GetHeight() * MARGIN );
152 padded.
Inflate( std::max( padX, 1 ), std::max( padY, 1 ) );
165 int outW = aRequestedW;
166 int outH = aRequestedH;
168 if( outW <= 0 && outH <= 0 )
170 constexpr int TARGET_PX = 1024;
171 double aspect = widthMM / std::max( heightMM, 0.001 );
176 outH =
static_cast<int>( TARGET_PX / aspect );
181 outW =
static_cast<int>( TARGET_PX * aspect );
186 outW =
static_cast<int>( outH * widthMM / std::max( heightMM, 0.001 ) );
190 outH =
static_cast<int>( outW * heightMM / std::max( widthMM, 0.001 ) );
193 vp.pixelWidth = std::max( outW, 1 );
194 vp.pixelHeight = std::max( outH, 1 );
224 static const unsigned char EMPTY_PNG[] = {
225 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A,
226 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52,
227 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
228 0x08, 0x06, 0x00, 0x00, 0x00, 0x1F, 0x15, 0xC4,
229 0x89, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x44, 0x41,
230 0x54, 0x78, 0x9C, 0x63, 0x00, 0x01, 0x00, 0x00,
231 0x05, 0x00, 0x01, 0x0D, 0x0A, 0x2D, 0xB4, 0x00,
232 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE,
236 wxFile out( aOutputPath, wxFile::write );
238 if( !out.IsOpened() )
241 return out.Write( EMPTY_PNG,
sizeof( EMPTY_PNG ) ) ==
sizeof( EMPTY_PNG );
247 static const char EMPTY_SVG[] =
248 "<?xml version=\"1.0\" standalone=\"no\"?>\n"
249 "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1\" height=\"1\"/>\n";
251 wxFile out( aOutputPath, wxFile::write );
253 if( !out.IsOpened() )
256 return out.Write( EMPTY_SVG,
sizeof( EMPTY_SVG ) - 1 )
257 ==
sizeof( EMPTY_SVG ) - 1;
286 plotter.
SetViewport( vp.offsetIU, vp.iuPerDecimil, vp.plotScale,
false );
288 if( !plotter.
OpenFile( aOutputPath ) )
291 if( !plotter.
StartPlot( wxEmptyString ) )
298 renderShapes( plotter,
ShapesFor( scene, cat ) );
319 plotter.
SetViewport( vp.offsetIU, vp.iuPerDecimil, vp.plotScale,
false );
321 if( !plotter.
OpenFile( aOutputPath ) )
324 if( !plotter.
StartPlot( wxEmptyString ) )
331 renderShapes( plotter,
ShapesFor( scene, cat ) );
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
constexpr size_type GetWidth() const
constexpr size_type GetHeight() const
constexpr const Vec & GetOrigin() const
virtual bool OpenFile(const wxString &aFullFilename)
Open or create the plot file aFullFilename.
virtual void Rect(const VECTOR2I &p1, const VECTOR2I &p2, FILL_T fill, int width, int aCornerRadius=0)=0
virtual void SetColorMode(bool aColorMode)
Plot in B/W or color.
virtual void PlotPoly(const std::vector< VECTOR2I > &aCornerList, FILL_T aFill, int aWidth, void *aData)=0
Draw a polygon ( filled or not ).
virtual void SetColor(const COLOR4D &color)=0
PNG rasterization plotter using Cairo graphics library.
void SetPixelSize(int aWidth, int aHeight)
Set the output image dimensions in pixels.
void SetBackgroundColor(const COLOR4D &aColor)
Set the background color for the image.
void SetResolution(int aDPI)
Set the output resolution in dots per inch.
virtual bool EndPlot() override
void SetAntialias(bool aEnable)
Enable or disable anti-aliasing.
virtual bool OpenFile(const wxString &aFullFilename) override
Open or create the plot file aFullFilename.
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
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int OutlineCount() const
Return the number of outlines in the set.
void Fracture(bool aSimplify=true)
Convert a set of polygons with holes to a single outline with "slits"/"fractures" connecting the oute...
virtual bool StartPlot(const wxString &aPageNumber) override
Create SVG file header.
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 EndPlot() override
@ FILLED_SHAPE
Fill with object color.
static bool writeEmptySvg(const wxString &aOutputPath)
constexpr int EffectivePlotWidth(int aWidth)
Return aWidth if positive, otherwise PLOT_HAIRLINE_IU.
const EDA_IU_SCALE & IuScaleForDocKind(DOC_KIND aKind)
Internal-unit scale a document kind's coordinates are expressed in.
bool RenderSceneToSvg(const DIFF_SCENE &aScene, const wxString &aOutputPath, const PLOTTER_RENDER_OPTIONS &aOptions)
Render a DIFF_SCENE to an SVG file.
bool RenderSceneToPng(const DIFF_SCENE &aScene, const wxString &aOutputPath, const PLOTTER_RENDER_OPTIONS &aOptions)
Render a DIFF_SCENE to a PNG file.
void IterateDocumentGeometry(const DOCUMENT_GEOMETRY &aGeometry, GEOMETRY_SINK &aSink)
Walk a DOCUMENT_GEOMETRY in the canonical render order shared by the GAL and plotter renderers: every...
static bool writeEmptyPng(const wxString &aOutputPath)
Write a tiny placeholder PNG (single empty pixel) so a "no differences" diff still produces a valid o...
void ExpandBBoxToGeometry(DIFF_SCENE &aScene)
Grow the scene's documentBBox to also include the extent of any background geometry.
CATEGORY
Visual category each ITEM_CHANGE belongs to in the scene.
const std::vector< SCENE_SHAPE > & ShapesFor(const DIFF_SCENE &aScene, CATEGORY aCategory)
Read-only access to a DIFF_SCENE's shape list for a given category.
constexpr std::array< CATEGORY, 4 > PAINT_ORDER
Paint order.
SHAPE_POLY_SET PolySetFromPolygonList(const SCENE_SHAPE::PolygonList &aPolygons)
Build a SHAPE_POLY_SET from a SCENE_SHAPE::PolygonList.
void DrawSegment(const ROUND_SEGMENT_2D &aSegment, unsigned int aNrSidesPerCircle)
Draw a thick line segment with rounded ends.
Plotting engines similar to ps (PostScript, Gerber, svg)
KIGFX::COLOR4D background
DOCUMENT_GEOMETRY referenceGeometry
Background geometry from the two source documents.
DOCUMENT_GEOMETRY comparisonGeometry
DOC_KIND docKind
Source document type.
Aggregate of background geometry extracted from one source document.
Sink for the shared DOCUMENT_GEOMETRY walk.
Options controlling the headless PNG/SVG renderer.
Shared rendering model consumed by both the GAL renderer (interactive widget) and the plotter rendere...
VECTOR2< int32_t > VECTOR2I