fcfd0af9fd
OpenType and many other font formats have the concept of pre-computed metrics for the union of all glyph bounding boxes. This allows for fast though course quick rejecting of bounds, since the glyphs themselves may potentially be quite a bit larger than the EM. With the introduction of variable fonts OpenType does not vary these bounds, so the bounds are only valid for the default non-varied font. As a result the fTop, fBottom, fXMax, and fXMin reported in SkFontMetrics may be bogus. Since simply always setting them to empty zeros may be disruptive, provide a way forward for new users to check if the bounds are valid. This exposed an issue where SkTextBlobBuilder::TightRunBounds does not handle SkTextBlob::kRSXform_Positioning, so add a test for that. Change-Id: I872729e0f16e2a196229f9902addf4b07b461590 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/301455 Reviewed-by: Herb Derby <herb@google.com> Reviewed-by: Mike Klein <mtklein@google.com> Commit-Queue: Ben Wagner <bungeman@google.com>
120 lines
5.2 KiB
C
120 lines
5.2 KiB
C
/*
|
|
* Copyright 2018 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#ifndef SkFontMetrics_DEFINED
|
|
#define SkFontMetrics_DEFINED
|
|
|
|
#include "include/core/SkScalar.h"
|
|
|
|
/** \class SkFontMetrics
|
|
The metrics of an SkFont.
|
|
The metric values are consistent with the Skia y-down coordinate system.
|
|
*/
|
|
struct SK_API SkFontMetrics {
|
|
|
|
/** \enum FontMetricsFlags
|
|
FontMetricsFlags indicate when certain metrics are valid;
|
|
the underline or strikeout metrics may be valid and zero.
|
|
Fonts with embedded bitmaps may not have valid underline or strikeout metrics.
|
|
*/
|
|
enum FontMetricsFlags {
|
|
kUnderlineThicknessIsValid_Flag = 1 << 0, //!< set if fUnderlineThickness is valid
|
|
kUnderlinePositionIsValid_Flag = 1 << 1, //!< set if fUnderlinePosition is valid
|
|
kStrikeoutThicknessIsValid_Flag = 1 << 2, //!< set if fStrikeoutThickness is valid
|
|
kStrikeoutPositionIsValid_Flag = 1 << 3, //!< set if fStrikeoutPosition is valid
|
|
kBoundsInvalid_Flag = 1 << 4, //!< set if fTop, fBottom, fXMin, fXMax invalid
|
|
};
|
|
|
|
uint32_t fFlags; //!< FontMetricsFlags indicating which metrics are valid
|
|
SkScalar fTop; //!< greatest extent above origin of any glyph bounding box, typically negative; deprecated with variable fonts
|
|
SkScalar fAscent; //!< distance to reserve above baseline, typically negative
|
|
SkScalar fDescent; //!< distance to reserve below baseline, typically positive
|
|
SkScalar fBottom; //!< greatest extent below origin of any glyph bounding box, typically positive; deprecated with variable fonts
|
|
SkScalar fLeading; //!< distance to add between lines, typically positive or zero
|
|
SkScalar fAvgCharWidth; //!< average character width, zero if unknown
|
|
SkScalar fMaxCharWidth; //!< maximum character width, zero if unknown
|
|
SkScalar fXMin; //!< greatest extent to left of origin of any glyph bounding box, typically negative; deprecated with variable fonts
|
|
SkScalar fXMax; //!< greatest extent to right of origin of any glyph bounding box, typically positive; deprecated with variable fonts
|
|
SkScalar fXHeight; //!< height of lower-case 'x', zero if unknown, typically negative
|
|
SkScalar fCapHeight; //!< height of an upper-case letter, zero if unknown, typically negative
|
|
SkScalar fUnderlineThickness; //!< underline thickness
|
|
SkScalar fUnderlinePosition; //!< distance from baseline to top of stroke, typically positive
|
|
SkScalar fStrikeoutThickness; //!< strikeout thickness
|
|
SkScalar fStrikeoutPosition; //!< distance from baseline to bottom of stroke, typically negative
|
|
|
|
/** Returns true if SkFontMetrics has a valid underline thickness, and sets
|
|
thickness to that value. If the underline thickness is not valid,
|
|
return false, and ignore thickness.
|
|
|
|
@param thickness storage for underline width
|
|
@return true if font specifies underline width
|
|
*/
|
|
bool hasUnderlineThickness(SkScalar* thickness) const {
|
|
if (SkToBool(fFlags & kUnderlineThicknessIsValid_Flag)) {
|
|
*thickness = fUnderlineThickness;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/** Returns true if SkFontMetrics has a valid underline position, and sets
|
|
position to that value. If the underline position is not valid,
|
|
return false, and ignore position.
|
|
|
|
@param position storage for underline position
|
|
@return true if font specifies underline position
|
|
*/
|
|
bool hasUnderlinePosition(SkScalar* position) const {
|
|
if (SkToBool(fFlags & kUnderlinePositionIsValid_Flag)) {
|
|
*position = fUnderlinePosition;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/** Returns true if SkFontMetrics has a valid strikeout thickness, and sets
|
|
thickness to that value. If the underline thickness is not valid,
|
|
return false, and ignore thickness.
|
|
|
|
@param thickness storage for strikeout width
|
|
@return true if font specifies strikeout width
|
|
*/
|
|
bool hasStrikeoutThickness(SkScalar* thickness) const {
|
|
if (SkToBool(fFlags & kStrikeoutThicknessIsValid_Flag)) {
|
|
*thickness = fStrikeoutThickness;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/** Returns true if SkFontMetrics has a valid strikeout position, and sets
|
|
position to that value. If the underline position is not valid,
|
|
return false, and ignore position.
|
|
|
|
@param position storage for strikeout position
|
|
@return true if font specifies strikeout position
|
|
*/
|
|
bool hasStrikeoutPosition(SkScalar* position) const {
|
|
if (SkToBool(fFlags & kStrikeoutPositionIsValid_Flag)) {
|
|
*position = fStrikeoutPosition;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/** Returns true if SkFontMetrics has a valid fTop, fBottom, fXMin, and fXMax.
|
|
If the bounds are not valid, return false.
|
|
|
|
@return true if font specifies maximum glyph bounds
|
|
*/
|
|
bool hasBounds() const {
|
|
return !SkToBool(fFlags & kBoundsInvalid_Flag);
|
|
}
|
|
};
|
|
|
|
#endif
|