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