KiCad PCB EDA Suite
KIGFX::STROKE_FONT Class Reference

Implement a 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)
 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)
 Draw 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...
 
double m_maxGlyphWidth
 The widest glyph in our set. More...
 

Static Private Attributes

static const double OVERBAR_POSITION_FACTOR = 1.33
 
static const double UNDERLINE_POSITION_FACTOR = 0.41
 Factor that determines relative line width for bold text. More...
 
static const double BOLD_FACTOR = 1.3
 Scale factor for a glyph. More...
 
static const double STROKE_FONT_SCALE = 1.0 / 21.0
 Tilt factor for italic style (the is is the scaling factor on dY relative coordinates to give a tilt shape. More...
 
static const double ITALIC_TILT = 1.0 / 8
 Factor that determines the pitch between 2 lines. More...
 
static const double INTERLINE_PITCH_RATIO = 1.61
 

Friends

class GAL
 

Detailed Description

Implement a stroke font drawing.

A stroke font is composed of lines.

Definition at line 54 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 ), m_maxGlyphWidth( 1.0 )
52 {
53 }
double m_maxGlyphWidth
The widest glyph in our set.
Definition: stroke_font.h:171
GAL * m_gal
Pointer to the GAL.
Definition: stroke_font.h:168
const std::vector< BOX2D > * m_glyphBoundingBoxes
Bounding boxes of the glyphs.
Definition: stroke_font.h:170
const GLYPH_LIST * m_glyphs
Glyph list.
Definition: stroke_font.h:169

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

174 {
175  VECTOR2D min( 0, 0 );
176  VECTOR2D max( aGlyphWidth, 0 );
177 
178  for( const std::vector<VECTOR2D>* pointList : *aGLYPH )
179  {
180  for( const VECTOR2D& point : *pointList )
181  {
182  min.y = std::min( min.y, point.y );
183  max.y = std::max( max.y, point.y );
184  }
185  }
186 
187  return BOX2D( min, max - min );
188 }
BOX2< VECTOR2D > BOX2D
Definition: box2.h:523
Define 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 500 of file stroke_font.cpp.

501 {
502  // Static method.
503  return aGlyphHeight * OVERBAR_POSITION_FACTOR;
504 }
static const double OVERBAR_POSITION_FACTOR
Definition: stroke_font.h:174

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

508 {
509  // Compute the Y position of the overbar. This is the distance between
510  // the text base line and the overbar axis.
512 }
const VECTOR2D & GetGlyphSize() const
GAL * m_gal
Pointer to the GAL.
Definition: stroke_font.h:168
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 529 of file stroke_font.cpp.

