46 using namespace KIGFX;
88 cairo_surface_destroy( imageSurface );
135 world_rotation = M_PI - world_rotation;
137 return std::fmod( aAngle + world_rotation, 2.0 * M_PI );
144 bool is_360deg_arc = std::abs( aEndAngle - aStartAngle ) >= 2 * M_PI;
145 double startAngle = aStartAngle;
146 double endAngle = aEndAngle;
152 startAngle = M_PI - startAngle;
153 endAngle = M_PI - endAngle;
157 SWAP( startAngle, >, endAngle );
169 aEndAngle = aStartAngle + 2 * M_PI;
179 return sqrt( dx * dx + dy * dy );
185 return floor( x + 0.5 ) + 0.5;
194 return VECTOR2D( floor( v.
x + 0.5 ), floor( v.
y + 0.5 ) );
259 VECTOR2D startEndVector = aEndPoint - aStartPoint;
260 double lineAngle = atan2( startEndVector.
y, startEndVector.
x );
262 double sa = sin( lineAngle + M_PI / 2.0 );
263 double ca = cos( lineAngle + M_PI / 2.0 );
283 startEndVector = center_b - center_a;
284 lineAngle = atan2( startEndVector.
y, startEndVector.
x );
288 double arcStartAngle = lineAngle - M_PI / 2.0;
289 cairo_arc(
m_currentContext, center_b.
x, center_b.
y, radius, arcStartAngle, arcStartAngle + M_PI );
292 arcStartAngle = lineAngle + M_PI / 2.0;
293 cairo_arc(
m_currentContext, center_a.x, center_a.y, radius, arcStartAngle, arcStartAngle + M_PI );
327 double r =
xform( aRadius );
355 double aStartAngle,
double aEndAngle,
double aWidth,
364 DrawArc( aCenterPoint, aRadius, aStartAngle, aEndAngle );
374 double startAngleS = aStartAngle;
375 double endAngleS = aEndAngle;
378 double r =
xform( aRadius );
387 double width =
xform( aWidth / 2.0 );
405 cairo_arc_negative(
m_currentContext, startPointS.
x, startPointS.
y, width, startAngleS,
406 startAngleS + M_PI );
409 cairo_arc(
m_currentContext, endPointS.
x, endPointS.
y, width, endAngleS, endAngleS + M_PI );
455 double aFilterValue )
493 cairo_surface_t*
image = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, w, h );
494 cairo_surface_flush(
image );
496 unsigned char* pix_buffer = cairo_image_surface_get_data(
image );
501 uint32_t mask_color = ( bm_pix_buffer.GetMaskRed() << 16 )
502 + ( bm_pix_buffer.GetMaskGreen() << 8 ) + ( bm_pix_buffer.GetMaskBlue() );
507 for(
int row = 0; row < h; row++ )
509 for(
int col = 0; col < w; col++ )
512 uint32_t pixel = bm_pix_buffer.GetRed( col, row ) << 16;
513 pixel += bm_pix_buffer.GetGreen( col, row ) << 8;
514 pixel += bm_pix_buffer.GetBlue( col, row );
516 if( bm_pix_buffer.HasAlpha() )
517 pixel += bm_pix_buffer.GetAlpha( col, row ) << 24;
518 else if( bm_pix_buffer.HasMask() && pixel == mask_color )
519 pixel += ( wxALPHA_TRANSPARENT << 24 );
521 pixel += ( wxALPHA_OPAQUE << 24 );
524 uint32_t* pix_ptr = (uint32_t*) pix_buffer;
530 cairo_surface_mark_dirty(
image );
657 cairo_matrix_t cairoTransformation, newXform;
659 cairo_matrix_init( &cairoTransformation, aTransformation.
m_data[0][0],
660 aTransformation.
m_data[1][0], aTransformation.
m_data[0][1],
661 aTransformation.
m_data[1][1], aTransformation.
m_data[0][2],
662 aTransformation.
m_data[1][2] );
664 cairo_matrix_multiply( &newXform, &
m_currentXform, &cairoTransformation );
799 for(
auto it =
m_groups[aGroupNumber].begin(); it !=
m_groups[aGroupNumber].end(); ++it )
801 switch( it->m_Command )
813 it->m_Argument.DblArg[2], it->m_Argument.DblArg[3] );
818 it->m_Argument.DblArg[2], it->m_Argument.DblArg[3] );
824 double x = 1.0, y = 1.0;
826 double minWidth = std::min( fabs( x ), fabs( y ) );
828 std::max( it->m_Argument.DblArg[0], minWidth ) );
862 cairo_translate(
m_currentContext, it->m_Argument.DblArg[0], it->m_Argument.DblArg[1] );
866 cairo_scale(
m_currentContext, it->m_Argument.DblArg[0], it->m_Argument.DblArg[1] );
889 for(
auto it =
m_groups[aGroupNumber].begin(); it !=
m_groups[aGroupNumber].end(); ++it )
893 it->m_Argument.DblArg[0] = aNewColor.
r;
894 it->m_Argument.DblArg[1] = aNewColor.
g;
895 it->m_Argument.DblArg[2] = aNewColor.
b;
896 it->m_Argument.DblArg[3] = aNewColor.
a;
914 std::deque<GROUP_ELEMENT>::iterator it, end;
916 for( it =
m_groups[aGroupNumber].begin(), end =
m_groups[aGroupNumber].end(); it != end; ++it )
919 cairo_path_destroy( it->m_CairoPath );
936 cairo_set_operator(
m_currentContext, aSetting ? CAIRO_OPERATOR_CLEAR : CAIRO_OPERATOR_OVER );
980 cairo_surface_destroy( imageSurface );
1066 double sw = std::max( 1.0, aWidth );
1067 double sh = std::max( 1.0, aHeight );
1072 p.
y - std::floor( sh / 2 ) - 0.5, sw, sh );
1164 wxColour
color( cColor.
r * cColor.
a * 255, cColor.
g * cColor.
a * 255, cColor.
b * cColor.
a * 255,
1166 clientDC.SetPen( wxPen(
color ) );
1167 clientDC.DrawLine( p.
x - cursorSize / 2, p.
y, p.
x + cursorSize / 2, p.
y );
1168 clientDC.DrawLine( p.
x, p.
y - cursorSize / 2, p.
x, p.
y + cursorSize / 2 );
1174 wxCHECK( aPointList.size() > 1, );
1177 std::deque<VECTOR2D>::const_iterator it = aPointList.begin();
1185 for( ++it; it != aPointList.end(); ++it )
1199 wxCHECK( aListSize > 1, );
1209 for(
int i = 1; i < aListSize; ++i )
1236 for(
int i = 1; i < numPoints; ++i )
1250 wxASSERT_MSG(
m_groups.size() < std::numeric_limits<unsigned int>::max(),
1251 wxT(
"There are no free slots to store a group" ) );
1261 wxEvtHandler* aMouseListener, wxEvtHandler* aPaintListener,
1262 const wxString& aName ) :
1264 wxWindow( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxEXPAND, aName )
1300 #if defined _WIN32 || defined _WIN64 1304 SetSize( aParent->GetClientSize() );
1344 pixman_image_t* dstImg = pixman_image_create_bits(
1345 wxPlatformInfo::Get().GetEndianness() == wxENDIAN_LITTLE ? PIXMAN_b8g8r8
1348 pixman_image_t* srcImg =
1352 pixman_image_composite( PIXMAN_OP_SRC, srcImg,
nullptr, dstImg, 0, 0, 0, 0, 0, 0,
1356 pixman_image_unref( srcImg );
1357 pixman_image_unref( dstImg );
1360 wxBitmap bmp( img );
1361 wxMemoryDC mdc( bmp );
1362 wxClientDC clientDC(
this );
1393 SetSize( wxSize( aWidth, aHeight ) );
1399 bool s = wxWindow::Show( aShow );
1455 unsigned int currentBuffer =
m_compositor->GetBuffer();
1485 cairo_status_t status = cairo_status(
m_context );
1486 wxASSERT_MSG( status == CAIRO_STATUS_SUCCESS, wxT(
"Cairo context creation error" ) );
1628 float doubleMarker = 2.0f * marker;
1634 drawAxes( worldStartPoint, worldEndPoint );
1645 gridThreshold *= 2.0;
1649 while( std::min( gridScreenSize.
x, gridScreenSize.
y ) <= gridThreshold )
1651 gridScreenSize = gridScreenSize * static_cast<double>(
m_gridTick );
1663 SWAP( gridStartX, >, gridEndX );
1664 SWAP( gridStartY, >, gridEndY );
1680 for(
int j = gridStartY; j <= gridEndY; j++ )
1693 for(
int i = gridStartX; i <= gridEndX; i++ )
1710 for(
int j = gridStartY; j <= gridEndY; j++ )
1714 for(
int i = gridStartX; i <= gridEndX; i++ )
1722 SetLineWidth( ( tickX && tickY ) ? doubleMarker : marker );
double EuclideanNorm(const wxPoint &vector)
Euclidean norm of a 2D vector.
void SetNegativeDrawMode(bool aSetting) override
Set negative draw mode in the renderer.
wxWindow * m_parentWindow
Parent window.
void initSurface()
Prepare Cairo surfaces for drawing.
unsigned char * m_wxOutput
wxImage compatible buffer
void DrawBitmap(const BITMAP_BASE &aBitmap) override
Draw a bitmap image.
std::map< int, GROUP > m_groups
List of graphic groups.
void ResizeScreen(int aWidth, int aHeight) override
Resizes the canvas.
bool m_isFillEnabled
Is filling of graphic objects enabled ?
CAIRO_GAL(GAL_DISPLAY_OPTIONS &aDisplayOptions, wxWindow *aParent, wxEvtHandler *aMouseListener=nullptr, wxEvtHandler *aPaintListener=nullptr, const wxString &aName=wxT("CairoCanvas"))
int OutlineCount() const
Return the number of vertices in a given outline/hole.
void EndGroup() override
End the group.
void ChangeGroupColor(int aGroupNumber, const COLOR4D &aNewColor) override
Change the color used to draw the group.
void EndDrawing() override
End the drawing, needs to be called for every new frame.
void EndDiffLayer() override
Ends rendering of a differential layer.
bool m_isInitialized
Are Cairo image & surface ready to use.
double m_lineWidthInPixels
bool updatedGalDisplayOptions(const GAL_DISPLAY_OPTIONS &aOptions) override
Handle updating display options.
The Cairo implementation of the graphics abstraction layer.
bool m_axesEnabled
Should the axes be drawn.
void ResizeScreen(int aWidth, int aHeight) override
Resizes the canvas.
void deinitSurface()
Destroy Cairo surfaces when are not needed anymore.
void SetIsStroke(bool aIsStrokeEnabled) override
Enable/disable stroked outlines.
double computeMinGridSpacing() const
compute minimum grid spacing from the grid settings
RENDER_TARGET m_currentTarget
Current rendering target.
MATRIX3x3D m_screenWorldMatrix
Screen transformation.
void EnableDepthTest(bool aEnabled=false) override
void ChangeGroupDepth(int aGroupNumber, int aDepth) override
Change the depth (Z-axis position) of the group.
void onPaint(wxPaintEvent &aEvent)
Paint event handler.
std::deque< GROUP_ELEMENT > GROUP
A graphic group type definition.
~CAIRO_GAL()
Return true if the GAL canvas is visible on the screen.
bool IsFlippedX() const
Return true if flip flag for the X axis is set.
void Translate(const VECTOR2D &aTranslation) override
Translate the context.
VECTOR2D ToScreen(const VECTOR2D &aPoint) const
Compute the point position in screen coordinates from given world coordinates.
CAIRO_GAL_BASE(GAL_DISPLAY_OPTIONS &aDisplayOptions)
void setCompositor()
Prepare the compositor.
void storePath()
Store the actual path.
VECTOR2D m_gridSize
The grid size.
unsigned int m_savedBuffer
Handle to buffer to restore after rendering to temp buffer.
GROUP * m_currentGroup
Currently used group.
Type definition for an graphics group element.
static const COLOR4D BLACK
void DeleteGroup(int aGroupNumber) override
Delete the group from the memory.
unsigned int m_tempBuffer
Handle to the temp buffer.
void BeginDrawing() override
Start/end drawing functions, draw calls can be only made in between the calls to BeginDrawing()/EndDr...
unsigned char * m_bitmapBuffer
Storage of the Cairo image.
union KIGFX::CAIRO_GAL_BASE::GROUP_ELEMENT::@26 m_Argument
void PostPaint(wxPaintEvent &aEvent)
Post an event to m_paint_listener.
void drawAxes(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
int PointCount() const
Return the number of points (vertices) in this line chain.
virtual void ComputeWorldScreenMatrix()
Compute the world <-> screen transformation matrix.
cairo_matrix_t m_cairoWorldScreenMatrix
Cairo world to screen transform matrix.
void SetLayerDepth(double aLayerDepth) override
Set the depth of the layer (position on the z-axis)
virtual void SetLayerDepth(double aLayerDepth)
Set the depth of the layer (position on the z-axis)
unsigned int m_groupCounter
Counter used for generating group keys.
int m_gridTick
Every tick line gets the double width.
unsigned int m_bufferSize
Size of buffers cairoOutput, bitmapBuffers.
float m_gridLineWidth
Line width of the grid.
const double angle_xform(const double aAngle)
Transform according to the rotation from m_currentWorld2Screen transform matrix.
MATRIX3x3D m_worldScreenMatrix
World transformation.
virtual void SetLineWidth(float aLineWidth)
Set the line width.
Class that handles multitarget rendering (ie.
Auxiliary rendering target (noncached)
COLOR4D m_gridColor
Color of the grid.
This class handle bitmap images in KiCad.
void ClearCache() override
Delete all data created during caching of graphic items.
double m_worldScale
The scale factor world->screen.
void DrawCircle(const VECTOR2D &aCenterPoint, double aRadius) override
Draw a circle using world coordinates.
CAIRO_ANTIALIASING_MODE cairo_antialiasing_mode
static double roundp(double x)
void DrawSegment(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint, double aWidth) override
Draw a rounded segment.
VECTOR2D m_cursorPosition
Current cursor position (world coordinates)
GAL_DISPLAY_OPTIONS & m_options
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
void drawGridPoint(const VECTOR2D &aPoint, double aWidth, double aHeight)
void ClearScreen() override
Clear the screen.
bool m_isElementAdded
Was an graphic element added ?
void SetGridColor(const COLOR4D &aGridColor)
Set the grid color.
void EndDrawing() override
End the drawing, needs to be called for every new frame.
GRAPHICS_COMMAND m_Command
Command to execute.
bool m_isStrokeEnabled
Are the outlines stroked ?
COLOR4D m_strokeColor
The color of the outlines.
void ClearTarget(RENDER_TARGET aTarget) override
Clear the target for rendering.
void DrawLine(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint) override
Draw a line.
std::vector< cairo_matrix_t > m_xformStack
VECTOR2< double > VECTOR2D
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
bool IsClosed() const override
bool m_gridVisibility
Should the grid be shown.
Represent a set of closed polygons.
static const wxCursor GetCursor(KICURSOR aCursorType)
void SetAxesColor(const COLOR4D &aAxesColor)
Set the axes color.
void DrawPolygon(const std::deque< VECTOR2D > &aPointList) override
Draw a polygon.
wxCursor m_currentwxCursor
wxCursor showing the current native cursor
Items that may change while the view stays the same (noncached)
cairo_t * m_currentContext
Currently used Cairo context for drawing.
bool SetNativeCursorStyle(KICURSOR aCursor) override
Set the cursor in the native panel.
void updateWorldScreenMatrix()
void DrawCursor(const VECTOR2D &aCursorPosition) override
Draw the cursor.
void onSetNativeCursor(wxSetCursorEvent &aEvent)
Give the correct cursor image when the native widget asks for it.
const double xform(double x)
int m_stride
Stride value for Cairo.
cairo_t * m_context
Cairo image.
void SetTarget(RENDER_TARGET aTarget) override
Set the target for rendering.
void skipMouseEvent(wxMouseEvent &aEvent)
Mouse event handler, forwards the event to the child.
Use small cross instead of dots for the grid.
Save the transformation matrix.
COLOR4D getCursorColor() const
Get the actual cursor color to draw.
void SetIsFill(bool aIsFillEnabled) override
Enable/disable fill.
const VECTOR2D roundp(const VECTOR2D &v)
virtual bool updatedGalDisplayOptions(const GAL_DISPLAY_OPTIONS &aOptions)
Handle updating display options.
bool m_validCompositor
Compositor initialization flag.
cairo_matrix_t m_currentWorld2Screen
virtual bool SetNativeCursorStyle(KICURSOR aCursor)
Set the cursor in the native panel.
void DrawArc(const VECTOR2D &aCenterPoint, double aRadius, double aStartAngle, double aEndAngle) override
Draw an arc.
void SetStrokeColor(const COLOR4D &aColor) override
Set the stroke color.
void DrawRectangle(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint) override
Draw a rectangle.
void Restore() override
Restore the context.
GRID_STYLE m_gridStyle
Grid display style.
bool Show(bool aShow) override
Show/hide the GAL canvas.
cairo_matrix_t m_currentXform
void StartDiffLayer() override
Begins rendering of a differential layer.
COLOR4D m_fillColor
The fill color.
int BeginGroup() override
Begin a group.
VECTOR2< T > Rotate(double aAngle) const
Rotate the vector by a given angle.
VECTOR2D m_depthRange
Range of the depth.
bool BoolArg
A bool argument.
COLOR4D m_axesColor
Color of the axes.
Main rendering target (cached)
void arc_angles_xform_and_normalize(double &aStartAngle, double &aEndAngle)
Transform according to the rotation from m_currentWorld2Screen transform matrix for the start angle a...
wxEvtHandler * m_mouseListener
Mouse listener.
RENDER_TARGET GetTarget() const override
Get the currently used target for rendering.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void drawPoly(const std::deque< VECTOR2D > &aPointList)
Drawing polygons & polylines is the same in Cairo, so here is the common code.
void EndNegativesLayer() override
Ends rendering of a negatives layer and draws it to the main layer.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
wxSize GetSizePixels() const
void Save() override
Save the context.
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Temporary target for drawing in separate layer.
#define SWAP(varA, condition, varB)
Swap the variables if a condition is met.
void drawGridLine(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Draw a grid line (usually a simplified line function).
unsigned int m_mainBuffer
Handle to the main buffer.
bool m_fullscreenCursor
Shape of the cursor (fullscreen or small cross)
cairo_path_t * m_CairoPath
Pointer to a Cairo path.
void SetLineWidth(float aLineWidth) override
Set the line width.
std::shared_ptr< CAIRO_COMPOSITOR > m_compositor
Object for layers compositing.
void Scale(const VECTOR2D &aScale) override
Scale the context.
void deleteBitmaps()
Allocate the bitmaps for drawing.
void DrawGroup(int aGroupNumber) override
Draw the stored group.
VECTOR2D m_gridOrigin
The grid origin.
void syncLineWidth(bool aForceWidth=false, double aWidth=0.0)
double m_worldUnitLength
The unit length of the world coordinates [inch].
int BeginGroup() override
Begin a group.
double DblArg[MAX_CAIRO_ARGUMENTS]
Arguments for Cairo commands.
RENDER_TARGET
RENDER_TARGET: Possible rendering targets.
void allocateBitmaps()
Allocate the bitmaps for drawing.
unsigned int m_overlayBuffer
Handle to the overlay buffer.
void Transform(const MATRIX3x3D &aTransformation) override
Transform the context.
bool IsCursorEnabled() const
Return information about cursor visibility.
VECTOR2I m_screenSize
Screen size in screen coordinates.
void DrawCurve(const VECTOR2D &startPoint, const VECTOR2D &controlPointA, const VECTOR2D &controlPointB, const VECTOR2D &endPoint, double aFilterValue=0.0) override
Draw a cubic bezier spline.
void DrawArcSegment(const VECTOR2D &aCenterPoint, double aRadius, double aStartAngle, double aEndAngle, double aWidth, double aMaxError) override
Draw an arc segment.
KICURSOR m_currentNativeCursor
Current cursor.
float m_lineWidth
The line width.
void EndGroup() override
End the group.
cairo_surface_t * m_surface
Cairo surface.
void BeginDrawing() override
Start/end drawing functions, draw calls can be only made in between the calls to BeginDrawing()/EndDr...
virtual void SetTarget(RENDER_TARGET aTarget)
Set the target for rendering.
void Flush() override
Force all remaining objects to be drawn.
std::vector< cairo_surface_t * > m_imageSurfaces
List of surfaces that were created by painting images, to be cleaned up later.
unsigned int getNewGroupNumber()
Return a valid key that can be used as a new group number.
bool m_isGrouping
Is grouping enabled ?
void blitCursor(wxMemoryDC &clientDC)
Blit cursor into the current screen.
Restore the transformation matrix.
void SetFillColor(const COLOR4D &aColor) override
Set the fill color.
void drawGridCross(const VECTOR2D &aPoint)
Abstract interface for drawing on a 2D-surface.
void Rotate(double aAngle) override
Rotate the context.
static constexpr cairo_format_t GAL_FORMAT
Format used to store pixels.
A color representation with 4 components: red, green, blue, alpha.
wxEvtHandler * m_paintListener
Paint listener.
void StartNegativesLayer() override
Begins rendering in a new layer that will be copied to the main layer in EndNegativesLayer().