KiCad PCB EDA Suite
ruler_item.cpp File Reference
#include <preview_items/ruler_item.h>
#include <preview_items/preview_utils.h>
#include <gal/graphics_abstraction_layer.h>
#include <layer_ids.h>
#include <painter.h>
#include <view/view.h>
#include <trigo.h>

Go to the source code of this file.

Classes

struct  TICK_FORMAT
 Description of a "tick format" for a scale factor - how many ticks there are between medium/major ticks and how each scale relates to the last one. More...
 

Functions

static int getShadowLayer (KIGFX::GAL *aGal)
 
static void drawCursorStrings (KIGFX::VIEW *aView, const VECTOR2D &aCursor, const VECTOR2D &aRulerVec, EDA_UNITS aUnits, bool aDrawingDropShadows, bool aFlipX, bool aFlipY)
 
static double getTickLineWidth (const TEXT_DIMS &textDims, bool aDrawingDropShadows)
 
static TICK_FORMAT getTickFormatForScale (double aScale, double &aTickSpace, EDA_UNITS aUnits)
 
void drawTicksAlongLine (KIGFX::VIEW *aView, const VECTOR2D &aOrigin, const VECTOR2D &aLine, double aMinorTickLen, EDA_UNITS aUnits, bool aDrawingDropShadows)
 Draw labelled ticks on a line. More...
 
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. More...
 

Variables

static const double maxTickDensity = 10.0
 
static const double midTickLengthFactor = 1.5
 
static const double majorTickLengthFactor = 2.5
 

Function Documentation

◆ drawBacksideTicks()

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.

Parameters
aGalthe GAL to draw on
aOriginstart of line to draw ticks on
aLineline vector
aTickLenlength of ticks in IU
aNumDivisionsnumber of parts to divide the line into

Definition at line 242 of file ruler_item.cpp.

