KiCad PCB EDA Suite
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 (C) 2017 Kicad Developers, see change_log.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, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
25 
29 #include <view/view.h>
30 #include <pcb_painter.h>
31 
32 #include <base_units.h>
33 #include <common.h>
34 
35 using namespace KIGFX::PREVIEW;
36 
37 static const double maxTickDensity = 10.0; // min pixels between tick marks
38 static const double midTickLengthFactor = 1.5;
39 static const double majorTickLengthFactor = 2.5;
40 
41 
42 static void drawCursorStrings( KIGFX::VIEW* aView, const VECTOR2D& aCursor,
43  const VECTOR2D& aRulerVec, EDA_UNITS_T aUnits )
44 {
45  // draw the cursor labels
46  std::vector<wxString> cursorStrings;
47 
48  cursorStrings.push_back( DimensionLabel( "x", aRulerVec.x, aUnits ) );
49  cursorStrings.push_back( DimensionLabel( "y", aRulerVec.y, aUnits ) );
50 
51  cursorStrings.push_back( DimensionLabel( "r", aRulerVec.EuclideanNorm(), aUnits ) );
52 
53  double degs = RAD2DECIDEG( -aRulerVec.Angle() );
54  cursorStrings.push_back( DimensionLabel( wxString::FromUTF8( "θ" ), degs, DEGREES ) );
55 
56  auto temp = aRulerVec;
57  DrawTextNextToCursor( aView, aCursor, -temp, cursorStrings );
58 }
59 
60 
66 {
67  double divisionBase;
68  int majorStep;
69  int midStep;
70 };
71 
72 
73 static TICK_FORMAT getTickFormatForScale( double aScale, double& aTickSpace, EDA_UNITS_T aUnits )
74 {
75  // simple 1/2/5 scales per decade
76  static std::vector<TICK_FORMAT> tickFormats =
77  {
78  { 2, 10, 5 }, // |....:....|
79  { 2, 5, 0 }, // |....|
80  { 2.5, 2, 0 }, // |.|.|
81  };
82 
83  // could start at a set number of MM, but that's not available in common
84  aTickSpace = 1;
85 
86  // convert to a round (mod-10) number of mils
87  if( aUnits == INCHES )
88  {
89  aTickSpace *= 2.54;
90  }
91 
92  int tickFormat = 0;
93 
94  while( true )
95  {
96  const auto pixelSpace = aTickSpace * aScale;
97 
98  if( pixelSpace >= maxTickDensity )
99  break;
100 
101  tickFormat = ( tickFormat + 1 ) % tickFormats.size();
102  aTickSpace *= tickFormats[tickFormat].divisionBase;
103  }
104 
105  return tickFormats[tickFormat];
106 }
107 
108 
118 void drawTicksAlongLine( KIGFX::VIEW *aView, const VECTOR2D& aOrigin,
119  const VECTOR2D& aLine, double aMinorTickLen, EDA_UNITS_T aUnits )
120 {
121  VECTOR2D tickLine = aLine.Rotate( -M_PI_2 );
122  auto gal = aView->GetGAL();
123  double tickSpace;
124  TICK_FORMAT tickF = getTickFormatForScale( gal->GetWorldScale(), tickSpace, aUnits );
125  auto rs = static_cast<KIGFX::PCB_RENDER_SETTINGS*>( aView->GetPainter()->GetSettings() );
126 
127  // number of ticks in whole ruler
128  int numTicks = (int) std::ceil( aLine.EuclideanNorm() / tickSpace );
129 
130  // work out which way up the tick labels go
131  double labelAngle = -tickLine.Angle();
132 
133  if( aLine.Angle() > 0 )
134  {
135  gal->SetHorizontalJustify( GR_TEXT_HJUSTIFY_LEFT );
136  }
137  else
138  {
139  gal->SetHorizontalJustify( GR_TEXT_HJUSTIFY_RIGHT );
140  labelAngle += M_PI;
141  }
142 
143  // text and ticks are dimmed
144  gal->SetStrokeColor( rs->GetLayerColor( LAYER_AUX_ITEMS ).WithAlpha( PreviewOverlayDeemphAlpha( true ) ) );
145 
146  const auto labelOffset = tickLine.Resize( aMinorTickLen * ( majorTickLengthFactor + 1 ) );
147 
148  for( int i = 0; i < numTicks; ++i )
149  {
150  const auto tickPos = aOrigin + aLine.Resize( tickSpace * i );
151 
152  double length = aMinorTickLen;
153  bool drawLabel = false;
154 
155  if( i % tickF.majorStep == 0)
156  {
157  drawLabel = true;
158  length *= majorTickLengthFactor;
159  }
160  else if( tickF.midStep && i % tickF.midStep == 0 )
161  {
162  drawLabel = true;
163  length *= midTickLengthFactor;
164  }
165 
166  gal->DrawLine( tickPos, tickPos + tickLine.Resize( length ) );
167 
168  if( drawLabel )
169  {
170  wxString label = DimensionLabel( "", tickSpace * i, aUnits );
171  gal->BitmapText( label, tickPos + labelOffset, labelAngle );
172  }
173  }
174 }
175 
176 
187 void drawBacksideTicks( KIGFX::GAL& aGal, const VECTOR2D& aOrigin,
188  const VECTOR2D& aLine, double aTickLen, int aNumDivisions )
189 {
190  const double backTickSpace = aLine.EuclideanNorm() / aNumDivisions;
191  const auto backTickVec = aLine.Rotate( M_PI_2 ).Resize( aTickLen );
192 
193  for( int i = 0; i < aNumDivisions + 1; ++i )
194  {
195  const auto backTickPos = aOrigin + aLine.Resize( backTickSpace * i );
196  aGal.DrawLine( backTickPos, backTickPos + backTickVec );
197  }
198 }
199 
200 
202  EDA_ITEM( NOT_USED ), // Never added to anything - just a preview
203  m_geomMgr( aGeomMgr ),
204  m_userUnits( userUnits )
205 {}
206 
207 
209 {
210  BOX2I tmp;
211 
212  tmp.SetOrigin( m_geomMgr.GetOrigin() );
213  tmp.SetEnd( m_geomMgr.GetEnd() );
214  tmp.Normalize();
215  return tmp;
216 }
217 
218 
219 void RULER_ITEM::ViewGetLayers( int aLayers[], int& aCount ) const
220 {
221  aLayers[0] = LAYER_GP_OVERLAY;
222  aCount = 1;
223 }
224 
225 
226 void RULER_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const
227 {
228  auto& gal = *aView->GetGAL();
229  auto rs = static_cast<KIGFX::RENDER_SETTINGS*>( aView->GetPainter()->GetSettings() );
230 
231  VECTOR2D origin = m_geomMgr.GetOrigin();
232  VECTOR2D end = m_geomMgr.GetEnd();
233 
234  gal.SetLineWidth( 1.0 );
235  gal.SetIsStroke( true );
236  gal.SetIsFill( false );
237 
238  gal.SetTextMirrored( false );
239  gal.SetStrokeColor( rs->GetLayerColor( LAYER_AUX_ITEMS ) );
240 
241  gal.ResetTextAttributes();
242 
243  // draw the main line from the origin to cursor
244  gal.DrawLine( origin, end );
245 
246  VECTOR2D rulerVec( end - origin );
247 
248  // constant text size on screen
249  SetConstantGlyphHeight( gal, 14.0 );
250 
251  drawCursorStrings( aView, end, rulerVec, m_userUnits );
252 
253  // tick label size
254  SetConstantGlyphHeight( gal, 12.0 );
255 
256  // basic tick size
257  const double minorTickLen = 5.0 / gal.GetWorldScale();
258 
259  drawTicksAlongLine( aView, origin, rulerVec, minorTickLen, m_userUnits );
260 
261  gal.SetStrokeColor( rs->GetLayerColor( LAYER_AUX_ITEMS ).WithAlpha( PreviewOverlayDeemphAlpha( true ) ) );
262  drawBacksideTicks( gal, origin, rulerVec, minorTickLen * majorTickLengthFactor, 2 );
263 
264  // draw the back of the origin "crosshair"
265  gal.DrawLine( origin, origin + rulerVec.Resize( -minorTickLen * midTickLengthFactor ) );
266 }
const BOX2I ViewBBox() const override
Definition: ruler_item.cpp:208
void drawTicksAlongLine(KIGFX::VIEW *aView, const VECTOR2D &aOrigin, const VECTOR2D &aLine, double aMinorTickLen, EDA_UNITS_T aUnits)
Draw labelled ticks on a line.
Definition: ruler_item.cpp:118
Implementation of conversion functions that require both schematic and board internal units.
the 3d code uses this value
Definition: typeinfo.h:80
double RAD2DECIDEG(double rad)
Definition: trigo.h:204
GAL * GetGAL() const
Function GetGAL() Returns the GAL this view is using to draw graphical primitives.
Definition: view.h:180
int midStep
ticks between major ticks
Definition: ruler_item.cpp:69
double divisionBase
Definition: ruler_item.cpp:67
virtual void DrawLine(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Draw a line.
void drawBacksideTicks(KIGFX::GAL &aGal, const VECTOR2D &aOrigin, const VECTOR2D &aLine, double aTickLen, int aNumDivisions)
Draw simple ticks on the back of a line such that the line is divided into n parts.
Definition: ruler_item.cpp:187
PAINTER * GetPainter() const
Function GetPainter() Returns the painter object used by the view for drawing VIEW_ITEMS.
Definition: view.h:199
const TWO_POINT_GEOMETRY_MANAGER & m_geomMgr
Definition: ruler_item.h:83
static const double majorTickLengthFactor
Definition: ruler_item.cpp:39
Auxiliary items (guides, rule, etc)
static TICK_FORMAT getTickFormatForScale(double aScale, double &aTickSpace, EDA_UNITS_T aUnits)
Definition: ruler_item.cpp:73
Definition: common.h:161
BOX2< Vec > & Normalize()
Function Normalize ensures that the height ant width are positive.
Definition: box2.h:127
static const double midTickLengthFactor
Definition: ruler_item.cpp:38
void DrawTextNextToCursor(KIGFX::VIEW *aView, const VECTOR2D &aCursorPos, const VECTOR2D &aTextQuadrant, const std::vector< wxString > &aStrings)
Draw strings next to the cursor.
RULER_ITEM(const TWO_POINT_GEOMETRY_MANAGER &m_geomMgr, EDA_UNITS_T userUnits)
Definition: ruler_item.cpp:201
double Angle() const
Function Angle computes the angle of the vector.
Definition: vector2d.h:306
double PreviewOverlayDeemphAlpha(bool aDeemph=true)
Default alpha of "de-emphasised" features (like previously locked-in lines.
void SetEnd(coord_type x, coord_type y)
Definition: box2.h:223
VECTOR2< T > Resize(T aNewLength) const
Function Resize returns a vector of the same direction, but length specified in aNewLength.
Definition: vector2d.h:385
virtual RENDER_SETTINGS * GetSettings()=0
Function GetSettings Returns pointer to current settings that are going to be used when drawing items...
VECTOR2< T > Rotate(double aAngle) const
Function Rotate rotates the vector by a given angle.
Definition: vector2d.h:370
void ViewGetLayers(int aLayers[], int &aCount) const override
Definition: ruler_item.cpp:219
Board layer functions and definitions.
void SetConstantGlyphHeight(KIGFX::GAL &aGal, double aHeight)
Set the GAL glyph height to a constant scaled value, so that it always looks the same on screen.
size_t i
Definition: json11.cpp:597
void SetOrigin(const Vec &pos)
Definition: box2.h:208
Class EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boa...
Definition: base_struct.h:154
The common library.
Description of a "tick format" for a scale factor - how many ticks there are between medium/major tic...
Definition: ruler_item.cpp:65
wxString DimensionLabel(const wxString &prefix, double aVal, EDA_UNITS_T aUnits)
Get a formatted string showing a dimension to a sane precision with an optional prefix and unit suffi...
T EuclideanNorm() const
Destructor.
Definition: vector2d.h:292
Class VIEW.
Definition: view.h:61
static const double maxTickDensity
Definition: ruler_item.cpp:37
static void drawCursorStrings(KIGFX::VIEW *aView, const VECTOR2D &aCursor, const VECTOR2D &aRulerVec, EDA_UNITS_T aUnits)
Definition: ruler_item.cpp:42
int majorStep
multiple from the last scale
Definition: ruler_item.cpp:68
void ViewDraw(int aLayer, KIGFX::VIEW *aView) const override final
Definition: ruler_item.cpp:226
EDA_UNITS_T
Definition: common.h:160
Class GAL is the abstract interface for drawing on a 2D-surface.