| /* | |
| * Copyright 2018 Google LLC | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #ifndef SkFontPriv_DEFINED | |
| #define SkFontPriv_DEFINED | |
| #include "include/core/SkFont.h" | |
| #include "include/core/SkFontTypes.h" | |
| #include "include/core/SkMatrix.h" | |
| #include "include/core/SkTypeface.h" | |
| #include "include/private/SkTemplates.h" | |
| class SkReadBuffer; | |
| class SkWriteBuffer; | |
| class SkFontPriv { | |
| public: | |
| /* This is the size we use when we ask for a glyph's path. We then | |
| * post-transform it as we draw to match the request. | |
| * This is done to try to re-use cache entries for the path. | |
| * | |
| * This value is somewhat arbitrary. In theory, it could be 1, since | |
| * we store paths as floats. However, we get the path from the font | |
| * scaler, and it may represent its paths as fixed-point (or 26.6), | |
| * so we shouldn't ask for something too big (might overflow 16.16) | |
| * or too small (underflow 26.6). | |
| * | |
| * This value could track kMaxSizeForGlyphCache, assuming the above | |
| * constraints, but since we ask for unhinted paths, the two values | |
| * need not match per-se. | |
| */ | |
| inline static constexpr int kCanonicalTextSizeForPaths = 64; | |
| /** | |
| * Return a matrix that applies the paint's text values: size, scale, skew | |
| */ | |
| static SkMatrix MakeTextMatrix(SkScalar size, SkScalar scaleX, SkScalar skewX) { | |
| SkMatrix m = SkMatrix::Scale(size * scaleX, size); | |
| if (skewX) { | |
| m.postSkew(skewX, 0); | |
| } | |
| return m; | |
| } | |
| static SkMatrix MakeTextMatrix(const SkFont& font) { | |
| return MakeTextMatrix(font.getSize(), font.getScaleX(), font.getSkewX()); | |
| } | |
| static void ScaleFontMetrics(SkFontMetrics*, SkScalar); | |
| /** | |
| Returns the union of bounds of all glyphs. | |
| Returned dimensions are computed by font manager from font data, | |
| ignoring SkPaint::Hinting. Includes font metrics, but not fake bold or SkPathEffect. | |
| If text size is large, text scale is one, and text skew is zero, | |
| returns the bounds as: | |
| { SkFontMetrics::fXMin, SkFontMetrics::fTop, SkFontMetrics::fXMax, SkFontMetrics::fBottom }. | |
| @return union of bounds of all glyphs | |
| */ | |
| static SkRect GetFontBounds(const SkFont&); | |
| /** Return the approximate largest dimension of typical text when transformed by the matrix. | |
| * | |
| * @param matrix used to transform size | |
| * @param textLocation location of the text prior to matrix transformation. Used if the | |
| * matrix has perspective. | |
| * @return typical largest dimension | |
| */ | |
| static SkScalar ApproximateTransformedTextSize(const SkFont& font, const SkMatrix& matrix, | |
| const SkPoint& textLocation); | |
| static bool IsFinite(const SkFont& font) { | |
| return SkIsFinite(font.getSize(), font.getScaleX(), font.getSkewX()); | |
| } | |
| // Returns the number of elements (characters or glyphs) in the array. | |
| static size_t CountTextElements(const void* text, size_t byteLength, SkTextEncoding); | |
| static void GlyphsToUnichars(const SkFont&, const SkGlyphID glyphs[], int count, SkUnichar[]); | |
| static void Flatten(const SkFont&, SkWriteBuffer& buffer); | |
| static bool Unflatten(SkFont*, SkReadBuffer& buffer); | |
| static inline uint8_t Flags(const SkFont& font) { return font.fFlags; } | |
| }; | |
| class [[nodiscard]] SkAutoToGlyphs { | |
| public: | |
| SkAutoToGlyphs(const SkFont& font, const void* text, size_t length, SkTextEncoding encoding) { | |
| if (encoding == SkTextEncoding::kGlyphID || length == 0) { | |
| fGlyphs = {reinterpret_cast<const uint16_t*>(text), length >> 1}; | |
| } else { | |
| const size_t count = font.countText(text, length, encoding); | |
| fStorage.reset(count); | |
| SkSpan<SkGlyphID> glyphs = {fStorage.get(), count}; | |
| (void)font.textToGlyphs(text, length, encoding, glyphs); | |
| fGlyphs = glyphs; | |
| } | |
| } | |
| size_t size() const { return fGlyphs.size(); } | |
| const SkGlyphID* data() const { return fGlyphs.data(); } | |
| size_t count() const { return fGlyphs.size(); } | |
| SkSpan<const SkGlyphID> glyphs() const { return fGlyphs; } | |
| private: | |
| skia_private::AutoSTArray<32, SkGlyphID> fStorage; | |
| SkSpan<const SkGlyphID> fGlyphs; | |
| }; | |
| #endif |