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) 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...
 
double computeUnderlineVerticalPosition () const
 
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.33
 

Factor that determines relative vertical position of the overbar.

More...
 
static const double UNDERLINE_POSITION_FACTOR = 0.41
 
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 50 of file stroke_font.cpp.

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

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 171 of file stroke_font.cpp.

172 {
173  VECTOR2D min( 0, 0 );
174  VECTOR2D max( aGlyphWidth, 0 );
175 
176  for( const std::vector<VECTOR2D>* pointList : *aGLYPH )
177  {
178  for( const VECTOR2D& point : *pointList )
179  {
180  min.y = std::min( min.y, point.y );
181  max.y = std::max( max.y, point.y );
182  }
183  }
184 
185  return BOX2D( min, max - min );
186 }
BOX2< VECTOR2D > BOX2D
Definition: box2.h:523
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) 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.
Returns
the relative position of the overbar axis.

Definition at line 493 of file stroke_font.cpp.

494 {
495  // Static method.
496  return aGlyphHeight * OVERBAR_POSITION_FACTOR;
497 }
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 500 of file stroke_font.cpp.

501 {
502  // Compute the Y position of the overbar. This is the distance between
503  // the text base line and the overbar axis.
505 }
const VECTOR2D & GetGlyphSize() const
GAL * m_gal
Pointer to the GAL.
Definition: stroke_font.h:116
double ComputeOverbarVerticalPosition(double aGlyphHeight) const
Compute the vertical position of an overbar, sometimes used in texts.

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

Referenced by drawSingleLineText().

◆ 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 522 of file stroke_font.cpp.

524 {
525  VECTOR2D string_bbox;
526  int line_count = 1;
527  double maxX = 0.0, curX = 0.0;
528 
529  double curScale = 1.0;
530  bool in_overbar = false;
531  bool in_super_or_subscript = false;
532 
533  for( UTF8::uni_iter it = aText.ubegin(), end = aText.uend(); it < end; ++it )
534  {
535  if( *it == '\n' )
536  {
537  curX = 0.0;
538  maxX = std::max( maxX, curX );
539  ++line_count;
540  continue;
541  }
542 
543  // Handle tabs as locked to the nearest 4th column (counting in spaces)
544  // The choice of spaces is somewhat arbitrary but sufficient for aligning text
545  if( *it == '\t' )
546  {
547  double spaces = m_glyphBoundingBoxes->at( 0 ).GetEnd().x;
548  double addlSpace = 3.0 * spaces - std::fmod( curX, 4.0 * spaces );
549 
550  // Add the remaining space (between 0 and 3 spaces)
551  curX += addlSpace;
552 
553  // Tab ends a super- or subscript
554  curScale = 1.0;
555  }
556  else if( *it == '~' )
557  {
558  if( ++it == end )
559  break;
560 
561  if( *it == '~' )
562  {
563  // double ~ is really a ~ so go ahead and process the second one
564 
565  // so what's a triple ~? It could be a real ~ followed by an overbar, or
566  // it could be an overbar followed by a real ~. The old algorithm did the
567  // former so we will too....
568  }
569  else
570  {
571  // single ~ toggles overbar
572  in_overbar = !in_overbar;
573  }
574  }
575  else if( *it == '^' || *it == '_' )
576  {
577  auto lookahead = it;
578 
579  if( ++lookahead != end && *lookahead == '{' )
580  {
581  // process superscript
582  it = lookahead;
583  in_super_or_subscript = true;
584  curScale = 0.8;
585  continue;
586  }
587  }
588  else if( *it == '}' && in_super_or_subscript )
589  {
590  in_super_or_subscript = false;
591  curScale = 1.0;
592  continue;
593  }
594 
595  // Index in the bounding boxes table
596  int dd = (signed) *it - ' ';
597 
598  if( dd >= (int) m_glyphBoundingBoxes->size() || dd < 0 )
599  {
600  int substitute = *it == '\t' ? ' ' : '?';
601  dd = substitute - ' ';
602  }
603 
604  const BOX2D& box = m_glyphBoundingBoxes->at( dd );
605  curX += box.GetEnd().x * curScale;
606  }
607 
608  string_bbox.x = std::max( maxX, curX ) * aGlyphSize.x;
609  string_bbox.x += aGlyphThickness;
610  string_bbox.y = line_count * GetInterline( aGlyphSize.y );
611 
612  // For italic correction, take in account italic tilt
613  if( m_gal->IsFontItalic() )
614  string_bbox.x += string_bbox.y * STROKE_FONT::ITALIC_TILT;
615 
616  return string_bbox;
617 }
const Vec GetEnd() const
Definition: box2.h:195
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:181
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:116
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:118

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 516 of file stroke_font.cpp.