531 {
532  VECTOR2D string_bbox;
533  int line_count = 1;
534  double maxX = 0.0, curX = 0.0;
535 
536  double curScale = 1.0;
537  bool in_overbar = false;
538  bool in_super_or_subscript = false;
539 
540  for( UTF8::uni_iter it = aText.ubegin(), end = aText.uend(); it < end; ++it )
541  {
542  if( *it == '\n' )
543  {
544  curX = 0.0;
545  maxX = std::max( maxX, curX );
546  ++line_count;
547  continue;
548  }
549 
550  // Handle tabs as locked to the nearest 4th column (counting in spaces)
551  // The choice of spaces is somewhat arbitrary but sufficient for aligning text
552  if( *it == '\t' )
553  {
554  double spaces = m_glyphBoundingBoxes->at( 0 ).GetEnd().x;
555  double addlSpace = 3.0 * spaces - std::fmod( curX, 4.0 * spaces );
556 
557  // Add the remaining space (between 0 and 3 spaces)
558  curX += addlSpace;
559 
560  // Tab ends an overbar
561  in_overbar = false;
562  }
563  else if( *it == '~' )
564  {
565  if( ++it == end )
566  break;
567 
568  if( *it == '~' )
569  {
570  // double ~ is really a ~ so go ahead and process the second one
571 
572  // so what's a triple ~? It could be a real ~ followed by an overbar, or
573  // it could be an overbar followed by a real ~. The old algorithm did the
574  // former so we will too....
575  }
576  else
577  {
578  // single ~ toggles overbar
579  in_overbar = !in_overbar;
580  }
581  }
582  else if( *it == '^' || *it == '_' )
583  {
584  auto lookahead = it;
585 
586  if( ++lookahead != end && *lookahead == '{' )
587  {
588  // process superscript
589  it = lookahead;
590  in_super_or_subscript = true;
591  curScale = 0.8;
592  continue;
593  }
594  }
595  else if( *it == '}' && in_super_or_subscript )
596  {
597  in_super_or_subscript = false;
598  curScale = 1.0;
599  continue;
600  }
601  // Overbar syntax is less precise so we have to have some special cases
602  else if( in_overbar && ( *it == ' ' || *it == '}' || *it == ')' ) )
603  {
604  in_overbar = false;
605  }
606 
607  // Index in the bounding boxes table
608  int dd = (signed) *it - ' ';
609 
610  if( dd >= (int) m_glyphBoundingBoxes->size() || dd < 0 )
611  {
612  int substitute = *it == '\t' ? ' ' : '?';
613  dd = substitute - ' ';
614  }
615 
616  const BOX2D& box = m_glyphBoundingBoxes->at( dd );
617  curX += box.GetEnd().x * curScale;
618  }
619 
620  string_bbox.x = std::max( maxX, curX ) * aGlyphSize.x;
621  string_bbox.x += aGlyphThickness;
622  string_bbox.y = line_count * GetInterline( aGlyphSize.y );
623 
624  // For italic correction, take in account italic tilt
625  if( m_gal->IsFontItalic() )
626  string_bbox.x += string_bbox.y * STROKE_FONT::ITALIC_TILT;
627 
628  return string_bbox;
629 }
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).
Define a general 2D-vector/point.
Definition: vector2d.h:61
uni_iter uend() const
Return a uni_iter initialized to the end of "this" UTF8 byte sequence.
Definition: utf8.h:287
static const double ITALIC_TILT
Factor that determines the pitch between 2 lines.
Definition: stroke_font.h:185
uni_iter ubegin() const
Returns a uni_iter initialized to the start of "this" UTF8 byte sequence.
Definition: utf8.h:279
GAL * m_gal
Pointer to the GAL.
Definition: stroke_font.h:168
uni_iter is a non-mutating iterator that walks through unicode code points in the UTF8 encoded string...
Definition: utf8.h:203
const std::vector< BOX2D > * m_glyphBoundingBoxes
Bounding boxes of the glyphs.
Definition: stroke_font.h:170

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

524 {
526 }
float GetLineWidth() const
Get the line width.
const VECTOR2D & GetGlyphSize() const
GAL * m_gal
Pointer to the GAL.
Definition: stroke_font.h:168
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 515 of file stroke_font.cpp.

516 {
517  // Compute the Y position of the underline. This is the distance between
518  // the text base line and the underline axis.
520 }
const VECTOR2D & GetGlyphSize() const
GAL * m_gal
Pointer to the GAL.
Definition: stroke_font.h:168
static const double UNDERLINE_POSITION_FACTOR
Factor that determines relative line width for bold text.
Definition: stroke_font.h:175

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

192 {
193  if( aText.empty() )
194  return;
195 
196  // Context needs to be saved before any transformations
197  m_gal->Save();
198 
199  m_gal->Translate( aPosition );
200  m_gal->Rotate( -aRotationAngle );
201 
202  // Single line height
203  int lineHeight = KiROUND( GetInterline( m_gal->GetGlyphSize().y ) );
204  int lineCount = linesCount( aText );
205  const VECTOR2D& glyphSize = m_gal->GetGlyphSize();
206 
207  // align the 1st line of text
208  switch( m_gal->GetVerticalJustify() )
209  {
211  m_gal->Translate( VECTOR2D( 0, glyphSize.y ) );
212  break;
213 
215  m_gal->Translate( VECTOR2D( 0, glyphSize.y / 2.0 ) );
216  break;
217 
219  break;
220 
221  default:
222  break;
223  }
224 
225  if( lineCount > 1 )
226  {
227  switch( m_gal->GetVerticalJustify() )
228  {
230  break;
231 
233  m_gal->Translate( VECTOR2D(0, -( lineCount - 1 ) * lineHeight / 2) );
234  break;
235 
237  m_gal->Translate( VECTOR2D(0, -( lineCount - 1 ) * lineHeight ) );
238  break;
239  }
240  }
241 
242  m_gal->SetIsStroke( true );
243  //m_gal->SetIsFill( false );
244 
245  if( m_gal->IsFontBold() )
247 
248  // Split multiline strings into separate ones and draw them line by line
249  size_t begin = 0;
250  size_t newlinePos = aText.find( '\n' );
251 
252  while( newlinePos != aText.npos )
253  {
254  size_t length = newlinePos - begin;
255 
256  drawSingleLineText( aText.substr( begin, length ) );
257  m_gal->Translate( VECTOR2D( 0.0, lineHeight ) );
258 
259  begin = newlinePos + 1;
260  newlinePos = aText.find( '\n', begin );
261  }
262 
263  // Draw the last (or the only one) line
264  if( !aText.empty() )
265  drawSingleLineText( aText.substr( begin ) );
266 
267  m_gal->Restore();
268 }
static constexpr std::string::size_type npos
Definition: utf8.h:151
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
Scale factor for a glyph.
Definition: stroke_font.h:178
Define 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:105
GAL * m_gal
Pointer to the GAL.
Definition: stroke_font.h:168
VECTOR2< double > VECTOR2D
Definition: vector2d.h:622
void drawSingleLineText(const UTF8 &aText)
Draw 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:159
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:178
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:103

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

