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 */
17struct 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 kBoundsInvalid_Flag = 1 << 4, //!< set if fTop, fBottom, fXMin, fXMax invalid
30 };
31
32 uint32_t fFlags; //!< FontMetricsFlags indicating which metrics are valid
33 SkScalar fTop; //!< greatest extent above origin of any glyph bounding box, typically negative; deprecated with variable fonts
34 SkScalar fAscent; //!< distance to reserve above baseline, typically negative
35 SkScalar fDescent; //!< distance to reserve below baseline, typically positive
36 SkScalar fBottom; //!< greatest extent below origin of any glyph bounding box, typically positive; deprecated with variable fonts
37 SkScalar fLeading; //!< distance to add between lines, typically positive or zero
38 SkScalar fAvgCharWidth; //!< average character width, zero if unknown
39 SkScalar fMaxCharWidth; //!< maximum character width, zero if unknown
40 SkScalar fXMin; //!< greatest extent to left of origin of any glyph bounding box, typically negative; deprecated with variable fonts
41 SkScalar fXMax; //!< greatest extent to right of origin of any glyph bounding box, typically positive; deprecated with variable fonts
42 SkScalar fXHeight; //!< height of lower-case 'x', zero if unknown, typically negative
43 SkScalar fCapHeight; //!< height of an upper-case letter, zero if unknown, typically negative
44 SkScalar fUnderlineThickness; //!< underline thickness
45 SkScalar fUnderlinePosition; //!< distance from baseline to top of stroke, typically positive
46 SkScalar fStrikeoutThickness; //!< strikeout thickness
47 SkScalar fStrikeoutPosition; //!< distance from baseline to bottom of stroke, typically negative
48
49 /** Returns true if SkFontMetrics has a valid underline thickness, and sets
50 thickness to that value. If the underline thickness is not valid,
51 return false, and ignore thickness.
52
53 @param thickness storage for underline width
54 @return true if font specifies underline width
55 */
56 bool hasUnderlineThickness(SkScalar* thickness) const {
57 if (SkToBool(fFlags & kUnderlineThicknessIsValid_Flag)) {
58 *thickness = fUnderlineThickness;
59 return true;
60 }
61 return false;
62 }
63
64 /** Returns true if SkFontMetrics has a valid underline position, and sets
65 position to that value. If the underline position is not valid,
66 return false, and ignore position.
67
68 @param position storage for underline position
69 @return true if font specifies underline position
70 */
71 bool hasUnderlinePosition(SkScalar* position) const {
72 if (SkToBool(fFlags & kUnderlinePositionIsValid_Flag)) {
73 *position = fUnderlinePosition;
74 return true;
75 }
76 return false;
77 }
78
79 /** Returns true if SkFontMetrics has a valid strikeout thickness, and sets
80 thickness to that value. If the underline thickness is not valid,
81 return false, and ignore thickness.
82
83 @param thickness storage for strikeout width
84 @return true if font specifies strikeout width
85 */
86 bool hasStrikeoutThickness(SkScalar* thickness) const {
87 if (SkToBool(fFlags & kStrikeoutThicknessIsValid_Flag)) {
88 *thickness = fStrikeoutThickness;
89 return true;
90 }
91 return false;
92 }
93
94 /** Returns true if SkFontMetrics has a valid strikeout position, and sets
95 position to that value. If the underline position is not valid,
96 return false, and ignore position.
97
98 @param position storage for strikeout position
99 @return true if font specifies strikeout position
100 */
101 bool hasStrikeoutPosition(SkScalar* position) const {
102 if (SkToBool(fFlags & kStrikeoutPositionIsValid_Flag)) {
103 *position = fStrikeoutPosition;
104 return true;
105 }
106 return false;
107 }
108
109 /** Returns true if SkFontMetrics has a valid fTop, fBottom, fXMin, and fXMax.
110 If the bounds are not valid, return false.
111
112 @return true if font specifies maximum glyph bounds
113 */
114 bool hasBounds() const {
115 return !SkToBool(fFlags & kBoundsInvalid_Flag);
116 }
117};
118
119#endif
120