Coverage Report

Created: 2021-08-22 09:07

/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/SkFontTypes.h"
12
#include "include/core/SkScalar.h"
13
#include "include/core/SkTypeface.h"
14
15
#include <vector>
16
17
class SkMatrix;
18
class SkPaint;
19
class SkPath;
20
struct SkFontMetrics;
21
22
/** \class SkFont
23
    SkFont controls options applied when drawing and measuring text.
24
*/
25
class SK_API SkFont {
26
public:
27
    /** Whether edge pixels draw opaque or with partial transparency.
28
    */
29
    enum class Edging {
30
        kAlias,              //!< no transparent pixels on glyph edges
31
        kAntiAlias,          //!< may have transparent pixels on glyph edges
32
        kSubpixelAntiAlias,  //!< glyph positioned in pixel using transparency
33
    };
34
35
    /** Constructs SkFont with default values.
36
37
        @return  default initialized SkFont
38
    */
39
    SkFont();
40
41
    /** Constructs SkFont with default values with SkTypeface and size in points.
42
43
        @param typeface  font and style used to draw and measure text
44
        @param size      typographic height of text
45
        @return          initialized SkFont
46
    */
47
    SkFont(sk_sp<SkTypeface> typeface, SkScalar size);
48
49
    /** Constructs SkFont with default values with SkTypeface.
50
51
        @param typeface  font and style used to draw and measure text
52
        @return          initialized SkFont
53
    */
54
    explicit SkFont(sk_sp<SkTypeface> typeface);
55
56
57
    /** Constructs SkFont with default values with SkTypeface and size in points,
58
        horizontal scale, and horizontal skew. Horizontal scale emulates condensed
59
        and expanded fonts. Horizontal skew emulates oblique fonts.
60
61
        @param typeface  font and style used to draw and measure text
62
        @param size      typographic height of text
63
        @param scaleX    text horizontal scale
64
        @param skewX     additional shear on x-axis relative to y-axis
65
        @return          initialized SkFont
66
    */
67
    SkFont(sk_sp<SkTypeface> typeface, SkScalar size, SkScalar scaleX, SkScalar skewX);
68
69
70
    /** Compares SkFont and font, and returns true if they are equivalent.
71
        May return false if SkTypeface has identical contents but different pointers.
72
73
        @param font  font to compare
74
        @return      true if SkFont pair are equivalent
75
    */
76
    bool operator==(const SkFont& font) const;
77
78
    /** Compares SkFont and font, and returns true if they are not equivalent.
79
        May return true if SkTypeface has identical contents but different pointers.
80
81
        @param font  font to compare
82
        @return      true if SkFont pair are not equivalent
83
    */
84
23.2k
    bool operator!=(const SkFont& font) const { return !(*this == font); }
85
86
    /** If true, instructs the font manager to always hint glyphs.
87
        Returned value is only meaningful if platform uses FreeType as the font manager.
88
89
        @return  true if all glyphs are hinted
90
    */
91
9.90M
    bool isForceAutoHinting() const { return SkToBool(fFlags & kForceAutoHinting_PrivFlag); }
92
93
    /** Returns true if font engine may return glyphs from font bitmaps instead of from outlines.
94
95
        @return  true if glyphs may be font bitmaps
96
    */
97
9.90M
    bool isEmbeddedBitmaps() const { return SkToBool(fFlags & kEmbeddedBitmaps_PrivFlag); }
98
99
    /** Returns true if glyphs may be drawn at sub-pixel offsets.
100
101
        @return  true if glyphs may be drawn at sub-pixel offsets.
102
    */
103
10.4M
    bool isSubpixel() const { return SkToBool(fFlags & kSubpixel_PrivFlag); }
104
105
    /** Returns true if font and glyph metrics are requested to be linearly scalable.
106
107
        @return  true if font and glyph metrics are requested to be linearly scalable.
108
    */
109
9.90M
    bool isLinearMetrics() const { return SkToBool(fFlags & kLinearMetrics_PrivFlag); }
110
111
    /** Returns true if bold is approximated by increasing the stroke width when creating glyph
112
        bitmaps from outlines.
113
114
        @return  bold is approximated through stroke width
115
    */
116
9.90M
    bool isEmbolden() const { return SkToBool(fFlags & kEmbolden_PrivFlag); }
117
118
    /** Returns true if baselines will be snapped to pixel positions when the current transformation
119
        matrix is axis aligned.
120
121
        @return  baselines may be snapped to pixels
122
     */
123
9.90M
    bool isBaselineSnap() const { return SkToBool(fFlags & kBaselineSnap_PrivFlag); }
124
125
    /** Sets whether to always hint glyphs.
126
        If forceAutoHinting is set, instructs the font manager to always hint glyphs.
127
128
        Only affects platforms that use FreeType as the font manager.
129
130
        @param forceAutoHinting  setting to always hint glyphs
131
    */
132
    void setForceAutoHinting(bool forceAutoHinting);
133
134
    /** Requests, but does not require, to use bitmaps in fonts instead of outlines.
135
136
        @param embeddedBitmaps  setting to use bitmaps in fonts
137
    */
138
    void setEmbeddedBitmaps(bool embeddedBitmaps);
139
140
    /** Requests, but does not require, that glyphs respect sub-pixel positioning.
141
142
        @param subpixel  setting for sub-pixel positioning
143
    */
144
    void setSubpixel(bool subpixel);
145
146
    /** Requests, but does not require, linearly scalable font and glyph metrics.
147
148
        For outline fonts 'true' means font and glyph metrics should ignore hinting and rounding.
149
        Note that some bitmap formats may not be able to scale linearly and will ignore this flag.
150
151
        @param linearMetrics  setting for linearly scalable font and glyph metrics.
152
    */
153
    void setLinearMetrics(bool linearMetrics);
154
155
    /** Increases stroke width when creating glyph bitmaps to approximate a bold typeface.
156
157
        @param embolden  setting for bold approximation
158
    */
159
    void setEmbolden(bool embolden);
160
161
    /** Requests that baselines be snapped to pixels when the current transformation matrix is axis
162
        aligned.
163
164
        @param baselineSnap  setting for baseline snapping to pixels
165
    */
166
    void setBaselineSnap(bool baselineSnap);
167
168
    /** Whether edge pixels draw opaque or with partial transparency.
169
    */
170
11.2M
    Edging getEdging() const { return (Edging)fEdging; }
171
172
    /** Requests, but does not require, that edge pixels draw opaque or with
173
        partial transparency.
174
    */
175
    void setEdging(Edging edging);
176
177
    /** Sets level of glyph outline adjustment.
178
        Does not check for valid values of hintingLevel.
179
    */
180
    void setHinting(SkFontHinting hintingLevel);
181
182
    /** Returns level of glyph outline adjustment.
183
     */
184
9.90M
    SkFontHinting getHinting() const { return (SkFontHinting)fHinting; }
185
186
    /** Returns a font with the same attributes of this font, but with the specified size.
187
        Returns nullptr if size is less than zero, infinite, or NaN.
188
189
        @param size  typographic height of text
190
        @return      initialized SkFont
191
     */
192
    SkFont makeWithSize(SkScalar size) const;
193
194
    /** Returns SkTypeface if set, or nullptr.
195
        Does not alter SkTypeface SkRefCnt.
196
197
        @return  SkTypeface if previously set, nullptr otherwise
198
    */
199
10.9M
    SkTypeface* getTypeface() const {return fTypeface.get(); }
200
201
    /** Returns SkTypeface if set, or the default typeface.
202
        Does not alter SkTypeface SkRefCnt.
203
204
        @return  SkTypeface if previously set or, a pointer to the default typeface if not
205
        previously set.
206
    */
207
    SkTypeface* getTypefaceOrDefault() const;
208
209
    /** Returns text size in points.
210
211
        @return  typographic height of text
212
    */
213
21.9M
    SkScalar    getSize() const { return fSize; }
214
215
    /** Returns text scale on x-axis.
216
        Default value is 1.
217
218
        @return  text horizontal scale
219
    */
220
21.2M
    SkScalar    getScaleX() const { return fScaleX; }
221
222
    /** Returns text skew on x-axis.
223
        Default value is zero.
224
225
        @return  additional shear on x-axis relative to y-axis
226
    */
227
20.7M
    SkScalar    getSkewX() const { return fSkewX; }
228
229
    /** Increases SkTypeface SkRefCnt by one.
230
231
        @return  SkTypeface if previously set, nullptr otherwise
232
    */
233
0
    sk_sp<SkTypeface> refTypeface() const { return fTypeface; }
234
235
    /** Increases SkTypeface SkRefCnt by one.
236
237
        @return  SkTypeface if previously set or, a pointer to the default typeface if not
238
        previously set.
239
    */
240
    sk_sp<SkTypeface> refTypefaceOrDefault() const;
241
242
    /** Sets SkTypeface to typeface, decreasing SkRefCnt of the previous SkTypeface.
243
        Pass nullptr to clear SkTypeface and use the default typeface. Increments
244
        tf SkRefCnt by one.
245
246
        @param tf  font and style used to draw text
247
    */
248
65.1k
    void setTypeface(sk_sp<SkTypeface> tf) { fTypeface = 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
69.1k
    int countText(const void* text, size_t byteLength, SkTextEncoding encoding) const {
324
69.1k
        return this->textToGlyphs(text, byteLength, encoding, nullptr, 0);
325
69.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            number of glyphs represented by text of length byteLength
335
    */
336
    SkScalar measureText(const void* text, size_t byteLength, SkTextEncoding encoding,
337
33.1k
                         SkRect* bounds = nullptr) const {
338
33.1k
        return this->measureText(text, byteLength, encoding, bounds, nullptr);
339
33.1k
    }
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            number of glyphs represented by text of length byteLength
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
63.3k
    void getWidths(const SkGlyphID glyphs[], int count, SkScalar widths[], SkRect bounds[]) const {
367
63.3k
        this->getWidthsBounds(glyphs, count, widths, bounds, nullptr);
368
63.3k
    }
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
493k
    void getWidths(const SkGlyphID glyphs[], int count, SkScalar widths[]) const {
385
493k
        this->getWidthsBounds(glyphs, count, widths, nullptr, nullptr);
386
493k
    }
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
433k
                   const SkPaint* paint) const {
414
433k
        this->getWidthsBounds(glyphs, count, nullptr, bounds, paint);
415
433k
    }
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
private:
502
    enum PrivFlags {
503
        kForceAutoHinting_PrivFlag      = 1 << 0,
504
        kEmbeddedBitmaps_PrivFlag       = 1 << 1,
505
        kSubpixel_PrivFlag              = 1 << 2,
506
        kLinearMetrics_PrivFlag         = 1 << 3,
507
        kEmbolden_PrivFlag              = 1 << 4,
508
        kBaselineSnap_PrivFlag          = 1 << 5,
509
    };
510
511
    static constexpr unsigned kAllFlags = kForceAutoHinting_PrivFlag
512
                                        | kEmbeddedBitmaps_PrivFlag
513
                                        | kSubpixel_PrivFlag
514
                                        | kLinearMetrics_PrivFlag
515
                                        | kEmbolden_PrivFlag
516
                                        | kBaselineSnap_PrivFlag;
517
518
    sk_sp<SkTypeface> fTypeface;
519
    SkScalar    fSize;
520
    SkScalar    fScaleX;
521
    SkScalar    fSkewX;
522
    uint8_t     fFlags;
523
    uint8_t     fEdging;
524
    uint8_t     fHinting;
525
526
    SkScalar setupForAsPaths(SkPaint*);
527
    bool hasSomeAntiAliasing() const;
528
529
    friend class SkFontPriv;
530
    friend class SkGlyphRunListPainter;
531
    friend class SkStrikeSpec;
532
};
533
534
#endif