• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     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     */
isForceAutoHinting()91     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     */
isEmbeddedBitmaps()97     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     */
isSubpixel()103     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     */
isLinearMetrics()109     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     */
isEmbolden()116     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      */
isBaselineSnap()123     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     */
getEdging()170     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      */
getHinting()184     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     */
getTypeface()199     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     */
getSize()213     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     */
getScaleX()220     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     */
getSkewX()227     SkScalar    getSkewX() const { return fSkewX; }
228 
229     /** Increases SkTypeface SkRefCnt by one.
230 
231         @return  SkTypeface if previously set, nullptr otherwise
232     */
refTypeface()233     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     */
setTypeface(sk_sp<SkTypeface> tf)248     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     */
countText(const void * text,size_t byteLength,SkTextEncoding encoding)323     int countText(const void* text, size_t byteLength, SkTextEncoding encoding) const {
324         return this->textToGlyphs(text, byteLength, encoding, nullptr, 0);
325     }
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                          SkRect* bounds = nullptr) const {
338         return this->measureText(text, byteLength, encoding, bounds, nullptr);
339     }
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     */
getWidths(const SkGlyphID glyphs[],int count,SkScalar widths[],SkRect bounds[])366     void getWidths(const SkGlyphID glyphs[], int count, SkScalar widths[], SkRect bounds[]) const {
367         this->getWidthsBounds(glyphs, count, widths, bounds, nullptr);
368     }
369 
370     // DEPRECATED
getWidths(const SkGlyphID glyphs[],int count,SkScalar widths[],std::nullptr_t)371     void getWidths(const SkGlyphID glyphs[], int count, SkScalar widths[], std::nullptr_t) const {
372         this->getWidths(glyphs, count, widths);
373     }
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      */
getWidths(const SkGlyphID glyphs[],int count,SkScalar widths[])384     void getWidths(const SkGlyphID glyphs[], int count, SkScalar widths[]) const {
385         this->getWidthsBounds(glyphs, count, widths, nullptr, nullptr);
386     }
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      */
getBounds(const SkGlyphID glyphs[],int count,SkRect bounds[],const SkPaint * paint)412     void getBounds(const SkGlyphID glyphs[], int count, SkRect bounds[],
413                    const SkPaint* paint) const {
414         this->getWidthsBounds(glyphs, count, nullptr, bounds, paint);
415     }
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     */
getSpacing()494     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
535