517 {
519 }
float GetLineWidth() const
Get the line width.
const VECTOR2D & GetGlyphSize() const
GAL * m_gal
Pointer to the GAL.
Definition: stroke_font.h:116
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().

◆ computeUnderlineVerticalPosition()

double STROKE_FONT::computeUnderlineVerticalPosition ( ) const
private

Definition at line 508 of file stroke_font.cpp.

509 {
510  // Compute the Y position of the underline. This is the distance between
511  // the text base line and the underline axis.
513 }
const VECTOR2D & GetGlyphSize() const
GAL * m_gal
Pointer to the GAL.
Definition: stroke_font.h:116
static const double UNDERLINE_POSITION_FACTOR
Definition: stroke_font.h:171

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

Referenced by drawSingleLineText().

◆ 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 189 of file stroke_font.cpp.

190 {
191  if( aText.empty() )
192  return;
193 
194  // Context needs to be saved before any transformations
195  m_gal->Save();
196 
197  m_gal->Translate( aPosition );
198  m_gal->Rotate( -aRotationAngle );
199 
200  // Single line height
201  int lineHeight = KiROUND( GetInterline( m_gal->GetGlyphSize().y ) );
202  int lineCount = linesCount( aText );
203  const VECTOR2D& glyphSize = m_gal->GetGlyphSize();
204 
205  // align the 1st line of text
206  switch( m_gal->GetVerticalJustify() )
207  {
209  m_gal->Translate( VECTOR2D( 0, glyphSize.y ) );
210  break;
211 
213  m_gal->Translate( VECTOR2D( 0, glyphSize.y / 2.0 ) );
214  break;
215 
217  break;
218 
219  default:
220  break;
221  }
222 
223  if( lineCount > 1 )
224  {
225  switch( m_gal->GetVerticalJustify() )
226  {
228  break;
229 
231  m_gal->Translate( VECTOR2D(0, -( lineCount - 1 ) * lineHeight / 2) );
232  break;
233 
235  m_gal->Translate( VECTOR2D(0, -( lineCount - 1 ) * lineHeight ) );
236  break;
237  }
238  }
239 
240  m_gal->SetIsStroke( true );
241  //m_gal->SetIsFill( false );
242 
243  if( m_gal->IsFontBold() )
245 
246  // Split multiline strings into separate ones and draw them line by line
247  size_t begin = 0;
248  size_t newlinePos = aText.find( '\n' );
249 
250  while( newlinePos != aText.npos )
251  {
252  size_t length = newlinePos - begin;
253 
254  drawSingleLineText( aText.substr( begin, length ) );
255  m_gal->Translate( VECTOR2D( 0.0, lineHeight ) );
256 
257  begin = newlinePos + 1;
258  newlinePos = aText.find( '\n', begin );
259  }
260 
261  // Draw the last (or the only one) line
262  if( !aText.empty() )
263  drawSingleLineText( aText.substr( begin ) );
264 
265  m_gal->Restore();
266 }
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:174
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
std::string::size_type find(char c) const
Definition: utf8.h:110
GAL * m_gal
Pointer to the GAL.
Definition: stroke_font.h:116
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:68
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 269 of file stroke_font.cpp.

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

References computeOverbarVerticalPosition(), computeTextLineSize(), computeUnderlineVerticalPosition(), 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::IsFontUnderlined(), 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 163 of file stroke_font.cpp.

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

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 56 of file stroke_font.cpp.

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

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 174 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 184 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 181 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 118 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 117 of file stroke_font.h.

Referenced by drawSingleLineText(), and LoadNewStrokeFont().

◆ OVERBAR_POSITION_FACTOR

const double STROKE_FONT::OVERBAR_POSITION_FACTOR = 1.33
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 177 of file stroke_font.h.

Referenced by LoadNewStrokeFont().

◆ UNDERLINE_POSITION_FACTOR

const double STROKE_FONT::UNDERLINE_POSITION_FACTOR = 0.41
staticprivate

Definition at line 171 of file stroke_font.h.

Referenced by computeUnderlineVerticalPosition().


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