KiCad PCB EDA Suite
KIGFX::STROKE_FONT Class Reference

Class STROKE_FONT implements stroke font drawing. More...

#include <stroke_font.h>

Public Member Functions

 STROKE_FONT (GAL *aGal)
 Constructor. More...
 
bool LoadNewStrokeFont (const char *const aNewStrokeFont[], int aNewStrokeFontSize)
 Load the new stroke font. More...
 
void Draw (const UTF8 &aText, const VECTOR2D &aPosition, double aRotationAngle)
 Draw a string. More...
 
void SetGAL (GAL *aGal)
 Function SetGAL Changes Graphics Abstraction Layer used for drawing items for a new one. More...
 
VECTOR2D ComputeStringBoundaryLimits (const UTF8 &aText, const VECTOR2D &aGlyphSize, double aGlyphThickness) const
 Compute the boundary limits of aText (the bounding box of all shapes). More...
 
double ComputeOverbarVerticalPosition (double aGlyphHeight, double aGlyphThickness) const
 Compute the vertical position of an overbar, sometimes used in texts. More...
 

Static Public Member Functions

static double GetInterline (double aGlyphHeight)
 Compute the distance (interline) between 2 lines of text (for multiline texts). More...
 

Private Member Functions

VECTOR2D computeTextLineSize (const UTF8 &aText) const
 Compute the X and Y size of a given text. More...
 
double computeOverbarVerticalPosition () const
 Compute the vertical position of an overbar, sometimes used in texts. More...
 
BOX2D computeBoundingBox (const GLYPH *aGlyph, double aGlyphWidth) const
 Compute the bounding box of a given glyph. More...
 
void drawSingleLineText (const UTF8 &aText)
 Draws a single line of text. More...
 
unsigned linesCount (const UTF8 &aText) const
 Returns number of lines for a given text. More...
 

Private Attributes

GALm_gal
 Pointer to the GAL. More...
 
const GLYPH_LISTm_glyphs
 Glyph list. More...
 
const std::vector< BOX2D > * m_glyphBoundingBoxes
 Bounding boxes of the glyphs. More...
 

Static Private Attributes

static const double OVERBAR_POSITION_FACTOR = 1.40
 

Factor that determines relative vertical position of the overbar.

More...
 
static const double BOLD_FACTOR = 1.3
 

Factor that determines relative line width for bold text.

More...
 
static const double STROKE_FONT_SCALE = 1.0 / 21.0
 

Scale factor for a glyph

More...
 
static const double ITALIC_TILT = 1.0 / 8
 

