1 /*
2  * Copyright 2018 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkFontMetrics_DEFINED
9 #define SkFontMetrics_DEFINED
10 
11 #include "include/core/SkScalar.h"
12 
13 /** \class SkFontMetrics
14     The metrics of an SkFont.
15     The metric values are consistent with the Skia y-down coordinate system.
16  */
17 struct SK_API SkFontMetrics {
18 
19     /** \enum FontMetricsFlags
20      FontMetricsFlags indicate when certain metrics are valid;
21      the underline or strikeout metrics may be valid and zero.
22      Fonts with embedded bitmaps may not have valid underline or strikeout metrics.
23      */
24     enum FontMetricsFlags {
25         kUnderlineThicknessIsValid_Flag = 1 << 0, //!< set if fUnderlineThickness is valid
26         kUnderlinePositionIsValid_Flag  = 1 << 1, //!< set if fUnderlinePosition is valid
27         kStrikeoutThicknessIsValid_Flag = 1 << 2, //!< set if fStrikeoutThickness is valid
28         kStrikeoutPositionIsValid_Flag  = 1 << 3, //!< set if fStrikeoutPosition is valid
29     };
30 
31     uint32_t fFlags;              //!< FontMetricsFlags indicating which metrics are valid
32     SkScalar fTop;                //!< greatest extent above origin of any glyph bounding box, typically negative; deprecated with variable fonts
33     SkScalar fAscent;             //!< distance to reserve above baseline, typically negative
34     SkScalar fDescent;            //!< distance to reserve below baseline, typically positive
35     SkScalar fBottom;             //!< greatest extent below origin of any glyph bounding box, typically positive; deprecated with variable fonts
36     SkScalar fLeading;            //!< distance to add between lines, typically positive or zero
37     SkScalar fAvgCharWidth;       //!< average character width, zero if unknown
38     SkScalar fMaxCharWidth;       //!< maximum character width, zero if unknown
39     SkScalar fXMin;               //!< greatest extent to left of origin of any glyph bounding box, typically negative; deprecated with variable fonts
40     SkScalar fXMax;               //!< greatest extent to right of origin of any glyph bounding box, typically positive; deprecated with variable fonts
41     SkScalar fXHeight;            //!< height of lower-case 'x', zero if unknown, typically negative
42     SkScalar fCapHeight;          //!< height of an upper-case letter, zero if unknown, typically negative
43     SkScalar fUnderlineThickness; //!< underline thickness
44     SkScalar fUnderlinePosition;  //!< distance from baseline to top of stroke, typically positive
45     SkScalar fStrikeoutThickness; //!< strikeout thickness
46     SkScalar fStrikeoutPosition;  //!< distance from baseline to bottom of stroke, typically negative
47 
48     /** Returns true if SkFontMetrics has a valid underline thickness, and sets
49      thickness to that value. If the underline thickness is not valid,
50      return false, and ignore thickness.
51 
52      @param thickness  storage for underline width
53      @return           true if font specifies underline width
54      */
hasUnderlineThicknessSkFontMetrics55     bool hasUnderlineThickness(SkScalar* thickness) const {
56         if (SkToBool(fFlags & kUnderlineThicknessIsValid_Flag)) {
57             *thickness = fUnderlineThickness;
58             return true;
59         }
60         return false;
61     }
62 
63     /** Returns true if SkFontMetrics has a valid underline position, and sets
64      position to that value. If the underline position is not valid,
65      return false, and ignore position.
66 
67      @param position  storage for underline position
68      @return          true if font specifies underline position
69      */
hasUnderlinePositionSkFontMetrics70     bool hasUnderlinePosition(SkScalar* position) const {
71         if (SkToBool(fFlags & kUnderlinePositionIsValid_Flag)) {
72             *position = fUnderlinePosition;
73             return true;
74         }
75         return false;
76     }
77 
78     /** Returns true if SkFontMetrics has a valid strikeout thickness, and sets
79      thickness to that value. If the underline thickness is not valid,
80      return false, and ignore thickness.
81 
82      @param thickness  storage for strikeout width
83      @return           true if font specifies strikeout width
84      */
hasStrikeoutThicknessSkFontMetrics85     bool hasStrikeoutThickness(SkScalar* thickness) const {
86         if (SkToBool(fFlags & kStrikeoutThicknessIsValid_Flag)) {
87             *thickness = fStrikeoutThickness;
88             return true;
89         }
90         return false;
91     }
92 
93     /** Returns true if SkFontMetrics has a valid strikeout position, and sets
94      position to that value. If the underline position is not valid,
95      return false, and ignore position.
96 
97      @param position  storage for strikeout position
98      @return          true if font specifies strikeout position
99      */
hasStrikeoutPositionSkFontMetrics100     bool hasStrikeoutPosition(SkScalar* position) const {
101         if (SkToBool(fFlags & kStrikeoutPositionIsValid_Flag)) {
102             *position = fStrikeoutPosition;
103             return true;
104         }
105         return false;
106     }
107 
108 };
109 
110 #endif
111