opennurbs_font.h
1 //
2 // Copyright (c) 1993-2015 Robert McNeel & Associates. All rights reserved.
3 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
4 // McNeel & Associates.
5 //
6 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
7 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
8 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
9 //
10 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
11 //
12 ////////////////////////////////////////////////////////////////
13 
14 
15 #if !defined(OPENNURBS_FONT_INC_)
16 #define OPENNURBS_FONT_INC_
17 
18 class ON_CLASS ON_FontMetrics
19 {
20 public:
21  ON_FontMetrics() = default;
22  ~ON_FontMetrics() = default;
23  ON_FontMetrics(const ON_FontMetrics&) = default;
24  ON_FontMetrics& operator=(const ON_FontMetrics&) = default;
25 
26 
27 public:
28  // All properties are zero.
29  static const ON_FontMetrics Unset;
30 
31  /*
32  ON_FontMetric::DefaultLineFeedRatio*ON_FontMetrics().AspectOfI()
33  can be used to cook up a line space value when using the
34  ON_FontMetrics.LineSpace() value defined by the font is
35  not desired.
36  */
37  static const double DefaultLineFeedRatio; // 1.6
38 
39  // UNICODE code point of the glyph used to determine HeightOfCapital()
40  // when no reaonable value is available from the font definition.
41  // Currently this is the 'I' glyph. Opennurbs has used 'I' since 2005.
42  // It is possible 'H' would work as well. All other glyphs, in
43  // particular 'M' and 'W', do not work.
44  static const ON__UINT32 HeightOfCapitalCodePoint; // 'I'
45 
46 public:
47  /*
48  Returns:
49  Signed distance from the baseline to highest point on a glyph outline.
50  Remarks:
51  If every glyph outline in the font has (0,0) on the basline, then Ascent()
52  is the maximum glyph bounding box Y.
53  */
54  int Ascent() const;
55 
56  /*
57  Returns:
58  Signed distance from the baseline to lowest point on a glyph outline.
59  Remarks:
60  This value is typically negative because glyphs for letters like 'j'
61  typically have a portion of their outline below the baseline. However,
62  some fonts have positive descent.
63  If every glyph outline in the font has (0,0) on the basline, then Ascent()
64  is the maximum glyph bounding box Y.
65  */
66  int Descent() const;
67 
68  /*
69  Returns:
70  The postive distance to move a base line when moving to a new line of text.
71 
72  Remarks:
73  For almost every font used to render text, LineSpace() > (Ascent() - Descent()).
74 
75  This metric is sometimes called "height", but that term is often confused
76  with (Ascent() - Descent()).
77 
78  For fonts designed to render horizontal lines of text, LineSpace() is a
79  vertical distance. For fonts desingned to render vertical lines of text,
80  LineSpace() is a horizontal distance. Depending on the context, the
81  direction to move can be up, down, left or right.
82  */
83  int LineSpace() const;
84 
85  /*
86  Returns:
87  The "units per EM". This is the height and width of the square grid
88  where the font glyphs are designed.
89  Remarks:
90  The width of the 'M' glyph in a font can be different from UPM.
91  The height of the 'M' glyph in a font is typically less than UPM.
92  In TrueType fonts, UPM is often a power of two and generally 1024 or 2048.
93  In OpenType fonts, UPM is often 1000.
94  In PostScript fonts, UPM is often 1000.
95  */
96  int UPM() const;
97 
98  /*
99  Returns:
100  The signed distance from the baseline to the highest point on the 'I' glyph.
101  Remarks:
102  The primary uses of AscentOfI() are:
103  1)
104  Calculate a scale factor to produce text with a user specified "text height".
105  2)
106  To calculate insertion location for ON::TextVerticalAlignment::Middle
107  and ON::TextVerticalAlignment::Top.
108 
109  Since 2005, opennurbs has used
110  (user specified text height)/AscentOfI()
111  as the scale factor to render glyphs when user interface has provided
112  a "text height" value. Users are more satisfied with this approach
113  than when the scaling is base on line space or maximum font glyph ascent
114  values. Experiments have ruled out the use of any other capital latin
115  letter glyph except 'H' for this use. When a font does not contain an
116  'I' glyph, a suitable value is returned that can be used for text height
117  scaling and vertical alignment.
118  */
119  int AscentOfI() const;
120 
121  /*
122  Description:
123  Get the scale to apply to normalized glyph boxes and outlines to
124  render the 'I' in the glyph's font at a height of text_height.
125  Parameters:
126  text_height - [in]
127  The desired height of typical capital latin letter glyphs.
128  Returns:
129  text_height / AscentOfI().
130  */
131  double GlyphScale(double text_height) const;
132 
133  /*
134  Returns:
135  Thickness of strikeout.
136  Remarks:
137  The signed distance from the baseline to the bottom of the strikeout
138  is StrikeoutPosition() - StrikeoutThickness()/2.
139  */
140  int StrikeoutThickness() const;
141 
142  /*
143  Returns:
144  Signed distance from baseline to center of strikeout.
145  A positive value indicates the strikeout is above the baseline (common).
146  Remarks:
147  The signed distance from the baseline to the bottom of the strikeout
148  is StrikeoutPosition() - StrikeoutThickness()/2.
149  */
150  int StrikeoutPosition() const;
151 
152 
153  /*
154  Returns:
155  Thickness of underscore
156  Remarks:
157  The signed distance from the baseline to the bottom of the underscore
158  is UnderscorePosition() - UnderscoreThickness()/2.
159  */
160  int UnderscoreThickness() const;
161 
162  /*
163  Returns:
164  Signed distance from baseline to center of underscore.
165  A negative value indicates the underscore is below the baseline (common).
166  Remarks:
167  The signed distance from the baseline to the bottom of the underscore
168  is UnderscorePosition() - UnderscoreThickness()/2.
169  */
170  int UnderscorePosition() const;
171 
172  static const ON_FontMetrics Scale(
173  const ON_FontMetrics& font_metrics,
174  double scale
175  );
176 
177  void SetHeights(
178  int ascent,
179  int descent,
180  int UPM,
181  int line_space
182  );
183 
184  bool HeightsAreValid() const;
185 
186  void SetAscentOfI(
187  int ascent_of_I
188  );
189 
190  void SetStrikeout(
191  int strikeout_position,
192  int strikeout_thickness
193  );
194 
195  void SetUnderscore(
196  int underscore_position,
197  int underscore_thickness
198  );
199 
200 private:
201  int m_UPM = 0; // units per EM
202  int m_ascent = 0; // max over all glyphs in font of (highest outline point - baseline point).y
203  int m_descent = 0; // min over all glyphs in font of (lowest outline point - baseline point).y
204  int m_line_space = 0; // distance between baselines
205  int m_ascent_of_I = 0; // (highest 'I' outline point - I baseline point).y
206 
207  int m_strikeout_thickness = 0; //
208  int m_strikeout_position = 0; //
209 
210  int m_underscore_thickness = 0; //
211  int m_underscore_position = 0; //
212 
213 private:
214  int m_reserved1 = 0;
215  double m_reserved2 = 0.0;
216  double m_reserved3 = 0.0;
217  ON__UINT_PTR m_reserved5 = 0;
218 };
219 
220 
221 /// <summary>
222 /// An ON_Font is a face in a font family. It corresponds to a Windows LOGFONT,
223 /// a .NET System.Drawing.Font or a FreeType FT_Face.
224 /// </summary>
225 class ON_CLASS ON_Font
226 {
227 public:
228 
229 #pragma region RH_C_SHARED_ENUM [ON_Font::Weight] [Rhino.DocObjects.Font.FontWeight] [nested:byte]
230  /// <summary>
231  /// Weight enum values
232  /// Avoid casting these values to int.
233  /// Use ON_Font::WindowsLogfontWeightFromWeight() or
234  /// ON_Font::AppleWeightOfFontFromWeight() or
235  /// add another converter.
236  /// </summary>
237  enum class Weight : unsigned char
238  {
239  /// <summary> Not set. </summary>
240  Unset = 0,
241 
242  /// <summary> IsLight = true </summary>
243  Thin = 1,
244 
245  /// <summary> IsLight = true </summary>
246  Ultralight = 2,
247 
248  //ExtraLight = 2,
249 
250  /// <summary> IsLight = true </summary>
251  Light = 3,
252 
253  /// <summary> Default font weight. IsNormalWeight = true Also called Regular.</summary>
254  Normal = 4,
255 
256  //Regular = 4,
257 
258  /// <summary> IsNormalWeight = true </summary>
259  Medium = 5,
260 
261  /// <summary> IsBold = true </summary>
262  Semibold = 6,
263 
264  //Demibold = 6,
265  //Demi = 6,
266  //Semi = 6,
267 
268  /// <summary> IsBold = true </summary>
269  Bold = 7,
270 
271  /// <summary> IsBold = true </summary>
272  Ultrabold = 8,
273 
274  //ExtraBold = 8,
275 
276  /// <summary> IsBold = true Also called Black</summary>
277  Heavy = 9
278 
279  //Black = 9,
280  };
281 #pragma endregion
282 
283  /*
284  Returns:
285  -1: weight_a is lighter, weight_b is heavier
286  +1: weight_a is heavier, weight_b is lighter
287  0: weight_a = weight_b
288  */
289  static int CompareWeight(
290  ON_Font::Weight weight_a,
291  ON_Font::Weight weight_b
292  );
293 
294  /*
295  Description:
296  In the rare cases when an ON_Font::Weight value must be passed
297  as an unsigned int, use ON_Font::FontWeightFromUnsigned() to
298  convert the unsigned value to an ON_Font::Weight value.
299  Parameters:
300  unsigned_font_weight - [in]
301  */
302  static ON_Font::Weight FontWeightFromUnsigned(
303  unsigned int unsigned_font_weight
304  );
305 
306  /*
307  Description:
308  The correspondence between Windows LOGFONT lfWeight values and
309  ON_Font::Weight enum values is
310  ON_Font::Weight::Thin = 100 LOGFONT lfWeight
311  ON_Font::Weight::Ultralight = 200 LOGFONT lfWeight
312  ON_Font::Weight::Light = 300 LOGFONT lfWeight
313  ON_Font::Weight::Normal = 400 LOGFONT lfWeight
314  ON_Font::Weight::Medium = 500 LOGFONT lfWeight
315  ON_Font::Weight::Semibold = 600 LOGFONT lfWeight
316  ON_Font::Weight::Bold = 700 LOGFONT lfWeight
317  ON_Font::Weight::Ultrabold = 800 LOGFONT lfWeight
318  ON_Font::Weight::Heavy = 900 LOGFONT lfWeight
319  Returns:
320  The Windows LOGFONT lfWeight value that corresponds to the ON_Font::Weight enum value.
321  */
322  static int WindowsLogfontWeightFromWeight(
323  ON_Font::Weight font_weight
324  );
325 
326  /*
327  Description:
328  The correspondence between Apple "weight of font" values and
329  ON_Font::Weight enum values is
330  ON_Font::Weight::Thin = 1
331  ON_Font::Weight::Ultralight = 2
332  ON_Font::Weight::Light = 3
333  ON_Font::Weight::Normal = 4
334  ON_Font::Weight::Medium = 5
335  ON_Font::Weight::Semibold = 6
336  ON_Font::Weight::Bold = 7
337  ON_Font::Weight::Ultrabold = 8
338  ON_Font::Weight::Heavy = 9
339  Returns:
340  The Apple "weight of font" value that corresponds to the ON_Font::Weight enum value.
341  */
342  static int AppleWeightOfFontFromWeight(
343  ON_Font::Weight font_weight
344  );
345 
346  /*
347  Description:
348  The correspondence between Apple "font weight trait" values and
349  ON_Font::Weight enum values is
350  ON_Font::Weight::Thin = -0.4 Apple font weight trait
351  ON_Font::Weight::Ultralight = -0.2667 Apple font weight trait
352  ON_Font::Weight::Light = -0.1333 Apple font weight trait
353  ON_Font::Weight::Normal = 0.0 Apple font weight trait
354  ON_Font::Weight::Medium = 0.1333 Apple font weight trait
355  ON_Font::Weight::Semibold = 0.2667 Apple font weight trait
356  ON_Font::Weight::Bold = 0.4 Apple font weight trait
357  ON_Font::Weight::Ultrabold = 0.5333 Apple font weight trait
358  ON_Font::Weight::Heavy = 0.6667 Apple font weight trait
359  Returns:
360  The Apple "NSFontWeightTrait" value that corresponds to the ON_Font::Weight enum value.
361  */
362  static double AppleFontWeightTraitFromWeight(
363  ON_Font::Weight font_weight
364  );
365 
366  /*
367  Description:
368  The correspondence between Windows LOGFONT lfWeight values and
369  ON_Font::Weight enum values is
370 
371  ON_Font::Weight::Thin = 100
372  ON_Font::Weight::Ultralight = 200
373  ON_Font::Weight::Light = 300
374  ON_Font::Weight::Normal = 400
375  ON_Font::Weight::Medium = 500
376  ON_Font::Weight::Semibold = 600
377  ON_Font::Weight::Bold = 700
378  ON_Font::Weight::Ultrabold = 800
379  ON_Font::Weight::Heavy = 900
380  Returns:
381  The best ON_Font::Weight enum value for the Windows LOGFONT weight.
382  */
383 
384  static ON_Font::Weight WeightFromWindowsLogfontWeight(
385  int windows_logfont_weight
386  );
387 
388  /*
389  Description:
390  The correspondence between Apple "weight of font" values and
391  ON_Font::Weight enum values is
392  ON_Font::Weight::Thin = 1
393  ON_Font::Weight::Ultralight = 2
394  ON_Font::Weight::Light = 3
395  ON_Font::Weight::Normal = 4
396  ON_Font::Weight::Medium = 5
397  ON_Font::Weight::Semibold = 6
398  ON_Font::Weight::Bold = 7
399  ON_Font::Weight::Ultrabold = 8
400  ON_Font::Weight::Heavy = 9
401  Returns:
402  The best ON_Font::Weight enum value for the Apple weight of font.
403  */
404  static ON_Font::Weight WeightFromAppleWeightOfFont(
405  int apple_weight_of_font
406  );
407 
408  /*
409  Parameters:
410  apple_font_weight_trait - [in]
411  Apple NSFontWeightTrait
412  The valid value range is from -1.0 to 1.0. The value of 0.0 corresponds to the regular or medium font weight.
413  */
414  static ON_Font::Weight WeightFromAppleFontWeightTrait(
415  double apple_font_weight_trait
416  );
417 
418  static const wchar_t* WeightToWideString(
419  ON_Font::Weight font_weight
420  );
421 
423 
424 #pragma region RH_C_SHARED_ENUM [ON_Font::Stretch] [Rhino.DocObjects.Font.FontStretch] [nested:byte]
425  /// <summary>
426  /// Horizontal expansion or contraction of font
427  /// </summary>
428  enum class Stretch : unsigned char
429  {
430  /// <summary> Not set. </summary>
431  Unset = 0,
432  /// <summary> </summary>
433  Ultracondensed = 1,
434  /// <summary> </summary>
435  Extracondensed = 2,
436  /// <summary> </summary>
437  Condensed = 3,
438  /// <summary> </summary>
439  Semicondensed = 4,
440 
441  /// <summary> Default font stretch. </summary>
442  Medium = 5,
443 
444  //Normal = 5,
445 
446  /// <summary> </summary>
447  Semiexpanded = 6,
448  /// <summary> </summary>
449  Expanded = 7,
450  /// <summary> </summary>
451  Extraexpanded = 8,
452  /// <summary> </summary>
453  Ultraexpanded = 9
454  };
455 #pragma endregion
456 
457  /*
458  Description:
459  In the rare cases when an ON_Font::Stretch value must be passed
460  as an unsigned int, use ON_Font::FontStretchFromUnsigned() to
461  convert the unsigned value to an ON_Font::Stretch value.
462  Parameters:
463  unsigned_font_stretch - [in]
464  */
465  static ON_Font::Stretch FontStretchFromUnsigned(
466  unsigned int unsigned_font_stretch
467  );
468 
469 
470 #pragma region RH_C_SHARED_ENUM [ON_Font::Style] [Rhino.DocObjects.Font.FontStyle] [nested:byte]
471  /// <summary>
472  /// Vertical angle of font
473  /// Upright, Italic, or Oblique
474  /// </summary>
475  enum class Style : unsigned char
476  {
477  /// <summary> Not set. </summary>
478  Unset = 0,
479 
480  /// <summary> Default font style. </summary>
481  Upright = 1,
482 
483  //Normal = 1,
484  //Roman = 1,
485 
486  /// <summary> </summary>
487  Italic = 2,
488 
489  /// <summary> </summary>
490  Oblique = 3
491  };
492 #pragma endregion
493 
494  /*
495  Description:
496  In the rare cases when an ON_Font::Style value must be passed
497  as an unsigned int, use ON_Font::FontStyleFromUnsigned() to
498  convert the unsigned value to an ON_Font::Style value.
499  Parameters:
500  unsigned_font_style - [in]
501  */
502  static ON_Font::Style FontStyleFromUnsigned(
503  unsigned int unsigned_font_style
504  );
505 
506  static const wchar_t* StyleToWideString(
507  ON_Font::Style font_style
508  );
509 
510 
511 public:
512  static const ON_Font Default;
513  static bool IsValidFaceName(
514  const wchar_t* face_name
515  );
516 
517 private:
518  // This private constructor is used to construct ON_Font::Default and managed fonts.
519  // Never make this constructor protected or public.
520  ON_Font(
521  unsigned char managed_status, // 0 = no, 1 = ON_Font::Default, 2 = managed
522  const ON_Font& src
523  );
524 
525 private:
526  // Use ON_Font( const ON_Font& ) or ON_Font::operator= if you need to make a copy.
527  // Never make CopyHelper protected or public.
528  void CopyHelper(
529  const ON_Font&
530  );
531 
532 public:
533  /*
534  Description:
535  Get a font managed by the application from the font characteristics.
536  Never delete a font returned by GetManagedFont().
537  Parameters:
538  face_name - [in]
539  font_weight - [in]
540  default = ON_Font::Default.FontWeight()
541  font_style - [in]
542  default = ON_Font::Default.FontStyle()
543  font_stretch - [in]
544  default = ON_Font::Default.FontStretch()
545  bUnderlined - [in]
546  default = ON_Font::Default.Underlined() = false
547  bStrikethrough - [in]
548  default = ON_Font::Default.Strikethrough() = false
549  linefeed_ratio - [in]
550  default = ON_Font::Default.LinefeedRatio()
551  windows_charset - [in]
552  default = ON_Font::WindowsCharSet::DefaultCharSet
553  */
554  static const ON_Font* GetManagedFont(
555  const wchar_t* face_name
556  );
557 
558  static const ON_Font* GetManagedFont(
559  double point_size,
560  const wchar_t* face_name
561  );
562 
563  static const ON_Font* GetManagedFont(
564  const wchar_t* face_name,
565  bool bBold
566  );
567 
568  static const ON_Font* GetManagedFont(
569  double point_size,
570  const wchar_t* face_name,
571  bool bBold
572  );
573 
574  static const ON_Font* GetManagedFont(
575  const wchar_t* face_name,
576  bool bBold,
577  bool bItalic
578  );
579 
580  static const ON_Font* GetManagedFont(
581  double point_size,
582  const wchar_t* face_name,
583  bool bBold,
584  bool bItalic
585  );
586 
587  static const ON_Font* GetManagedFont(
588  const wchar_t* face_name,
589  ON_Font::Weight font_weight,
590  ON_Font::Style font_style
591  );
592 
593  static const ON_Font* GetManagedFont(
594  double point_size,
595  const wchar_t* face_name,
596  ON_Font::Weight font_weight,
597  ON_Font::Style font_style
598  );
599 
600  static const ON_Font* GetManagedFont(
601  const wchar_t* face_name,
602  ON_Font::Weight font_weight,
603  ON_Font::Style font_style,
604  ON_Font::Stretch font_stretch,
605  bool bUnderlined,
606  bool bStrikethrough,
607  double linefeed_ratio,
608  unsigned int logfont_charset
609  );
610 
611  static const ON_Font* GetManagedFont(
612  double point_size,
613  const wchar_t* face_name,
614  ON_Font::Weight font_weight,
615  ON_Font::Style font_style,
616  ON_Font::Stretch font_stretch,
617  bool bUnderlined,
618  bool bStrikethrough,
619  double linefeed_ratio,
620  unsigned int logfont_charset
621  );
622 
623  static const ON_Font* GetManagedFontFromFontDescription(
624  const wchar_t* font_description
625  );
626 
627 #if defined(ON_OS_WINDOWS_GDI)
628  /*
629  Description:
630  Get a managed font from a LOGFONT
631  Parameters:
632  map_mode - [in]
633  If map_mode is 0, then ::GetMapMode(hdc) is called to get the mapping mode.
634  Otherwised, map_mode must identify a Windows mapping mode
635  (MM_TEXT, MM_LOMETRIC, MM_HIMETRIC, MM_LOENGLISH, MM_HIENGLISH, M_TWIPS).
636  If map_mode = MM_TEXT (1), then hdc is used as described in the hdc parameter.
637  hdc - [in]
638  Windows device context.
639  If map_mode is set and not MM_TEXT, then hdc is ignored.
640  Otherwise the device context is used to get the mapping mode ( GetMapMode(hdc) ).
641  If the mapping mode is MM_TEXT, then the additional device context values
642  GetDeviceCaps(hdc, LOGPIXELSY) and conversion between device and logical pixel heights
643  DPtoLP(hdc,...) and LPtoDP(hdc,...) are used.
644  logfont - [in]
645  These logfont properties are used to find the managed font.
646  lfHeight (when dc is not zero)
647  lfWeight;
648  lfItalic;
649  lfUnderline;
650  lfStrikeOut;
651  lfCharSet;
652  lfFaceName[LF_FACESIZE];
653  All other LOGFONT properties is ignored.
654  See Also:
655  ON_Font::GetManagedFontFromWindowsLogfontComplete
656  */
657  static const ON_Font* GetManagedFontFromWindowsLogfont(
658  int map_mode,
659  HDC hdc,
660  const LOGFONT& logfont
661  );
662 
663  enum : int
664  {
665  MAP_MODE_ZERO_ERROR_SUPPRESS = MM_MAX + 3
666  };
667 
668 #endif
669 
670  static const ON_Font* GetManagedFontFromAppleFontName(
671  const wchar_t* apple_font_name
672  );
673 
674  /*
675  Returns:
676  The managed font for this font.
677  Remarks:
678  If this->IsManagedFont() is true, then "this" is returned.
679  */
680  const ON_Font* ManagedFont() const;
681 
682  /*
683  Description:
684  Returns the glpyh informationh for used to render a specific code point
685  Parameters:
686  unicode_code_point
687  UNICODE code point value
688  Returns:
689  Glyph rendering information.
690 
691  Remarks:
692  Typically the returned glpyh uses is a single glpyh in this->ManagedFont().
693  In this case, glyph->SubstitueCount() is 0.
694 
695  In some cases one or more glyphs from one or more substitute fonts are required
696  to render the code point. In this case, glyph->SubstitueCount() is 0.
697 
698  Example:
699  ON_Font* font = ...;
700  unsigned int code_point = ...;
701  const ON_FontGlyph* g = font->CodePointGlyph(code_point);
702  if (nullptr != g )
703  {
704  if ( g->SubstituteCount() > 0 )
705  {
706  // complicate case - one of more substitutes must be rendered to render g
707  for ( const ON_FontGlyph* gsub = g.NextSubstitute(); nullptr != gsub; gsub = gsub->NextSubstitute() )
708  {
709  ...
710  }
711  }
712  else
713  {
714  // simple case - this computer can directly render g
715  ...
716  }
717  }
718  */
719  const class ON_FontGlyph* CodePointGlyph(
720  ON__UINT32 unicode_code_point
721  ) const;
722 
723 private:
724  friend class ON_FontGlyph;
725  const class ON_FontGlyph* Internal_ManagedCodePointGlyph(
726  ON__UINT32 unicode_code_point,
727  bool bCreateIfMissing,
728  bool bFindSubstitutes
729  ) const;
730 
731 public:
732 
733  /*
734  Description:
735  When reading version 5 3dm achives, the font description can be
736  a generic font description or an Apple font name. This function
737  rejects certain descriptions like "Default" and "Arial" for
738  use as Apple font names.
739  */
740  static bool IsNotAppleFontName(
741  const wchar_t* font_description
742  );
743 
744  static const ON_Font* GetManagedFont(
745  const ON_Font& font_characteristics,
746  bool bCreateIfNotFound
747  );
748 
749  static const ON_Font* GetManagedFontFromSerialNumber(
750  unsigned int managed_font_runtime_serial_number
751  );
752 
753  static unsigned int GetManagedFontList(
754  ON_SimpleArray< const ON_Font* >& managed_fonts
755  );
756 
757  /*
758  Returns:
759  True if this font is a managed font returned by one of the
760  static ON_Font::GetManagedFont(...) functions.
761  Remarks:
762  ON_Font::Default is managed.
763  */
764  bool IsManagedFont() const;
765 
766 public:
767 
768  /*
769  Description:
770  If opennurbs is built with FreeType support then
771  FT_Face freetype_face = (FT_Face)ON_Font::FreeTypeFace(font)
772  will return a FreeType face that can be used to render the font.
773  Parameters:
774  font - [in]
775  Returns:
776  A value that can be cast as a FreeType FT_Face.
777  Example
778  const ON_Font* font = ...;
779  FT_Face freetype_face = (FT_Face)ON_Font::FreeTypeFace(font);
780  Remarks:
781  Many fonts do not have a glyph for a every UNICODE codepoint and font
782  substitution is required. If you want to get the freetype face
783  used for a specfic UNICODE codepoint, call ON_Font::CodepointFreeTypeFace().
784  */
785  static ON__UINT_PTR FreeTypeFace(
786  const ON_Font* font
787  );
788 
789 private:
790  /*
791  Description:
792  Helper function used by destructor to deallocate memory used
793  by FreeType face
794  */
795  static void DestroyFreeTypeFace(
796  const ON_Font* font
797  );
798 
799 public:
800  ON_Font();
801  ~ON_Font() = default;
802  ON_Font(const ON_Font& src);
803  ON_Font& operator=(const ON_Font& src);
804 
805 public:
806  /*
807  Description:
808  Create a font with a specified facename and properties.
809  Parameters:
810  face_name - [in]
811  nullptr is treated as ON_Font::Default.FaceName().
812  bBold - [in]
813  True for a bold version of the font.
814  bItalic - [in]
815  True for an italic version of the font.
816  Returns:
817  True if the font characteristics were valid and set on the font.
818  */
819  bool SetFontCharacteristics(
820  const wchar_t* face_name,
821  bool bBold,
822  bool bItalic,
823  bool bUnderlined,
824  bool bStrikethrough
825  );
826 
827  /*
828  Description:
829  Create a font with a specified facename and properties.
830  Parameters:
831  point_size - [in]
832  If point_size > 0.0, then it specifies which size of font definition
833  should be used. Otherwise the font size used for annotation text
834  is used.
835  For high quality fonts it is generally the case that
836  different point sizes of the same font face have
837  subtle differences in glyph design and are not
838  simply scaled versions of a base glyph.
839  face_name - [in]
840  nullptr is treated as ON_Font::Default.FaceName().
841  bBold - [in]
842  True for a bold version of the font.
843  bItalic - [in]
844  True for an italic version of the font.
845  Returns:
846  True if the font characteristics were valid and set on the font.
847  */
848  bool SetFontCharacteristics(
849  double point_size,
850  const wchar_t* face_name,
851  bool bBold,
852  bool bItalic,
853  bool bUnderlined,
854  bool bStrikethrough
855  );
856 
857  /*
858  Description:
859  Set the font's face name and characteristics.
860  Parameters:
861  face_name - [in]
862  nullptr is not permitted.
863  Pass ON_Font::Default.FaceName() if you don't have a face name.
864  Returns:
865  True if the font characteristics were valid and set on the font.
866  */
867  bool SetFontCharacteristics(
868  const wchar_t* face_name,
869  ON_Font::Weight font_weight,
870  ON_Font::Style font_style,
871  ON_Font::Stretch font_stretch,
872  bool bUnderlined,
873  bool bStrikethrough
874  );
875 
876  bool SetFontCharacteristics(
877  double point_size,
878  const wchar_t* face_name,
879  ON_Font::Weight font_weight,
880  ON_Font::Style font_style,
881  ON_Font::Stretch font_stretch,
882  bool bUnderlined,
883  bool bStrikethrough
884  );
885 
886  bool SetFontCharacteristics(
887  const wchar_t* face_name,
888  ON_Font::Weight font_weight,
889  ON_Font::Style font_style,
890  ON_Font::Stretch font_stretch,
891  bool bUnderlined,
892  bool bStrikethrough,
893  double linefeed_ratio,
894  unsigned int logfont_charset
895  );
896 
897  bool SetFontCharacteristics(
898  double point_size,
899  const wchar_t* face_name,
900  ON_Font::Weight font_weight,
901  ON_Font::Style font_style,
902  ON_Font::Stretch font_stretch,
903  bool bUnderlined,
904  bool bStrikethrough,
905  double linefeed_ratio,
906  unsigned int logfont_charset
907  );
908 
909 
910  /*
911  Description:
912  The font properties weight, style, stretch, underlined,
913  and strikethrough are encoded in the returned value.
914  Remarks:
915  This is a legacy value used in 3dm archive reading/writing
916  and some sorting operations.
917  */
918  unsigned int FontCharacteristicsAsUnsigned() const;
919 
920 private:
921  /*
922  Description:
923  All font characterisics defined by the input parameters are encoded
924  in the returned value.
925  Remarks:
926  Used in 3dm archive reading/writing.
927  */
928  static unsigned int Internal_FontCharacteristicsAsUnsigned(
929  ON_Font::Weight font_weight,
930  ON_Font::Style font_style,
931  ON_Font::Stretch font_stretch,
932  bool bUnderlined,
933  bool bStrikethrough
934  );
935 
936  /*
937  Description:
938  All font characterisics except facename (weight, style, stretch,
939  underlined, strikethrough, charset) are encoded in the returned
940  value.
941  Parameters:
942  font_characteristics_as_unsigned - [in]
943  Value returned from ON_Font.FontCharacteristicsAsUnsigned()
944  Returns:
945  True if the characterstics were set.
946  Remarks:
947  Used in 3dm archive reading/writing.
948  */
949  bool Internal_SetFontCharacteristicsFromUnsigned(
950  unsigned int font_characteristics_as_unsigned
951  );
952 
953 public:
954  /*
955  Description:
956  Returns a 32-bit crc of the font weight, style, stretch, underline, strikethrough,
957  and facename characteristics.
958 
959  Parameters:
960  bIgnoreFaceNameOrdinalCase - [in]
961  If true, ON_wString::MapStringOrdinal() is applied to the face name
962  and the returned CRC is ordinal case independent.
963  */
964  ON__UINT32 CRC32(
965  bool bIgnoreFaceNameOrdinalCase
966  ) const;
967 
968 #if defined(ON_OS_WINDOWS_GDI)
969 
970  /*
971  Description:
972  Get the scale factors for converting heights beween
973  Windows device coordinates and Windows logical coordinates.
974 
975  Parameters:
976  hdc - [in]
977  Windows device context.
978  The device context is used to get the conversion between device
979  and logical pixel heights. The Windows GDI functions
980  DPtoLP(hdc,...) and LPtoDP(hdc,...) are used.
981 
982  device_to_logical_scale - [out]
983  logical_height = device_to_logical_scale*device_height
984 
985  logical_to_device_scale - [out]
986  device_height = logical_to_device_scale*logical_height
987 
988  Returns:
989  True if successful.
990  False otherwise. In the returned scale factors are set to 1.0.
991  */
992  static bool GetWindowsDeviceToLogicalHeightScales(
993  HDC hdc,
994  double* device_to_logical_scale,
995  double* logical_to_device_scale
996  );
997 
998  /*
999  Description:
1000  Convert a character height in points to a Windows LOGFONT lfHeight value (negative number).
1001 
1002  The mapping mode determines the length unit system for the returned value.
1003 
1004 
1005  The Windows convention is to use negative lfHeight values to specify
1006  font character heights and postive height values to specify font cell heights.
1007 
1008  font cell height = font acsent + font descent.
1009 
1010  font character height = Cell height - internal leading.
1011 
1012  Parameters:
1013  map_mode - [in]
1014  If map_mode is 0, then ::GetMapMode(hdc) is called to get the mapping mode.
1015  Otherwised, map_mode must identify a Windows mapping mode
1016  (MM_TEXT, MM_LOMETRIC, MM_HIMETRIC, MM_LOENGLISH, MM_HIENGLISH, M_TWIPS).
1017  If map_mode = MM_TEXT (1), then hdc is used as described in the hdc parameter.
1018 
1019  hdc - [in]
1020  Windows device context.
1021  If map_mode is set and not MM_TEXT, then hdc is ignored.
1022  Otherwise the device context is used to get the mapping mode ( GetMapMode(hdc) ).
1023  If the mapping mode is MM_TEXT, then the additional device context values
1024  GetDeviceCaps(hdc, LOGPIXELSY) and conversion between device and logical pixel heights
1025  DPtoLP(hdc,...) and LPtoDP(hdc,...) are used.
1026 
1027  point_size - [in]
1028  Font character height in points (1 point = 1/72 inch = 25.4/72 millimeters).
1029  In terms of font metrics, character height = ascent + descent - internal leading.
1030 
1031  Returns:
1032  LOGFONT lfHeight value.
1033 
1034  This value is always negative.
1035 
1036  The absolute value of the returned value
1037  = character height
1038  = ascent + descent - internal leading
1039  For many common fonts, the "character height" is close to the distance
1040  from the bottom of a lower case g to the top of an upper case M.
1041  The internal leading is space reseved for diacritical marks like the
1042  ring above the A in the UNICODE "LATIN LETTER A WITH RING" U+00C5 glyph.
1043  Character height is also known as the "em height".
1044  Note that the "em height" is typically larger than the height of the
1045  letter M because "em height" inlcude descent.
1046  */
1047  static int WindowsLogfontCharacterHeightFromPointSize(
1048  int map_mode,
1049  HDC hdc,
1050  double point_size
1051  );
1052 
1053  /*
1054  Parameters:
1055  map_mode - [in]
1056  If map_mode is 0, then ::GetMapMode(hdc) is called to get the mapping mode.
1057  Otherwised, map_mode must identify a Windows mapping mode
1058  (MM_TEXT, MM_LOMETRIC, MM_HIMETRIC, MM_LOENGLISH, MM_HIENGLISH, M_TWIPS).
1059  If map_mode = MM_TEXT (1), then hdc is used as described in the hdc parameter.
1060 
1061  hdc - [in]
1062  Windows device context.
1063  If map_mode is set and not MM_TEXT, then hdc is ignored.
1064  Otherwise the device context is used to get the mapping mode ( GetMapMode(hdc) ).
1065  If the mapping mode is MM_TEXT, then the additional device context values
1066  GetDeviceCaps(hdc, LOGPIXELSY) and conversion between device and logical pixel heights
1067  DPtoLP(hdc,...) and LPtoDP(hdc,...) are used.
1068 
1069  logfont_character_height - [in]
1070  This value must be a Windows LOGFONT character height in units
1071  determine from map_mode and hdc. If you have a LOGFONT with postive
1072  lfHeight value, you must get the fonts TEXTMETRICS and subbr
1073 
1074  Returns:
1075  Character height in points (1 point = 1/72 inch).
1076 
1077  font character height = font ascent + font descent - font internal leading.
1078 
1079  Remarks:
1080  See ON_Font::PointSize() for information about point units,
1081  font character height, and font cell height.
1082  */
1083  static double PointSizeFromWindowsLogfontCharacterHeight(
1084  int map_mode,
1085  HDC hdc,
1086  int logfont_character_height
1087  );
1088 
1089  /*
1090  Description:
1091  Get a Windows LOGFONT character height
1092  = -(TEXTMETRIC.tmAscent + TEXTMETRIC.tmDescent - TEXTMETRIC.tmLeading )
1093  as a negative integer.
1094 
1095  Parameters:
1096  map_mode - [in]
1097  The best results are obtained when map_mode = MM_TEXT and the hdc is
1098  correctly set for the context where the font is being rendered. Otherwise
1099  the loss of precision when length units system conversion scale factors
1100  are applied and results are stored in int LOGFONT and TEXTMETRIC fields
1101  lead to discrepancies.
1102 
1103  If map_mode is 0, then ::GetMapMode(hdc) is called to get the mapping mode.
1104  Otherwised, map_mode must identify a Windows mapping mode
1105  (MM_TEXT, MM_LOMETRIC, MM_HIMETRIC, MM_LOENGLISH, MM_HIENGLISH, M_TWIPS).
1106  If map_mode = MM_TEXT (1), then hdc is used as described in the hdc parameter.
1107 
1108  hdc - [in]
1109  Windows device context.
1110  If map_mode is set and not MM_TEXT, then hdc is ignored.
1111  Otherwise the device context is used to get the mapping mode ( GetMapMode(hdc) ).
1112  If the mapping mode is MM_TEXT, then the additional device context values
1113  GetDeviceCaps(hdc, LOGPIXELSY) and conversion between device and logical pixel heights
1114  DPtoLP(hdc,...) and LPtoDP(hdc,...) are used.
1115 
1116  logfont - [in]
1117  If logfont.lfHeight <= 0, then logfont.lfHeight is returned.
1118  If logfont.lfHeight > 0, then logfont face name, map_mode and hdc are
1119  used to calculate the font's TEXTMETRICS tmInternalLeading value
1120  -((tm.tmAscent + tm.tmDescent) - tmInternalLeading) is returned.
1121 
1122  Returns:
1123  0: failure
1124  <0: Windows LOGFONT character height in units specified by map_mode and hdc.
1125  */
1126  static int WindowsLogfontCharacterHeight(
1127  int map_mode,
1128  HDC hdc,
1129  const LOGFONT& logfont
1130  );
1131 
1132  /*
1133  Description:
1134  Get a Windows LOGFONT cell height
1135  = (TEXTMETRIC.tmAscent + TEXTMETRIC.tmDescent)
1136  as a positive integer.
1137 
1138  Parameters:
1139  map_mode - [in]
1140  The best results are obtained when map_mode = MM_TEXT and the hdc is
1141  correctly set for the context where the font is being rendered. Otherwise
1142  the loss of precision when length units system conversion scale factors
1143  are applied and results are stored in int LOGFONT and TEXTMETRIC fields
1144  lead to discrepancies.
1145 
1146  If map_mode is 0, then ::GetMapMode(hdc) is called to get the mapping mode.
1147  Otherwised, map_mode must identify a Windows mapping mode
1148  (MM_TEXT, MM_LOMETRIC, MM_HIMETRIC, MM_LOENGLISH, MM_HIENGLISH, M_TWIPS).
1149  If map_mode = MM_TEXT (1), then hdc is used as described in the hdc parameter.
1150 
1151  hdc - [in]
1152  Windows device context.
1153  If map_mode is set and not MM_TEXT, then hdc is ignored.
1154  Otherwise the device context is used to get the mapping mode ( GetMapMode(hdc) ).
1155  If the mapping mode is MM_TEXT, then the additional device context values
1156  GetDeviceCaps(hdc, LOGPIXELSY) and conversion between device and logical pixel heights
1157  DPtoLP(hdc,...) and LPtoDP(hdc,...) are used.
1158 
1159  logfont - [in]
1160  If logfont.lfHeight >= 0, then logfont.lfHeight is returned.
1161  If logfont.lfHeight < 0, then logfont face name, map_mode and hdc are
1162  used to calculate the font's TEXTMETRIC and
1163  (tm.tmAscent + tm.tmDescent) is returned.
1164 
1165  Returns:
1166  0: failure
1167  >0: Windows LOGFONT cell height in units specified by map_mode and hdc.
1168  */
1169  static int WindowsLogfontCellHeight(
1170  int map_mode,
1171  HDC hdc,
1172  const LOGFONT& logfont
1173  );
1174 
1175 
1176  /*
1177  Description:
1178  Get a Windows text metrics.
1179 
1180  Parameters:
1181  map_mode - [in]
1182  The best results are obtained when map_mode = MM_TEXT and the hdc is
1183  correctly set for the context where the font is being rendered. Otherwise
1184  the loss of precision when length units system conversion scale factors
1185  are applied and results are stored in int LOGFONT and TEXTMETRIC fields
1186  lead to discrepancies.
1187 
1188  If map_mode is 0, then ::GetMapMode(hdc) is called to get the mapping mode.
1189  Otherwised, map_mode must identify a Windows mapping mode
1190  (MM_TEXT, MM_LOMETRIC, MM_HIMETRIC, MM_LOENGLISH, MM_HIENGLISH, M_TWIPS).
1191  If map_mode = MM_TEXT (1), then hdc is used as described in the hdc parameter.
1192 
1193  hdc - [in]
1194  Windows device context.
1195  If map_mode is set and not MM_TEXT, then hdc is ignored.
1196  Otherwise the device context is used to get the mapping mode ( GetMapMode(hdc) ).
1197  If the mapping mode is MM_TEXT, then the additional device context values
1198  GetDeviceCaps(hdc, LOGPIXELSY) and conversion between device and logical pixel heights
1199  DPtoLP(hdc,...) and LPtoDP(hdc,...) are used.
1200 
1201  logfont - [in]
1202  If logfont.lfHeight >= 0, then logfont.lfHeight is returned.
1203  If logfont.lfHeight < 0, then logfont face name, map_mode and hdc are
1204  used to calculate the font's TEXTMETRIC and
1205  (tm.tmAscent + tm.tmDescent) is returned.
1206 
1207  textmetric - [out]
1208 
1209  Returns:
1210  0: failure
1211  >0: Windows LOGFONT cell height in units specified by map_mode and hdc.
1212  */
1213  static bool GetWindowsTextMetrics(
1214  int map_mode,
1215  HDC hdc,
1216  const LOGFONT& logfont,
1217  TEXTMETRIC& textmetric
1218  );
1219 
1220 private:
1221  static HDC Internal_CreateWindowsLogfontDeviceContext();
1222  static void Internal_DeleteWindowsLogfontDeviceContext(
1223  HDC hdc
1224  );
1225 
1226 public:
1227  /*
1228  Description:
1229  Set ON_Font properties from a subset of the LOGFONT properties.
1230  Parameters:
1231  map_mode - [in]
1232  If map_mode is 0, then ::GetMapMode(hdc) is called to get the mapping mode.
1233  Otherwised, map_mode must identify a Windows mapping mode
1234  (MM_TEXT, MM_LOMETRIC, MM_HIMETRIC, MM_LOENGLISH, MM_HIENGLISH, M_TWIPS).
1235  If map_mode = MM_TEXT (1), then hdc is used as described in the hdc parameter.
1236  hdc - [in]
1237  Windows device context.
1238  If map_mode is set and not MM_TEXT, then hdc is ignored.
1239  Otherwise the device context is used to get the mapping mode ( GetMapMode(hdc) ).
1240  If the mapping mode is MM_TEXT, then the additional device context values
1241  GetDeviceCaps(hdc, LOGPIXELSY) and conversion between device and logical pixel heights
1242  DPtoLP(hdc,...) and LPtoDP(hdc,...) are used.
1243  logfont - [in]
1244  These logfont properties are used to set the ON_Font.
1245  lfHeight (when dc is not zero),
1246  lfWeight
1247  lfItalic
1248  lfUnderline
1249  lfStrikeOut
1250  lfCharSet
1251  lfFaceName[LF_FACESIZE];
1252  All other LOGFONT properties are ignored.
1253  See Also:
1254  ON_Font::SetFromWindowsLogFontPartialComplete
1255  */
1256  bool SetFromWindowsLogFont(
1257  int map_mode,
1258  HDC hdc,
1259  const LOGFONT& logfont
1260  );
1261 
1262  /*
1263  Parameters:
1264  map_mode - [in]
1265  If map_mode is 0, then ::GetMapMode(hdc) is called to get the mapping mode.
1266  Otherwised, map_mode must identify a Windows mapping mode
1267  (MM_TEXT, MM_LOMETRIC, MM_HIMETRIC, MM_LOENGLISH, MM_HIENGLISH, M_TWIPS).
1268  If map_mode = MM_TEXT (1), then hdc is used as described in the hdc parameter.
1269  hdc - [in]
1270  Windows device context.
1271  If map_mode is set and not MM_TEXT, then hdc is ignored.
1272  Otherwise the device context is used to get the mapping mode ( GetMapMode(hdc) ).
1273  If the mapping mode is MM_TEXT, then the additional device context values
1274  GetDeviceCaps(hdc, LOGPIXELSY) and conversion between device and logical pixel heights
1275  DPtoLP(hdc,...) and LPtoDP(hdc,...) are used.
1276  Returns:
1277  A Windows LOGFONT with propeties copied from this ON_Font.
1278  If WindowsLogFontIsComplete() is true, then all LOGFONT properties
1279  are copied from the ON_Font.
1280  If WindowsLogFontIsComplete() is false, then the LOGFONT lfHeight,
1281  lfWidth, lfEscapement, lfOrientation, lfClipPrecision, lfQuality,
1282  lfPitchAndFamily, and lfOutPrecision properties are set to ON_Font
1283  default values.
1284  */
1285  const LOGFONT WindowsLogFont(
1286  int map_mode,
1287  HDC hdc
1288  ) const;
1289 
1290  const MAT2 WindowsFontMat2() const;
1291 
1292 #endif
1293 
1294 #if defined (ON_RUNTIME_APPLE_OBJECTIVE_C_AVAILABLE)
1295  bool SetFromAppleFont (NSFont* apple_font);
1296  NSFont* AppleFont() const;
1297 #endif
1298 
1299  bool SetFromAppleFontName(
1300  const wchar_t* apple_font_name
1301  );
1302 
1303  const ON_wString& AppleFontName() const;
1304 
1305  const wchar_t* AppleFontNameAsPointer() const;
1306 
1307  bool SetFromFontDescription(
1308  const wchar_t* font_description
1309  );
1310 
1311  bool SetFromFontDescription(
1312  const wchar_t* font_description,
1313  const wchar_t* apple_font_name
1314  );
1315 
1316  /*
1317  Description:
1318  Tests an object to see if its data members are correctly
1319  initialized.
1320  Parameters:
1321  text_log - [in] if the object is not valid and text_log
1322  is not nullptr, then a brief englis description of the
1323  reason the object is not valid is appened to the log.
1324  The information appended to text_log is suitable for
1325  low-level debugging purposes by programmers and is
1326  not intended to be useful as a high level user
1327  interface tool.
1328  Returns:
1329  @untitled table
1330  true object is valid
1331  false object is invalid, uninitialized, etc.
1332  */
1333  bool IsValid( ON_TextLog* text_log = nullptr ) const;
1334 
1335  void Dump( ON_TextLog& ) const; // for debugging
1336 
1337 
1338  void DumpFreeType(
1339  ON_TextLog& text_log
1340  ) const;
1341 
1342  static void DumpFreeTypeFace(
1343  ON__UINT_PTR free_type_face_ptr,
1344  ON_TextLog& text_log
1345  );
1346 
1347 #if defined(ON_OS_WINDOWS_GDI)
1348  static void DumpLogfont(
1349  const LOGFONT* logfont,
1350  ON_TextLog& text_log
1351  );
1352 #endif
1353 
1354  // serialize definition to binary archive
1355  bool Write( ON_BinaryArchive& ) const;
1356 
1357  // restore definition from binary archive
1358  bool Read( ON_BinaryArchive& );
1359 
1360  // V6 separated the V5 ON_Font into ON_TextStyle and ON_Font.
1361  bool WriteV5(
1362  int V5_font_index,
1363  ON_UUID V5_font_id,
1365  ) const;
1366 
1367  // V6 separated the V5 ON_Font into ON_TextStyle and ON_Font.
1368  bool ReadV5(
1369  ON_BinaryArchive&,
1370  int* V5_font_index,
1371  ON_UUID* V5_font_id
1372  );
1373 
1374  /*
1375  Returns:
1376  0: This is not a managed font.
1377  1: This is the managed font ON_Font::Default.
1378  >= 2: This is a managed font other than ON_Font::Default.
1379  Remark:
1380  For managed fonts other than ON_Font::Default, the value of RuntimeSerialNumber()
1381  typically varies between instances of the same application.
1382  Different platforms and application versions may use different font faces for ON_Font::Default.
1383  If an ON_Font is a managed font, then RuntimeSerialNumber() and ManagedFontSerialNumber()
1384  are identical. If an ON_Font is not a managed font, then RuntimeSerialNumber() is zero.
1385  */
1386  unsigned int RuntimeSerialNumber() const;
1387 
1388  /*
1389  Description:
1390  Two ON_Font classes reference the same platform font and create identical glyphs
1391  if and only if the have the same ManagedFontSerialNumber().
1392  Returns:
1393  0: This font is unset.
1394  >= 1: Serial number of the managed font with the same characteristics.
1395  Remark:
1396  For managed fonts other than ON_Font::Default, the value of ManagedFontSerialNumber()
1397  typically varies between instances of the same application.
1398  Different platforms and application versions may use different font faces
1399  for ON_Font::Default.
1400  If an ON_Font is a managed font, then RuntimeSerialNumber() and ManagedFontSerialNumber()
1401  are identical. If an ON_Font is not a managed font, then RuntimeSerialNumber() is zero.
1402  */
1403  unsigned int ManagedFontSerialNumber() const;
1405  //////////////////////////////////////////////////////////////////////
1406  //
1407  // Interface
1408 
1409  enum WindowsConstants : unsigned char
1410  {
1411  // Values used to set Windows LOGFONT fields.
1412 #if defined(ON_OS_WINDOWS_GDI)
1413  logfont_ansi_charset = ANSI_CHARSET,
1414  logfont_default_charset = DEFAULT_CHARSET, // LOGFONT.lfCharSet
1415  logfont_symbol_charset = SYMBOL_CHARSET, // LOGFONT.lfCharSet
1416  logfont_out_precis = OUT_TT_ONLY_PRECIS, // LOGFONT.lfOutPrecision
1417 
1418  // 2017-07-27, Brian Gillespie
1419  // Changed ON_Font::WindowsConstants::logfont_quality from ANTIALIASED_QUALITY to DEFAULT_QUALITY.
1420  // This makes it so that ON_Font conversion to LOGFONT results in a good-looking font when rendered by MFC.
1421  // With lfQuality set to ANTIALIASED_QUALITY, the font looks crummy - probably because all the rest of the fonts
1422  // are being rendered today with CLEARTYPE_QUALITY. Letting Windows decide what to do is probably better.
1423  logfont_quality = DEFAULT_QUALITY, // LOGFONT.lfQuality
1424 
1425  logfont_pitch_and_family = (DEFAULT_PITCH | FF_DONTCARE), // LOGFONT.lfPitchAndFamily
1426 #else
1427  // The values below are identical to the ones above and
1428  // are used to insure code compiles for Apple and other
1429  // platforms.
1430  logfont_ansi_charset = 0,
1431  logfont_default_charset = 1,
1432  logfont_symbol_charset = 2,
1433  logfont_out_precis = 7,
1434  logfont_quality = 4,
1435  logfont_pitch_and_family = 0
1436 #endif
1437  };
1438 
1439  /*
1440  Parameters:
1441  face_name - [in]
1442  Returns:
1443  If the code is running on Windows:
1444  The appropriate value of LOGFONT.lfCharSet for the input facename.
1445  If the code is not running on Windows:
1446  ON_Font::WindowsConstants::logfont_default_charset.
1447  */
1448  static unsigned char WindowsLogfontCharSetFromFaceName(
1449  const wchar_t* face_name
1450  );
1452  // miscellaneous constants use to initialize Windows LOGFONT fields
1453  enum Constants: int
1454  {
1455  // 1995 - 2015:
1456  // Windows fonts have variations in glyph size, design and kerning
1457  // for different point sizes. Text in Rhino is generally
1458  // placed around geometry and the relative spatial
1459  // relationships between the text and the geometry must
1460  // remain constant on all devices and at all "zoom" levels.
1461  // We have to choose a point size and then apply appropriate
1462  // scaling during display, printing, and in other rendering
1463  // calculations. After many experiments and 20 years of commercial use,
1464  // (1995-2015) we have found 256 works best.
1465  // This value is used on all platforms because the calculations
1466  // it is used in occur on all platforms. These calculations must return
1467  // consistent results so models exchanged between platforms maintain
1468  // spatial relationships between text and geometry.
1469  //
1470  // 2017:
1471  // (switching to freetype)
1472  // The value ON_Font::Constants::AnnotationFontCellHeight is used to define
1473  // "opennurbs normalized font coordinates". The scale
1474  // ((double)ON_Font::Constants::AnnotationFontCellHeight)/(font definition grid height)
1475  // is used to convert bounding information and outlines from a native
1476  // font definition to opennurbs normalized font coordinates.
1477  // Many TrueType fonts have font definition grid height = 2048.
1478  // Many PostScript fonts have font definition grid height = 1000.
1479  AnnotationFontCellHeight = 256, // LOGFONT.lfHeight value
1480 
1481  // ON_Font::Constants::metric_char is the unicode code point value
1482  // for the glpyh used to calculate critical glyph metrics.
1483  // It must be an 'I' or 'H', but we have not tested 'H'.
1484  // There are problems with any other upper case latin letter in common fonts.
1485  // In particular, the standard 'M' does not work.
1486  // We have used 'I' for 22 years (1995 - 2017).
1487  // This value is used on all platforms because the calculations
1488  // it is used in occur on all platforms. These calculations must return
1489  // consistent results so models exchanged between platforms maintain
1490  // spatial relationships between text and geometry.
1491  MetricsGlyphCodePoint = 'I'
1492  };
1493 
1494  /*
1495  Description:
1496  Get a text description of the font.
1497  Parameters:
1498  font_description - [out]
1499  Returns:
1500  A pointer to the font description string stored in the font_description parameter.
1501  */
1502  const ON_wString& FontDescription() const;
1503 
1504  /*
1505  Description:
1506  Get a text description of the font.
1507  Parameters:
1508  font_description - [out]
1509  Returns:
1510  A pointer to the font description string stored in the font_description parameter.
1511  */
1512  const wchar_t* FontDescriptionAsPointer() const;
1513 
1514  ON_DEPRECATED_MSG("Use ON_FontMetrics::DefaultLineFeedRatio")
1515  double LinefeedRatio() const;
1516 
1517  /*
1518  Returns:
1519  Normalized font metrics.
1520 
1521  Remarks:
1522  Font metric "normalized" units are comparable between different fonts.
1523  Normalized font metrics exist so that code that positions glyphs from
1524  multiple fonts does not have to take the unit system and resolution used
1525  in the design of each font.
1526  In opennurbs, much of this code that positions glyphs is located in ON_Annotation,
1527  ON_TextContent, and ON_TextRun member functions and is used when rendering
1528  annotation objects.
1529 
1530  Fonts can be designed and defined at different resolutions and
1531  relative scaling is necessary when text contains glyphs from
1532  fonts desinged at different grid resolutions. For example,
1533  TrueType font grid with and height is often 1024x1024 or
1534  2048x2014, OpenType grids are often 1000x1000, and PostScript
1535  grids are often 1000x1000. Opennurbs "font units" are the units
1536  the font was designed in.
1537 
1538  Long ago, opennurbs and Rhino used only Windows TrueType fonts
1539  and ran only in Microsoft Windows. During this era,
1540  the "normalized units" were for a Windows LOGFONT created
1541  with lfHeight = ON_Font::Constants::AnnotationFontCellHeight.
1542 
1543  Currently opennurbs and Rhino work on Microsoft Windows and Apple
1544  platforms and use FreeType to access font information. When a font
1545  is not "tricky", the "font design" units are the the units FreeType
1546  uses when a font is loaded with FT_LOAD_NO_SCALE.
1547 
1548  When working with fonts and glyhphs in opennurbs and Rhino,
1549  SDK users almost always want to use normalized font and glyph metrics.
1550  */
1551  const ON_FontMetrics& FontMetrics() const;
1552 
1553  /*
1554  Description:
1555  This function is for expert users doing something complicated.
1556  Returns:
1557  Font metrics read directly from the font definition with no or minimal
1558  scaling.
1559  Remarks:
1560  See ON_Font.FontMetrics() documentation for important information
1561  about the differnce bewteen normalized and font unit metrics.
1562  */
1563  const ON_FontMetrics& FontUnitFontMetrics() const;
1564 
1565  /*
1566  Returns:
1567  scale to apply when converting from a FT_LOAD_NO_SCALE FreeType
1568  glyph metric or outline to normalized opennurbs font coordinates.
1569  */
1570  double FontUnitToNormalizedScale() const;
1571 
1572  /*
1573  Returns:
1574  scale to apply when converting from a FT_LOAD_NO_SCALE FreeType
1575  glyph metric or outline to normalized opennurbs font coordinates.
1576  */
1577  double NormalizedToFontUnitScale() const;
1578 
1579  /*
1580  Returns:
1581  Font character height in points (1 point = 1/72 inch).
1582 
1583  See the remarks for a defintion of "character height".
1584 
1585  Remarks:
1586  A "point" is a length unit system.
1587  1 point = 1/72 inch = 25.4/72 millimeters.
1588 
1589  Typically, fonts are designed for maximum clarity when the rendered
1590  character height is close to PointSize().
1591 
1592  font cell height = font ascent + font descent.
1593 
1594  font character height = font cell height - font internal leading.
1595 
1596  For fonts designed for languages that use latin letters, it is common for
1597  the character height to be equal to or a little larger than the distance
1598  from the bottom of a lower case g to the top of an upper case M.
1599  The character height is also called the "em hieght".
1600 
1601  Font internal leading is the space above typical capital latin letters
1602  that is reseved for diacritical marks like the ring above the A in
1603  the UNICODE "LATIN LETTER A WITH RING" U+00C5 glyph (Angstrom symbol).
1604  */
1605  double PointSize() const;
1606 
1607  /*
1608  Parameters:
1609  point_size - [in]
1610  font character height in point units.
1611 
1612  Remarks:
1613  See the remarks section ON_Font::PointSize() for more information
1614  about point units and character height.
1615  */
1616  bool SetPointSize(
1617  double point_size
1618  );
1619 
1620  bool SetFontFaceName(
1621  const wchar_t* face_name
1622  );
1623  const wchar_t* FontFaceName() const;
1624 
1625  ON_Font::Weight FontWeight() const;
1626 
1627  int WindowsLogfontWeight() const;
1628  int AppleWeightOfFont() const;
1629  double AppleFontWeightTrait() const;
1630 
1631  bool SetFontWeight(
1632  ON_Font::Weight font_weight
1633  );
1634 
1635  bool SetWindowsLogfontWeight(
1636  int windows_logfont_weight
1637  );
1638 
1639  bool SetAppleWeightOfFont(
1640  int apple_weight_of_font
1641  );
1642 
1643  bool SetAppleFontWeightTrait(
1644  double apple_font_weight_trait
1645  );
1646 
1647 private:
1648  bool Internal_SetFontWeightTrio(
1649  ON_Font::Weight font_weight,
1650  int windows_logfont_weight,
1651  double apple_font_weight_trait,
1652  bool bUpdateFontDescription
1653  );
1654 
1655 public:
1656  /*
1657  Description:
1658  User interfaces that want to behave as if there are 3 font weights,
1659  light < normal < < bold, can use the functions
1660  ON_Font.IsLight(),
1661  ON_Font.IsNormalWeight(),
1662  ON_Font.IsBold(),
1663  to query font weight ranges.
1664  Returns:
1665  True if FontWeight() is lighter than ON_Font::Weight::Normal
1666  */
1667  bool IsLight() const;
1668 
1669  /*
1670  Description:
1671  User interfaces that want to behave as if there are 3 font weights,
1672  light < normal < < bold, can use the functions
1673  ON_Font.IsLight(),
1674  ON_Font.IsNormalWeight(),
1675  ON_Font.IsBold(),
1676  to query font weight ranges.
1677  Returns:
1678  True if FontWeight() is ON_Font::Normal or ON_Font::Weight::Medium
1679  */
1680  bool IsNormalWeight() const;
1681 
1682  /*
1683  Description:
1684  User interfaces that want to behave as if there are 3 font weights,
1685  light < normal < < bold, can use the functions
1686  ON_Font.IsLight(),
1687  ON_Font.IsNormalWeight(),
1688  ON_Font.IsBold(),
1689  to query font weight ranges.
1690  Returns:
1691  True if heavier than ON_Font::Weight::Medium.
1692  */
1693  bool IsBold() const;
1694 
1695  ON_Font::Style FontStyle() const;
1696 
1697  bool SetFontStyle(
1698  ON_Font::Style font_style
1699  );
1700 
1701  /*
1702  Returns:
1703  true if FontStyle() is ON_Font::Style::Italic.
1704  false if FontStyle() is ON_Font::Style::Upright or .ON_Font::Style::Oblique.
1705  */
1706  bool IsItalic() const;
1707 
1708  /*
1709  Returns:
1710  true if FontStyle() is ON_Font::Style::Upright.
1711  false if FontStyle() is ON_Font::Style::Italic or .ON_Font::Style::Oblique.
1712  */
1713  bool IsUpright() const;
1714 
1715  /*
1716  Returns:
1717  true if FontStyle() is ON_Font::Style::Oblique.
1718  false if FontStyle() is ON_Font::Style::Upright or .ON_Font::Style::Italic.
1719  */
1720  bool IsOblique();
1721 
1722 
1723  ON_Font::Stretch FontStretch() const;
1724 
1725  bool SetFontStretch(
1726  ON_Font::Stretch font_stretch
1727  );
1728 
1729  bool IsUnderlined() const;
1730  bool SetUnderlined(
1731  bool bUnderlined
1732  );
1733 
1734  bool IsStrikethrough() const;
1735  bool SetStrikethrough(
1736  bool bStrikethrough
1737  );
1738 
1739  unsigned char LogfontCharSet() const;
1740 
1741  bool SetLogfontCharSet(
1742  unsigned char logfont_charset
1743  );
1744 
1745  ON_DEPRECATED_MSG("Use FontMetrics().AscentOfI()")
1746  int HeightOfI() const;
1747 
1748  ON_DEPRECATED_MSG("Use FontMetrics().LineSpace()")
1749  int HeightOfLinefeed() const;
1750 
1751  ON_DEPRECATED_MSG("Use FontMetrics().GlyphScale()")
1752  double HeightScale(double text_height) const;
1753 
1754  ON_DEPRECATED_MSG("Use FontMetrics().StrikeoutThickness()")
1755  int GetStrikeoutSize() const;
1756 
1757  ON_DEPRECATED_MSG("Use FontMetrics().StrikeoutPosition()")
1758  int GetStrikeoutPosition() const;
1759 
1760  ON_DEPRECATED_MSG("Use FontMetrics().UnderscoreThickness()")
1761  int GetUnderscoreSize() const;
1762 
1763 
1764  ON_DEPRECATED_MSG("Use FontMetrics().UnderscorePosition()")
1765  int GetUnderscorePosition() const;
1766 
1767  /*
1768  Returns:
1769  A SHA-1 hash of all font characteristics, including platform specific settings.
1770  Two fonts have identical font characteristics, if and only if they have identical
1771  FontCharacteristicsHash() values.
1772 
1773  Example:
1774  ON_Font f1 = ...
1775  ON_Font f2 = ...
1776  if ( f1.FontCharacteristicsHash() == f2.FontCharacteristicsHash() )
1777  {
1778  // f1 and f2 have identical font characteristics
1779  }
1780  else
1781  {
1782  // f1 and f2 have different font characteristics
1783  }
1784  */
1785  const class ON_SHA1_Hash& FontCharacteristicsHash() const;
1786 
1787 private:
1788 
1789 public:
1790 
1791  /*
1792  Description:
1793  Compares the font weight, style, stretch, underline, strikethrough, linefeed_ratio
1794  and facename characteristics.
1795  Returns:
1796  -1: a characteristics < b characteristics
1797  0: a characteristics = b characteristics
1798  +1: a characteristics > b characteristics
1799  Remarks:
1800  This is a legacy function and to preserve past behavior, some platform specific
1801  characteristics are not checked.
1802  Use FontCharacteristicsHash() when every characteristic needs to be compared.
1803  */
1804  static int CompareFontCharacteristics(
1805  const ON_Font& a,
1806  const ON_Font& b
1807  );
1808 
1809  /*
1810  Description:
1811  Compares the font weight, style, stretch, underline, strikethrough, linefeed_ratio
1812  and facename characteristics.
1813  Returns:
1814  0 == ON_Font::CompareFontCharacteristics(a,b).
1815  Remarks:
1816  This is a legacy function and to preserve past behavior, some platform specific
1817  characteristics are not checked.
1818  Use FontCharacteristicsHash() when every characteristic needs to be compared.
1819  */
1820  static bool EqualFontCharacteristics(
1821  const ON_Font& a,
1822  const ON_Font& b
1823  );
1824 
1825 private:
1826  friend class ON_ManagedFonts;
1827 
1828  //////////////////////////////////////////////////////////////////////////////////
1829  //
1830  // The "font glpyh definition" parameters completely determine the appearance
1831  // of font glyphs.
1832  //
1833  // If all "font glpyh definition" parameters have identical values,
1834  // text rendered using those fonts will look identical.
1835  //
1836  // If two fonts have a "font glpyh definition" parameter with different values,
1837  // text rendered using those fonts will not look identical.
1838  //
1839  // BEGIN "font glpyh definition" parameters:
1840  //
1841 
1842  // The font ON_Font::Default has m_runtime_serial_number = 1.
1843  // Managed fonts have m_runtime_serial_number >= 1.
1844  // Unmanaged fonts have m_runtime_serial_number = 0;
1845  static unsigned int __runtime_serial_number_generator;
1846  const unsigned int m_runtime_serial_number = 0;
1847 
1848  int m_windows_logfont_weight = 400; // 100 <= m_windows_logfont_weight <= 1000
1849  double m_point_size = 0.0;
1850  double m_apple_font_weight_trait = 0.0; // = Apple NSFontWeightTrait value -1.0 <= m_apple_font_weight < 1.0, 0.0 = "normal"
1851  ON_Font::Weight m_font_weight = ON_Font::Weight::Normal;
1852 
1853  ON_Font::Style m_font_style = ON_Font::Style::Upright; // m_font_style corresponds to Windows LOGFONT.lfItalic field
1854  ON_Font::Stretch m_font_stretch = ON_Font::Stretch::Medium;
1855  bool m_font_bUnderlined = false; // Same as Windows LOGFONT.lfUnderlined
1856  bool m_font_bStrikethrough = false; // Same as Windows LOGFONT.lfStrikeOut
1857  unsigned char m_logfont_charset = ON_Font::WindowsConstants::logfont_default_charset;
1858 
1859 private:
1860  unsigned char m_reserved_char1 = 0;
1861 
1862 private:
1863  // If m_bCompleteLOGFONT is true, then the m_LOGFONT_* values are set.
1864  // If m_bCompleteLOGFONT is false, then the m_LOGFONT_* values are undefined and must be ignored.
1865  /*
1866  unsigned char m_bCompleteLOGFONT = 0;
1867  unsigned char m_LOGFONT_lfClipPrecision = 0;
1868  unsigned char m_LOGFONT_lfQuality = 0;
1869  unsigned char m_LOGFONT_lfPitchAndFamily = 0;
1870  unsigned char m_LOGFONT_lfOutPrecision = 0;
1871  int m_LOGFONT_lfHeight = 0;
1872  int m_LOGFONT_lfWidth = 0;
1873  int m_LOGFONT_lfEscapement = 0;
1874  int m_LOGFONT_lfOrientation = 0;
1875  */
1876 
1877 private:
1878  enum : int
1879  {
1880  face_name_capacity = 32
1881  };
1882  // https://en.wikipedia.org/wiki/List_of_typefaces_included_with_Microsoft_Windows
1883  wchar_t m_face_name[ON_Font::face_name_capacity+2]; // same as Windows LOGFONT.lfFaceName
1884 
1885  // If m_linefeed_ratio needs to become a variable or variables are required for tracking or stretch,
1886  // these fields will be used.
1887  double m_reserved_double_0 = 0.0;
1888  double m_reserved_double_1 = 0.0;
1889  //
1890  // END "font glpyh definition" parameters:
1891  //
1892  //////////////////////////////////////////////////////////////////////////////////
1893 
1894 private:
1895  // https://support.apple.com/en-us/HT201375
1896  // https://en.wikipedia.org/wiki/List_of_typefaces_included_with_OS_X
1897  ON_wString m_apple_font_name;
1898 
1899 private:
1900  ON_wString m_font_description;
1901 
1902 private:
1903  // A sha1 hash of all font characteristics.
1904  // This value is set using lazy evaluation.
1905  // A zero digest indicates it is not set.
1906  mutable ON_SHA1_Hash m_font_characteristics_hash;
1907 
1908 private:
1909  bool ModificationPermitted(
1910  const char* function_name,
1911  const char* file_name,
1912  int line_number
1913  ) const;
1914 
1915 private:
1916  void Internal_SetFontDescription();
1917 
1918 
1919 private:
1920  //////////////////////////////////////////////////////////////////////////////////
1921  //
1922  // BEGIN global font glyph cache interface
1923  //
1924  // There is a single font glyph cache for each managed font.
1925  // Fonts that are not managed use a glyph cache from a managed font.
1926  // This make functions like ON_Font.FindGlyph() efficient and reliable.
1927  //
1928  void DestroyFontGlyphCache();
1929  class ON_FontGlyphCache* FontGlyphCache(
1930  bool bCreateIfMissing
1931  ) const;
1932 #pragma ON_PRAGMA_WARNING_PUSH
1933 #pragma ON_PRAGMA_WARNING_DISABLE_MSC( 4251 )
1934  // C4251: '...std::shared_ptr<class ON_FontGlyphCache>...'
1935  // needs to have dll-interface to be used by clients of class 'ON_Font'
1936  // m_font_glyph_cache is private and all code that manages m_font_glyph_cache is explicitly implemented in the DLL.
1937 private:
1938  mutable std::shared_ptr<class ON_FontGlyphCache> m_font_glyph_cache;
1939 #pragma ON_PRAGMA_WARNING_POP
1940  //
1941  // END global font cache interface
1942  //
1943  //////////////////////////////////////////////////////////////////////////////////
1944 
1945 private:
1946  // Only managed fonts have a non-null m_free_type_face face.
1947  mutable class ON_FreeTypeFace* m_free_type_face = nullptr;
1948 
1949 private:
1950  ON__UINT_PTR m_reserved_ptr = 0;
1951 
1952 public:
1953  // Returns free type glyph index (or nonzero equivalent) if glyph is defined fo the glyph.CodePoint() in glyph.Font()
1954  // and glyph_box is set.
1955  typedef ON__UINT_PTR (*ON_GetGlyphMetricsFuncType)(
1956  const class ON_Font* font,
1957  ON__UINT32 unicode_code_point,
1958  class ON_TextBox& font_unit_glyph_box
1959  );
1960 
1961  typedef void (*ON_GetFontMetricsFuncType)(
1962  const ON_Font* font,
1963  ON_FontMetrics& font_unit_font_metrics
1964  );
1965 
1966  static void SetCustomMeasurementFunctions(
1967  ON_GetGlyphMetricsFuncType measureGlyphFunc,
1968  ON_GetFontMetricsFuncType metricsFunction
1969  );
1970 
1971 private:
1972  static ON_GetGlyphMetricsFuncType Internal_CustomGetGlyphMetricsFunc;
1973  static ON_GetFontMetricsFuncType Internal_CustomGetFontMetricsFunc;
1974 
1975 public:
1976  static void GetRunBounds(
1977  const ON_Font& font,
1978  const wchar_t* text,
1979  double fontSizePixels,
1980  ON::TextHorizontalAlignment horizontalAlignment,
1981  ON::TextVerticalAlignment verticalAlignment,
1982  ON_2dPoint& boundsMin,
1983  ON_2dPoint& boundsMax,
1984  int& lineCount
1985  );
1986 };
1987 
1988 class ON_CLASS ON_TextBox
1989 {
1990 public:
1991  ON_TextBox() = default;
1992  ~ON_TextBox() = default;
1993  ON_TextBox(const ON_TextBox&) = default;
1994  ON_TextBox& operator=(const ON_TextBox&) = default;
1995 
1996  ON_TextBox(
1997  ON_2dPoint bbmin,
1998  ON_2dPoint bbmax
1999  );
2000 
2001  /*
2002  Returns:
2003  true if bounding box is set.
2004  */
2005  bool IsSet() const;
2006 
2007  static const ON_TextBox Scale(
2008  const ON_TextBox& text_box,
2009  double scale
2010  );
2011 
2012  /*
2013  Returns:
2014  A text box with m_bbmin, m_bbmax, m_max_basepoint are translated by delta.
2015  m_advance is not changed.
2016  */
2017  static const ON_TextBox Translate(
2018  const ON_TextBox& text_box,
2019  const ON_2dVector& delta
2020  );
2021 
2022  static const ON_TextBox Translate(
2023  const ON_TextBox& text_box,
2024  const ON_2dex& delta
2025  );
2026 
2027  /*
2028  Parameters:
2029  lhs - [in]
2030  lhs.m_advance is ignored
2031  rhs - [in]
2032  rhs.m_advance is ignored
2033  Returns:
2034  Returned m_bbmin, m_bbmax, m_max_basepoint are the union of the lhs and rhs bounding box.
2035  Returned m_advance = (0,0)
2036  */
2037  static const ON_TextBox Union(
2038  const ON_TextBox& lhs,
2039  const ON_TextBox& rhs
2040  );
2041 
2042 public:
2043  static const ON_TextBox Unset;
2044 
2045 public:
2046  // Default units are with respect to a LOGFONT height = ON_Font::Constants::AnnotationFontCellHeight.
2047  // and (0,0) is the font glyph base point.
2048  //
2049  // Application of a Scale or Translate will change distance units and base point.
2050  //
2051 
2052  // Tight bounding box of the rendered glyphs.
2053  ON_2dex m_bbmin = ON_2dex::Unset;
2054  ON_2dex m_bbmax = ON_2dex::Unset;
2055 
2056  // m_max_basepoint.i = maximum horizontal delta in any line. Increases to the right, decreases to the left.
2057  // m_max_basepoint.i = vertical delta to basline of bottom line. Increases upward, decreases downward.
2058  ON_2dex m_max_basepoint = ON_2dex::Zero;
2059 
2060  // m_advance is a vector that specifies where the basepoint should be moved
2061  // to after the text is rendered. m_advance.i and m_advance.j are is always >= 0.
2062  // When glyphs are rendered right to left (Arabic and Hebrew being examples)
2063  // or bottom to top, the rendering code must apply the correct sign. One reason
2064  // is that Arabic and Hebrew text can be mixed with latin and Cyrillic text
2065  // and text rendering is much more complicated than a signed advance can handle.
2066  // Another is that the sign of y associated with "up" is sometimes positive and sometimes negative.
2067  // ON_TextBox::Translate does not modify the vector m_advance.
2068  // ON_TextBox::Union ignored input advance values and returns a box with advance = (0,0).
2069  // 0 <= m_advance.i will be <= m_max_basepoint.i.
2070  ON_2dex m_advance = ON_2dex::Zero;
2071 };
2074 {
2075 public:
2076  ON_FontGlyphOutlinePoint() = default;
2077  ~ON_FontGlyphOutlinePoint() = default;
2079  ON_FontGlyphOutlinePoint& operator= (const ON_FontGlyphOutlinePoint&) = default;
2080 public:
2081  enum class ContourPointType : ON__UINT8
2082  {
2083  Unset = 0,
2084  MoveTo = 1,
2085  LineTo = 2,
2086 
2087  // quadratic bezier (degree=2, order=3) control point.
2088  QuadraticBezierPoint = 3,
2089 
2090  // cubic bezier (degree=3, order=4) control point.
2091  CubicBezierPoint = 4,
2092 
2093  // a line segment added to close an open contour.
2094  // This is common. It does not indicate the glyph is a single stroke glyph.
2095  LineToCloseContour = 5
2096  };
2097 
2098  static ON_FontGlyphOutlinePoint::ContourPointType ContourPointTypeFromUnsigned(unsigned contour_point_type_as_unsigned);
2099 
2100  static const ON_FontGlyphOutlinePoint Unset;
2101 
2102 public:
2103  ON_FontGlyphOutlinePoint::ContourPointType m_point_type = ContourPointType::Unset;
2104  ON__UINT8 m_bToPoint = 0; // 1 if the point is a move to, line to, or the start or end of a bezier segment.
2105  // 0 otherwise
2106  ON__UINT16 m_contour_index = 0; // 0 = unset. The first contour has m_contour_index = 1.
2107  ON_2iPoint m_point = ON_2iPoint::Unset;
2108 };
2109 
2110 
2111 /*
2112  The best way to get a useful ON_FontGlyph is to call
2113  ON_Font.CodePointGlyph(unicode_code_point)
2114 */
2115 class ON_CLASS ON_FontGlyph
2116 {
2117 public:
2118  /*
2119  The best way to get a useful ON_FontGlyph is to call
2120  ON_Font.CodePointGlyph(unicode_code_point)
2121  */
2122  ON_FontGlyph() = default;
2123  ~ON_FontGlyph() = default;
2124  ON_FontGlyph(const ON_FontGlyph& src);
2125  ON_FontGlyph& operator=(const ON_FontGlyph& src);
2126 
2127 
2128  /*
2129  If the font and code point are valid, constructs an unmanaged
2130  glyph with the specified font and code point.
2131  The glyph box is not set.
2132  */
2133  ON_FontGlyph(
2134  const ON_Font* font,
2135  ON__UINT32 code_point
2136  );
2137 
2138 public:
2139  static const ON_FontGlyph Unset;
2140 
2141  const ON_Font* Font() const;
2142 
2143  const ON__UINT32 CodePoint() const;
2144 
2145  bool IsEndOfLineCodePoint() const;
2146 
2147  static bool IsEndOfLineCodePoint(
2148  ON__UINT32 unicode_code_point
2149  );
2150 
2151  static bool IsCarriageReturnAndLineFeed(
2152  ON__UINT32 unicode_code_point,
2153  ON__UINT32 next_unicode_code_point
2154  );
2155 
2156  /*
2157  Returns:
2158  Glyph box in opennurbs normalized font coordinates.
2159  */
2160  const ON_TextBox& GlyphBox() const;
2161 
2162  /*
2163  Returns:
2164  Font unit glyph box.
2165  Remarks:
2166  Must be used with ON_Font::FontUnitFontMetrics() and a single font to obtain useful results.
2167  You are probably better of using normalized font coordinates in a ON_FontGlyph.GlyphBox().
2168  */
2169  const ON_TextBox& FontUnitGlyphBox() const;
2170 
2171  static int CompareCodePointAndFont(
2172  ON_FontGlyph& lhs,
2173  ON_FontGlyph& rhs
2174  );
2175 
2176  /*
2177  Parameters:
2178  text - [in]
2179  Null terminated wchar_t string.
2180  font - [in]
2181  The font used to render the glyphs.
2182  unicode_CRLF_code_point - [in]
2183  If unicode_CRLF_code_point is a valid unicode code point,
2184  then consecutive carriage return line feed pairs are converted
2185  to a single glyph with code point = unicode_CRLF_code_point.
2186 
2187  ON_UnicodeCodePoint::ON_LineSeparator is a good choice when you want to
2188  condense carriage return line feed pairs to a single unambiguous code point.
2189 
2190  ON_UnicodeCodePoint::ON_InvalidCodePoint is a good choice when you want to
2191  preserve carriage return line feed pairs as two separate glyphs.
2192 
2193  glyph_list - [out]
2194  Note that glyph_list.Count() is often different than the
2195  length of the text string or the number of unicode codepoints
2196  in the decoded text.
2197  Adjacent carriage return and line feed codepoints are
2198  converted to single a hard end of line.
2199  All trailing end of line code points are removed from text.
2200  Invalid unicode encoding sequences are replaced with
2201  ON_UnicodeCodePoint::ReplacementCharacter glyphs.
2202 
2203  text_box - [out]
2204  tight bounding boxt of text extents.
2205  text_box.m_advance.i = maximum of all line horizontal advance values..
2206  text_box.m_advance.j = vertical advance to baseline of last line
2207  If if the font height
2208  is ON_Font::Constants::AnnotationFontCellHeight. If you will render the font
2209  at a different height from ON_Font::Constants::AnnotationFontCellHeight, then
2210  use ON_TextBox::Scale as follows:
2211  ON_TextBox scaled_box
2212  = ON_TextBox::Scale(
2213  text_box,
2214  (font render height)/((double)ON_Font::Constants::AnnotationFontCellHeight)
2215  );
2216  Return:
2217  number of lines of text or 0 if input is not valid or text is empty.
2218  */
2219  static int GetGlyphList
2220  (
2221  const wchar_t* text,
2222  const ON_Font* font,
2223  ON__UINT32 unicode_CRLF_code_point,
2225  ON_TextBox& text_box
2226  );
2227 
2228  static int GetGlyphList
2229  (
2230  size_t code_point_count,
2231  ON__UINT32* code_points,
2232  const ON_Font* font,
2233  ON__UINT32 unicode_CRLF_code_point,
2235  ON_TextBox& text_box
2236  );
2237 
2238  /*
2239  Parameters:
2240  font - [in]
2241  The font used to render the glyphs.
2242  text_box - [out]
2243  tight bounding boxt of text extents.
2244  text_box.m_advance.i = maximum of all line horizontal advance values..
2245  text_box.m_advance.j = vertical advance to baseline of last line
2246  If if the font height
2247  is ON_Font::Constants::AnnotationFontCellHeight. If you will render the font
2248  at a different height from ON_Font::Constants::AnnotationFontCellHeight, then
2249  use ON_TextBox::Scale as follows:
2250  ON_TextBox scaled_box
2251  = ON_TextBox::Scale(
2252  text_box,
2253  (font render height)/((double)ON_Font::Constants::AnnotationFontCellHeight)
2254  );
2255  Return:
2256  number of lines of text or 0 if input is not valid or text is empty.
2257  */
2258  static int GetGlyphListBoundingBox
2259  (
2260  const wchar_t* text,
2261  const ON_Font* font,
2262  ON_TextBox& text_box
2263  );
2264 
2265  static int GetGlyphListBoundingBox
2266  (
2267  size_t code_point_count,
2268  ON__UINT32* code_points,
2269  const ON_Font* font,
2270  ON_TextBox& text_box
2271  );
2272 
2273  /*
2274  Description:
2275  Sets the font and code point and unsets every other property including the
2276  glyph box and substitute information.
2277  Parameters:
2278  font - [in]
2279  code_point - [in]
2280  */
2281  bool SetCodePoint(
2282  const ON_Font* font,
2283  ON__UINT32 code_point
2284  );
2285 
2286  /*
2287  Returns:
2288  True if the unicode code point and font are set
2289  */
2290  bool CodePointIsSet() const;
2291 
2292  /*
2293  Returns:
2294  true if this is a managed instance.
2295  Managed instances persist for the lifetime of the application
2296  and the pointer can be safely saved and referenced at any time.
2297  */
2298  bool IsManaged() const;
2299 
2300  /*
2301  Returns:
2302  If this->CodePointIsSet() is true, then a persistent pointer
2303  to a managed glyph with the same code point and font is returned.
2304  Otherwise nullptr is returned.
2305  */
2306  const ON_FontGlyph* ManagedGlyph() const;
2307 
2308  /*
2309  Parameters:
2310  bUseReplacementCharacter - [in]
2311  When this->CodePointIsSet() is true,
2312  and bUseReplacementCharacter is true,
2313  and no reasonable glyph definition exists,
2314  and no substitued is available,
2315  then the replacement character glyph for UNICODE code point
2316  ON_UnicodeCodePoint::ON_ReplacementCharacter (U+FFFD) will be returned.
2317 
2318  Returns:
2319  A managed glyph that can be used to render "this".
2320  If this->CodePointIsSet() is false, nullptr is returned.
2321  If this->CodePointIsSet() is true, the returned glyph may
2322  have a different font and code point when the current
2323  computer requires font or glyph substitution to draw
2324  the glyph. When the current platform cannot render this,
2325  nullptr or the replacement glyph is returned depending on
2326  the value of bUseReplacementCharacter.
2327 
2328  See Also:
2329  ON_FontGlyph.SubstituteGlyph().
2330  */
2331  const ON_FontGlyph* RenderGlyph(
2332  bool bUseReplacementCharacter
2333  ) const;
2334 
2335  /*
2336  Returns:
2337  If this is a managed glyph or a copy of a managed glyph,
2338  and a substitute font or code point is used to render the glyph,
2339  then the substitue is returned.
2340  In all other cases, nullptr is returned.
2341  See Also:
2342  ON_FontGlyph.RenderGlyph().
2343  */
2344  const ON_FontGlyph* SubstituteGlyph() const;
2345 
2346  /*
2347  Parameters:
2348  bIncludeCharMaps - [in]
2349  If true, then char information is printed.
2350  */
2351  void Dump(
2352  bool bIncludeCharMaps,
2353  ON_TextLog& text_log
2354  ) const;
2355 
2356  /*
2357  Description:
2358  This is a debugging tool to test the code that starts with a font and
2359  Unicode code point and and finds a glyph in the font definition for
2360  that code point.
2361  Parameters:
2362  text_log - [in]
2363  If text_log is not nullptr, then diagnostic messages are sent to this log.
2364  Returns:
2365  True:
2366  No errors were found. Every available charmap either returned the same glyph id
2367  that FontGlyphId() function returns or had no glyph id for this code point.
2368  False:
2369  Inconsistent results were returned from different charmaps.
2370  Remarks:
2371  If a font or charmap is known to contain a bug and that bug is
2372  handled by opennurbs, then true is returned and a message is printed
2373  to the log.
2374  */
2375  bool TestFaceCharMaps(
2376  ON_TextLog* text_log
2377  ) const;
2378 
2379 public:
2380 
2381  const ON__UINT_PTR FreeTypeFace() const;
2382 
2383  /*
2384  Returns:
2385  Font glyph id.
2386  Remarks:
2387  The glyph id depends on the font and is assigned by the font designer.
2388  In particular the font glyph id for the same Unicode code point
2389  often varies from font to font. In a font, it is often the case that
2390  multiple Unicode code points map to the same glyph. For example,
2391  space an non-breaking space typically map to the same font glyph id.
2392  */
2393  const ON__UINT_PTR FontGlyphId() const;
2394 
2395  /*
2396  Description:
2397  Get glyph contours as NURBS curves.
2398  Parameters:
2399  bSingleStrokeFont - [in]
2400  If true, open contours will not be closed by adding a line segment.
2401  text_height - [in]
2402  If > 0, ouptut curves, bounding box, and advance vector are scaled
2403  so that a capital latin letter I would have a height of text_height.
2404  Otherwise, no scaling is applied to the output curves, bounding box,
2405  and advance vector.
2406  Pass 0.0 or in this->Font()->HeightOfI() to get the contours to be in opennurbs
2407  normalized font coordinates.
2408  Pass ON_UNSET_VALUE to get the contours to be in native font definition units.
2409  All other values < 0 are treated as 0.0.
2410  glyph_contours - [out]
2411  glyph_bbox - [out]
2412  glyph bounding box.
2413  glyph_advance - [out]
2414  glyph_advance->x = horizontal advance to apply when rendering glyphs horizontally.
2415  A positive horizontal advance indicates advance to the right.
2416  glyph_advance->y = vertical advance to apply when rendering glyphs vertically.
2417  A positive vertical advance indicates advance downwards.
2418  */
2419  bool GetGlyphContours(
2420  bool bSingleStrokeFont,
2421  double text_height,
2422  ON_ClassArray< ON_SimpleArray< ON_Curve* > >& glyph_contours,
2423  ON_BoundingBox* glyph_bbox,
2424  ON_3dVector* glyph_advance
2425  ) const;
2426 
2427  static bool GetStringContours(
2428  const wchar_t* text_string,
2429  const ON_Font* font,
2430  bool bSingleStrokeFont,
2431  double text_height,
2432  double small_caps_scale,
2434  );
2435 
2436 
2437 private:
2438  friend class ON_GlyphMap;
2439  friend class ON_Font;
2440 
2441  // NOTE WELL:
2442  // The offset of m_codepoint in ON_FontGlyph must be >= 8 bytes.
2443  // so the ON_FixeSizePool that manages memory for the glyph cache
2444  // can efficiently iteratate all active managed glyphs.
2445  //
2446  ON_TextBox m_font_unit_glyph_bbox; // values in the native font definition units (freetype FT_LOAD_NO_SCALE units)
2447  ON_TextBox m_normalized_glyph_bbox; // bounding box in opennurbs normalized font coordinates
2448 
2449  // This box is for the platform native glyph. It can be different than m_glyph_box.
2450  // Example:
2451  // Start with a Windows LOGFONT with face = Arial, height = ON_Font::Constants::AnnotationFontCellHeight (256)
2452  // Native Windows height of Arial I = 165, height of LF = ...
2453  // FreeType made from the same LOGFONT on the same has height of Arial I = 184, height of LF = ...
2454 
2455  // When font does not contain a glyph to render a specified unicode codepoint,
2456  // then one or more glyphs from one or more subsitution fonts are used to
2457  // render the codepoint. In this case, m_substitutes points to a linked
2458  // list of substitute used to render the glyph.
2459  //
2460  ON__UINT32 m_code_point = ON_UnicodeCodePoint::ON_InvalidCodePoint;
2461 
2462  ON__UINT8 m_is_managed = 0; // 1 = managed glyph
2463  ON__UINT8 m_reserved1 = 0;
2464  ON__UINT16 m_reserved2 = 0;
2465  ON__UINT_PTR m_font_glyph_id = 0;
2466  const class ON_Font* m_managed_font = nullptr;
2467  const class ON_FontGlyph* m_substitute = nullptr;
2468 
2469 
2470 private:
2471  void Internal_SetFontGlyphId(ON__UINT_PTR font_glyph_id);
2472  void Internal_CopyFrom(const ON_FontGlyph& src);
2473  static ON_FontGlyph* Internal_AllocateManagedGlyph(const ON_FontGlyph& src);
2474  bool Internal_GetPlatformSubstitute(
2475  ON_FontGlyph& substitue
2476  ) const;
2477 };
2478 
2479 
2480 #if defined(ON_RUNTIME_WIN)
2481 
2482 /*
2483 Remarks:
2484  Windows GDI functions used by ON_WindowsMeasureGlyph fail when the
2485  UTF-16 encoding of unicode_code_point requires a surrogate pair.
2486 */
2487 ON_DECL
2488 bool ON_WindowsGetGlyphMetrics(
2489  const ON_Font* font,
2490  ON__UINT32 unicode_code_point,
2491  class ON_TextBox& font_unit_glyph_box
2492 );
2493 
2494 
2495 
2496 #endif
2497 
2498 
2499 #if defined(ON_DLL_TEMPLATE)
2500 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_Font*>;
2501 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<const ON_Font*>;
2502 ON_DLL_TEMPLATE template class ON_CLASS ON_ClassArray<ON_Font>;
2503 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_FontGlyph*>;
2504 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<const ON_FontGlyph*>;
2505 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_FontGlyph>;
2506 #endif
2507 
2508 #endif
2509 
2510 
Constants
miscellaneous constants use to initialize Windows LOGFONT fields
Definition: opennurbs_font.h:1423
friend class ON_Font
Definition: opennurbs_font.h:2389
Definition: opennurbs_ipoint.h:24
ON_UUID is a 16 byte universally unique identifier.
Definition: opennurbs_uuid.h:32
Weight
Weight enum values Avoid casting these values to int. Use ON_Font::WindowsLogfontWeightFromWeight() o...
Definition: opennurbs_font.h:237
Definition: opennurbs_font.h:1958
WindowsConstants
Definition: opennurbs_font.h:1379
static const ON_2iPoint Unset
Definition: opennurbs_ipoint.h:46
Definition: opennurbs_array.h:36
Stretch
Horizontal expansion or contraction of font
Definition: opennurbs_font.h:422
static const ON__UINT32 HeightOfCapitalCodePoint
Definition: opennurbs_font.h:44
Definition: opennurbs_sha1.h:19
ON_FontGlyph & operator=(const ON_FontGlyph &src)
Definition: opennurbs_internal_glyph.h:30
Definition: opennurbs_string.h:2020
const ON__UINT_PTR FreeTypeFace() const
Definition: opennurbs_point.h:277
static const double DefaultLineFeedRatio
Definition: opennurbs_font.h:37
Definition: opennurbs_font.h:2081
Definition: opennurbs_font.h:18
Definition: opennurbs_bounding_box.h:25
Definition: opennurbs_font.h:2039
Definition: opennurbs_internal_glyph.h:84
An ON_Font is a face in a font family. It corresponds to a Windows LOGFONT, a .NET System...
Definition: opennurbs_font.h:225
void Dump(bool bIncludeCharMaps, ON_TextLog &text_log) const
static const ON_FontMetrics Unset
All properties are zero.
Definition: opennurbs_font.h:29
Definition: opennurbs_array.h:409
Definition: opennurbs_textlog.h:20
Definition: opennurbs_archive.h:1783
Style
Vertical angle of font Upright, Italic, or Oblique
Definition: opennurbs_font.h:467
Definition: opennurbs_point.h:839
Definition: opennurbs_point.h:1152
ContourPointType
Definition: opennurbs_font.h:2047