KiCad PCB EDA Suite
Loading...
Searching...
No Matches
ruler_item.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 The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#include <algorithm>
21#include <cmath>
22#include <limits>
23
27#include <layer_ids.h>
28#include <gal/painter.h>
29#include <view/view.h>
30#include <trigo.h>
31
32using namespace KIGFX::PREVIEW;
33
34static const double maxTickDensity = 10.0; // min pixels between tick marks
35static const double midTickLengthFactor = 1.5;
36static const double majorTickLengthFactor = 2.5;
37
38
39/*
40 * It would be nice to know why Cairo seems to have an opposite layer order from GAL, but
41 * only when drawing RULER_ITEMs (the TWO_POINT_ASSISTANT and ARC_ASSISTANT are immune from
42 * this issue).
43 *
44 * Until then, this egregious hack...
45 */
46static int getShadowLayer( KIGFX::GAL* aGal )
47{
48 if( aGal->IsCairoEngine() )
50 else
51 return LAYER_GP_OVERLAY;
52}
53
54
55static double getTickLineWidth( const TEXT_DIMS& textDims, bool aDrawingDropShadows )
56{
57 double width = textDims.StrokeWidth * 0.8;
58
59 if( aDrawingDropShadows )
60 width += textDims.ShadowWidth;
61
62 return width;
63}
64
65
71{
72 double divisionBase;
74 int midStep;
75};
76
77
78static TICK_FORMAT getTickFormatForScale( double aScale, double& aTickSpace, EDA_UNITS aUnits )
79{
80 // simple 1/2/5 scales per decade
81 static std::vector<TICK_FORMAT> tickFormats =
82 {
83 { 2, 10, 5 }, // |....:....|
84 { 2, 5, 0 }, // |....|
85 { 2.5, 2, 0 }, // |.|.|
86 };
87
88 // could start at a set number of MM, but that's not available in common
89 aTickSpace = 1;
90
91 // Convert to a round (mod-10) number of mils for imperial units
92 if( EDA_UNIT_UTILS::IsImperialUnit( aUnits ) )
93 aTickSpace *= 2.54;
94
95 int tickFormat = 0;
96
97 while( true )
98 {
99 const auto pixelSpace = aTickSpace * aScale;
100
101 if( pixelSpace >= maxTickDensity )
102 break;
103
104 tickFormat = ( tickFormat + 1 ) % tickFormats.size();
105 aTickSpace *= tickFormats[tickFormat].divisionBase;
106 }
107
108 return tickFormats[tickFormat];
109}
110
111
121void drawTicksAlongLine( KIGFX::VIEW* aView, const VECTOR2D& aOrigin, const VECTOR2D& aLine,
122 double aMinorTickLen, const EDA_IU_SCALE& aIuScale, EDA_UNITS aUnits,
123 bool aDrawingDropShadows )
124{
125 KIGFX::GAL* gal = aView->GetGAL();
127 double tickSpace;
128 TICK_FORMAT tickFormat = getTickFormatForScale( gal->GetWorldScale(), tickSpace, aUnits );
129 double majorTickLen = aMinorTickLen * ( majorTickLengthFactor + 1 );
130 VECTOR2D tickLine = aLine;
131
132 RotatePoint( tickLine, ANGLE_90 );
133
134 const double rulerLen = aLine.EuclideanNorm();
135
136 // A degenerate or non-finite ruler makes the unit-axis vectors below divide by zero and the
137 // tick-index casts below undefined; bail before either.
138 if( !( rulerLen > 0.0 ) || !( tickSpace > 0.0 ) || !std::isfinite( rulerLen )
139 || !std::isfinite( tickSpace ) )
140 return;
141
142 // Convert a tick-index double to int64_t without undefined behaviour. The int64_t bounds are
143 // not exactly representable as double, so compare and return the sentinels directly rather
144 // than casting a rounded boundary back to int64_t.
145 auto toTick =
146 []( double aValue ) -> int64_t
147 {
148 constexpr double lo = static_cast<double>( std::numeric_limits<int64_t>::min() );
149 constexpr double hi = static_cast<double>( std::numeric_limits<int64_t>::max() );
150
151 if( aValue <= lo )
152 return std::numeric_limits<int64_t>::min();
153
154 if( aValue >= hi )
155 return std::numeric_limits<int64_t>::max();
156
157 return static_cast<int64_t>( aValue );
158 };
159
160 const int64_t lastRulerTick = std::max<int64_t>( 0, toTick( std::ceil( rulerLen / tickSpace ) ) - 1 );
161
162 // work out which way up the tick labels go
163 TEXT_DIMS labelDims = GetConstantGlyphHeight( gal, -1 );
164 EDA_ANGLE labelAngle = - EDA_ANGLE( tickLine );
165 VECTOR2D labelOffset = tickLine.Resize( majorTickLen );
166
167 // text is left (or right) aligned, so shadow text need a small offset to be draw
168 // around the basic text
169 double shadowXoffset = 0.0;
170
171 if( aDrawingDropShadows )
172 {
173 labelDims.StrokeWidth += 2 * labelDims.ShadowWidth;
174 shadowXoffset = labelDims.ShadowWidth;
175
176 // Due to the fact a shadow text is drawn left or right aligned,
177 // it needs an offset = shadowXoffset to be drawn at the same place as normal text
178 // But for some reason we need to slightly modify this offset
179 // for a better look for KiCad font (better alignment of shadow shape)
180 const double adjust = 1.2; // Value chosen after tests
181 shadowXoffset *= adjust;
182 }
183
184 if( aView->IsMirroredX() )
185 {
186 labelOffset = -labelOffset;
187 shadowXoffset = -shadowXoffset;
188 }
189
190 TEXT_ATTRIBUTES labelAttrs;
191 labelAttrs.m_Size = labelDims.GlyphSize;
192 labelAttrs.m_StrokeWidth = labelDims.StrokeWidth;
193 labelAttrs.m_Mirrored = aView->IsMirroredX(); // Prevent text mirrored when view is mirrored
194
195 if( EDA_ANGLE( aLine ) > ANGLE_0 )
196 {
197 labelAttrs.m_Halign = GR_TEXT_H_ALIGN_LEFT;
198 labelAttrs.m_Angle = labelAngle;
199
200 // Adjust the text position of the shadow shape:
201 labelOffset.x -= shadowXoffset * labelAttrs.m_Angle.Cos();
202 labelOffset.y += shadowXoffset * labelAttrs.m_Angle.Sin();
203 }
204 else
205 {
206 labelAttrs.m_Halign = GR_TEXT_H_ALIGN_RIGHT;
207 labelAttrs.m_Angle = labelAngle + ANGLE_180;
208
209 // Adjust the text position of the shadow shape:
210 labelOffset.x += shadowXoffset * labelAttrs.m_Angle.Cos();
211 labelOffset.y -= shadowXoffset * labelAttrs.m_Angle.Sin();
212 }
213
214 BOX2D viewportD = aView->GetViewport();
215 viewportD.Inflate( majorTickLen * 2 ); // Doesn't have to be accurate, just big enough not
216 // to exclude anything that should be partially drawn
217
218 // Project the inflated viewport onto the ruler axis to skip off-screen ticks.
219 // At extreme zoom tickSpace can be tiny, causing millions of iterations without this cull.
220 // Projecting an AABB onto a unit axis gives center.axis +/- sum( abs( halfExtent_i * axis_i ) ).
221 const VECTOR2D unitLine = aLine / rulerLen;
222 const VECTOR2D center = viewportD.Centre();
223 const double halfWidth = viewportD.GetWidth() / 2;
224 const double halfHeight = viewportD.GetHeight() / 2;
225 const double centerProj = ( center - aOrigin ).Dot( unitLine );
226 const double halfProj = std::abs( halfWidth * unitLine.x ) + std::abs( halfHeight * unitLine.y );
227 const double minProj = centerProj - halfProj;
228 const double maxProj = centerProj + halfProj;
229
230 // Guard the float-to-int casts below against a NaN/inf viewport.
231 if( !std::isfinite( minProj ) || !std::isfinite( maxProj ) )
232 return;
233
234 // The -1/+1 pad is a one-tick safety margin; saturate so it cannot overflow the sentinels.
235 const int64_t minTick = toTick( std::floor( minProj / tickSpace ) );
236 const int64_t maxTick = toTick( std::ceil( maxProj / tickSpace ) );
237 const int64_t firstTick = std::max<int64_t>( 0, minTick > std::numeric_limits<int64_t>::min()
238 ? minTick - 1 : minTick );
239 const int64_t lastTick = std::min<int64_t>( lastRulerTick,
240 maxTick < std::numeric_limits<int64_t>::max()
241 ? maxTick + 1 : maxTick );
242
243 if( firstTick > lastTick )
244 return;
245
246 int isign = aView->IsMirroredX() ? -1 : 1;
247
248 const VECTOR2D tickDir = tickLine / rulerLen; // unit perpendicular to ruler axis
249
250 for( int64_t i = firstTick; i <= lastTick; ++i )
251 {
252 const VECTOR2D tickPos = aOrigin + unitLine * ( tickSpace * i );
253
254 double length = aMinorTickLen;
255 bool drawLabel = false;
256
257 if( i % tickFormat.majorStep == 0 )
258 {
259 drawLabel = true;
260 length *= majorTickLengthFactor;
261 }
262 else if( tickFormat.midStep && i % tickFormat.midStep == 0 )
263 {
264 drawLabel = true;
265 length *= midTickLengthFactor;
266 }
267
268 gal->SetLineWidth( labelAttrs.m_StrokeWidth / 2 );
269 gal->DrawLine( tickPos, tickPos + tickDir * ( length * isign ) );
270
271 if( drawLabel )
272 {
273 wxString label = DimensionLabel( "", tickSpace * i, aIuScale, aUnits, false );
274 font->Draw( gal, label, tickPos + labelOffset, labelAttrs, KIFONT::METRICS::Default() );
275 }
276 }
277}
278
279
290void drawBacksideTicks( KIGFX::VIEW* aView, const VECTOR2D& aOrigin, const VECTOR2D& aLine,
291 double aTickLen, int aNumDivisions, bool aDrawingDropShadows )
292{
293 KIGFX::GAL* gal = aView->GetGAL();
294 TEXT_DIMS textDims = GetConstantGlyphHeight( gal, -1 );
295 const double backTickSpace = aLine.EuclideanNorm() / aNumDivisions;
296 VECTOR2D backTickVec = aLine;
297 int isign = aView->IsMirroredX() ? -1 : 1;
298
299 RotatePoint( backTickVec, -ANGLE_90 );
300 backTickVec = backTickVec.Resize( aTickLen * isign );
301
302 BOX2D viewportD = aView->GetViewport();
303 viewportD.Inflate( aTickLen * 4 ); // Doesn't have to be accurate, just big enough not to
304 // exclude anything that should be partially drawn
305
306 for( int i = 0; i < aNumDivisions + 1; ++i )
307 {
308 const VECTOR2D backTickPos = aOrigin + aLine.Resize( backTickSpace * i );
309
310 if( !viewportD.Contains( backTickPos ) )
311 continue;
312
313 gal->SetLineWidth( getTickLineWidth( textDims, aDrawingDropShadows ) );
314 gal->DrawLine( backTickPos, backTickPos + backTickVec );
315 }
316}
317
318
320 EDA_UNITS userUnits, bool aFlipX, bool aFlipY )
321 : EDA_ITEM( NOT_USED ), // Never added to anything - just a preview
322 m_geomMgr( aGeomMgr ),
323 m_userUnits( userUnits ),
324 m_iuScale( aIuScale ),
325 m_flipX( aFlipX ),
326 m_flipY( aFlipY )
327{
328}
329
330
332{
333 BOX2I tmp;
334
335 if( m_geomMgr.GetOrigin() == m_geomMgr.GetEnd() )
336 return tmp;
337
338 // this is an edit-time artefact; no reason to try and be smart with the bounding box
339 // (besides, we can't tell the text extents without a view to know what the scale is)
340 tmp.SetMaximum();
341 return tmp;
342}
343
344
345std::vector<int> RULER_ITEM::ViewGetLayers() const
346{
347 std::vector<int> layers{ LAYER_SELECT_OVERLAY, LAYER_GP_OVERLAY };
348 return layers;
349}
350
351
352void RULER_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
353{
354 KIGFX::GAL* gal = aView->GetGAL();
355 RENDER_SETTINGS* rs = aView->GetPainter()->GetSettings();
356 bool drawingDropShadows = ( aLayer == getShadowLayer( gal ) );
357
359 gal->SetLayerDepth( gal->GetMinDepth() );
360
361 VECTOR2D origin = m_geomMgr.GetOrigin();
362 VECTOR2D end = m_geomMgr.GetEnd();
363
364 gal->SetIsStroke( true );
365 gal->SetIsFill( false );
366 gal->SetTextMirrored( false );
367
368 if( m_color )
369 gal->SetStrokeColor( *m_color );
370 else
372
373 if( drawingDropShadows )
375
376 gal->ResetTextAttributes();
377 TEXT_DIMS textDims = GetConstantGlyphHeight( gal );
378
379 // draw the main line from the origin to cursor
380 gal->SetLineWidth( getTickLineWidth( textDims, drawingDropShadows ) );
381 gal->DrawLine( origin, end );
382
383 VECTOR2D rulerVec( end - origin );
384
385 wxArrayString cursorStrings = GetDimensionStrings();
386
387 // Choose a text quadrant that keeps the measurement text on-screen while avoiding
388 // overlapping the ruler geometry. Start with the preferred direction (away from the
389 // origin) and fall back to other quadrants as needed to keep the label visible.
390 int prefX = rulerVec.y < 0.0 ? -1 : 1;
391 int prefY = rulerVec.x < 0.0 ? 1 : -1;
392
393 double scale = gal->GetWorldScale();
394
395 TEXT_DIMS dims = GetConstantGlyphHeight( gal );
397 double width = 0.0;
398
399 for( const wxString& s : cursorStrings )
400 {
401 VECTOR2I extents = font->StringBoundaryLimits( s, dims.GlyphSize, dims.StrokeWidth, false, false,
403 width = std::max( width, (double) extents.x );
404 }
405
406 double height = dims.LinePitch * cursorStrings.size();
407
408 // Convert to screen coordinates for visibility checks
409 VECTOR2D cursorScreen = gal->ToScreen( end );
410 VECTOR2I screenSize = gal->GetScreenPixelSize();
411 double offsetX = 15.0; // same as DrawTextNextToCursor()
412 double offsetY = dims.LinePitch * scale; // vertical spacing from cursor
413
414 auto fits =
415 [&]( int sx, int sy )
416 {
417 double left, right, top, bottom;
418 double xStart = cursorScreen.x + ( sx < 0 ? offsetX : -offsetX );
419
420 if( sx < 0 )
421 {
422 left = xStart;
423 right = left + width * scale;
424 }
425 else
426 {
427 right = xStart;
428 left = right - width * scale;
429 }
430
431 if( sy > 0 ) // above cursor
432 {
433 bottom = cursorScreen.y - offsetY;
434 top = bottom - height * scale;
435 }
436 else // below cursor
437 {
438 top = cursorScreen.y + offsetY;
439 bottom = top + height * scale;
440 }
441
442 return left >= 0 && right <= screenSize.x && top >= 0 && bottom <= screenSize.y;
443 };
444
445 std::vector<VECTOR2I> candidates = { { prefX, prefY }, { -prefX, prefY },
446 { prefX, -prefY }, { -prefX, -prefY } };
447
448 VECTOR2I chosen = candidates[0];
449 double bestDot = -1.0;
450
451 for( const VECTOR2I& c : candidates )
452 {
453 double dot = c.x * prefX + c.y * prefY;
454
455 if( dot >= 0 && fits( c.x, c.y ) )
456 {
457 if( dot > bestDot )
458 {
459 bestDot = dot;
460 chosen = c;
461 }
462 }
463 }
464
465 VECTOR2D quadrant( chosen.x, chosen.y );
466 DrawTextNextToCursor( aView, end, quadrant, cursorStrings, drawingDropShadows );
467
468 // basic tick size
469 double minorTickLen = 5.0 / gal->GetWorldScale();
470 double majorTickLen = minorTickLen * majorTickLengthFactor;
471
472 if( m_showTicks )
473 {
474 drawTicksAlongLine( aView, origin, rulerVec, minorTickLen, m_iuScale, m_userUnits, drawingDropShadows );
475 drawBacksideTicks( aView, origin, rulerVec, majorTickLen, 2, drawingDropShadows );
476 }
477
479 {
480 const EDA_ANGLE arrowAngle{ 30.0 };
481 VECTOR2D arrowHead = rulerVec;
482 RotatePoint( arrowHead, arrowAngle );
483 arrowHead = arrowHead.Resize( majorTickLen );
484
485 gal->DrawLine( end, end - arrowHead );
486
487 arrowHead = rulerVec;
488 RotatePoint( arrowHead, -arrowAngle );
489 arrowHead = arrowHead.Resize( majorTickLen );
490
491 gal->DrawLine( end, end - arrowHead );
492 }
493 else
494 {
495 // draw the back of the origin "crosshair"
496 gal->DrawLine( origin, origin + rulerVec.Resize( -minorTickLen * midTickLengthFactor ) );
497 }
498}
499
500
502{
503 const VECTOR2D rulerVec = m_geomMgr.GetEnd() - m_geomMgr.GetOrigin();
504 VECTOR2D temp = rulerVec;
505
506 if( m_flipX )
507 temp.x = -temp.x;
508
509 if( m_flipY )
510 temp.y = -temp.y;
511
512 wxArrayString cursorStrings;
513
514 cursorStrings.push_back( DimensionLabel( "x", temp.x, m_iuScale, m_userUnits ) );
515 cursorStrings.push_back( DimensionLabel( "y", temp.y, m_iuScale, m_userUnits ) );
516
517 cursorStrings.push_back( DimensionLabel( "r", rulerVec.EuclideanNorm(), m_iuScale, m_userUnits ) );
518
519 EDA_ANGLE angle = -EDA_ANGLE( rulerVec );
520 cursorStrings.push_back( DimensionLabel( wxString::FromUTF8( "θ" ), angle.AsDegrees(), m_iuScale,
522 return cursorStrings;
523}
BOX2< VECTOR2I > BOX2I
Definition box2.h:918
BOX2< VECTOR2D > BOX2D
Definition box2.h:919
constexpr void SetMaximum()
Definition box2.h:76
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition box2.h:554
constexpr size_type GetWidth() const
Definition box2.h:210
constexpr Vec Centre() const
Definition box2.h:93
constexpr size_type GetHeight() const
Definition box2.h:211
constexpr bool Contains(const Vec &aPoint) const
Definition box2.h:164
double Sin() const
Definition eda_angle.h:178
double AsDegrees() const
Definition eda_angle.h:116
double Cos() const
Definition eda_angle.h:197
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
Definition eda_item.cpp:37
FONT is an abstract base class for both outline and stroke fonts.
Definition font.h:94
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:143
void Draw(KIGFX::GAL *aGal, const wxString &aText, const VECTOR2I &aPosition, const VECTOR2I &aCursor, const TEXT_ATTRIBUTES &aAttributes, const METRICS &aFontMetrics, std::optional< VECTOR2I > aMousePos=std::nullopt, wxString *aActiveUrl=nullptr) const
Draw a string.
Definition font.cpp:246
VECTOR2I StringBoundaryLimits(const wxString &aText, const VECTOR2I &aSize, int aThickness, bool aBold, bool aItalic, const METRICS &aFontMetrics) const
Compute the boundary limits of aText (the bounding box of all shapes).
Definition font.cpp:447
static const METRICS & Default()
Definition font.cpp:48
Attribute save/restore for GAL attributes.
Abstract interface for drawing on a 2D-surface.
virtual void SetLayerDepth(double aLayerDepth)
Set the depth of the layer (position on the z-axis)
virtual void SetIsFill(bool aIsFillEnabled)
Enable/disable fill.
VECTOR2D ToScreen(const VECTOR2D &aPoint) const
Compute the point position in screen coordinates from given world coordinates.
const COLOR4D & GetStrokeColor() const
Get the stroke color.
void ResetTextAttributes()
Reset text attributes to default styling.
virtual void SetLineWidth(float aLineWidth)
Set the line width.
void SetTextMirrored(const bool aMirrored)
virtual void SetStrokeColor(const COLOR4D &aColor)
Set the stroke color.
virtual void SetIsStroke(bool aIsStrokeEnabled)
Enable/disable stroked outlines.
virtual bool IsCairoEngine()
Return true if the GAL engine is a Cairo based type.
virtual void DrawLine(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Draw a line.
double GetMinDepth() const
const VECTOR2I & GetScreenPixelSize() const
Return GAL canvas size in pixels.
double GetWorldScale() const
Get the world scale.
virtual RENDER_SETTINGS * GetSettings()=0
Return a pointer to current settings that are going to be used when drawing items.
std::vector< int > ViewGetLayers() const override
RULER_ITEM(const TWO_POINT_GEOMETRY_MANAGER &m_geomMgr, const EDA_IU_SCALE &aIuScale, EDA_UNITS userUnits, bool aFlipX, bool aFlipY)
Return the bounding box of the item covering all its layers.
const TWO_POINT_GEOMETRY_MANAGER & m_geomMgr
Definition ruler_item.h:97
wxArrayString GetDimensionStrings() const
Get the strings for the dimensions of the ruler.
std::optional< COLOR4D > m_color
Definition ruler_item.h:102
void ViewDraw(int aLayer, KIGFX::VIEW *aView) const override final
Draw the parts of the object belonging to layer aLayer.
const BOX2I ViewBBox() const override
Return the all the layers within the VIEW the object is painted on.
const EDA_IU_SCALE & m_iuScale
Definition ruler_item.h:99
Represent a very simple geometry manager for items that have a start and end point.
Container for all the knowledge about how graphical objects are drawn on any output surface/device.
const COLOR4D & GetLayerColor(int aLayer) const
Return the color used to draw a layer.
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition view.h:63
BOX2D GetViewport() const
Return the current viewport visible area rectangle.
Definition view.cpp:597
GAL * GetGAL() const
Return the GAL this view is using to draw graphical primitives.
Definition view.h:207
bool IsMirroredX() const
Return true if view is flipped across the X axis.
Definition view.h:255
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition view.h:225
GR_TEXT_H_ALIGN_T m_Halign
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition vector2d.h:279
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
Definition vector2d.h:381
static constexpr EDA_ANGLE ANGLE_0
Definition eda_angle.h:411
static constexpr EDA_ANGLE ANGLE_90
Definition eda_angle.h:413
static constexpr EDA_ANGLE ANGLE_180
Definition eda_angle.h:415
EDA_UNITS
Definition eda_units.h:44
@ LAYER_GP_OVERLAY
General purpose overlay.
Definition layer_ids.h:275
@ LAYER_AUX_ITEMS
Auxiliary items (guides, rule, etc).
Definition layer_ids.h:279
@ LAYER_SELECT_OVERLAY
Selected items overlay.
Definition layer_ids.h:276
KICOMMON_API bool IsImperialUnit(EDA_UNITS aUnit)
Definition eda_units.cpp:43
COLOR4D GetShadowColor(const COLOR4D &aColor)
void DrawTextNextToCursor(KIGFX::VIEW *aView, const VECTOR2D &aCursorPos, const VECTOR2D &aTextQuadrant, const wxArrayString &aStrings, bool aDrawingDropShadows)
Draw strings next to the cursor.
wxString DimensionLabel(const wxString &prefix, double aVal, const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, bool aIncludeUnits=true)
Get a formatted string showing a dimension to a sane precision with an optional prefix and unit suffi...
TEXT_DIMS GetConstantGlyphHeight(KIGFX::GAL *aGal, int aRelativeSize=0)
Set the GAL glyph height to a constant scaled value, so that it always looks the same on screen.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:400
static double getTickLineWidth(const TEXT_DIMS &textDims, bool aDrawingDropShadows)
static const double maxTickDensity
static TICK_FORMAT getTickFormatForScale(double aScale, double &aTickSpace, EDA_UNITS aUnits)
void drawBacksideTicks(KIGFX::VIEW *aView, const VECTOR2D &aOrigin, const VECTOR2D &aLine, double aTickLen, int aNumDivisions, bool aDrawingDropShadows)
Draw simple ticks on the back of a line such that the line is divided into n parts.
void drawTicksAlongLine(KIGFX::VIEW *aView, const VECTOR2D &aOrigin, const VECTOR2D &aLine, double aMinorTickLen, const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, bool aDrawingDropShadows)
Draw labeled ticks on a line.
static const double majorTickLengthFactor
static int getShadowLayer(KIGFX::GAL *aGal)
static const double midTickLengthFactor
const int scale
Description of a "tick format" for a scale factor - how many ticks there are between medium/major tic...
int majorStep
ticks between major ticks
double divisionBase
multiple from the last scale
int midStep
ticks between medium ticks (0 if no medium ticks)
KIBIS top(path, &reporter)
VECTOR2I center
VECTOR2I end
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition trigo.cpp:225
@ NOT_USED
the 3d code uses this value
Definition typeinfo.h:72
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683
VECTOR2< double > VECTOR2D
Definition vector2d.h:682