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
124void drawTicksAlongLine( KIGFX::VIEW* aView, const VECTOR2D& aOrigin, const VECTOR2D& aLine,
125 double aMinorTickLen, const EDA_IU_SCALE& aIuScale, EDA_UNITS aUnits,
126 bool aDrawingDropShadows )
127{
128 KIGFX::GAL* gal = aView->GetGAL();
130 double tickSpace;
131 TICK_FORMAT tickFormat = getTickFormatForScale( gal->GetWorldScale(), tickSpace, aUnits );
132 double majorTickLen = aMinorTickLen * ( majorTickLengthFactor + 1 );
133 VECTOR2D tickLine = aLine;
134
135 RotatePoint( tickLine, ANGLE_90 );
136
137 const double rulerLen = aLine.EuclideanNorm();
138
139 // A degenerate or non-finite ruler makes the unit-axis vectors below divide by zero and the
140 // tick-index casts below undefined; bail before either.
141 if( !( rulerLen > 0.0 ) || !( tickSpace > 0.0 ) || !std::isfinite( rulerLen )
142 || !std::isfinite( tickSpace ) )
143 return;
144
145 // Convert a tick-index double to int64_t without undefined behaviour. The int64_t bounds are
146 // not exactly representable as double, so compare and return the sentinels directly rather
147 // than casting a rounded boundary back to int64_t.
148 auto toTick =
149 []( double aValue ) -> int64_t
150 {
151 constexpr double lo = static_cast<double>( std::numeric_limits<int64_t>::min() );
152 constexpr double hi = static_cast<double>( std::numeric_limits<int64_t>::max() );
153
154 if( aValue <= lo )
155 return std::numeric_limits<int64_t>::min();
156
157 if( aValue >= hi )
158 return std::numeric_limits<int64_t>::max();
159
160 return static_cast<int64_t>( aValue );
161 };
162
163 const int64_t lastRulerTick = std::max<int64_t>( 0, toTick( std::ceil( rulerLen / tickSpace ) ) - 1 );
164
165 // work out which way up the tick labels go
166 TEXT_DIMS labelDims = GetConstantGlyphHeight( gal, -1 );
167 EDA_ANGLE labelAngle = - EDA_ANGLE( tickLine );
168 VECTOR2D labelOffset = tickLine.Resize( majorTickLen );
169
170 // text is left (or right) aligned, so shadow text need a small offset to be draw
171 // around the basic text
172 double shadowXoffset = 0.0;
173
174 if( aDrawingDropShadows )
175 {
176 labelDims.StrokeWidth += 2 * labelDims.ShadowWidth;
177 shadowXoffset = labelDims.ShadowWidth;
178
179 // Due to the fact a shadow text is drawn left or right aligned,
180 // it needs an offset = shadowXoffset to be drawn at the same place as normal text
181 // But for some reason we need to slightly modify this offset
182 // for a better look for KiCad font (better alignment of shadow shape)
183 const double adjust = 1.2; // Value chosen after tests
184 shadowXoffset *= adjust;
185 }
186
187 if( aView->IsMirroredX() )
188 {
189 labelOffset = -labelOffset;
190 shadowXoffset = -shadowXoffset;
191 }
192
193 TEXT_ATTRIBUTES labelAttrs;
194 labelAttrs.m_Size = labelDims.GlyphSize;
195 labelAttrs.m_StrokeWidth = labelDims.StrokeWidth;
196 labelAttrs.m_Mirrored = aView->IsMirroredX(); // Prevent text mirrored when view is mirrored
197
198 if( EDA_ANGLE( aLine ) > ANGLE_0 )
199 {
200 labelAttrs.m_Halign = GR_TEXT_H_ALIGN_LEFT;
201 labelAttrs.m_Angle = labelAngle;
202
203 // Adjust the text position of the shadow shape:
204 labelOffset.x -= shadowXoffset * labelAttrs.m_Angle.GetAngle().Cos();
205 labelOffset.y += shadowXoffset * labelAttrs.m_Angle.GetAngle().Sin();
206 }
207 else
208 {
209 labelAttrs.m_Halign = GR_TEXT_H_ALIGN_RIGHT;
210 labelAttrs.m_Angle = labelAngle + ANGLE_180;
211
212 // Adjust the text position of the shadow shape:
213 labelOffset.x += shadowXoffset * labelAttrs.m_Angle.GetAngle().Cos();
214 labelOffset.y -= shadowXoffset * labelAttrs.m_Angle.GetAngle().Sin();
215 }
216
217 BOX2D viewportD = aView->GetViewport();
218 viewportD.Inflate( majorTickLen * 2 ); // Doesn't have to be accurate, just big enough not
219 // to exclude anything that should be partially drawn
220
221 // Project the inflated viewport onto the ruler axis to skip off-screen ticks.
222 // At extreme zoom tickSpace can be tiny, causing millions of iterations without this cull.
223 // Projecting an AABB onto a unit axis gives center.axis +/- sum( abs( halfExtent_i * axis_i ) ).
224 const VECTOR2D unitLine = aLine / rulerLen;
225 const VECTOR2D center = viewportD.Centre();
226 const double halfWidth = viewportD.GetWidth() / 2;
227 const double halfHeight = viewportD.GetHeight() / 2;
228 const double centerProj = ( center - aOrigin ).Dot( unitLine );
229 const double halfProj = std::abs( halfWidth * unitLine.x ) + std::abs( halfHeight * unitLine.y );
230 const double minProj = centerProj - halfProj;
231 const double maxProj = centerProj + halfProj;
232
233 // Guard the float-to-int casts below against a NaN/inf viewport.
234 if( !std::isfinite( minProj ) || !std::isfinite( maxProj ) )
235 return;
236
237 // The -1/+1 pad is a one-tick safety margin; saturate so it cannot overflow the sentinels.
238 const int64_t minTick = toTick( std::floor( minProj / tickSpace ) );
239 const int64_t maxTick = toTick( std::ceil( maxProj / tickSpace ) );
240 const int64_t firstTick = std::max<int64_t>( 0, minTick > std::numeric_limits<int64_t>::min()
241 ? minTick - 1 : minTick );
242 const int64_t lastTick = std::min<int64_t>( lastRulerTick,
243 maxTick < std::numeric_limits<int64_t>::max()
244 ? maxTick + 1 : maxTick );
245
246 if( firstTick > lastTick )
247 return;
248
249 int isign = aView->IsMirroredX() ? -1 : 1;
250
251 const VECTOR2D tickDir = tickLine / rulerLen; // unit perpendicular to ruler axis
252
253 for( int64_t i = firstTick; i <= lastTick; ++i )
254 {
255 const VECTOR2D tickPos = aOrigin + unitLine * ( tickSpace * i );
256
257 double length = aMinorTickLen;
258 bool drawLabel = false;
259
260 if( i % tickFormat.majorStep == 0 )
261 {
262 drawLabel = true;
263 length *= majorTickLengthFactor;
264 }
265 else if( tickFormat.midStep && i % tickFormat.midStep == 0 )
266 {
267 drawLabel = true;
268 length *= midTickLengthFactor;
269 }
270
271 gal->SetLineWidth( labelAttrs.m_StrokeWidth / 2 );
272 gal->DrawLine( tickPos, tickPos + tickDir * ( length * isign ) );
273
274 if( drawLabel )
275 {
276 wxString label = DimensionLabel( "", tickSpace * i, aIuScale, aUnits, false );
277 font->Draw( gal, label, tickPos + labelOffset, labelAttrs, KIFONT::METRICS::Default() );
278 }
279 }
280}
281
282
293void drawBacksideTicks( KIGFX::VIEW* aView, const VECTOR2D& aOrigin, const VECTOR2D& aLine,
294 double aTickLen, int aNumDivisions, bool aDrawingDropShadows )
295{
296 KIGFX::GAL* gal = aView->GetGAL();
297 TEXT_DIMS textDims = GetConstantGlyphHeight( gal, -1 );
298 const double backTickSpace = aLine.EuclideanNorm() / aNumDivisions;
299 VECTOR2D backTickVec = aLine;
300 int isign = aView->IsMirroredX() ? -1 : 1;
301
302 RotatePoint( backTickVec, -ANGLE_90 );
303 backTickVec = backTickVec.Resize( aTickLen * isign );
304
305 BOX2D viewportD = aView->GetViewport();
306 viewportD.Inflate( aTickLen * 4 ); // Doesn't have to be accurate, just big enough not to
307 // exclude anything that should be partially drawn
308
309 for( int i = 0; i < aNumDivisions + 1; ++i )
310 {
311 const VECTOR2D backTickPos = aOrigin + aLine.Resize( backTickSpace * i );
312
313 if( !viewportD.Contains( backTickPos ) )
314 continue;
315
316 gal->SetLineWidth( getTickLineWidth( textDims, aDrawingDropShadows ) );
317 gal->DrawLine( backTickPos, backTickPos + backTickVec );
318 }
319}
320
321
323 EDA_UNITS userUnits, bool aFlipX, bool aFlipY )
324 : EDA_ITEM( NOT_USED ), // Never added to anything - just a preview
325 m_geomMgr( aGeomMgr ),
326 m_userUnits( userUnits ),
327 m_iuScale( aIuScale ),
328 m_flipX( aFlipX ),
329 m_flipY( aFlipY )
330{
331}
332
333
335{
336 BOX2I tmp;
337
338 if( m_geomMgr.GetOrigin() == m_geomMgr.GetEnd() )
339 return tmp;
340
341 // this is an edit-time artefact; no reason to try and be smart with the bounding box
342 // (besides, we can't tell the text extents without a view to know what the scale is)
343 tmp.SetMaximum();
344 return tmp;
345}
346
347
348std::vector<int> RULER_ITEM::ViewGetLayers() const
349{
350 std::vector<int> layers{ LAYER_SELECT_OVERLAY, LAYER_GP_OVERLAY };
351 return layers;
352}
353
354
355void RULER_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
356{
357 KIGFX::GAL* gal = aView->GetGAL();
358 RENDER_SETTINGS* rs = aView->GetPainter()->GetSettings();
359 bool drawingDropShadows = ( aLayer == getShadowLayer( gal ) );
360
362 gal->SetLayerDepth( gal->GetMinDepth() );
363
364 VECTOR2D origin = m_geomMgr.GetOrigin();
365 VECTOR2D end = m_geomMgr.GetEnd();
366
367 gal->SetIsStroke( true );
368 gal->SetIsFill( false );
369 gal->SetTextMirrored( false );
370
371 if( m_color )
372 gal->SetStrokeColor( *m_color );
373 else
375
376 if( drawingDropShadows )
378
379 gal->ResetTextAttributes();
380 TEXT_DIMS textDims = GetConstantGlyphHeight( gal );
381
382 // draw the main line from the origin to cursor
383 gal->SetLineWidth( getTickLineWidth( textDims, drawingDropShadows ) );
384 gal->DrawLine( origin, end );
385
386 VECTOR2D rulerVec( end - origin );
387
388 wxArrayString cursorStrings = GetDimensionStrings();
389
390 // Choose a text quadrant that keeps the measurement text on-screen while avoiding
391 // overlapping the ruler geometry. Start with the preferred direction (away from the
392 // origin) and fall back to other quadrants as needed to keep the label visible.
393 int prefX = rulerVec.y < 0.0 ? -1 : 1;
394 int prefY = rulerVec.x < 0.0 ? 1 : -1;
395
396 double scale = gal->GetWorldScale();
397
398 TEXT_DIMS dims = GetConstantGlyphHeight( gal );
400 double width = 0.0;
401
402 for( const wxString& s : cursorStrings )
403 {
404 VECTOR2I extents = font->StringBoundaryLimits( s, dims.GlyphSize, dims.StrokeWidth, false, false,
406 width = std::max( width, (double) extents.x );
407 }
408
409 double height = dims.LinePitch * cursorStrings.size();
410
411 // Convert to screen coordinates for visibility checks
412 VECTOR2D cursorScreen = gal->ToScreen( end );
413 VECTOR2I screenSize = gal->GetScreenPixelSize();
414 double offsetX = 15.0; // same as DrawTextNextToCursor()
415 double offsetY = dims.LinePitch * scale; // vertical spacing from cursor
416
417 auto fits =
418 [&]( int sx, int sy )
419 {
420 double left, right, top, bottom;
421 double xStart = cursorScreen.x + ( sx < 0 ? offsetX : -offsetX );
422
423 if( sx < 0 )
424 {
425 left = xStart;
426 right = left + width * scale;
427 }
428 else
429 {
430 right = xStart;
431 left = right - width * scale;
432 }
433
434 if( sy > 0 ) // above cursor
435 {
436 bottom = cursorScreen.y - offsetY;
437 top = bottom - height * scale;
438 }
439 else // below cursor
440 {
441 top = cursorScreen.y + offsetY;
442 bottom = top + height * scale;
443 }
444
445 return left >= 0 && right <= screenSize.x && top >= 0 && bottom <= screenSize.y;
446 };
447
448 std::vector<VECTOR2I> candidates = { { prefX, prefY }, { -prefX, prefY },
449 { prefX, -prefY }, { -prefX, -prefY } };
450
451 VECTOR2I chosen = candidates[0];
452 double bestDot = -1.0;
453
454 for( const VECTOR2I& c : candidates )
455 {
456 double dot = c.x * prefX + c.y * prefY;
457
458 if( dot >= 0 && fits( c.x, c.y ) )
459 {
460 if( dot > bestDot )
461 {
462 bestDot = dot;
463 chosen = c;
464 }
465 }
466 }
467
468 VECTOR2D quadrant( chosen.x, chosen.y );
469 DrawTextNextToCursor( aView, end, quadrant, cursorStrings, drawingDropShadows );
470
471 // basic tick size
472 double minorTickLen = 5.0 / gal->GetWorldScale();
473 double majorTickLen = minorTickLen * majorTickLengthFactor;
474
475 if( m_showTicks )
476 {
477 drawTicksAlongLine( aView, origin, rulerVec, minorTickLen, m_iuScale, m_userUnits, drawingDropShadows );
478 drawBacksideTicks( aView, origin, rulerVec, majorTickLen, 2, drawingDropShadows );
479 }
480
482 {
483 const EDA_ANGLE arrowAngle{ 30.0 };
484 VECTOR2D arrowHead = rulerVec;
485 RotatePoint( arrowHead, arrowAngle );
486 arrowHead = arrowHead.Resize( majorTickLen );
487
488 gal->DrawLine( end, end - arrowHead );
489
490 arrowHead = rulerVec;
491 RotatePoint( arrowHead, -arrowAngle );
492 arrowHead = arrowHead.Resize( majorTickLen );
493
494 gal->DrawLine( end, end - arrowHead );
495 }
496 else
497 {
498 // draw the back of the origin "crosshair"
499 gal->DrawLine( origin, origin + rulerVec.Resize( -minorTickLen * midTickLengthFactor ) );
500 }
501}
502
503
505{
506 const VECTOR2D rulerVec = m_geomMgr.GetEnd() - m_geomMgr.GetOrigin();
507 VECTOR2D temp = rulerVec;
508
509 if( m_flipX )
510 temp.x = -temp.x;
511
512 if( m_flipY )
513 temp.y = -temp.y;
514
515 wxArrayString cursorStrings;
516
517 cursorStrings.push_back( DimensionLabel( "x", temp.x, m_iuScale, m_userUnits ) );
518 cursorStrings.push_back( DimensionLabel( "y", temp.y, m_iuScale, m_userUnits ) );
519
520 cursorStrings.push_back( DimensionLabel( "r", rulerVec.EuclideanNorm(), m_iuScale, m_userUnits ) );
521
522 EDA_ANGLE angle = -EDA_ANGLE( rulerVec );
523 cursorStrings.push_back( DimensionLabel( wxString::FromUTF8( "θ" ), angle.AsDegrees(), m_iuScale,
525 return cursorStrings;
526}
BOX2< VECTOR2I > BOX2I
Definition box2.h:914
BOX2< VECTOR2D > BOX2D
Definition box2.h:915
constexpr void SetMaximum()
Definition box2.h:77
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition box2.h:553
constexpr size_type GetWidth() const
Definition box2.h:211
constexpr Vec Centre() const
Definition box2.h:94
constexpr size_type GetHeight() const
Definition box2.h:212
constexpr bool Contains(const Vec &aPoint) const
Definition box2.h:165
double Sin() const
Definition eda_angle.h:177
double AsDegrees() const
Definition eda_angle.h:115
double Cos() const
Definition eda_angle.h:196
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
Definition eda_item.cpp:84
EDA_ANGLE GetAngle() const
Definition eda_angle.h:533
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:240
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:439
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
Return the all the layers within the VIEW the object is painted on.
RULER_ITEM(const TWO_POINT_GEOMETRY_MANAGER &m_geomMgr, const EDA_IU_SCALE &aIuScale, EDA_UNITS userUnits, bool aFlipX, bool aFlipY)
const TWO_POINT_GEOMETRY_MANAGER & m_geomMgr
Definition ruler_item.h:96
wxArrayString GetDimensionStrings() const
Get the strings for the dimensions of the ruler.
std::optional< COLOR4D > m_color
Definition ruler_item.h:101
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 bounding box of the item covering all its layers.
const EDA_IU_SCALE & m_iuScale
Definition ruler_item.h:98
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:611
GAL * GetGAL() const
Return the GAL this view is using to draw graphical primitives.
Definition view.h:209
bool IsMirroredX() const
Return true if view is flipped across the X axis.
Definition view.h:257
PAINTER * GetPainter() const
Return the painter object used by the view for drawing VIEW_ITEM objects.
Definition view.h:227
EDA_ORIENTATION m_Angle
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:281
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
Definition vector2d.h:406
static constexpr EDA_ANGLE ANGLE_0
Definition eda_angle.h:448
static constexpr EDA_ANGLE ANGLE_90
Definition eda_angle.h:450
static constexpr EDA_ANGLE ANGLE_180
Definition eda_angle.h:452
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:437
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)
static std::vector< int > candidates(const SEGMENT_INDEX &aIndex, const SEG &aQuery, int aPadding)
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:227
@ NOT_USED
the 3d code uses this value
Definition typeinfo.h:71
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708
VECTOR2< double > VECTOR2D
Definition vector2d.h:707