• 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 "SkFontTypes.h"
12 #include "SkScalar.h"
13 #include "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 at different sub-pixel positions may differ on pixel edge coverage.
98 
99         @return  true if glyph positioned in pixel using transparency
100     */
isSubpixel()101     bool isSubpixel() const { return SkToBool(fFlags & kSubpixel_PrivFlag); }
102 
103     /** Returns true if text is converted to SkPath before drawing and measuring.
104 
105         @return  true glyph hints are never applied
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, that glyphs are converted to SkPath
138         before drawing and measuring.
139 
140         @param linearMetrics  setting for converting glyphs to paths
141     */
142     void setLinearMetrics(bool linearMetrics);
143 
144     /** Increases stroke width when creating glyph bitmaps to approximate a bold typeface.
145 
146         @param embolden  setting for bold approximation
147     */
148     void setEmbolden(bool embolden);
149 
150     /** Whether edge pixels draw opaque or with partial transparency.
151 
152         @return  one of: Edging::kAlias, Edging::kAntiAlias, Edging::kSubpixelAntiAlias
153     */
getEdging()154     Edging getEdging() const { return (Edging)fEdging; }
155 
156     /** Requests, but does not require, that edge pixels draw opaque or with
157         partial transparency.
158 
159         @param edging  one of: Edging::kAlias, Edging::kAntiAlias, Edging::kSubpixelAntiAlias
160     */
161     void setEdging(Edging edging);
162 
163     /** Sets level of glyph outline adjustment.
164         Does not check for valid values of hintingLevel.
165 
166         @param hintingLevel  one of: SkFontHinting::kNone, SkFontHinting::kSlight,
167                                      SkFontHinting::kNormal, SkFontHinting::kFull
168     */
169     void setHinting(SkFontHinting hintingLevel);
170 
171     /** Returns level of glyph outline adjustment.
172 
173         @return  one of: SkFontHinting::kNone, SkFontHinting::kSlight, SkFontHinting::kNormal,
174                          SkFontHinting::kFull
175      */
getHinting()176     SkFontHinting getHinting() const { return (SkFontHinting)fHinting; }
177 
178     /** Returns a font with the same attributes of this font, but with the specified size.
179         Returns nullptr if size is less than zero, infinite, or NaN.
180 
181         @param size  typographic height of text
182         @return      initialized SkFont
183      */
184     SkFont makeWithSize(SkScalar size) const;
185 
186     /** Returns SkTypeface if set, or nullptr.
187         Does not alter SkTypeface SkRefCnt.
188 
189         @return  SkTypeface if previously set, nullptr otherwise
190     */
getTypeface()191     SkTypeface* getTypeface() const {return fTypeface.get(); }
192 
193     /** Returns SkTypeface if set, or the default typeface.
194         Does not alter SkTypeface SkRefCnt.
195 
196         @return  SkTypeface if previously set or, a pointer to the default typeface if not
197         previously set.
198     */
199     SkTypeface* getTypefaceOrDefault() const;
200 
201     /** Returns text size in points.
202 
203         @return  typographic height of text
204     */
getSize()205     SkScalar    getSize() const { return fSize; }
206 
207     /** Returns text scale on x-axis.
208         Default value is 1.
209 
210         @return  text horizontal scale
211     */
getScaleX()212     SkScalar    getScaleX() const { return fScaleX; }
213 
214     /** Returns text skew on x-axis.
215         Default value is zero.
216 
217         @return  additional shear on x-axis relative to y-axis
218     */
getSkewX()219     SkScalar    getSkewX() const { return fSkewX; }
220 
221     /** Increases SkTypeface SkRefCnt by one.
222 
223         @return  SkTypeface if previously set, nullptr otherwise
224     */
refTypeface()225     sk_sp<SkTypeface> refTypeface() const { return fTypeface; }
226 
227     /** Increases SkTypeface SkRefCnt by one.
228 
229         @return  SkTypeface if previously set or, a pointer to the default typeface if not
230         previously set.
231     */
232     sk_sp<SkTypeface> refTypefaceOrDefault() const;
233 
234     /** Sets SkTypeface to typeface, decreasing SkRefCnt of the previous SkTypeface.
235         Pass nullptr to clear SkTypeface and use the default typeface. Increments
236         tf SkRefCnt by one.
237 
238         @param tf  font and style used to draw text
239     */
setTypeface(sk_sp<SkTypeface> tf)240     void setTypeface(sk_sp<SkTypeface> tf) { fTypeface = tf; }
241 
242     /** Sets text size in points.
243         Has no effect if textSize is not greater than or equal to zero.
244 
245         @param textSize  typographic height of text
246     */
247     void setSize(SkScalar textSize);
248 
249     /** Sets text scale on x-axis.
250         Default value is 1.
251 
252         @param scaleX  text horizontal scale
253     */
254     void setScaleX(SkScalar scaleX);
255 
256     /** Sets text skew on x-axis.
257         Default value is zero.
258 
259         @param skewX  additional shear on x-axis relative to y-axis
260     */
261     void setSkewX(SkScalar skewX);
262 
263     /** Converts text into glyph indices.
264         Returns the number of glyph indices represented by text.
265         SkTextEncoding specifies how text represents characters or glyphs.
266         glyphs may be nullptr, to compute the glyph count.
267 
268         Does not check text for valid character codes or valid glyph indices.
269 
270         If byteLength equals zero, returns zero.
271         If byteLength includes a partial character, the partial character is ignored.
272 
273         If encoding is kUTF8_SkTextEncoding and text contains an invalid UTF-8 sequence,
274         zero is returned.
275 
276         When encoding is SkTextEncoding::kUTF8, SkTextEncoding::kUTF16, or
277         SkTextEncoding::kUTF32; then each Unicode codepoint is mapped to a
278         single glyph.  This function uses the default character-to-glyph
279         mapping from the SkTypeface and maps characters not found in the
280         SkTypeface to zero.
281 
282         If maxGlyphCount is not sufficient to store all the glyphs, no glyphs are copied.
283         The total glyph count is returned for subsequent buffer reallocation.
284 
285         @param text          character storage encoded with SkTextEncoding
286         @param byteLength    length of character storage in bytes
287         @param encoding      one of: kUTF8_SkTextEncoding, kUTF16_SkTextEncoding,
288                              kUTF32_SkTextEncoding, kGlyphID_SkTextEncoding
289         @param glyphs        storage for glyph indices; may be nullptr
290         @param maxGlyphCount storage capacity
291         @return              number of glyphs represented by text of length byteLength
292     */
293     int textToGlyphs(const void* text, size_t byteLength, SkTextEncoding encoding,
294                      SkGlyphID glyphs[], int maxGlyphCount) const;
295 
296     /** Returns glyph index for Unicode character.
297 
298         If the character is not supported by the SkTypeface, returns 0.
299 
300         @param uni  Unicode character
301         @return     glyph index
302     */
303     SkGlyphID unicharToGlyph(SkUnichar uni) const;
304 
305     /** Returns number of glyphs represented by text.
306 
307         If encoding is kUTF8_SkTextEncoding, kUTF16_SkTextEncoding, or
308         kUTF32_SkTextEncoding; then each Unicode codepoint is mapped to a
309         single glyph.
310 
311         @param text          character storage encoded with SkTextEncoding
312         @param byteLength    length of character storage in bytes
313         @param encoding      one of: kUTF8_SkTextEncoding, kUTF16_SkTextEncoding,
314                              kUTF32_SkTextEncoding, kGlyphID_SkTextEncoding
315         @return              number of glyphs represented by text of length byteLength
316     */
countText(const void * text,size_t byteLength,SkTextEncoding encoding)317     int countText(const void* text, size_t byteLength, SkTextEncoding encoding) const {
318         return this->textToGlyphs(text, byteLength, encoding, nullptr, 0);
319     }
320 
321     /** Returns the advance width of text.
322         The advance is the normal distance to move before drawing additional text.
323         Returns the bounding box of text if bounds is not nullptr.
324 
325         @param text        character storage encoded with SkTextEncoding
326         @param byteLength  length of character storage in bytes
327         @param encoding    one of: kUTF8_SkTextEncoding, kUTF16_SkTextEncoding,
328                            kUTF32_SkTextEncoding, kGlyphID_SkTextEncoding
329         @param bounds      returns bounding box relative to (0, 0) if not nullptr
330         @return            number of glyphs represented by text of length byteLength
331     */
332     SkScalar measureText(const void* text, size_t byteLength, SkTextEncoding encoding,
333                          SkRect* bounds = nullptr) const {
334         return this->measureText(text, byteLength, encoding, bounds, nullptr);
335     }
336 
337     /** Returns the advance width of text.
338         The advance is the normal distance to move before drawing additional text.
339         Returns the bounding box of text if bounds is not nullptr. paint
340         stroke width or SkPathEffect may modify the advance with.
341 
342         @param text        character storage encoded with SkTextEncoding
343         @param byteLength  length of character storage in bytes
344         @param encoding    one of: kUTF8_SkTextEncoding, kUTF16_SkTextEncoding,
345                            kUTF32_SkTextEncoding, kGlyphID_SkTextEncoding
346         @param bounds      returns bounding box relative to (0, 0) if not nullptr
347         @param paint       optional; may be nullptr
348         @return            number of glyphs represented by text of length byteLength
349     */
350     SkScalar measureText(const void* text, size_t byteLength, SkTextEncoding encoding,
351                          SkRect* bounds, const SkPaint* paint) const;
352 
353     /** DEPRECATED
354         Retrieves the advance and bounds for each glyph in glyphs.
355         Both widths and bounds may be nullptr.
356         If widths is not nullptr, widths must be an array of count entries.
357         if bounds is not nullptr, bounds must be an array of count entries.
358 
359         @param glyphs      array of glyph indices to be measured
360         @param count       number of glyphs
361         @param widths      returns text advances for each glyph; may be nullptr
362         @param bounds      returns bounds for each glyph relative to (0, 0); may be nullptr
363     */
getWidths(const uint16_t glyphs[],int count,SkScalar widths[],SkRect bounds[])364     void getWidths(const uint16_t glyphs[], int count, SkScalar widths[], SkRect bounds[]) const {
365         this->getWidthsBounds(glyphs, count, widths, bounds, nullptr);
366     }
367 
368     // DEPRECATED
getWidths(const uint16_t glyphs[],int count,SkScalar widths[],std::nullptr_t)369     void getWidths(const uint16_t glyphs[], int count, SkScalar widths[], std::nullptr_t) const {
370         this->getWidths(glyphs, count, widths);
371     }
372 
373     /** Retrieves the advance and bounds for each glyph in glyphs.
374         Both widths and bounds may be nullptr.
375         If widths is not nullptr, widths must be an array of count entries.
376         if bounds is not nullptr, bounds must be an array of count entries.
377 
378         @param glyphs      array of glyph indices to be measured
379         @param count       number of glyphs
380         @param widths      returns text advances for each glyph
381      */
getWidths(const uint16_t glyphs[],int count,SkScalar widths[])382     void getWidths(const uint16_t glyphs[], int count, SkScalar widths[]) const {
383         this->getWidthsBounds(glyphs, count, widths, nullptr, nullptr);
384     }
385 
386     /** Retrieves the advance and bounds for each glyph in glyphs.
387         Both widths and bounds may be nullptr.
388         If widths is not nullptr, widths must be an array of count entries.
389         if bounds is not nullptr, bounds must be an array of count entries.
390 
391         @param glyphs      array of glyph indices to be measured
392         @param count       number of glyphs
393         @param widths      returns text advances for each glyph; may be nullptr
394         @param bounds      returns bounds for each glyph relative to (0, 0); may be nullptr
395         @param paint       optional, specifies stroking, SkPathEffect and SkMaskFilter
396      */
397     void getWidthsBounds(const uint16_t glyphs[], int count, SkScalar widths[], SkRect bounds[],
398                          const SkPaint* paint) const;
399 
400 
401     /** Retrieves the bounds for each glyph in glyphs.
402         bounds must be an array of count entries.
403         If paint is not nullptr, its stroking, SkPathEffect, and SkMaskFilter fields are respected.
404 
405         @param glyphs      array of glyph indices to be measured
406         @param count       number of glyphs
407         @param bounds      returns bounds for each glyph relative to (0, 0); may be nullptr
408         @param paint       optional, specifies stroking, SkPathEffect, and SkMaskFilter
409      */
getBounds(const uint16_t glyphs[],int count,SkRect bounds[],const SkPaint * paint)410     void getBounds(const uint16_t glyphs[], int count, SkRect bounds[],
411                    const SkPaint* paint) const {
412         this->getWidthsBounds(glyphs, count, nullptr, bounds, paint);
413     }
414 
415     /** Retrieves the positions for each glyph, beginning at the specified origin. The caller
416         must allocated at least count number of elements in the pos[] array.
417 
418         @param glyphs   array of glyph indices to be positioned
419         @param count    number of glyphs
420         @param pos      returns glyphs positions
421         @param origin   location of the first glyph. Defaults to {0, 0}.
422      */
423     void getPos(const uint16_t glyphs[], int count, SkPoint pos[], SkPoint origin = {0, 0}) const;
424 
425     /** Retrieves the x-positions for each glyph, beginning at the specified origin. The caller
426         must allocated at least count number of elements in the xpos[] array.
427 
428         @param glyphs   array of glyph indices to be positioned
429         @param count    number of glyphs
430         @param xpos     returns glyphs x-positions
431         @param origin   x-position of the first glyph. Defaults to 0.
432      */
433     void getXPos(const uint16_t glyphs[], int count, SkScalar xpos[], SkScalar origin = 0) const;
434 
435     /** Returns path corresponding to glyph outline.
436         If glyph has an outline, copies outline to path and returns true.
437         path returned may be empty.
438         If glyph is described by a bitmap, returns false and ignores path parameter.
439 
440         @param glyphID  index of glyph
441         @param path     pointer to existing SkPath
442         @return         true if glyphID is described by path
443      */
444     bool getPath(uint16_t glyphID, SkPath* path) const;
445 
446     /** Returns path corresponding to glyph array.
447 
448         @param glyphIDs      array of glyph indices
449         @param count         number of glyphs
450         @param glyphPathProc function returning one glyph description as path
451         @param ctx           function context
452    */
453     void getPaths(const uint16_t glyphIDs[], int count,
454                   void (*glyphPathProc)(const SkPath* pathOrNull, const SkMatrix& mx, void* ctx),
455                   void* ctx) const;
456 
457     /** Returns SkFontMetrics associated with SkTypeface.
458         The return value is the recommended spacing between lines: the sum of metrics
459         descent, ascent, and leading.
460         If metrics is not nullptr, SkFontMetrics is copied to metrics.
461         Results are scaled by text size but does not take into account
462         dimensions required by text scale, text skew, fake bold,
463         style stroke, and SkPathEffect.
464 
465         @param metrics  storage for SkFontMetrics; may be nullptr
466         @return         recommended spacing between lines
467     */
468     SkScalar getMetrics(SkFontMetrics* metrics) const;
469 
470     /** Returns the recommended spacing between lines: the sum of metrics
471         descent, ascent, and leading.
472         Result is scaled by text size but does not take into account
473         dimensions required by stroking and SkPathEffect.
474         Returns the same result as getMetrics().
475 
476         @return  recommended spacing between lines
477     */
getSpacing()478     SkScalar getSpacing() const { return this->getMetrics(nullptr); }
479 
480     /** Experimental.
481      *  Dumps fields of the font to SkDebugf. May change its output over time, so clients should
482      *  not rely on this for anything specific. Used to aid in debugging.
483      */
484     void dump() const;
485 
486 private:
487     enum PrivFlags {
488         kForceAutoHinting_PrivFlag      = 1 << 0,
489         kEmbeddedBitmaps_PrivFlag       = 1 << 1,
490         kSubpixel_PrivFlag              = 1 << 2,
491         kLinearMetrics_PrivFlag         = 1 << 3,
492         kEmbolden_PrivFlag              = 1 << 4,
493     };
494 
495     static constexpr unsigned kAllFlags = 0x1F;
496 
497     sk_sp<SkTypeface> fTypeface;
498     SkScalar    fSize;
499     SkScalar    fScaleX;
500     SkScalar    fSkewX;
501     uint8_t     fFlags;
502     uint8_t     fEdging;
503     uint8_t     fHinting;
504 
505     SkScalar setupForAsPaths(SkPaint*);
506     bool hasSomeAntiAliasing() const;
507 
508     void glyphsToUnichars(const SkGlyphID glyphs[], int count, SkUnichar text[]) const;
509 
510     friend class GrTextBlob;
511     friend class SkCanonicalizeFont;
512     friend class SkFontPriv;
513     friend class SkGlyphRunListPainter;
514     friend class SkTextBlobCacheDiffCanvas;
515     friend class SVGTextBuilder;
516 };
517 
518 #endif
519