KiCad PCB EDA Suite
Loading...
Searching...
No Matches
graphics_abstraction_layer.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KICAD, a free EDA CAD application.
3 *
4 * Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * Graphics Abstraction Layer (GAL) - base class
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, you may find one here:
21 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22 * or you may search the http://www.gnu.org website for the version 2 license,
23 * or you may write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 */
26
27#include <wx/log.h>
28
30#include <gal/definitions.h>
31#include <font/font.h>
32
33#include <math/util.h> // for KiROUND
34
35#include <cmath>
36
37using namespace KIGFX;
38
39
40GAL::GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions ) :
41 m_options( aDisplayOptions ),
42
43 // m_currentNativeCursor is initialized with KICURSOR::DEFAULT value to avoid
44 // if comparison with uninitialized value on SetNativeCursorStyle method.
45 // Some classes inheriting from GAL has different SetNativeCursorStyle method
46 // implementation and therefore it's called also on constructor
47 // to change the value from DEFAULT to KICURSOR::ARROW
48 m_currentNativeCursor( KICURSOR::DEFAULT )
49{
50 // Set the default values for the internal variables
51 SetIsFill( false );
52 SetIsStroke( true );
53 SetFillColor( COLOR4D( 0.0, 0.0, 0.0, 0.0 ) );
54 SetStrokeColor( COLOR4D( 1.0, 1.0, 1.0, 1.0 ) );
55 SetLookAtPoint( VECTOR2D( 0, 0 ) );
56 SetZoomFactor( 1.0 );
57 SetRotation( 0.0 );
58
59 // this value for SetWorldUnitLength is only suitable for Pcbnew.
60 // Other editors/viewer must call SetWorldUnitLength with their internal units
61 SetWorldUnitLength( 1e-9 /* 1 nm */ / 0.0254 /* 1 inch in meters */ );
62
63 // wxDC::GetPPI() reports 96 DPI, but somehow this value
64 // is the closest match to the legacy renderer
65 SetScreenDPI( 91 );
67 SetLayerDepth( 0.0 );
68 SetFlip( false, false );
69 SetLineWidth( 1.0f );
71 SetAxesEnabled( false );
72
73 // Set grid defaults
74 SetGridVisibility( true );
75 SetCoarseGrid( 10 );
76 m_gridLineWidth = 0.5f;
79
80 // Initialize the cursor shape
81 SetCursorColor( COLOR4D( 1.0, 1.0, 1.0, 1.0 ) );
82 m_fullscreenCursor = false;
84 SetCursorEnabled( false );
85
86 // Initialize the native widget to an arrow cursor
87 SetNativeCursorStyle( KICURSOR::ARROW, false );
88
89 // Initialize text properties
91
92 // subscribe for settings updates
94}
95
96
98{
99}
100
101
103{
104 // defer to the child class first
105 updatedGalDisplayOptions( aOptions );
106
107 // there is no refresh to do at this level
108}
109
110
112{
113 bool refresh = false;
114
116 {
118 refresh = true;
119 }
120
122 {
124 refresh = true;
125 }
126
128 {
130 refresh = true;
131 }
132
134 {
136 refresh = true;
137 }
138
140 {
142 refresh = true;
143 }
144
146 {
148 refresh = true;
149 }
150
151 // tell the derived class if the base class needs an update or not
152 return refresh;
153}
154
155
157{
158 // Tiny but non-zero - this will always need setting
159 // there is no built-in default
160 SetGlyphSize( { 1, 1 } );
161
164
165 SetFontBold( false );
166 SetFontItalic( false );
167 SetFontUnderlined( false );
168 SetTextMirrored( false );
169}
170
171
173{
175
176 MATRIX3x3D translation;
177 translation.SetIdentity();
178 // We're deliberately dividing integers to avoid fractional pixel offsets.
179 translation.SetTranslation( VECTOR2D( m_screenSize.x/2, m_screenSize.y/2 ) );
180
181 MATRIX3x3D rotate;
182 rotate.SetIdentity();
183 rotate.SetRotation( m_rotation );
184
186 scale.SetIdentity();
187 scale.SetScale( VECTOR2D( m_worldScale, m_worldScale ) );
188
189 MATRIX3x3D flip;
190 flip.SetIdentity();
191 flip.SetScale( VECTOR2D( m_globalFlipX ? -1.0 : 1.0, m_globalFlipY ? -1.0 : 1.0 ) );
192
193 MATRIX3x3D lookat;
194 lookat.SetIdentity();
195 lookat.SetTranslation( -m_lookAtPoint );
196
197 m_worldScreenMatrix = translation * rotate * flip * scale * lookat;
199}
200
201
203{
204 const MATRIX3x3D& matrix = GetScreenWorldMatrix();
205
206 VECTOR2D halfSize = VECTOR2D( matrix.GetScale().x * m_screenSize.x * 0.5,
207 matrix.GetScale().y * m_screenSize.y * 0.5 );
208
209 BOX2D extents;
210 extents.SetOrigin( GetLookAtPoint() - halfSize );
211 extents.SetSize( halfSize * 2 );
212
213 return extents;
214}
215
216
218{
219 // just return the current value. This could be cleverer and take
220 // into account other settings in future
221 return m_gridMinSpacing;
222}
223
224
225VECTOR2D GAL::GetGridPoint( const VECTOR2D& aPoint ) const
226{
227#if 0
228 // This old code expects a non zero grid size, which can be wrong here.
229 return VECTOR2D( KiROUND( ( aPoint.x - m_gridOffset.x ) / m_gridSize.x ) *
231 KiROUND( ( aPoint.y - m_gridOffset.y ) / m_gridSize.y ) *
233#else
234 // if grid size == 0.0 there is no grid, so use aPoint as grid reference position
235 double cx = m_gridSize.x > 0.0 ? KiROUND( ( aPoint.x - m_gridOffset.x ) / m_gridSize.x ) *
237 : aPoint.x;
238 double cy = m_gridSize.y > 0.0 ? KiROUND( ( aPoint.y - m_gridOffset.y ) / m_gridSize.y ) *
240 : aPoint.y;
241
242 return VECTOR2D( cx, cy );
243#endif
244}
245
246
247// MIN_DEPTH must be set to be - (VIEW::VIEW_MAX_LAYERS + abs(VIEW::TOP_LAYER_MODIFIER))
248// MAX_DEPTH must be set to be VIEW::VIEW_MAX_LAYERS + abs(VIEW::TOP_LAYER_MODIFIER) -1
249// VIEW_MAX_LAYERS and TOP_LAYER_MODIFIER are defined in view.h.
250// TOP_LAYER_MODIFIER is set as -VIEW_MAX_LAYERS
251// Currently KIGFX::VIEW::VIEW_MAX_LAYERS = MAX_LAYERS_FOR_VIEW
253const int GAL::MAX_DEPTH = 2*MAX_LAYERS_FOR_VIEW - 1;
254const int GAL::GRID_DEPTH = MAX_DEPTH - 1;
255
256
258{
260
261 // dim the cursor if it's only on because it was forced
262 // (this helps to provide a hint for active tools)
263 if( !m_isCursorEnabled )
264 color.a = color.a * 0.5;
265
266 return color;
267}
268
269
270void GAL::BitmapText( const wxString& aText, const VECTOR2I& aPosition, const EDA_ANGLE& aAngle )
271{
273
274 if( aText.IsEmpty() )
275 return;
276
278 attrs.m_Angle = aAngle;
279 attrs.m_Mirrored = m_globalFlipX; // Prevent text flipping when view is flipped
280
281 // Bitmap font has different metrics than the stroke font so we compensate a bit before
282 // stroking
284 attrs.m_StrokeWidth = GetLineWidth() * 0.74;
285
286 font->Draw( this, aText, aPosition, attrs, KIFONT::METRICS::Default() );
287}
288
289
290bool GAL::SetNativeCursorStyle( KICURSOR aCursor, bool aHiDPI )
291{
292 if( m_currentNativeCursor == aCursor )
293 return false;
294
295 m_currentNativeCursor = aCursor;
296
297 return true;
298}
int color
Definition: DXF_plotter.cpp:60
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition: box2.h:990
constexpr void SetOrigin(const Vec &pos)
Definition: box2.h:237
constexpr void SetSize(const SizeVec &size)
Definition: box2.h:248
FONT is an abstract base class for both outline and stroke fonts.
Definition: font.h:131
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false, const std::vector< wxString > *aEmbeddedFiles=nullptr, bool aForDrawingSheet=false)
Definition: font.cpp:149
void Draw(KIGFX::GAL *aGal, const wxString &aText, const VECTOR2I &aPosition, const VECTOR2I &aCursor, const TEXT_ATTRIBUTES &aAttributes, const METRICS &aFontMetrics) const
Draw a string.
Definition: font.cpp:252
static const METRICS & Default()
Definition: font.cpp:52
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
double m_gridLineWidth
Minimum pixel distance between displayed grid lines.
double m_gridMinSpacing
Whether or not to draw the coordinate system axes.
bool m_forceDisplayCursor
The pixel scale factor (>1 for hi-DPI scaled displays)
KIGFX::GRID_STYLE m_gridStyle
Snapping options for the grid.
bool m_axesEnabled
Fullscreen crosshair or small cross.
bool m_fullscreenCursor
Force cursor display.
virtual void SetLayerDepth(double aLayerDepth)
Set the depth of the layer (position on the z-axis)
virtual void SetIsFill(bool aIsFillEnabled)
Enable/disable fill.
bool m_isCursorEnabled
Is the cursor enabled?
BOX2D GetVisibleWorldExtents() const
MATRIX3x3D m_worldScreenMatrix
World transformation.
void SetVerticalJustify(const GR_TEXT_V_ALIGN_T aVerticalJustify)
void SetFontBold(const bool aBold)
MATRIX3x3D m_screenWorldMatrix
Screen transformation.
void SetFontUnderlined(bool aUnderlined)
void SetHorizontalJustify(const GR_TEXT_H_ALIGN_T aHorizontalJustify)
bool m_axesEnabled
Should the axes be drawn.
void SetRotation(double aRotation)
Get/set the rotation angle (in radians).
float m_gridLineWidth
Line width of the grid.
void SetFlip(bool xAxis, bool yAxis)
Sets flipping of the screen.
VECTOR2I m_screenSize
Screen size in screen (wx logical) coordinates.
virtual void SetFillColor(const COLOR4D &aColor)
Set the fill color.
void OnGalDisplayOptionsChanged(const GAL_DISPLAY_OPTIONS &aOptions) override
Handler for observer settings changes.
void SetCursorEnabled(bool aCursorEnabled)
Enable/disable cursor.
void SetAxesEnabled(bool aAxesEnabled)
Enable drawing the axes.
virtual bool SetNativeCursorStyle(KICURSOR aCursor, bool aHiDPI)
Set the cursor in the native panel.
GRID_STYLE m_gridStyle
Grid display style.
void SetCursorColor(const COLOR4D &aCursorColor)
Set the cursor color.
COLOR4D m_cursorColor
Cursor color.
int m_gridMinSpacing
Minimum screen size of the grid (pixels) below which the grid is not drawn.
const VECTOR2D & GetLookAtPoint() const
const MATRIX3x3D & GetScreenWorldMatrix() const
Get the screen <-> world transformation matrix.
void SetZoomFactor(double aZoomFactor)
void computeWorldScale()
Compute the scaling factor for the world->screen matrix.
TEXT_ATTRIBUTES m_attributes
void ResetTextAttributes()
Reset text attributes to default styling.
static const int MIN_DEPTH
Possible depth range.
virtual void SetLineWidth(float aLineWidth)
Set the line width.
double m_rotation
Rotation transformation (radians)
VECTOR2D m_gridSize
The grid size.
COLOR4D getCursorColor() const
Get the actual cursor color to draw.
void SetTextMirrored(const bool aMirrored)
void SetCoarseGrid(int aInterval)
Draw every tick line wider.
virtual bool updatedGalDisplayOptions(const GAL_DISPLAY_OPTIONS &aOptions)
Handle updating display options.
virtual void SetStrokeColor(const COLOR4D &aColor)
Set the stroke color.
VECTOR2D m_gridOffset
The grid offset to compensate cursor position.
virtual void SetIsStroke(bool aIsStrokeEnabled)
Enable/disable stroked outlines.
double m_worldScale
The scale factor world->screen.
void SetLookAtPoint(const VECTOR2D &aPoint)
Get/set the Point in world space to look at.
VECTOR2D GetGridPoint(const VECTOR2D &aPoint) const
For a given point it returns the nearest point belonging to the grid in world coordinates.
void SetWorldUnitLength(double aWorldUnitLength)
Set the unit length.
KICURSOR m_currentNativeCursor
Current cursor.
bool m_globalFlipY
Flag for Y axis flipping.
bool m_fullscreenCursor
Shape of the cursor (fullscreen or small cross)
static const int GRID_DEPTH
Depth level on which the grid is drawn.
void SetGlyphSize(const VECTOR2I aSize)
virtual void ComputeWorldScreenMatrix()
Compute the world <-> screen transformation matrix.
double computeMinGridSpacing() const
Compute minimum grid spacing from the grid settings.
void SetFontItalic(bool aItalic)
GAL_DISPLAY_OPTIONS & m_options
virtual void BitmapText(const wxString &aText, const VECTOR2I &aPosition, const EDA_ANGLE &aAngle)
Draw a text using a bitmap font.
void SetGridVisibility(bool aVisibility)
Set the visibility setting of the grid.
float GetLineWidth() const
Get the line width.
bool m_globalFlipX
Flag for X axis flipping.
void SetDepthRange(const VECTOR2D &aDepthRange)
Set the range of the layer depth.
VECTOR2D m_lookAtPoint
Point to be looked at in world space.
GAL(GAL_DISPLAY_OPTIONS &aOptions)
void SetScreenDPI(double aScreenDPI)
Set the dots per inch of the screen.
bool m_forceDisplayCursor
Always show cursor.
static const int MAX_DEPTH
void SetIdentity()
Set the matrix to the identity matrix.
Definition: matrix3x3.h:240
void SetRotation(T aAngle)
Set the rotation components of the matrix.
Definition: matrix3x3.h:275
void SetScale(VECTOR2< T > aScale)
Set the scale components of the matrix.
Definition: matrix3x3.h:287
VECTOR2< T > GetScale() const
Get the scale components of the matrix.
Definition: matrix3x3.h:295
void SetTranslation(VECTOR2< T > aTranslation)
Set the translation components of the matrix.
Definition: matrix3x3.h:256
MATRIX3x3 Inverse() const
Determine the inverse of the matrix.
Definition: matrix3x3.h:384
LINK Subscribe(ObserverInterface *aObserver)
Add a subscription returning an RAII link.
Definition: observable.h:157
KICURSOR
Definition: cursors.h:34
#define MAX_LAYERS_FOR_VIEW
Definition: definitions.h:45
The Cairo implementation of the graphics abstraction layer.
Definition: color4d.cpp:247
@ LINES
Use lines for the grid.
const int scale
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_V_ALIGN_CENTER
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:695
VECTOR2< double > VECTOR2D
Definition: vector2d.h:694