Draw a single line of text.

Multiline texts should be split before using the function.

Parameters
aTextis the text to be drawn.

Definition at line 271 of file stroke_font.cpp.

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

166 {
167  // Do not add the glyph thickness to the interline. This makes bold text line-spacing
168  // different from normal text, which is poor typography.
169  return ( aGlyphHeight * INTERLINE_PITCH_RATIO );
170 }
static const double INTERLINE_PITCH_RATIO
Definition: stroke_font.h:188

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 159 of file stroke_font.h.

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

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  m_maxGlyphWidth = std::max( m_maxGlyphWidth,
155  g_newStrokeFontGlyphBoundingBoxes->back().GetWidth() );
156  }
157 
160  return true;
161 }
std::vector< std::vector< VECTOR2D > * > GLYPH
Definition: stroke_font.h:44
double m_maxGlyphWidth
The widest glyph in our set.
Definition: stroke_font.h:171
Define 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:47
GLYPH_LIST * g_newStrokeFontGlyphs
Glyph list.
Definition: stroke_font.cpp:46
static const double STROKE_FONT_SCALE
Tilt factor for italic style (the is is the scaling factor on dY relative coordinates to give a tilt ...
Definition: stroke_font.h:181
#define FONT_OFFSET
const std::vector< BOX2D > * m_glyphBoundingBoxes
Bounding boxes of the glyphs.
Definition: stroke_font.h:170
const GLYPH_LIST * m_glyphs
Glyph list.
Definition: stroke_font.h:169
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, m_maxGlyphWidth, STROKE_FONT_SCALE, VECTOR2< T >::x, and VECTOR2< T >::y.

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

◆ SetGAL()

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

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

Parameters
aGalis the new GAL instance.

Definition at line 85 of file stroke_font.h.

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

References m_gal.

Friends And Related Function Documentation

◆ GAL

friend class GAL
friend

Definition at line 56 of file stroke_font.h.

Member Data Documentation

◆ BOLD_FACTOR

const double STROKE_FONT::BOLD_FACTOR = 1.3
staticprivate

Scale factor for a glyph.

Definition at line 178 of file stroke_font.h.

Referenced by Draw().

◆ INTERLINE_PITCH_RATIO

const double STROKE_FONT::INTERLINE_PITCH_RATIO = 1.61
staticprivate

Definition at line 188 of file stroke_font.h.

Referenced by GetInterline().

◆ ITALIC_TILT

const double STROKE_FONT::ITALIC_TILT = 1.0 / 8
staticprivate

Factor that determines the pitch between 2 lines.

Definition at line 185 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 170 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 169 of file stroke_font.h.

Referenced by drawSingleLineText(), and LoadNewStrokeFont().

◆ m_maxGlyphWidth

double KIGFX::STROKE_FONT::m_maxGlyphWidth
private

The widest glyph in our set.

Factor that determines relative vertical position of the overbar.

Definition at line 171 of file stroke_font.h.

Referenced by drawSingleLineText(), and LoadNewStrokeFont().

◆ OVERBAR_POSITION_FACTOR

const double STROKE_FONT::OVERBAR_POSITION_FACTOR = 1.33
staticprivate

Definition at line 174 of file stroke_font.h.

Referenced by ComputeOverbarVerticalPosition().

◆ STROKE_FONT_SCALE

const double STROKE_FONT::STROKE_FONT_SCALE = 1.0 / 21.0
staticprivate

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

Definition at line 181 of file stroke_font.h.

Referenced by LoadNewStrokeFont().

◆ UNDERLINE_POSITION_FACTOR

const double STROKE_FONT::UNDERLINE_POSITION_FACTOR = 0.41
staticprivate

Factor that determines relative line width for bold text.

Definition at line 175 of file stroke_font.h.

Referenced by computeUnderlineVerticalPosition().


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