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