Tilt factor for italic style (the is is the scaling factor on dY relative coordinates to give a tilst shape

More...
 
static const double INTERLINE_PITCH_RATIO = 1.61
 

Factor that determines the pitch between 2 lines.

More...
 

Friends

class GAL
 

Detailed Description

Class STROKE_FONT implements stroke font drawing.

A stroke font is composed of lines.

Definition at line 53 of file stroke_font.h.

Constructor & Destructor Documentation

◆ STROKE_FONT()

STROKE_FONT::STROKE_FONT ( GAL aGal)

Constructor.

Definition at line 49 of file stroke_font.cpp.

49  :
50  m_gal( aGal ), m_glyphs( nullptr ), m_glyphBoundingBoxes( nullptr )
51 {
52 }
GAL * m_gal
Pointer to the GAL.
Definition: stroke_font.h:117
const std::vector< BOX2D > * m_glyphBoundingBoxes
Bounding boxes of the glyphs.
Definition: stroke_font.h:119
const GLYPH_LIST * m_glyphs
Glyph list.
Definition: stroke_font.h:118

Member Function Documentation

◆ computeBoundingBox()

BOX2D STROKE_FONT::computeBoundingBox ( const GLYPH aGlyph,
double  aGlyphWidth 
) const
private

Compute the bounding box of a given glyph.

Parameters
aGlyphis the glyph.
aGlyphWidthis the x-component of the bounding box size.
Returns
is the complete bounding box size.

Definition at line 170 of file stroke_font.cpp.

171 {
172  VECTOR2D min( 0, 0 );
173  VECTOR2D max( aGlyphWidth, 0 );
174 
175  for( const std::vector<VECTOR2D>* pointList : *aGLYPH )
176  {
177  for( const VECTOR2D& point : *pointList )
178  {
179  min.y = std::min( min.y, point.y );
180  max.y = std::max( max.y, point.y );
181  }
182  }
183 
184  return BOX2D( min, max - min );
185 }
BOX2< VECTOR2D > BOX2D
Definition: box2.h:522
VECTOR2 defines a general 2D-vector/point.
Definition: vector2d.h:61

References VECTOR2< T >::y.

Referenced by LoadNewStrokeFont().

◆ ComputeOverbarVerticalPosition()

double STROKE_FONT::ComputeOverbarVerticalPosition ( double  aGlyphHeight,
double  aGlyphThickness 
) const

Compute the vertical position of an overbar, sometimes used in texts.

This is the distance between the text base line and the overbar.

Parameters
aGlyphHeightis the height (vertical size) of the text.
aGlyphThicknessis the thickness of the lines used to draw the text.
Returns
the relative position of the overbar axis.

Definition at line 478 of file stroke_font.cpp.

479 {
480  // Static method.
481  // Compute the Y position of the overbar. This is the distance between the text base line
482  // and the overbar axis.
483  // Don't use the glyph thickness anymore. We don't know how much of it is "real" and how
484  // much it has been plumped for drop shadows, etc.
485  return aGlyphHeight * OVERBAR_POSITION_FACTOR;
486 }
static const double OVERBAR_POSITION_FACTOR
Factor that determines relative vertical position of the overbar.
Definition: stroke_font.h:170

References OVERBAR_POSITION_FACTOR.

Referenced by computeOverbarVerticalPosition().

◆ computeOverbarVerticalPosition()

double STROKE_FONT::computeOverbarVerticalPosition ( ) const
private

Compute the vertical position of an overbar, sometimes used in texts.

This is the distance between the text base line and the overbar.

Returns
the relative position of the overbar axis.

Definition at line 489 of file stroke_font.cpp.

490 {
491  // Compute the Y position of the overbar. This is the distance between
492  // the text base line and the overbar axis.
494 }
float GetLineWidth() const
Get the line width.
const VECTOR2D & GetGlyphSize() const
double ComputeOverbarVerticalPosition(double aGlyphHeight, double aGlyphThickness) const
Compute the vertical position of an overbar, sometimes used in texts.
GAL * m_gal
Pointer to the GAL.
Definition: stroke_font.h:117

References ComputeOverbarVerticalPosition(), KIGFX::GAL::GetGlyphSize(), KIGFX::GAL::GetLineWidth(), m_gal, and VECTOR2< T >::y.

Referenced by drawSingleLineText(), and KIGFX::GAL::GetOverbarVerticalPosition().

◆ ComputeStringBoundaryLimits()

VECTOR2D STROKE_FONT::ComputeStringBoundaryLimits ( const UTF8 aText,
const VECTOR2D aGlyphSize,
double  aGlyphThickness 
) const

Compute the boundary limits of aText (the bounding box of all shapes).

The overbar and alignment are not taken in account, '~' characters are skipped.

Returns
a VECTOR2D giving the width and height of text.

Definition at line 503 of file stroke_font.cpp.

505 {
506  VECTOR2D string_bbox;
507  int line_count = 1;
508  double maxX = 0.0, curX = 0.0;
509 
510  double curScale = 1.0;
511  bool in_overbar = false;
512  bool in_super_or_subscript = false;
513 
514  for( UTF8::uni_iter it = aText.ubegin(), end = aText.uend(); it < end; ++it )
515  {
516  if( *it == '\n' )
517  {
518  curX = 0.0;
519  maxX = std::max( maxX, curX );
520  ++line_count;
521  continue;
522  }
523 
524  // Handle tabs as locked to the nearest 4th column (counting in spaces)
525  // The choice of spaces is somewhat arbitrary but sufficient for aligning text
526  if( *it == '\t' )
527  {
528  double spaces = m_glyphBoundingBoxes->at( 0 ).GetEnd().x;
529  double addlSpace = 3.0 * spaces - std::fmod( curX, 4.0 * spaces );
530 
531  // Add the remaining space (between 0 and 3 spaces)
532  curX += addlSpace;
533 
534  // Tab ends a super- or subscript
535  curScale = 1.0;
536  }
537  else if( *it == '~' )
538  {
539  if( ++it == end )
540  break;
541 
542  if( *it == '~' )
543  {
544  // double ~ is really a ~ so go ahead and process the second one
545 
546  // so what's a triple ~? It could be a real ~ followed by an overbar, or
547  // it could be an overbar followed by a real ~. The old algorithm did the
548  // former so we will too....
549  }
550  else
551  {
552  // single ~ toggles overbar
553  in_overbar = !in_overbar;
554  }
555  }
556  else if( *it == '^' || *it == '_' )
557  {
558  auto lookahead = it;
559 
560  if( ++lookahead != end && *lookahead == '{' )
561  {
562  // process superscript
563  it = lookahead;
564  in_super_or_subscript = true;
565  curScale = 0.8;
566  continue;
567  }
568  }
569  else if( *it == '}' && in_super_or_subscript )
570  {
571  in_super_or_subscript = false;
572  curScale = 1.0;
573  continue;
574  }
575 
576  // Index in the bounding boxes table
577  int dd = (signed) *it - ' ';
578 
579  if( dd >= (int) m_glyphBoundingBoxes->size() || dd < 0 )
580  {
581  int substitute = *it == '\t' ? ' ' : '?';
582  dd = substitute - ' ';
583  }
584 
585  const BOX2D& box = m_glyphBoundingBoxes->at( dd );
586  curX += box.GetEnd().x * curScale;
587  }
588 
589  string_bbox.x = std::max( maxX, curX ) * aGlyphSize.x;
590  string_bbox.x += aGlyphThickness;
591  string_bbox.y = line_count * GetInterline( aGlyphSize.y );
592 
593  // For italic correction, take in account italic tilt
594  if( m_gal->IsFontItalic() )
595  string_bbox.x += string_bbox.y * STROKE_FONT::ITALIC_TILT;
596 
597  return string_bbox;
598 }
const Vec GetEnd() const
Definition: box2.h:194
static double GetInterline(double aGlyphHeight)
Compute the distance (interline) between 2 lines of text (for multiline texts).
VECTOR2 defines a general 2D-vector/point.
Definition: vector2d.h:61
uni_iter uend() const
Function uend returns a uni_iter initialized to the end of "this" UTF8 byte sequence.
Definition: utf8.h:294
static const double ITALIC_TILT
Tilt factor for italic style (the is is the scaling factor on dY relative coordinates to give a tilst...
Definition: stroke_font.h:180
uni_iter ubegin() const
Function ubegin returns a uni_iter initialized to the start of "this" UTF8 byte sequence.
Definition: utf8.h:285
GAL * m_gal
Pointer to the GAL.
Definition: stroke_font.h:117
bool IsFontItalic() const
Returns true if current font has 'italic' attribute enabled.
uni_iter is a non-mutating iterator that walks through unicode code points in the UTF8 encoded string...
Definition: utf8.h:207
const std::vector< BOX2D > * m_glyphBoundingBoxes
Bounding boxes of the glyphs.
Definition: stroke_font.h:119

References BOX2< Vec >::GetEnd(), GetInterline(), KIGFX::GAL::IsFontItalic(), ITALIC_TILT, m_gal, m_glyphBoundingBoxes, UTF8::ubegin(), UTF8::uend(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by computeTextLineSize().

◆ computeTextLineSize()

VECTOR2D STROKE_FONT::computeTextLineSize ( const UTF8 aText) const
private

Compute the X and Y size of a given text.

The text is expected to be a only one line text.

Parameters
aTextis the text string (one line).
Returns
the text size.

Definition at line 497 of file stroke_font.cpp.

498 {
500 }
float GetLineWidth() const
Get the line width.
const VECTOR2D & GetGlyphSize() const
GAL * m_gal
Pointer to the GAL.
Definition: stroke_font.h:117
VECTOR2D ComputeStringBoundaryLimits(const UTF8 &aText, const VECTOR2D &aGlyphSize, double aGlyphThickness) const
Compute the boundary limits of aText (the bounding box of all shapes).

References ComputeStringBoundaryLimits(), KIGFX::GAL::GetGlyphSize(), KIGFX::GAL::GetLineWidth(), and m_gal.

Referenced by drawSingleLineText(), and KIGFX::GAL::GetTextLineSize().

◆ Draw()

void STROKE_FONT::Draw ( const UTF8 aText,
const VECTOR2D aPosition,
double  aRotationAngle 
)

Draw a string.

Parameters
aTextis the text to be drawn.
aPositionis the text position in world coordinates.
aRotationAngleis the text rotation angle in radians.

Definition at line 188 of file stroke_font.cpp.

189 {
190  if( aText.empty() )
191  return;
192 
193  // Context needs to be saved before any transformations
194  m_gal->Save();
195 
196  m_gal->Translate( aPosition );
197  m_gal->Rotate( -aRotationAngle );
198 
199  // Single line height
200  int lineHeight = KiROUND( GetInterline( m_gal->GetGlyphSize().y ) );
201  int lineCount = linesCount( aText );
202  const VECTOR2D& glyphSize = m_gal->GetGlyphSize();
203 
204  // align the 1st line of text
205  switch( m_gal->GetVerticalJustify() )
206  {
208  m_gal->Translate( VECTOR2D( 0, glyphSize.y ) );
209  break;
210 
212  m_gal->Translate( VECTOR2D( 0, glyphSize.y / 2.0 ) );
213  break;
214 
216  break;
217 
218  default:
219  break;
220  }
221 
222  if( lineCount > 1 )
223  {
224  switch( m_gal->GetVerticalJustify() )
225  {
227  break;
228 
230  m_gal->Translate( VECTOR2D(0, -( lineCount - 1 ) * lineHeight / 2) );
231  break;
232 
234  m_gal->Translate( VECTOR2D(0, -( lineCount - 1 ) * lineHeight ) );
235  break;
236  }
237  }
238 
239  m_gal->SetIsStroke( true );
240  //m_gal->SetIsFill( false );
241 
242  if( m_gal->IsFontBold() )
244 
245  // Split multiline strings into separate ones and draw them line by line
246  size_t begin = 0;
247  size_t newlinePos = aText.find( '\n' );
248 
249  while( newlinePos != aText.npos )
250  {
251  size_t length = newlinePos - begin;
252 
253  drawSingleLineText( aText.substr( begin, length ) );
254  m_gal->Translate( VECTOR2D( 0.0, lineHeight ) );
255 
256  begin = newlinePos + 1;
257  newlinePos = aText.find( '\n', begin );
258  }
259 
260  // Draw the last (or the only one) line
261  if( !aText.empty() )
262  drawSingleLineText( aText.substr( begin ) );
263 
264  m_gal->Restore();
265 }
static constexpr std::string::size_type npos
Definition: utf8.h:155
float GetLineWidth() const
Get the line width.
static double GetInterline(double aGlyphHeight)
Compute the distance (interline) between 2 lines of text (for multiline texts).
static const double BOLD_FACTOR
Factor that determines relative line width for bold text.
Definition: stroke_font.h:173
VECTOR2 defines a general 2D-vector/point.
Definition: vector2d.h:61
virtual void SetLineWidth(float aLineWidth)
Set the line width.
virtual void Rotate(double aAngle)
Rotate the context.
const VECTOR2D & GetGlyphSize() const
bool IsFontBold() const
Returns true if current font has 'bold' attribute enabled.
std::string::size_type find(char c) const
Definition: utf8.h:110
GAL * m_gal
Pointer to the GAL.
Definition: stroke_font.h:117
VECTOR2< double > VECTOR2D
Definition: vector2d.h:593
void drawSingleLineText(const UTF8 &aText)
Draws a single line of text.
virtual void Restore()
Restore the context.
EDA_TEXT_VJUSTIFY_T GetVerticalJustify() const
Returns current text vertical justification setting.
unsigned linesCount(const UTF8 &aText) const
Returns number of lines for a given text.
Definition: stroke_font.h:160
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:61
std::string substr(size_t pos=0, size_t len=npos) const
Definition: utf8.h:182
virtual void Save()
Save the context.
virtual void Translate(const VECTOR2D &aTranslation)
Translate the context.
virtual void SetIsStroke(bool aIsStrokeEnabled)
Enable/disable stroked outlines.
bool empty() const
Definition: utf8.h:108

References BOLD_FACTOR, drawSingleLineText(), UTF8::empty(), UTF8::find(), KIGFX::GAL::GetGlyphSize(), GetInterline(), KIGFX::GAL::GetLineWidth(), KIGFX::GAL::GetVerticalJustify(), GR_TEXT_VJUSTIFY_BOTTOM, GR_TEXT_VJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_TOP, KIGFX::GAL::IsFontBold(), KiROUND(), linesCount(), m_gal, UTF8::npos, KIGFX::GAL::Restore(), KIGFX::GAL::Rotate(), KIGFX::GAL::Save(), KIGFX::GAL::SetIsStroke(), KIGFX::GAL::SetLineWidth(), UTF8::substr(), KIGFX::GAL::Translate(), and VECTOR2< T >::y.

Referenced by KIGFX::GAL::StrokeText().

◆ drawSingleLineText()

void STROKE_FONT::drawSingleLineText ( const UTF8 aText)
private

Draws a single line of text.

Multiline texts should be split before using the function.

Parameters
aTextis the text to be drawn.

Definition at line 268 of file stroke_font.cpp.

269 {
270  double xOffset;
271  double yOffset;
272  VECTOR2D baseGlyphSize( m_gal->GetGlyphSize() );
273  double overbar_italic_comp = computeOverbarVerticalPosition() * ITALIC_TILT;
274 
275  if( m_gal->IsTextMirrored() )
276  overbar_italic_comp = -overbar_italic_comp;
277 
278  // Compute the text size
279  VECTOR2D textSize = computeTextLineSize( aText );
280  double half_thickness = m_gal->GetLineWidth()/2;
281 
282  // Context needs to be saved before any transformations
283  m_gal->Save();
284 
285  // First adjust: the text X position is corrected by half_thickness
286  // because when the text with thickness is draw, its full size is textSize,
287  // but the position of lines is half_thickness to textSize - half_thickness
288  // so we must translate the coordinates by half_thickness on the X axis
289  // to place the text inside the 0 to textSize X area.
290  m_gal->Translate( VECTOR2D( half_thickness, 0 ) );
291 
292  // Adjust the text position to the given horizontal justification
293  switch( m_gal->GetHorizontalJustify() )
294  {
296  m_gal->Translate( VECTOR2D( -textSize.x / 2.0, 0 ) );
297  break;
298 
300  if( !m_gal->IsTextMirrored() )
301  m_gal->Translate( VECTOR2D( -textSize.x, 0 ) );
302  break;
303 
305  if( m_gal->IsTextMirrored() )
306  m_gal->Translate( VECTOR2D( -textSize.x, 0 ) );
307  break;
308 
309  default:
310  break;
311  }
312 
313  if( m_gal->IsTextMirrored() )
314  {
315  // In case of mirrored text invert the X scale of points and their X direction
316  // (m_glyphSize.x) and start drawing from the position where text normally should end
317  // (textSize.x)
318  xOffset = textSize.x - m_gal->GetLineWidth();
319  baseGlyphSize.x = -baseGlyphSize.x;
320  }
321  else
322  {
323  xOffset = 0.0;
324  }
325 
326  // The overbar is indented inward at the beginning of an italicized section, but
327  // must not be indented on subsequent letters to ensure that the bar segments
328  // overlap.
329  bool last_had_overbar = false;
330  bool in_overbar = false;
331  bool in_super_or_subscript = false;
332  VECTOR2D glyphSize = baseGlyphSize;
333 
334  yOffset = 0;
335 
336  for( UTF8::uni_iter chIt = aText.ubegin(), end = aText.uend(); chIt < end; ++chIt )
337  {
338  // Handle tabs as locked to the nearest 4th column (counting in spaces)
339  // The choice of spaces is somewhat arbitrary but sufficient for aligning text
340  if( *chIt == '\t' )
341  {
342  double space = glyphSize.x * m_glyphBoundingBoxes->at( 0 ).GetEnd().x;
343 
344  // We align to the 4th column (fmod) but only need to account for 3 of
345  // the four spaces here with the extra. This ensures that we have at
346  // least 1 space for the \t character
347  double addlSpace = 3.0 * space - std::fmod( xOffset, 4.0 * space );
348 
349  // Add the remaining space (between 0 and 3 spaces)
350  // The fourth space is added by the 'dd' character
351  xOffset += addlSpace;
352 
353  glyphSize = baseGlyphSize;
354  yOffset = 0;
355  }
356  else if( *chIt == '~' )
357  {
358  if( ++chIt == end )
359  break;
360 
361  if( *chIt == '~' )
362  {
363  // double ~ is really a ~ so go ahead and process the second one
364 
365  // so what's a triple ~? It could be a real ~ followed by an overbar, or
366  // it could be an overbar followed by a real ~. The old algorithm did the
367  // former so we will too....
368  }
369  else
370  {
371  in_overbar = !in_overbar;
372  }
373  }
374  else if( *chIt == '^' )
375  {
376  auto lookahead = chIt;
377 
378  if( ++lookahead != end && *lookahead == '{' )
379  {
380  // process superscript
381  chIt = lookahead;
382  in_super_or_subscript = true;
383  glyphSize = baseGlyphSize * 0.8;
384  yOffset = -baseGlyphSize.y * 0.3;
385  continue;
386  }
387  }
388  else if( *chIt == '_' )
389  {
390  auto lookahead = chIt;
391 
392  if( ++lookahead != end && *lookahead == '{' )
393  {
394  // process subscript
395  chIt = lookahead;
396  in_super_or_subscript = true;
397  glyphSize = baseGlyphSize * 0.8;
398  yOffset = baseGlyphSize.y * 0.1;
399  continue;
400  }
401  }
402  else if( *chIt == '}' && in_super_or_subscript )
403  {
404  in_super_or_subscript = false;
405  glyphSize = baseGlyphSize;
406  yOffset = 0;
407  continue;
408  }
409 
410  // Index into bounding boxes table
411  int dd = (signed) *chIt - ' ';
412 
413  if( dd >= (int) m_glyphBoundingBoxes->size() || dd < 0 )
414  {
415  int substitute = *chIt == '\t' ? ' ' : '?';
416  dd = substitute - ' ';
417  }
418 
419  const GLYPH* glyph = m_glyphs->at( dd );
420  const BOX2D& bbox = m_glyphBoundingBoxes->at( dd );
421 
422  if( in_overbar )
423  {
424  double overbar_start_x = xOffset;
425  double overbar_start_y = - computeOverbarVerticalPosition();
426  double overbar_end_x = xOffset + glyphSize.x * bbox.GetEnd().x;
427  double overbar_end_y = overbar_start_y;
428 
429  if( !last_had_overbar )
430  {
431  if( m_gal->IsFontItalic() )
432  overbar_start_x += overbar_italic_comp;
433 
434  last_had_overbar = true;
435  }
436 
437  VECTOR2D startOverbar( overbar_start_x, overbar_start_y );
438  VECTOR2D endOverbar( overbar_end_x, overbar_end_y );
439 
440  m_gal->DrawLine( startOverbar, endOverbar );
441  }
442  else
443  {
444  last_had_overbar = false;
445  }
446 
447  for( const std::vector<VECTOR2D>* ptList : *glyph )
448  {
449  std::deque<VECTOR2D> ptListScaled;
450 
451  for( const VECTOR2D& pt : *ptList )
452  {
453  VECTOR2D scaledPt( pt.x * glyphSize.x + xOffset, pt.y * glyphSize.y + yOffset );
454 
455  if( m_gal->IsFontItalic() )
456  {
457  // FIXME should be done other way - referring to the lowest Y value of point
458  // because now italic fonts are translated a bit
459  if( m_gal->IsTextMirrored() )
460  scaledPt.x += scaledPt.y * STROKE_FONT::ITALIC_TILT;
461  else
462  scaledPt.x -= scaledPt.y * STROKE_FONT::ITALIC_TILT;
463  }
464 
465  ptListScaled.push_back( scaledPt );
466  }
467 
468  m_gal->DrawPolyline( ptListScaled );
469  }
470 
471  xOffset += glyphSize.x * bbox.GetEnd().x;
472  }
473 
474  m_gal->Restore();
475 }
std::vector< std::vector< VECTOR2D > * > GLYPH
Definition: stroke_font.h:43
virtual void DrawPolyline(const std::deque< VECTOR2D > &aPointList)
Draw a polyline.
float GetLineWidth() const
Get the line width.
const Vec GetEnd() const
Definition: box2.h:194
bool IsTextMirrored() const
Returns true if text should displayed mirrored.
VECTOR2 defines a general 2D-vector/point.
Definition: vector2d.h:61
uni_iter uend() const
Function uend returns a uni_iter initialized to the end of "this" UTF8 byte sequence.
Definition: utf8.h:294
static const double ITALIC_TILT
Tilt factor for italic style (the is is the scaling factor on dY relative coordinates to give a tilst...
Definition: stroke_font.h:180
virtual void DrawLine(const VECTOR2D &aStartPoint, const VECTOR2D &aEndPoint)
Draw a line.
EDA_TEXT_HJUSTIFY_T GetHorizontalJustify() const
Returns current text horizontal justification setting.
const VECTOR2D & GetGlyphSize() const
uni_iter ubegin() const
Function ubegin returns a uni_iter initialized to the start of "this" UTF8 byte sequence.
Definition: utf8.h:285
GAL * m_gal
Pointer to the GAL.
Definition: stroke_font.h:117
VECTOR2< double > VECTOR2D
Definition: vector2d.h:593
VECTOR2D computeTextLineSize(const UTF8 &aText) const
Compute the X and Y size of a given text.
bool IsFontItalic() const
Returns true if current font has 'italic' attribute enabled.
uni_iter is a non-mutating iterator that walks through unicode code points in the UTF8 encoded string...
Definition: utf8.h:207
double computeOverbarVerticalPosition() const
Compute the vertical position of an overbar, sometimes used in texts.
virtual void Restore()
Restore the context.
const std::vector< BOX2D > * m_glyphBoundingBoxes
Bounding boxes of the glyphs.
Definition: stroke_font.h:119
virtual void Save()
Save the context.
const GLYPH_LIST * m_glyphs
Glyph list.
Definition: stroke_font.h:118
virtual void Translate(const VECTOR2D &aTranslation)
Translate the context.

References computeOverbarVerticalPosition(), computeTextLineSize(), KIGFX::GAL::DrawLine(), KIGFX::GAL::DrawPolyline(), BOX2< Vec >::GetEnd(), KIGFX::GAL::GetGlyphSize(), KIGFX::GAL::GetHorizontalJustify(), KIGFX::GAL::GetLineWidth(), GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_HJUSTIFY_RIGHT, KIGFX::GAL::IsFontItalic(), KIGFX::GAL::IsTextMirrored(), ITALIC_TILT, m_gal, m_glyphBoundingBoxes, m_glyphs, KIGFX::GAL::Restore(), KIGFX::GAL::Save(), KIGFX::GAL::Translate(), UTF8::ubegin(), UTF8::uend(), VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by Draw().

◆ GetInterline()

double STROKE_FONT::GetInterline ( double  aGlyphHeight)
static

Compute the distance (interline) between 2 lines of text (for multiline texts).

Parameters
aGlyphHeightis the height (vertical size) of the text.
Returns
the interline.

Definition at line 162 of file stroke_font.cpp.

163 {
164  // Do not add the glyph thickness to the interline. This makes bold text line-spacing
165  // different from normal text, which is poor typography.
166  return ( aGlyphHeight * INTERLINE_PITCH_RATIO );
167 }
static const double INTERLINE_PITCH_RATIO
Factor that determines the pitch between 2 lines.
Definition: stroke_font.h:183

References INTERLINE_PITCH_RATIO.

Referenced by ComputeStringBoundaryLimits(), Draw(), and EDA_TEXT::GetInterline().

◆ linesCount()

unsigned KIGFX::STROKE_FONT::linesCount ( const UTF8 aText) const
inlineprivate

Returns number of lines for a given text.

Parameters
aTextis the text to be checked.
Returns
unsigned - The number of lines in aText.

Definition at line 160 of file stroke_font.h.

161  {
162  if( aText.empty() )
163  return 0; // std::count does not work well with empty strings
164  else
165  // aText.end() - 1 is to skip a newline character that is potentially at the end
166  return std::count( aText.begin(), aText.end() - 1, '\n' ) + 1;
167  }
std::string::const_iterator end() const
Definition: utf8.h:197
std::string::const_iterator begin() const
Definition: utf8.h:196
bool empty() const
Definition: utf8.h:108

References UTF8::begin(), UTF8::empty(), and UTF8::end().

Referenced by Draw().

◆ LoadNewStrokeFont()

bool STROKE_FONT::LoadNewStrokeFont ( const char *const  aNewStrokeFont[],
int  aNewStrokeFontSize 
)

Load the new stroke font.

Parameters
aNewStrokeFontis the pointer to the font data.
aNewStrokeFontSizeis the size of the font data.
Returns
True, if the font was successfully loaded, else false.

Definition at line 55 of file stroke_font.cpp.

56 {
58  {
61  return true;
62  }
63 
65  g_newStrokeFontGlyphs->reserve( aNewStrokeFontSize );
66 
67  g_newStrokeFontGlyphBoundingBoxes = new std::vector<BOX2D>;
68  g_newStrokeFontGlyphBoundingBoxes->reserve( aNewStrokeFontSize );
69 
70  for( int j = 0; j < aNewStrokeFontSize; j++ )
71  {
72  GLYPH* glyph = new GLYPH;
73  double glyphStartX = 0.0;
74  double glyphEndX = 0.0;
75  double glyphWidth = 0.0;
76 
77  std::vector<VECTOR2D>* pointList = nullptr;
78 
79  int strokes = 0;
80  int i = 0;
81 
82  while( aNewStrokeFont[j][i] )
83  {
84 
85  if( aNewStrokeFont[j][i] == ' ' && aNewStrokeFont[j][i+1] == 'R' )
86  strokes++;
87 
88  i += 2;
89  }
90 
91  glyph->reserve( strokes + 1 );
92 
93  i = 0;
94 
95  while( aNewStrokeFont[j][i] )
96  {
97  VECTOR2D point( 0.0, 0.0 );
98  char coordinate[2] = { 0, };
99 
100  for( int k : { 0, 1 } )
101  coordinate[k] = aNewStrokeFont[j][i + k];
102 
103  if( i < 2 )
104  {
105  // The first two values contain the width of the char
106  glyphStartX = ( coordinate[0] - 'R' ) * STROKE_FONT_SCALE;
107  glyphEndX = ( coordinate[1] - 'R' ) * STROKE_FONT_SCALE;
108  glyphWidth = glyphEndX - glyphStartX;
109  }
110  else if( ( coordinate[0] == ' ' ) && ( coordinate[1] == 'R' ) )
111  {
112  if( pointList )
113  pointList->shrink_to_fit();
114 
115  // Raise pen
116  pointList = nullptr;
117  }
118  else
119  {
120  // In stroke font, coordinates values are coded as <value> + 'R',
121  // <value> is an ASCII char.
122  // therefore every coordinate description of the Hershey format has an offset,
123  // it has to be subtracted
124  // Note:
125  // * the stroke coordinates are stored in reduced form (-1.0 to +1.0),
126  // and the actual size is stroke coordinate * glyph size
127  // * a few shapes have a height slightly bigger than 1.0 ( like '{' '[' )
128  point.x = (double) ( coordinate[0] - 'R' ) * STROKE_FONT_SCALE - glyphStartX;
129  #define FONT_OFFSET -10
130  // FONT_OFFSET is here for historical reasons, due to the way the stroke font
131  // was built. It allows shapes coordinates like W M ... to be >= 0
132  // Only shapes like j y have coordinates < 0
133  point.y = (double) ( coordinate[1] - 'R' + FONT_OFFSET ) * STROKE_FONT_SCALE;
134 
135  if( !pointList )
136  {
137  pointList = new std::vector<VECTOR2D>;
138  glyph->push_back( pointList );
139  }
140 
141  pointList->push_back( point );
142  }
143 
144  i += 2;
145  }
146 
147  if( pointList )
148  pointList->shrink_to_fit();
149 
150  // Compute the bounding box of the glyph
151  g_newStrokeFontGlyphBoundingBoxes->emplace_back( computeBoundingBox( glyph, glyphWidth ) );
152  g_newStrokeFontGlyphs->push_back( glyph );
153  }
154 
157  return true;
158 }
std::vector< std::vector< VECTOR2D > * > GLYPH
Definition: stroke_font.h:43
VECTOR2 defines a general 2D-vector/point.
Definition: vector2d.h:61
std::vector< BOX2D > * g_newStrokeFontGlyphBoundingBoxes
Bounding boxes of the glyphs.
Definition: stroke_font.cpp:46
std::vector< GLYPH * > GLYPH_LIST
Definition: stroke_font.h:46
GLYPH_LIST * g_newStrokeFontGlyphs
Glyph list.
Definition: stroke_font.cpp:45
static const double STROKE_FONT_SCALE
Scale factor for a glyph
Definition: stroke_font.h:176
#define FONT_OFFSET
const std::vector< BOX2D > * m_glyphBoundingBoxes
Bounding boxes of the glyphs.
Definition: stroke_font.h:119
const GLYPH_LIST * m_glyphs
Glyph list.
Definition: stroke_font.h:118
BOX2D computeBoundingBox(const GLYPH *aGlyph, double aGlyphWidth) const
Compute the bounding box of a given glyph.

References computeBoundingBox(), FONT_OFFSET, g_newStrokeFontGlyphBoundingBoxes, g_newStrokeFontGlyphs, m_glyphBoundingBoxes, m_glyphs, STROKE_FONT_SCALE, VECTOR2< T >::x, and VECTOR2< T >::y.

Referenced by KIGFX::GAL::GAL().

◆ SetGAL()

void KIGFX::STROKE_FONT::SetGAL ( GAL aGal)
inline

Function SetGAL Changes Graphics Abstraction Layer used for drawing items for a new one.

Parameters
aGalis the new GAL instance.

Definition at line 84 of file stroke_font.h.

85  {
86  m_gal = aGal;
87  }
GAL * m_gal
Pointer to the GAL.
Definition: stroke_font.h:117

References m_gal.

Friends And Related Function Documentation

◆ GAL

friend class GAL
friend

Definition at line 55 of file stroke_font.h.

Member Data Documentation

◆ BOLD_FACTOR

const double STROKE_FONT::BOLD_FACTOR = 1.3
staticprivate

Factor that determines relative line width for bold text.

Definition at line 173 of file stroke_font.h.

Referenced by Draw().

◆ INTERLINE_PITCH_RATIO

const double STROKE_FONT::INTERLINE_PITCH_RATIO = 1.61
staticprivate

Factor that determines the pitch between 2 lines.

Definition at line 183 of file stroke_font.h.

Referenced by GetInterline().

◆ ITALIC_TILT

const double STROKE_FONT::ITALIC_TILT = 1.0 / 8
staticprivate

Tilt factor for italic style (the is is the scaling factor on dY relative coordinates to give a tilst shape

Definition at line 180 of file stroke_font.h.

Referenced by ComputeStringBoundaryLimits(), and drawSingleLineText().

◆ m_gal

GAL* KIGFX::STROKE_FONT::m_gal
private

◆ m_glyphBoundingBoxes

const std::vector<BOX2D>* KIGFX::STROKE_FONT::m_glyphBoundingBoxes
private

Bounding boxes of the glyphs.

Definition at line 119 of file stroke_font.h.

Referenced by ComputeStringBoundaryLimits(), drawSingleLineText(), and LoadNewStrokeFont().

◆ m_glyphs

const GLYPH_LIST* KIGFX::STROKE_FONT::m_glyphs
private

Glyph list.

Definition at line 118 of file stroke_font.h.

Referenced by drawSingleLineText(), and LoadNewStrokeFont().

◆ OVERBAR_POSITION_FACTOR

const double STROKE_FONT::OVERBAR_POSITION_FACTOR = 1.40
staticprivate

Factor that determines relative vertical position of the overbar.

Definition at line 170 of file stroke_font.h.

Referenced by ComputeOverbarVerticalPosition().

◆ STROKE_FONT_SCALE

const double STROKE_FONT::STROKE_FONT_SCALE = 1.0 / 21.0
staticprivate

Scale factor for a glyph

Definition at line 176 of file stroke_font.h.

Referenced by LoadNewStrokeFont().


The documentation for this class was generated from the following files: