KiCad PCB EDA Suite
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 (C) 2012-2017 Kicad Developers, see change_log.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 // m_currentNativeCursor is initialized with KICURSOR::DEFAULT value to avoid
43 // if comparison with uninitialized value on SetNativeCursorStyle method.
44 // Some classes inheriting from GAL has different SetNativeCursorStyle method
45 // implementation and therefore it's called also on constructor
46 // to change the value from DEFAULT to KICURSOR::ARROW
47 m_currentNativeCursor( KICURSOR::DEFAULT )
48{
49 // Set the default values for the internal variables
50 SetIsFill( false );
51 SetIsStroke( true );
52 SetFillColor( COLOR4D( 0.0, 0.0, 0.0, 0.0 ) );
53 SetStrokeColor( COLOR4D( 1.0, 1.0, 1.0, 1.0 ) );
54 SetLookAtPoint( VECTOR2D( 0, 0 ) );
55 SetZoomFactor( 1.0 );
56 SetRotation( 0.0 );
57 // this value for SetWorldUnitLength is only suitable for Pcbnew.
58 // Other editors/viewer must call SetWorldUnitLength with their internal units
59 SetWorldUnitLength( 1e-9 /* 1 nm */ / 0.0254 /* 1 inch in meters */ );
60 // wxDC::GetPPI() reports 96 DPI, but somehow this value
61 // is the closest match to the legacy renderer
62 SetScreenDPI( 91 );
64 SetLayerDepth( 0.0 );
65 SetFlip( false, false );
66 SetLineWidth( 1.0f );
68 SetAxesEnabled( false );
69
70 // Set grid defaults
71 SetGridVisibility( true );
72 SetCoarseGrid( 10 );
73 m_gridLineWidth = 0.5f;
76
77 // Initialize the cursor shape
78 SetCursorColor( COLOR4D( 1.0, 1.0, 1.0, 1.0 ) );
79 m_fullscreenCursor = false;
81 SetCursorEnabled( false );
82
83 // Initialize the native widget to an arrow cursor
85
86 // Initialize text properties
88
89 // subscribe for settings updates
91}
92
93
95{
96}
97
98
100{
101 // defer to the child class first
102 updatedGalDisplayOptions( aOptions );
103
104 // there is no refresh to do at this level
105}
106
107
109{
110 bool refresh = false;
111
113 {
115 refresh = true;
116 }
117
119 {
120 m_gridLineWidth = std::floor( m_options.m_gridLineWidth + 0.5 );
121 refresh = true;
122 }
123
125 {
127 refresh = true;
128 }
129
131 {
133 refresh = true;
134 }
135
137 {
139 refresh = true;
140 }
141
143 {
145 refresh = true;
146 }
147
148 // tell the derived class if the base class needs an update or not
149 return refresh;
150}
151
152
154{
155 // Tiny but non-zero - this will always need setting
156 // there is no built-in default
157 SetGlyphSize( { 1, 1 } );
158
161
162 SetFontBold( false );
163 SetFontItalic( false );
164 SetFontUnderlined( false );
165 SetTextMirrored( false );
166}
167
168
170{
172
173 MATRIX3x3D translation;
174 translation.SetIdentity();
175 // We're deliberately dividing integers to avoid fractional pixel offsets.
176 translation.SetTranslation( VECTOR2D( m_screenSize.x/2, m_screenSize.y/2 ) );
177
178 MATRIX3x3D rotate;
179 rotate.SetIdentity();
180 rotate.SetRotation( m_rotation );
181
183 scale.SetIdentity();
184 scale.SetScale( VECTOR2D( m_worldScale, m_worldScale ) );
185
186 MATRIX3x3D flip;
187 flip.SetIdentity();
188 flip.SetScale( VECTOR2D( m_globalFlipX ? -1.0 : 1.0, m_globalFlipY ? -1.0 : 1.0 ) );
189
190 MATRIX3x3D lookat;
191 lookat.SetIdentity();
192 lookat.SetTranslation( -m_lookAtPoint );
193
194 m_worldScreenMatrix = translation * rotate * flip * scale * lookat;
196}
197
198
200{
201 const MATRIX3x3D& matrix = GetScreenWorldMatrix();
202
203 VECTOR2D halfSize = VECTOR2D( matrix.GetScale().x * m_screenSize.x * 0.5,
204 matrix.GetScale().y * m_screenSize.y * 0.5 );
205
206 BOX2D extents;
207 extents.SetOrigin( GetLookAtPoint() - halfSize );
208 extents.SetSize( halfSize * 2 );
209
210 return extents;
211}
212
213
215{
216 // just return the current value. This could be cleverer and take
217 // into account other settings in future
218 return m_gridMinSpacing;
219}
220
221
222VECTOR2D GAL::GetGridPoint( const VECTOR2D& aPoint ) const
223{
224#if 0
225 // This old code expects a non zero grid size, which can be wrong here.
226 return VECTOR2D( KiROUND( ( aPoint.x - m_gridOffset.x ) / m_gridSize.x ) * m_gridSize.x + m_gridOffset.x,
227 KiROUND( ( aPoint.y - m_gridOffset.y ) / m_gridSize.y ) * m_gridSize.y + m_gridOffset.y );
228#else
229 // if grid size == 0.0 there is no grid, so use aPoint as grid reference position
230 double cx = m_gridSize.x > 0.0 ? KiROUND( ( aPoint.x - m_gridOffset.x ) / m_gridSize.x ) * m_gridSize.x + m_gridOffset.x
231 : aPoint.x;
232 double cy = m_gridSize.y > 0.0 ? KiROUND( ( aPoint.y - m_gridOffset.y ) / m_gridSize.y ) * m_gridSize.y + m_gridOffset.y
233 : aPoint.y;
234
235 return VECTOR2D( cx, cy );
236#endif
237}
238
239const int GAL::MIN_DEPTH = -1024;
240const int GAL::MAX_DEPTH = 1023;
241const int GAL::GRID_DEPTH = MAX_DEPTH - 1;
242
243
245{
247
248 // dim the cursor if it's only on because it was forced
249 // (this helps to provide a hint for active tools)
250 if( !m_isCursorEnabled )
251 color.a = color.a * 0.5;
252
253 return color;
254}
255
256
257/*
258 * Fallback for implementations that don't implement bitmap text: use stroke font
259 */
260void GAL::BitmapText( const wxString& aText, const VECTOR2I& aPosition, const EDA_ANGLE& aAngle )
261{
263
264 if( aText.IsEmpty() )
265 return;
266
268 attrs.m_Angle = aAngle;
269 attrs.m_Mirrored = m_globalFlipX; // Prevent text flipping when view is flipped
270
271 // Bitmap font has different metrics than the stroke font so we compensate a bit before
272 // stroking
274 attrs.m_StrokeWidth = GetLineWidth() * 0.74;
275
276 font->Draw( this, aText, aPosition, attrs );
277}
278
279
281{
282 if( m_currentNativeCursor == aCursor )
283 return false;
284
285 m_currentNativeCursor = aCursor;
286
287 return true;
288}
int color
Definition: DXF_plotter.cpp:57
void SetOrigin(const Vec &pos)
Definition: box2.h:202
void SetSize(const Vec &size)
Definition: box2.h:213
FONT is an abstract base class for both outline and stroke fonts.
Definition: font.h:105
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false)
Definition: font.cpp:65
void Draw(KIGFX::GAL *aGal, const wxString &aText, const VECTOR2I &aPosition, const VECTOR2I &aCursor, const TEXT_ATTRIBUTES &aAttrs) const
Draw a string.
Definition: font.cpp:159
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 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.
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.
virtual bool SetNativeCursorStyle(KICURSOR aCursor)
Set the cursor in the native panel.
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.
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:210
void SetRotation(T aAngle)
Set the rotation components of the matrix.
Definition: matrix3x3.h:245
void SetScale(VECTOR2< T > aScale)
Set the scale components of the matrix.
Definition: matrix3x3.h:257
VECTOR2< T > GetScale() const
Get the scale components of the matrix.
Definition: matrix3x3.h:265
void SetTranslation(VECTOR2< T > aTranslation)
Set the translation components of the matrix.
Definition: matrix3x3.h:226
MATRIX3x3 Inverse() const
Determine the inverse of the matrix.
Definition: matrix3x3.h:339
LINK Subscribe(ObserverInterface *aObserver)
Add a subscription returning an RAII link.
Definition: observable.h:157
KICURSOR
Definition: cursors.h:34
The Cairo implementation of the graphics abstraction layer.
Definition: color4d.cpp:266
@ LINES
Use lines for the grid.
const int scale
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_V_ALIGN_CENTER
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:85
VECTOR2< double > VECTOR2D
Definition: vector2d.h:617
VECTOR2< int > VECTOR2I
Definition: vector2d.h:618