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 
32 #include <math/util.h> // for KiROUND
33 
34 #include <cmath>
35 
36 using namespace KIGFX;
37 
38 
39 GAL::GAL( GAL_DISPLAY_OPTIONS& aDisplayOptions ) :
40  m_options( aDisplayOptions ),
41  m_strokeFont( this )
42 {
43  // Set the default values for the internal variables
44  SetIsFill( false );
45  SetIsStroke( true );
46  SetFillColor( COLOR4D( 0.0, 0.0, 0.0, 0.0 ) );
47  SetStrokeColor( COLOR4D( 1.0, 1.0, 1.0, 1.0 ) );
48  SetLookAtPoint( VECTOR2D( 0, 0 ) );
49  SetZoomFactor( 1.0 );
50  SetRotation( 0.0 );
51  // this value for SetWorldUnitLength is only suitable for Pcbnew.
52  // Other editors/viewer must call SetWorldUnitLength with their internal units
53  SetWorldUnitLength( 1e-9 /* 1 nm */ / 0.0254 /* 1 inch in meters */ );
54  // wxDC::GetPPI() reports 96 DPI, but somehow this value
55  // is the closest match to the legacy renderer
56  SetScreenDPI( 91 );
58  SetLayerDepth( 0.0 );
59  SetFlip( false, false );
60  SetLineWidth( 1.0f );
62  SetAxesEnabled( false );
63 
64  // Set grid defaults
65  SetGridVisibility( true );
66  SetCoarseGrid( 10 );
67  m_gridLineWidth = 0.5f;
69  m_gridMinSpacing = 10;
70 
71  // Initialize the cursor shape
72  SetCursorColor( COLOR4D( 1.0, 1.0, 1.0, 1.0 ) );
73  m_fullscreenCursor = false;
74  m_forceDisplayCursor = false;
75  SetCursorEnabled( false );
76 
77  // Initialize the native widget to an arrow cursor
79 
80  // Initialize text properties
82 
84 
85  // subscribe for settings updates
87 }
88 
89 
91 {
92 }
93 
94 
96 {
97  // defer to the child class first
98  updatedGalDisplayOptions( aOptions );
99 
100  // there is no refresh to do at this level
101 }
102 
103 
105 {
106  bool refresh = false;
107 
109  {
111  refresh = true;
112  }
113 
115  {
116  m_gridLineWidth = std::floor( m_options.m_gridLineWidth + 0.5 );
117  refresh = true;
118  }
119 
121  {
123  refresh = true;
124  }
125 
127  {
129  refresh = true;
130  }
131 
133  {
135  refresh = true;
136  }
137 
139  {
141  refresh = true;
142  }
143 
144  // tell the derived class if the base class needs an update or not
145  return refresh;
146 }
147 
148 
149 void GAL::SetTextAttributes( const EDA_TEXT* aText )
150 {
151  SetGlyphSize( VECTOR2D( aText->GetTextSize() ) );
154  SetFontBold( aText->IsBold() );
155  SetFontItalic( aText->IsItalic() );
156  SetFontUnderlined( false );
157  SetTextMirrored( aText->IsMirrored() );
158 }
159 
160 
162 {
163  // Tiny but non-zero - this will always need setting
164  // there is no built-in default
165  SetGlyphSize( { 1.0, 1.0 } );
166 
169 
170  SetFontBold( false );
171  SetFontItalic( false );
172  SetFontUnderlined( false );
173  SetTextMirrored( false );
174 }
175 
176 
177 VECTOR2D GAL::GetTextLineSize( const UTF8& aText ) const
178 {
179  // Compute the X and Y size of a given text.
180  // Because computeTextLineSize expects a one line text,
181  // aText is expected to be only one line text.
182  return m_strokeFont.computeTextLineSize( aText );
183 }
184 
185 
187 {
189 
190  MATRIX3x3D translation;
191  translation.SetIdentity();
192  translation.SetTranslation( 0.5 * VECTOR2D( m_screenSize ) );
193 
194  MATRIX3x3D rotate;
195  rotate.SetIdentity();
196  rotate.SetRotation( m_rotation );
197 
199  scale.SetIdentity();
200  scale.SetScale( VECTOR2D( m_worldScale, m_worldScale ) );
201 
202  MATRIX3x3D flip;
203  flip.SetIdentity();
204  flip.SetScale( VECTOR2D( m_globalFlipX ? -1.0 : 1.0, m_globalFlipY ? -1.0 : 1.0 ) );
205 
206  MATRIX3x3D lookat;
207  lookat.SetIdentity();
208  lookat.SetTranslation( -m_lookAtPoint );
209 
210  m_worldScreenMatrix = translation * rotate * flip * scale * lookat;
212 }
213 
214 
216 {
217  const MATRIX3x3D& matrix = GetScreenWorldMatrix();
218 
219  VECTOR2D halfSize = VECTOR2D( matrix.GetScale().x * m_screenSize.x * 0.5,
220  matrix.GetScale().y * m_screenSize.y * 0.5 );
221 
222  BOX2D extents;
223  extents.SetOrigin( GetLookAtPoint() - halfSize );
224  extents.SetSize( halfSize * 2 );
225 
226  return extents;
227 }
228 
229 
231 {
232  // just return the current value. This could be cleverer and take
233  // into account other settings in future
234  return m_gridMinSpacing;
235 }
236 
237 
238 VECTOR2D GAL::GetGridPoint( const VECTOR2D& aPoint ) const
239 {
240 #if 0
241  // This old code expects a non zero grid size, which can be wrong here.
242  return VECTOR2D( KiROUND( ( aPoint.x - m_gridOffset.x ) / m_gridSize.x ) * m_gridSize.x + m_gridOffset.x,
243  KiROUND( ( aPoint.y - m_gridOffset.y ) / m_gridSize.y ) * m_gridSize.y + m_gridOffset.y );
244 #else
245  // if grid size == 0.0 there is no grid, so use aPoint as grid reference position
246  double cx = m_gridSize.x > 0.0 ? KiROUND( ( aPoint.x - m_gridOffset.x ) / m_gridSize.x ) * m_gridSize.x + m_gridOffset.x
247  : aPoint.x;
248  double cy = m_gridSize.y > 0.0 ? KiROUND( ( aPoint.y - m_gridOffset.y ) / m_gridSize.y ) * m_gridSize.y + m_gridOffset.y
249  : aPoint.y;
250 
251  return VECTOR2D( cx, cy );
252 #endif
253 }
254 
255 const int GAL::MIN_DEPTH = -1024;
256 const int GAL::MAX_DEPTH = 1023;
257 const int GAL::GRID_DEPTH = MAX_DEPTH - 1;
258 
259 
261 {
263 
264  // dim the cursor if it's only on because it was forced
265  // (this helps to provide a hint for active tools)
266  if( !m_isCursorEnabled )
267  color.a = color.a * 0.5;
268 
269  return color;
270 }
271 
272 
274 {
275  if( m_currentNativeCursor == aCursor )
276  return false;
277 
278  m_currentNativeCursor = aCursor;
279 
280  return true;
281 }
static const int GRID_DEPTH
Depth level on which the grid is drawn.
virtual void SetFillColor(const COLOR4D &aColor)
Set the fill color.
An 8 bit string that is assuredly encoded in UTF8, and supplies special conversion support to and fro...
Definition: utf8.h:70
bool IsBold() const
Definition: eda_text.h:190
Use lines for the grid.
EDA_TEXT_VJUSTIFY_T GetVertJustify() const
Definition: eda_text.h:206
bool IsMirrored() const
Definition: eda_text.h:196
The Cairo implementation of the graphics abstraction layer.
Definition: color4d.cpp:175
bool m_axesEnabled
Should the axes be drawn.
const MATRIX3x3D & GetScreenWorldMatrix() const
Get the screen <-> world transformation matrix.
void SetRotation(T aAngle)
Set the rotation components of the matrix.
Definition: matrix3x3.h:249
double computeMinGridSpacing() const
compute minimum grid spacing from the grid settings
STROKE_FONT m_strokeFont
Instance of object that stores information about how to draw texts.
KIGFX::GRID_STYLE m_gridStyle
Snapping options for the grid.
MATRIX3x3D m_screenWorldMatrix
Screen transformation.
void SetCursorEnabled(bool aCursorEnabled)
Enable/disable cursor.
virtual void SetTextAttributes(const EDA_TEXT *aText)
Loads attributes of the given text (bold/italic/underline/mirrored and so on).
MATRIX3x3 Inverse() const
Determine the inverse of the matrix.
Definition: matrix3x3.h:343
LINK Subscribe(ObserverInterface *aObserver)
Add a subscription returning an RAII link.
Definition: observable.h:157
int color
Definition: DXF_plotter.cpp:60
VECTOR2D m_gridSize
The grid size.
void SetFlip(bool xAxis, bool yAxis)
Sets flipping of the screen.
VECTOR2D m_lookAtPoint
Point to be looked at in world space.
bool LoadNewStrokeFont(const char *const aNewStrokeFont[], int aNewStrokeFontSize)
Load the new stroke font.
Definition: stroke_font.cpp:56
KICURSOR
Definition: cursors.h:33
bool m_forceDisplayCursor
The pixel scale factor (>1 for hi-DPI scaled displays)
double m_gridMinSpacing
Whether or not to draw the coordinate system axes.
VECTOR2D GetTextLineSize(const UTF8 &aText) const
Compute the X and Y size of a given text.
virtual void ComputeWorldScreenMatrix()
Compute the world <-> screen transformation matrix.
void SetScreenDPI(double aScreenDPI)
Set the dots per inch of the screen.
void SetIdentity()
Set the matrix to the identity matrix.
Definition: matrix3x3.h:214
virtual void SetLayerDepth(double aLayerDepth)
Set the depth of the layer (position on the z-axis)
VECTOR2< T > GetScale() const
Get the scale components of the matrix.
Definition: matrix3x3.h:269
float m_gridLineWidth
Line width of the grid.
MATRIX3x3D m_worldScreenMatrix
World transformation.
virtual void SetLineWidth(float aLineWidth)
Set the line width.
bool m_axesEnabled
Fullscreen crosshair or small cross.
double m_worldScale
The scale factor world->screen.
VECTOR2D GetGridPoint(const VECTOR2D &aPoint) const
For a given point it returns the nearest point belonging to the grid in world coordinates.
bool IsItalic() const
Definition: eda_text.h:187
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:119
static const int MIN_DEPTH
Possible depth range.
GAL_DISPLAY_OPTIONS & m_options
GAL(GAL_DISPLAY_OPTIONS &aOptions)
void SetFontBold(const bool aBold)
Set bold property of current font.
bool m_globalFlipX
Flag for X axis flipping.
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
Definition: eda_text.h:205
const char *const newstroke_font[]
Array containing strokes for unicode glyphs.
void OnGalDisplayOptionsChanged(const GAL_DISPLAY_OPTIONS &aOptions) override
Handler for observer settings changes.
void ResetTextAttributes()
Reset text attributes to default styling.
VECTOR2< double > VECTOR2D
Definition: vector2d.h:622
virtual void SetIsFill(bool aIsFillEnabled)
Enable/disable fill.
int m_gridMinSpacing
Minimum screen size of the grid (pixels) below which the grid is not drawn.
bool m_isCursorEnabled
Is the cursor enabled?
const wxSize & GetTextSize() const
Definition: eda_text.h:245
VECTOR2D computeTextLineSize(const UTF8 &aText) const
Compute the X and Y size of a given text.
void SetTextMirrored(const bool aMirrored)
Set a mirrored property of text.
void SetCursorColor(const COLOR4D &aCursorColor)
Set the cursor color.
void SetVerticalJustify(const EDA_TEXT_VJUSTIFY_T aVerticalJustify)
Set the vertical justify for text drawing.
void SetFontItalic(bool aItalic)
Set italic property of current font.
void SetAxesEnabled(bool aAxesEnabled)
Enable drawing the axes.
void SetWorldUnitLength(double aWorldUnitLength)
Set the unit length.
COLOR4D getCursorColor() const
Get the actual cursor color to draw.
COLOR4D m_cursorColor
Cursor color.
virtual bool updatedGalDisplayOptions(const GAL_DISPLAY_OPTIONS &aOptions)
Handle updating display options.
virtual bool SetNativeCursorStyle(KICURSOR aCursor)
Set the cursor in the native panel.
const int newstroke_font_bufsize
void computeWorldScale()
Compute the scaling factor for the world->screen matrix.
GRID_STYLE m_gridStyle
Grid display style.
const VECTOR2D & GetLookAtPoint() const
Get the look at point.
virtual void SetStrokeColor(const COLOR4D &aColor)
Set the stroke color.
void SetCoarseGrid(int aInterval)
Draw every tick line wider.
double m_rotation
Rotation transformation (radians)
void SetGlyphSize(const VECTOR2D aSize)
Set the font glyph size.
const int scale
bool m_forceDisplayCursor
Always show cursor.
void SetFontUnderlined(bool aUnderlined)
void SetScale(VECTOR2< T > aScale)
Set the scale components of the matrix.
Definition: matrix3x3.h:261
void SetRotation(double aRotation)
Set the rotation angle.
bool m_globalFlipY
Flag for Y axis flipping.
VECTOR2D m_gridOffset
The grid offset to compensate cursor position.
void SetOrigin(const Vec &pos)
Definition: box2.h:210
double m_gridLineWidth
Minimum pixel distance between displayed grid lines.
void SetZoomFactor(double aZoomFactor)
Set the zoom factor of the scene.
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:68
BOX2D GetVisibleWorldExtents() const
void SetGridVisibility(bool aVisibility)
Set the visibility setting of the grid.
bool m_fullscreenCursor
Shape of the cursor (fullscreen or small cross)
void SetTranslation(VECTOR2< T > aTranslation)
Set the translation components of the matrix.
Definition: matrix3x3.h:230
void SetLookAtPoint(const VECTOR2D &aPoint)
Set the Point in world space to look at.
void SetHorizontalJustify(const EDA_TEXT_HJUSTIFY_T aHorizontalJustify)
Set the horizontal justify for text drawing.
virtual void SetIsStroke(bool aIsStrokeEnabled)
Enable/disable stroked outlines.
void SetDepthRange(const VECTOR2D &aDepthRange)
Set the range of the layer depth.
VECTOR2I m_screenSize
Screen size in screen coordinates.
bool m_fullscreenCursor
Force cursor display.
KICURSOR m_currentNativeCursor
Current cursor.
static const int MAX_DEPTH
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:98