xref: /aosp_15_r20/external/skia/src/core/SkFontPriv.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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 SkFontPriv_DEFINED
9 #define SkFontPriv_DEFINED
10 
11 #include "include/core/SkFont.h"
12 #include "include/core/SkFontTypes.h"
13 #include "include/core/SkMatrix.h"
14 #include "include/core/SkTypeface.h"
15 #include "include/private/base/SkTemplates.h"
16 
17 class SkReadBuffer;
18 class SkWriteBuffer;
19 
20 class SkFontPriv {
21 public:
22     /*  This is the size we use when we ask for a glyph's path. We then
23      *  post-transform it as we draw to match the request.
24      *  This is done to try to re-use cache entries for the path.
25      *
26      *  This value is somewhat arbitrary. In theory, it could be 1, since
27      *  we store paths as floats. However, we get the path from the font
28      *  scaler, and it may represent its paths as fixed-point (or 26.6),
29      *  so we shouldn't ask for something too big (might overflow 16.16)
30      *  or too small (underflow 26.6).
31      *
32      *  This value could track kMaxSizeForGlyphCache, assuming the above
33      *  constraints, but since we ask for unhinted paths, the two values
34      *  need not match per-se.
35      */
36     inline static constexpr int kCanonicalTextSizeForPaths  = 64;
37 
38     /**
39      *  Return a matrix that applies the paint's text values: size, scale, skew
40      */
MakeTextMatrix(SkScalar size,SkScalar scaleX,SkScalar skewX)41     static SkMatrix MakeTextMatrix(SkScalar size, SkScalar scaleX, SkScalar skewX) {
42         SkMatrix m = SkMatrix::Scale(size * scaleX, size);
43         if (skewX) {
44             m.postSkew(skewX, 0);
45         }
46         return m;
47     }
48 
MakeTextMatrix(const SkFont & font)49     static SkMatrix MakeTextMatrix(const SkFont& font) {
50         return MakeTextMatrix(font.getSize(), font.getScaleX(), font.getSkewX());
51     }
52 
53     static void ScaleFontMetrics(SkFontMetrics*, SkScalar);
54 
55     /**
56         Returns the union of bounds of all glyphs.
57         Returned dimensions are computed by font manager from font data,
58         ignoring SkPaint::Hinting. Includes font metrics, but not fake bold or SkPathEffect.
59 
60         If text size is large, text scale is one, and text skew is zero,
61         returns the bounds as:
62         { SkFontMetrics::fXMin, SkFontMetrics::fTop, SkFontMetrics::fXMax, SkFontMetrics::fBottom }.
63 
64         @return  union of bounds of all glyphs
65      */
66     static SkRect GetFontBounds(const SkFont&);
67 
68     /** Return the approximate largest dimension of typical text when transformed by the matrix.
69      *
70      * @param matrix  used to transform size
71      * @param textLocation  location of the text prior to matrix transformation. Used if the
72      *                      matrix has perspective.
73      * @return  typical largest dimension
74      */
75     static SkScalar ApproximateTransformedTextSize(const SkFont& font, const SkMatrix& matrix,
76                                                    const SkPoint& textLocation);
77 
IsFinite(const SkFont & font)78     static bool IsFinite(const SkFont& font) {
79         return SkIsFinite(font.getSize(), font.getScaleX(), font.getSkewX());
80     }
81 
82     // Returns the number of elements (characters or glyphs) in the array.
83     static int CountTextElements(const void* text, size_t byteLength, SkTextEncoding);
84 
85     static void GlyphsToUnichars(const SkFont&, const uint16_t glyphs[], int count, SkUnichar[]);
86 
87     static void Flatten(const SkFont&, SkWriteBuffer& buffer);
88     static bool Unflatten(SkFont*, SkReadBuffer& buffer);
89 
Flags(const SkFont & font)90     static inline uint8_t Flags(const SkFont& font) { return font.fFlags; }
91 };
92 
93 class SkAutoToGlyphs {
94 public:
SkAutoToGlyphs(const SkFont & font,const void * text,size_t length,SkTextEncoding encoding)95     SkAutoToGlyphs(const SkFont& font, const void* text, size_t length, SkTextEncoding encoding) {
96         if (encoding == SkTextEncoding::kGlyphID || length == 0) {
97             fGlyphs = reinterpret_cast<const uint16_t*>(text);
98             fCount = SkToInt(length >> 1);
99         } else {
100             fCount = font.countText(text, length, encoding);
101             if (fCount < 0) {
102                 fCount = 0;
103             }
104             fStorage.reset(fCount);
105             font.textToGlyphs(text, length, encoding, fStorage.get(), fCount);
106             fGlyphs = fStorage.get();
107         }
108     }
109 
count()110     int count() const { return fCount; }
glyphs()111     const uint16_t* glyphs() const { return fGlyphs; }
112 
113 private:
114     skia_private::AutoSTArray<32, uint16_t> fStorage;
115     const uint16_t* fGlyphs;
116     int             fCount;
117 };
118 
119 #endif
120