244 {
245  KIGFX::GAL* gal = aView->GetGAL();
246  const double backTickSpace = aLine.EuclideanNorm() / aNumDivisions;
247  const VECTOR2D backTickVec = aLine.Rotate( M_PI_2 ).Resize( aTickLen );
248  TEXT_DIMS textDims = SetConstantGlyphHeight( gal, -1 );
249 
250  BOX2D viewportD = aView->GetViewport();
251  BOX2I viewport( VECTOR2I( viewportD.GetPosition() ), VECTOR2I( viewportD.GetSize() ) );
252 
253  viewport.Inflate( aTickLen * 4 ); // Doesn't have to be accurate, just big enough not to
254  // exclude anything that should be partially drawn
255 
256  for( int i = 0; i < aNumDivisions + 1; ++i )
257  {
258  const VECTOR2D backTickPos = aOrigin + aLine.Resize( backTickSpace * i );
259 
260  if( !viewport.Contains( backTickPos ) )
261  continue;
262 
263  gal->SetLineWidth( getTickLineWidth( textDims, aDrawingDropShadows ) );
264  gal->DrawLine( backTickPos, backTickPos + backTickVec );
265  }
266 }
BOX2D GetViewport() const
Return the current viewport visible area rectangle.
Definition: view.cpp:512
TEXT_DIMS SetConstantGlyphHeight(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.
#define M_PI_2
Definition: transline.cpp:40
GAL * GetGAL() const
Return the #GAL this view is using to draw graphical primitives.
Definition: view.h:190
virtual void DrawLine(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Draw a line.
VECTOR2< int > VECTOR2I
Definition: vector2d.h:622
virtual void SetLineWidth(float aLineWidth)
Set the line width.
static double getTickLineWidth(const TEXT_DIMS &textDims, bool aDrawingDropShadows)
Definition: ruler_item.cpp:84
const Vec & GetPosition() const
Definition: box2.h:177
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
Definition: vector2d.h:404
VECTOR2< T > Rotate(double aAngle) const
Rotate the vector by a given angle.
Definition: vector2d.h:371
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition: vector2d.h:293
const Vec & GetSize() const
Definition: box2.h:172
Abstract interface for drawing on a 2D-surface.

References BOX2< Vec >::Contains(), KIGFX::GAL::DrawLine(), VECTOR2< T >::EuclideanNorm(), KIGFX::VIEW::GetGAL(), BOX2< Vec >::GetPosition(), BOX2< Vec >::GetSize(), getTickLineWidth(), KIGFX::VIEW::GetViewport(), BOX2< Vec >::Inflate(), M_PI_2, VECTOR2< T >::Resize(), VECTOR2< T >::Rotate(), KIGFX::PREVIEW::SetConstantGlyphHeight(), and KIGFX::GAL::SetLineWidth().

Referenced by KIGFX::PREVIEW::RULER_ITEM::ViewDraw().

◆ drawCursorStrings()

static void drawCursorStrings ( KIGFX::VIEW aView,
const VECTOR2D aCursor,
const VECTOR2D aRulerVec,
EDA_UNITS  aUnits,
bool  aDrawingDropShadows,
bool  aFlipX,
bool  aFlipY 
)
static

Definition at line 55 of file ruler_item.cpp.

58 {
59  // draw the cursor labels
60  std::vector<wxString> cursorStrings;
61 
62  VECTOR2D temp = aRulerVec;
63 
64  if( aFlipX )
65  temp.x = -temp.x;
66 
67  if( aFlipY )
68  temp.y = -temp.y;
69 
70  cursorStrings.push_back( DimensionLabel( wxT( "x" ), temp.x, aUnits ) );
71  cursorStrings.push_back( DimensionLabel( wxT( "y" ), temp.y, aUnits ) );
72 
73  cursorStrings.push_back( DimensionLabel( wxT( "r" ), aRulerVec.EuclideanNorm(), aUnits ) );
74 
75  double degs = RAD2DECIDEG( -aRulerVec.Angle() );
76  cursorStrings.push_back( DimensionLabel( wxString::FromUTF8( "θ" ), degs,
78 
79  temp = aRulerVec;
80  DrawTextNextToCursor( aView, aCursor, -temp, cursorStrings, aDrawingDropShadows );
81 }
double RAD2DECIDEG(double rad)
Definition: trigo.h:234
wxString DimensionLabel(const wxString &prefix, double aVal, EDA_UNITS aUnits, bool aIncludeUnits=true)
Get a formatted string showing a dimension to a sane precision with an optional prefix and unit suffi...
double Angle() const
Compute the angle of the vector.
Definition: vector2d.h:307
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition: vector2d.h:293
void DrawTextNextToCursor(KIGFX::VIEW *aView, const VECTOR2D &aCursorPos, const VECTOR2D &aTextQuadrant, const std::vector< wxString > &aStrings, bool aDrawingDropShadows)
Draw strings next to the cursor.

References VECTOR2< T >::Angle(), DEGREES, KIGFX::PREVIEW::DimensionLabel(), KIGFX::PREVIEW::DrawTextNextToCursor(), VECTOR2< T >::EuclideanNorm(), RAD2DECIDEG(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by KIGFX::PREVIEW::RULER_ITEM::ViewDraw().

◆ drawTicksAlongLine()

void drawTicksAlongLine ( KIGFX::VIEW aView,
const VECTOR2D aOrigin,
const VECTOR2D aLine,
double  aMinorTickLen,
EDA_UNITS  aUnits,
bool  aDrawingDropShadows 
)

Draw labelled ticks on a line.

Ticks are spaced according to a maximum density. Minor ticks are not labelled.

Parameters
aGalthe GAL to draw on
aOriginstart of line to draw ticks on
aLineline vector
aMinorTickLenlength of minor ticks in IU

Definition at line 150 of file ruler_item.cpp.

152 {
153  KIGFX::GAL* gal = aView->GetGAL();
154  VECTOR2D tickLine = aLine.Rotate( -M_PI_2 );
155  double tickSpace;
156  TICK_FORMAT tickF = getTickFormatForScale( gal->GetWorldScale(), tickSpace, aUnits );
157 
158  // number of ticks in whole ruler
159  int numTicks = (int) std::ceil( aLine.EuclideanNorm() / tickSpace );
160 
161  // work out which way up the tick labels go
162  TEXT_DIMS textDims = SetConstantGlyphHeight( gal, -1 );
163  double textThickness = textDims.StrokeWidth;
164  double labelAngle = -tickLine.Angle();
165  double textOffset = 0;
166 
167  if( aDrawingDropShadows )
168  {
169  textOffset = textDims.ShadowWidth;
170  textThickness += 2 * textDims.ShadowWidth;
171  }
172 
173  double majorTickLen = aMinorTickLen * ( majorTickLengthFactor + 1 );
174  VECTOR2D labelOffset = tickLine.Resize( majorTickLen - textOffset );
175 
176  if( aView->IsMirroredX() )
177  {
178  textOffset = -textOffset;
179  labelOffset = -labelOffset;
180  }
181 
182  if( aLine.Angle() > 0 )
183  {
185  }
186  else
187  {
189  labelAngle += M_PI;
190  }
191 
192  BOX2D viewportD = aView->GetViewport();
193  BOX2I viewport( VECTOR2I( viewportD.GetPosition() ), VECTOR2I( viewportD.GetSize() ) );
194 
195  viewport.Inflate( majorTickLen * 2 ); // Doesn't have to be accurate, just big enough not
196  // to exclude anything that should be partially drawn
197 
198  for( int i = 0; i < numTicks; ++i )
199  {
200  const VECTOR2D tickPos = aOrigin + aLine.Resize( tickSpace * i );
201 
202  if( !viewport.Contains( tickPos ) )
203  continue;
204 
205  double length = aMinorTickLen;
206  bool drawLabel = false;
207 
208  if( i % tickF.majorStep == 0 )
209  {
210  drawLabel = true;
211  length *= majorTickLengthFactor;
212  }
213  else if( tickF.midStep && i % tickF.midStep == 0 )
214  {
215  drawLabel = true;
216  length *= midTickLengthFactor;
217  }
218 
219  gal->SetLineWidth( textThickness / 2 );
220  gal->DrawLine( tickPos, tickPos + tickLine.Resize( length ) );
221 
222  if( drawLabel )
223  {
224  wxString label = DimensionLabel( wxEmptyString, tickSpace * i, aUnits, false );
225  gal->SetLineWidth( textThickness );
226  gal->StrokeText( label, tickPos + labelOffset, labelAngle );
227  }
228  }
229 }
BOX2D GetViewport() const
Return the current viewport visible area rectangle.
Definition: view.cpp:512
TEXT_DIMS SetConstantGlyphHeight(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.
#define M_PI_2
Definition: transline.cpp:40
GAL * GetGAL() const
Return the #GAL this view is using to draw graphical primitives.
Definition: view.h:190
int midStep
ticks between medium ticks (0 if no medium ticks)
Definition: ruler_item.cpp:103
virtual void DrawLine(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Draw a line.
VECTOR2< int > VECTOR2I
Definition: vector2d.h:622
wxString DimensionLabel(const wxString &prefix, double aVal, EDA_UNITS aUnits, bool aIncludeUnits=true)
Get a formatted string showing a dimension to a sane precision with an optional prefix and unit suffi...
virtual void SetLineWidth(float aLineWidth)
Set the line width.
static const double majorTickLengthFactor
Definition: ruler_item.cpp:36
virtual void StrokeText(const wxString &aText, const VECTOR2D &aPosition, double aRotationAngle)
Draw a vector type text using preloaded Newstroke font.
static const double midTickLengthFactor
Definition: ruler_item.cpp:35
double Angle() const
Compute the angle of the vector.
Definition: vector2d.h:307
bool IsMirroredX() const
Return true if view is flipped across the X axis.
Definition: view.h:238
const Vec & GetPosition() const
Definition: box2.h:177
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
Definition: vector2d.h:404
VECTOR2< T > Rotate(double aAngle) const
Rotate the vector by a given angle.
Definition: vector2d.h:371
Description of a "tick format" for a scale factor - how many ticks there are between medium/major tic...
Definition: ruler_item.cpp:99
static TICK_FORMAT getTickFormatForScale(double aScale, double &aTickSpace, EDA_UNITS aUnits)
Definition: ruler_item.cpp:107
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
Definition: vector2d.h:293
const Vec & GetSize() const
Definition: box2.h:172
void SetHorizontalJustify(const EDA_TEXT_HJUSTIFY_T aHorizontalJustify)
Set the horizontal justify for text drawing.
int majorStep
ticks between major ticks
Definition: ruler_item.cpp:102
double GetWorldScale() const
Get the world scale.
Abstract interface for drawing on a 2D-surface.

References VECTOR2< T >::Angle(), BOX2< Vec >::Contains(), KIGFX::PREVIEW::DimensionLabel(), KIGFX::GAL::DrawLine(), VECTOR2< T >::EuclideanNorm(), KIGFX::VIEW::GetGAL(), BOX2< Vec >::GetPosition(), BOX2< Vec >::GetSize(), getTickFormatForScale(), KIGFX::VIEW::GetViewport(), KIGFX::GAL::GetWorldScale(), GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_HJUSTIFY_RIGHT, BOX2< Vec >::Inflate(), KIGFX::VIEW::IsMirroredX(), M_PI_2, TICK_FORMAT::majorStep, majorTickLengthFactor, TICK_FORMAT::midStep, midTickLengthFactor, VECTOR2< T >::Resize(), VECTOR2< T >::Rotate(), KIGFX::PREVIEW::SetConstantGlyphHeight(), KIGFX::GAL::SetHorizontalJustify(), KIGFX::GAL::SetLineWidth(), KIGFX::PREVIEW::TEXT_DIMS::ShadowWidth, KIGFX::GAL::StrokeText(), and KIGFX::PREVIEW::TEXT_DIMS::StrokeWidth.

Referenced by KIGFX::PREVIEW::RULER_ITEM::ViewDraw().

◆ getShadowLayer()

static int getShadowLayer ( KIGFX::GAL aGal)
static

Definition at line 46 of file ruler_item.cpp.

47 {
48  if( aGal->IsCairoEngine() )
49  return LAYER_SELECT_OVERLAY;
50  else
51  return LAYER_GP_OVERLAY;
52 }
currently selected items overlay
Definition: layer_ids.h:226
virtual bool IsCairoEngine()
Return true if the GAL engine is a Cairo based type.
general purpose overlay
Definition: layer_ids.h:225

References KIGFX::GAL::IsCairoEngine(), LAYER_GP_OVERLAY, and LAYER_SELECT_OVERLAY.

Referenced by KIGFX::PREVIEW::RULER_ITEM::ViewDraw().

◆ getTickFormatForScale()

static TICK_FORMAT getTickFormatForScale ( double  aScale,
double &  aTickSpace,
EDA_UNITS  aUnits 
)
static

Definition at line 107 of file ruler_item.cpp.

108 {
109  // simple 1/2/5 scales per decade
110  static std::vector<TICK_FORMAT> tickFormats =
111  {
112  { 2, 10, 5 }, // |....:....|
113  { 2, 5, 0 }, // |....|
114  { 2.5, 2, 0 }, // |.|.|
115  };
116 
117  // could start at a set number of MM, but that's not available in common
118  aTickSpace = 1;
119 
120  // Convert to a round (mod-10) number of mils for imperial units
121  if( EDA_UNIT_UTILS::IsImperialUnit( aUnits ) )
122  aTickSpace *= 2.54;
123 
124  int tickFormat = 0;
125 
126  while( true )
127  {
128  const auto pixelSpace = aTickSpace * aScale;
129 
130  if( pixelSpace >= maxTickDensity )
131  break;
132 
133  tickFormat = ( tickFormat + 1 ) % tickFormats.size();
134  aTickSpace *= tickFormats[tickFormat].divisionBase;
135  }
136 
137  return tickFormats[tickFormat];
138 }
bool IsImperialUnit(EDA_UNITS aUnit)
Definition: eda_units.cpp:26
static const double maxTickDensity
Definition: ruler_item.cpp:34

References TICK_FORMAT::divisionBase, EDA_UNIT_UTILS::IsImperialUnit(), and maxTickDensity.

Referenced by drawTicksAlongLine().

◆ getTickLineWidth()

static double getTickLineWidth ( const TEXT_DIMS textDims,
bool  aDrawingDropShadows 
)
static

Definition at line 84 of file ruler_item.cpp.

85 {
86  double width = textDims.StrokeWidth * 0.8;
87 
88  if( aDrawingDropShadows )
89  width += textDims.ShadowWidth;
90 
91  return width;
92 }

References KIGFX::PREVIEW::TEXT_DIMS::ShadowWidth, and KIGFX::PREVIEW::TEXT_DIMS::StrokeWidth.

Referenced by drawBacksideTicks(), and KIGFX::PREVIEW::RULER_ITEM::ViewDraw().

Variable Documentation

◆ majorTickLengthFactor

const double majorTickLengthFactor = 2.5
static

Definition at line 36 of file ruler_item.cpp.

Referenced by drawTicksAlongLine(), and KIGFX::PREVIEW::RULER_ITEM::ViewDraw().

◆ maxTickDensity

const double maxTickDensity = 10.0
static

Definition at line 34 of file ruler_item.cpp.

Referenced by getTickFormatForScale().

◆ midTickLengthFactor

const double midTickLengthFactor = 1.5
static

Definition at line 35 of file ruler_item.cpp.

Referenced by drawTicksAlongLine(), and KIGFX::PREVIEW::RULER_ITEM::ViewDraw().