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 (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
84 SetNativeCursorStyle( KICURSOR::ARROW, false );
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 {
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, KIFONT::METRICS::Default() );
277}
278
279
280bool GAL::SetNativeCursorStyle( KICURSOR aCursor, bool aHiDPI )
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:58
void SetOrigin(const Vec &pos)
Definition: box2.h:227
void SetSize(const SizeVec &size)
Definition: box2.h:238
FONT is an abstract base class for both outline and stroke fonts.
Definition: font.h:131
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:257
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false, const std::vector< wxString > *aEmbeddedFiles=nullptr)
Definition: font.cpp:146
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
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
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:121
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:673
VECTOR2< double > VECTOR2D
Definition: vector2d.h:672