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 #include "include/private/base/SkTo.h" 13 14 /** \class SkFontMetrics 15 The metrics of an SkFont. 16 The metric values are consistent with the Skia y-down coordinate system. 17 */ 18 struct SK_API SkFontMetrics { 19 bool operator==(const SkFontMetrics& that) { 20 return 21 this->fFlags == that.fFlags && 22 this->fTop == that.fTop && 23 this->fAscent == that.fAscent && 24 this->fDescent == that.fDescent && 25 this->fBottom == that.fBottom && 26 this->fLeading == that.fLeading && 27 this->fAvgCharWidth == that.fAvgCharWidth && 28 this->fMaxCharWidth == that.fMaxCharWidth && 29 this->fXMin == that.fXMin && 30 this->fXMax == that.fXMax && 31 this->fXHeight == that.fXHeight && 32 this->fCapHeight == that.fCapHeight && 33 this->fUnderlineThickness == that.fUnderlineThickness && 34 this->fUnderlinePosition == that.fUnderlinePosition && 35 this->fStrikeoutThickness == that.fStrikeoutThickness && 36 this->fStrikeoutPosition == that.fStrikeoutPosition; 37 } 38 39 /** \enum FontMetricsFlags 40 FontMetricsFlags indicate when certain metrics are valid; 41 the underline or strikeout metrics may be valid and zero. 42 Fonts with embedded bitmaps may not have valid underline or strikeout metrics. 43 */ 44 enum FontMetricsFlags { 45 kUnderlineThicknessIsValid_Flag = 1 << 0, //!< set if fUnderlineThickness is valid 46 kUnderlinePositionIsValid_Flag = 1 << 1, //!< set if fUnderlinePosition is valid 47 kStrikeoutThicknessIsValid_Flag = 1 << 2, //!< set if fStrikeoutThickness is valid 48 kStrikeoutPositionIsValid_Flag = 1 << 3, //!< set if fStrikeoutPosition is valid 49 kBoundsInvalid_Flag = 1 << 4, //!< set if fTop, fBottom, fXMin, fXMax invalid 50 }; 51 52 uint32_t fFlags; //!< FontMetricsFlags indicating which metrics are valid 53 SkScalar fTop; //!< greatest extent above origin of any glyph bounding box, typically negative; deprecated with variable fonts 54 SkScalar fAscent; //!< distance to reserve above baseline, typically negative 55 SkScalar fDescent; //!< distance to reserve below baseline, typically positive 56 SkScalar fBottom; //!< greatest extent below origin of any glyph bounding box, typically positive; deprecated with variable fonts 57 SkScalar fLeading; //!< distance to add between lines, typically positive or zero 58 SkScalar fAvgCharWidth; //!< average character width, zero if unknown 59 SkScalar fMaxCharWidth; //!< maximum character width, zero if unknown 60 SkScalar fXMin; //!< greatest extent to left of origin of any glyph bounding box, typically negative; deprecated with variable fonts 61 SkScalar fXMax; //!< greatest extent to right of origin of any glyph bounding box, typically positive; deprecated with variable fonts 62 SkScalar fXHeight; //!< height of lower-case 'x', zero if unknown, typically negative 63 SkScalar fCapHeight; //!< height of an upper-case letter, zero if unknown, typically negative 64 SkScalar fUnderlineThickness; //!< underline thickness 65 SkScalar fUnderlinePosition; //!< distance from baseline to top of stroke, typically positive 66 SkScalar fStrikeoutThickness; //!< strikeout thickness 67 SkScalar fStrikeoutPosition; //!< distance from baseline to bottom of stroke, typically negative 68 69 /** Returns true if SkFontMetrics has a valid underline thickness, and sets 70 thickness to that value. If the underline thickness is not valid, 71 return false, and ignore thickness. 72 73 @param thickness storage for underline width 74 @return true if font specifies underline width 75 */ hasUnderlineThicknessSkFontMetrics76 bool hasUnderlineThickness(SkScalar* thickness) const { 77 if (SkToBool(fFlags & kUnderlineThicknessIsValid_Flag)) { 78 *thickness = fUnderlineThickness; 79 return true; 80 } 81 return false; 82 } 83 84 /** Returns true if SkFontMetrics has a valid underline position, and sets 85 position to that value. If the underline position is not valid, 86 return false, and ignore position. 87 88 @param position storage for underline position 89 @return true if font specifies underline position 90 */ hasUnderlinePositionSkFontMetrics91 bool hasUnderlinePosition(SkScalar* position) const { 92 if (SkToBool(fFlags & kUnderlinePositionIsValid_Flag)) { 93 *position = fUnderlinePosition; 94 return true; 95 } 96 return false; 97 } 98 99 /** Returns true if SkFontMetrics has a valid strikeout thickness, and sets 100 thickness to that value. If the underline thickness is not valid, 101 return false, and ignore thickness. 102 103 @param thickness storage for strikeout width 104 @return true if font specifies strikeout width 105 */ hasStrikeoutThicknessSkFontMetrics106 bool hasStrikeoutThickness(SkScalar* thickness) const { 107 if (SkToBool(fFlags & kStrikeoutThicknessIsValid_Flag)) { 108 *thickness = fStrikeoutThickness; 109 return true; 110 } 111 return false; 112 } 113 114 /** Returns true if SkFontMetrics has a valid strikeout position, and sets 115 position to that value. If the underline position is not valid, 116 return false, and ignore position. 117 118 @param position storage for strikeout position 119 @return true if font specifies strikeout position 120 */ hasStrikeoutPositionSkFontMetrics121 bool hasStrikeoutPosition(SkScalar* position) const { 122 if (SkToBool(fFlags & kStrikeoutPositionIsValid_Flag)) { 123 *position = fStrikeoutPosition; 124 return true; 125 } 126 return false; 127 } 128 129 /** Returns true if SkFontMetrics has a valid fTop, fBottom, fXMin, and fXMax. 130 If the bounds are not valid, return false. 131 132 @return true if font specifies maximum glyph bounds 133 */ hasBoundsSkFontMetrics134 bool hasBounds() const { 135 return !SkToBool(fFlags & kBoundsInvalid_Flag); 136 } 137 }; 138 139 #endif 140