Coverage Report

Created: 2024-05-20 07:14

/src/skia/include/core/SkFont.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2014 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 SkFont_DEFINED
9
#define SkFont_DEFINED
10
11
#include "include/core/SkRect.h"
12
#include "include/core/SkRefCnt.h"
13
#include "include/core/SkScalar.h"
14
#include "include/core/SkTypeface.h"
15
#include "include/core/SkTypes.h"
16
#include "include/private/base/SkTo.h"
17
#include "include/private/base/SkTypeTraits.h"
18
19
#include <cstddef>
20
#include <cstdint>
21
#include <type_traits>
22
#include <vector>
23
24
class SkMatrix;
25
class SkPaint;
26
class SkPath;
27
enum class SkFontHinting;
28
enum class SkTextEncoding;
29
struct SkFontMetrics;
30
struct SkPoint;
31
32
/** \class SkFont
33
    SkFont controls options applied when drawing and measuring text.
34
*/
35
class SK_API SkFont {
36
public:
37
    /** Whether edge pixels draw opaque or with partial transparency.
38
    */
39
    enum class Edging {
40
        kAlias,              //!< no transparent pixels on glyph edges
41
        kAntiAlias,          //!< may have transparent pixels on glyph edges
42
        kSubpixelAntiAlias,  //!< glyph positioned in pixel using transparency
43
    };
44
45
    /** Constructs SkFont with default values.
46
47
        @return  default initialized SkFont
48
    */
49
    SkFont();
50
51
    /** Constructs SkFont with default values with SkTypeface and size in points.
52
53
        @param typeface  font and style used to draw and measure text
54
        @param size      typographic height of text
55
        @return          initialized SkFont
56
    */
57
    SkFont(sk_sp<SkTypeface> typeface, SkScalar size);
58
59
    /** Constructs SkFont with default values with SkTypeface.
60
61
        @param typeface  font and style used to draw and measure text
62
        @return          initialized SkFont
63
    */
64
    explicit SkFont(sk_sp<SkTypeface> typeface);
65
66
67
    /** Constructs SkFont with default values with SkTypeface and size in points,
68
        horizontal scale, and horizontal skew. Horizontal scale emulates condensed
69
        and expanded fonts. Horizontal skew emulates oblique fonts.
70
71
        @param typeface  font and style used to draw and measure text
72
        @param size      typographic height of text
73
        @param scaleX    text horizontal scale
74
        @param skewX     additional shear on x-axis relative to y-axis
75
        @return          initialized SkFont
76
    */
77
    SkFont(sk_sp<SkTypeface> typeface, SkScalar size, SkScalar scaleX, SkScalar skewX);
78
79
80
    /** Compares SkFont and font, and returns true if they are equivalent.
81
        May return false if SkTypeface has identical contents but different pointers.
82
83
        @param font  font to compare
84
        @return      true if SkFont pair are equivalent
85
    */
86
    bool operator==(const SkFont& font) const;
87
88
    /** Compares SkFont and font, and returns true if they are not equivalent.
89
        May return true if SkTypeface has identical contents but different pointers.
90
91
        @param font  font to compare
92
        @return      true if SkFont pair are not equivalent
93
    */
94
17.7k
    bool operator!=(const SkFont& font) const { return !(*this == font); }
95
96
    /** If true, instructs the font manager to always hint glyphs.
97
        Returned value is only meaningful if platform uses FreeType as the font manager.
98
99
        @return  true if all glyphs are hinted
100
    */
101
131k
    bool isForceAutoHinting() const { return SkToBool(fFlags & kForceAutoHinting_PrivFlag); }
102
103
    /** Returns true if font engine may return glyphs from font bitmaps instead of from outlines.
104
105
        @return  true if glyphs may be font bitmaps
106
    */
107
131k
    bool isEmbeddedBitmaps() const { return SkToBool(fFlags & kEmbeddedBitmaps_PrivFlag); }
108
109
    /** Returns true if glyphs may be drawn at sub-pixel offsets.
110
111
        @return  true if glyphs may be drawn at sub-pixel offsets.
112
    */
113
131k
    bool isSubpixel() const { return SkToBool(fFlags & kSubpixel_PrivFlag); }
114
115
    /** Returns true if font and glyph metrics are requested to be linearly scalable.
116
117
        @return  true if font and glyph metrics are requested to be linearly scalable.
118
    */
119
131k
    bool isLinearMetrics() const { return SkToBool(fFlags & kLinearMetrics_PrivFlag); }
120
121
    /** Returns true if bold is approximated by increasing the stroke width when creating glyph
122
        bitmaps from outlines.
123
124
        @return  bold is approximated through stroke width
125
    */
126
131k
    bool isEmbolden() const { return SkToBool(fFlags & kEmbolden_PrivFlag); }
127
128
    /** Returns true if baselines will be snapped to pixel positions when the current transformation
129
        matrix is axis aligned.
130
131
        @return  baselines may be snapped to pixels
132
     */
133
131k
    bool isBaselineSnap() const { return SkToBool(fFlags & kBaselineSnap_PrivFlag); }
134
135
    /** Sets whether to always hint glyphs.
136
        If forceAutoHinting is set, instructs the font manager to always hint glyphs.
137
138
        Only affects platforms that use FreeType as the font manager.
139
140
        @param forceAutoHinting  setting to always hint glyphs
141
    */
142
    void setForceAutoHinting(bool forceAutoHinting);
143
144
    /** Requests, but does not require, to use bitmaps in fonts instead of outlines.
145
146
        @param embeddedBitmaps  setting to use bitmaps in fonts
147
    */
148
    void setEmbeddedBitmaps(bool embeddedBitmaps);
149
150
    /** Requests, but does not require, that glyphs respect sub-pixel positioning.
151
152
        @param subpixel  setting for sub-pixel positioning
153
    */
154
    void setSubpixel(bool subpixel);
155
156
    /** Requests, but does not require, linearly scalable font and glyph metrics.
157
158
        For outline fonts 'true' means font and glyph metrics should ignore hinting and rounding.
159
        Note that some bitmap formats may not be able to scale linearly and will ignore this flag.
160
161
        @param linearMetrics  setting for linearly scalable font and glyph metrics.
162
    */
163
    void setLinearMetrics(bool linearMetrics);
164
165
    /** Increases stroke width when creating glyph bitmaps to approximate a bold typeface.
166
167
        @param embolden  setting for bold approximation
168
    */
169
    void setEmbolden(bool embolden);
170
171
    /** Requests that baselines be snapped to pixels when the current transformation matrix is axis
172
        aligned.
173
174
        @param baselineSnap  setting for baseline snapping to pixels
175
    */
176
    void setBaselineSnap(bool baselineSnap);
177
178
    /** Whether edge pixels draw opaque or with partial transparency.
179
    */
180
186k
    Edging getEdging() const { return (Edging)fEdging; }
181
182
    /** Requests, but does not require, that edge pixels draw opaque or with
183
        partial transparency.
184
    */
185
    void setEdging(Edging edging);
186
187
    /** Sets level of glyph outline adjustment.
188
        Does not check for valid values of hintingLevel.
189
    */
190
    void setHinting(SkFontHinting hintingLevel);
191
192
    /** Returns level of glyph outline adjustment.
193
     */
194
131k
    SkFontHinting getHinting() const { return (SkFontHinting)fHinting; }
195
196
    /** Returns a font with the same attributes of this font, but with the specified size.
197
        Returns nullptr if size is less than zero, infinite, or NaN.
198
199
        @param size  typographic height of text
200
        @return      initialized SkFont
201
     */
202
    SkFont makeWithSize(SkScalar size) const;
203
204
    /** Does not alter SkTypeface SkRefCnt.
205
206
        @return  non-null SkTypeface
207
    */
208
324k
    SkTypeface* getTypeface() const {
209
324k
        SkASSERT(fTypeface);
210
324k
        return fTypeface.get();
211
324k
    }
212
213
    /** Returns text size in points.
214
215
        @return  typographic height of text
216
    */
217
410k
    SkScalar    getSize() const { return fSize; }
218
219
    /** Returns text scale on x-axis.
220
        Default value is 1.
221
222
        @return  text horizontal scale
223
    */
224
300k
    SkScalar    getScaleX() const { return fScaleX; }
225
226
    /** Returns text skew on x-axis.
227
        Default value is zero.
228
229
        @return  additional shear on x-axis relative to y-axis
230
    */
231
300k
    SkScalar    getSkewX() const { return fSkewX; }
232
233
    /** Increases SkTypeface SkRefCnt by one.
234
235
        @return  A non-null SkTypeface.
236
    */
237
128k
    sk_sp<SkTypeface> refTypeface() const {
238
128k
        SkASSERT(fTypeface);
239
128k
        return fTypeface;
240
128k
    }
241
242
    /** Sets SkTypeface to typeface, decreasing SkRefCnt of the previous SkTypeface.
243
        Pass nullptr to clear SkTypeface and use an empty typeface (which draws nothing).
244
        Increments tf SkRefCnt by one.
245
246
        @param tf  font and style used to draw text
247
    */
248
    void setTypeface(sk_sp<SkTypeface> tf);
249
250
    /** Sets text size in points.
251
        Has no effect if textSize is not greater than or equal to zero.
252
253
        @param textSize  typographic height of text
254
    */
255
    void setSize(SkScalar textSize);
256
257
    /** Sets text scale on x-axis.
258
        Default value is 1.
259
260
        @param scaleX  text horizontal scale
261
    */
262
    void setScaleX(SkScalar scaleX);
263
264
    /** Sets text skew on x-axis.
265
        Default value is zero.
266
267
        @param skewX  additional shear on x-axis relative to y-axis
268
    */
269
    void setSkewX(SkScalar skewX);
270
271
    /** Converts text into glyph indices.
272
        Returns the number of glyph indices represented by text.
273
        SkTextEncoding specifies how text represents characters or glyphs.
274
        glyphs may be nullptr, to compute the glyph count.
275
276
        Does not check text for valid character codes or valid glyph indices.
277
278
        If byteLength equals zero, returns zero.
279
        If byteLength includes a partial character, the partial character is ignored.
280
281
        If encoding is SkTextEncoding::kUTF8 and text contains an invalid UTF-8 sequence,
282
        zero is returned.
283
284
        When encoding is SkTextEncoding::kUTF8, SkTextEncoding::kUTF16, or
285
        SkTextEncoding::kUTF32; then each Unicode codepoint is mapped to a
286
        single glyph.  This function uses the default character-to-glyph
287
        mapping from the SkTypeface and maps characters not found in the
288
        SkTypeface to zero.
289
290
        If maxGlyphCount is not sufficient to store all the glyphs, no glyphs are copied.
291
        The total glyph count is returned for subsequent buffer reallocation.
292
293
        @param text          character storage encoded with SkTextEncoding
294
        @param byteLength    length of character storage in bytes
295
        @param glyphs        storage for glyph indices; may be nullptr
296
        @param maxGlyphCount storage capacity
297
        @return              number of glyphs represented by text of length byteLength
298
    */
299
    int textToGlyphs(const void* text, size_t byteLength, SkTextEncoding encoding,
300
                     SkGlyphID glyphs[], int maxGlyphCount) const;
301
302
    /** Returns glyph index for Unicode character.
303
304
        If the character is not supported by the SkTypeface, returns 0.
305
306
        @param uni  Unicode character
307
        @return     glyph index
308
    */
309
    SkGlyphID unicharToGlyph(SkUnichar uni) const;
310
311
    void unicharsToGlyphs(const SkUnichar uni[], int count, SkGlyphID glyphs[]) const;
312
313
    /** Returns number of glyphs represented by text.
314
315
        If encoding is SkTextEncoding::kUTF8, SkTextEncoding::kUTF16, or
316
        SkTextEncoding::kUTF32; then each Unicode codepoint is mapped to a
317
        single glyph.
318
319
        @param text          character storage encoded with SkTextEncoding
320
        @param byteLength    length of character storage in bytes
321
        @return              number of glyphs represented by text of length byteLength
322
    */
323
36.1k
    int countText(const void* text, size_t byteLength, SkTextEncoding encoding) const {
324
36.1k
        return this->textToGlyphs(text, byteLength, encoding, nullptr, 0);
325
36.1k
    }
326
327
    /** Returns the advance width of text.
328
        The advance is the normal distance to move before drawing additional text.
329
        Returns the bounding box of text if bounds is not nullptr.
330
331
        @param text        character storage encoded with SkTextEncoding
332
        @param byteLength  length of character storage in bytes
333
        @param bounds      returns bounding box relative to (0, 0) if not nullptr
334
        @return            the sum of the default advance widths
335
    */
336
    SkScalar measureText(const void* text, size_t byteLength, SkTextEncoding encoding,
337
13.7k
                         SkRect* bounds = nullptr) const {
338
13.7k
        return this->measureText(text, byteLength, encoding, bounds, nullptr);
339
13.7k
    }
340
341
    /** Returns the advance width of text.
342
        The advance is the normal distance to move before drawing additional text.
343
        Returns the bounding box of text if bounds is not nullptr. The paint
344
        stroke settings, mask filter, or path effect may modify the bounds.
345
346
        @param text        character storage encoded with SkTextEncoding
347
        @param byteLength  length of character storage in bytes
348
        @param bounds      returns bounding box relative to (0, 0) if not nullptr
349
        @param paint       optional; may be nullptr
350
        @return            the sum of the default advance widths
351
    */
352
    SkScalar measureText(const void* text, size_t byteLength, SkTextEncoding encoding,
353
                         SkRect* bounds, const SkPaint* paint) const;
354
355
    /** DEPRECATED
356
        Retrieves the advance and bounds for each glyph in glyphs.
357
        Both widths and bounds may be nullptr.
358
        If widths is not nullptr, widths must be an array of count entries.
359
        if bounds is not nullptr, bounds must be an array of count entries.
360
361
        @param glyphs      array of glyph indices to be measured
362
        @param count       number of glyphs
363
        @param widths      returns text advances for each glyph; may be nullptr
364
        @param bounds      returns bounds for each glyph relative to (0, 0); may be nullptr
365
    */
366
0
    void getWidths(const SkGlyphID glyphs[], int count, SkScalar widths[], SkRect bounds[]) const {
367
0
        this->getWidthsBounds(glyphs, count, widths, bounds, nullptr);
368
0
    }
369
370
    // DEPRECATED
371
0
    void getWidths(const SkGlyphID glyphs[], int count, SkScalar widths[], std::nullptr_t) const {
372
0
        this->getWidths(glyphs, count, widths);
373
0
    }
374
375
    /** Retrieves the advance and bounds for each glyph in glyphs.
376
        Both widths and bounds may be nullptr.
377
        If widths is not nullptr, widths must be an array of count entries.
378
        if bounds is not nullptr, bounds must be an array of count entries.
379
380
        @param glyphs      array of glyph indices to be measured
381
        @param count       number of glyphs
382
        @param widths      returns text advances for each glyph
383
     */
384
0
    void getWidths(const SkGlyphID glyphs[], int count, SkScalar widths[]) const {
385
0
        this->getWidthsBounds(glyphs, count, widths, nullptr, nullptr);
386
0
    }
387
388
    /** Retrieves the advance and bounds for each glyph in glyphs.
389
        Both widths and bounds may be nullptr.
390
        If widths is not nullptr, widths must be an array of count entries.
391
        if bounds is not nullptr, bounds must be an array of count entries.
392
393
        @param glyphs      array of glyph indices to be measured
394
        @param count       number of glyphs
395
        @param widths      returns text advances for each glyph; may be nullptr
396
        @param bounds      returns bounds for each glyph relative to (0, 0); may be nullptr
397
        @param paint       optional, specifies stroking, SkPathEffect and SkMaskFilter
398
     */
399
    void getWidthsBounds(const SkGlyphID glyphs[], int count, SkScalar widths[], SkRect bounds[],
400
                         const SkPaint* paint) const;
401
402
403
    /** Retrieves the bounds for each glyph in glyphs.
404
        bounds must be an array of count entries.
405
        If paint is not nullptr, its stroking, SkPathEffect, and SkMaskFilter fields are respected.
406
407
        @param glyphs      array of glyph indices to be measured
408
        @param count       number of glyphs
409
        @param bounds      returns bounds for each glyph relative to (0, 0); may be nullptr
410
        @param paint       optional, specifies stroking, SkPathEffect, and SkMaskFilter
411
     */
412
    void getBounds(const SkGlyphID glyphs[], int count, SkRect bounds[],
413
3.17k
                   const SkPaint* paint) const {
414
3.17k
        this->getWidthsBounds(glyphs, count, nullptr, bounds, paint);
415
3.17k
    }
416
417
    /** Retrieves the positions for each glyph, beginning at the specified origin. The caller
418
        must allocated at least count number of elements in the pos[] array.
419
420
        @param glyphs   array of glyph indices to be positioned
421
        @param count    number of glyphs
422
        @param pos      returns glyphs positions
423
        @param origin   location of the first glyph. Defaults to {0, 0}.
424
     */
425
    void getPos(const SkGlyphID glyphs[], int count, SkPoint pos[], SkPoint origin = {0, 0}) const;
426
427
    /** Retrieves the x-positions for each glyph, beginning at the specified origin. The caller
428
        must allocated at least count number of elements in the xpos[] array.
429
430
        @param glyphs   array of glyph indices to be positioned
431
        @param count    number of glyphs
432
        @param xpos     returns glyphs x-positions
433
        @param origin   x-position of the first glyph. Defaults to 0.
434
     */
435
    void getXPos(const SkGlyphID glyphs[], int count, SkScalar xpos[], SkScalar origin = 0) const;
436
437
    /** Returns intervals [start, end] describing lines parallel to the advance that intersect
438
     *  with the glyphs.
439
     *
440
     *  @param glyphs   the glyphs to intersect
441
     *  @param count    the number of glyphs and positions
442
     *  @param pos      the position of each glyph
443
     *  @param top      the top of the line intersecting
444
     *  @param bottom   the bottom of the line intersecting
445
        @return         array of pairs of x values [start, end]. May be empty.
446
     */
447
    std::vector<SkScalar> getIntercepts(const SkGlyphID glyphs[], int count, const SkPoint pos[],
448
                                        SkScalar top, SkScalar bottom,
449
                                        const SkPaint* = nullptr) const;
450
451
    /** Modifies path to be the outline of the glyph.
452
        If the glyph has an outline, modifies path to be the glyph's outline and returns true.
453
        The glyph outline may be empty. Degenerate contours in the glyph outline will be skipped.
454
        If glyph is described by a bitmap, returns false and ignores path parameter.
455
456
        @param glyphID  index of glyph
457
        @param path     pointer to existing SkPath
458
        @return         true if glyphID is described by path
459
     */
460
    bool getPath(SkGlyphID glyphID, SkPath* path) const;
461
462
    /** Returns path corresponding to glyph array.
463
464
        @param glyphIDs      array of glyph indices
465
        @param count         number of glyphs
466
        @param glyphPathProc function returning one glyph description as path
467
        @param ctx           function context
468
   */
469
    void getPaths(const SkGlyphID glyphIDs[], int count,
470
                  void (*glyphPathProc)(const SkPath* pathOrNull, const SkMatrix& mx, void* ctx),
471
                  void* ctx) const;
472
473
    /** Returns SkFontMetrics associated with SkTypeface.
474
        The return value is the recommended spacing between lines: the sum of metrics
475
        descent, ascent, and leading.
476
        If metrics is not nullptr, SkFontMetrics is copied to metrics.
477
        Results are scaled by text size but does not take into account
478
        dimensions required by text scale, text skew, fake bold,
479
        style stroke, and SkPathEffect.
480
481
        @param metrics  storage for SkFontMetrics; may be nullptr
482
        @return         recommended spacing between lines
483
    */
484
    SkScalar getMetrics(SkFontMetrics* metrics) const;
485
486
    /** Returns the recommended spacing between lines: the sum of metrics
487
        descent, ascent, and leading.
488
        Result is scaled by text size but does not take into account
489
        dimensions required by stroking and SkPathEffect.
490
        Returns the same result as getMetrics().
491
492
        @return  recommended spacing between lines
493
    */
494
0
    SkScalar getSpacing() const { return this->getMetrics(nullptr); }
495
496
    /** Dumps fields of the font to SkDebugf. May change its output over time, so clients should
497
     *  not rely on this for anything specific. Used to aid in debugging.
498
     */
499
    void dump() const;
500
501
    using sk_is_trivially_relocatable = std::true_type;
502
503
private:
504
    enum PrivFlags {
505
        kForceAutoHinting_PrivFlag      = 1 << 0,
506
        kEmbeddedBitmaps_PrivFlag       = 1 << 1,
507
        kSubpixel_PrivFlag              = 1 << 2,
508
        kLinearMetrics_PrivFlag         = 1 << 3,
509
        kEmbolden_PrivFlag              = 1 << 4,
510
        kBaselineSnap_PrivFlag          = 1 << 5,
511
    };
512
513
    static constexpr unsigned kAllFlags = kForceAutoHinting_PrivFlag
514
                                        | kEmbeddedBitmaps_PrivFlag
515
                                        | kSubpixel_PrivFlag
516
                                        | kLinearMetrics_PrivFlag
517
                                        | kEmbolden_PrivFlag
518
                                        | kBaselineSnap_PrivFlag;
519
520
    sk_sp<SkTypeface> fTypeface;
521
    SkScalar    fSize;
522
    SkScalar    fScaleX;
523
    SkScalar    fSkewX;
524
    uint8_t     fFlags;
525
    uint8_t     fEdging;
526
    uint8_t     fHinting;
527
528
    static_assert(::sk_is_trivially_relocatable<decltype(fTypeface)>::value);
529
530
    SkScalar setupForAsPaths(SkPaint*);
531
    bool hasSomeAntiAliasing() const;
532
533
    friend class SkFontPriv;
534
    friend class SkGlyphRunListPainterCPU;
535
    friend class SkStrikeSpec;
536
    friend class SkRemoteGlyphCacheTest;
537
};
538
539
#endif