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
15class SkMatrix;
16class SkPaint;
17class SkPath;
18struct SkFontMetrics;
19
20/** \class SkFont
21 SkFont controls options applied when drawing and measuring text.
22*/
23class SK_API SkFont {
24public:
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 */
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 */
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 */
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 */
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 */
114 bool isEmbolden() const { return SkToBool(fFlags & kEmbolden_PrivFlag); }
115
116 /** Returns true if baselines will be snapped to pixel positions when the current transformation
117 matrix is axis aligned.
118
119 @return baselines may be snapped to pixels
120 */
121 bool isBaselineSnap() const { return SkToBool(fFlags & kBaselineSnap_PrivFlag); }
122
123 /** Sets whether to always hint glyphs.
124 If forceAutoHinting is set, instructs the font manager to always hint glyphs.
125
126 Only affects platforms that use FreeType as the font manager.
127
128 @param forceAutoHinting setting to always hint glyphs
129 */
130 void setForceAutoHinting(bool forceAutoHinting);
131
132 /** Requests, but does not require, to use bitmaps in fonts instead of outlines.
133
134 @param embeddedBitmaps setting to use bitmaps in fonts
135 */
136 void setEmbeddedBitmaps(bool embeddedBitmaps);
137
138 /** Requests, but does not require, that glyphs respect sub-pixel positioning.
139
140 @param subpixel setting for sub-pixel positioning
141 */
142 void setSubpixel(bool subpixel);
143
144 /** Requests, but does not require, linearly scalable font and glyph metrics.
145
146 For outline fonts 'true' means font and glyph metrics should ignore hinting and rounding.
147 Note that some bitmap formats may not be able to scale linearly and will ignore this flag.
148
149 @param linearMetrics setting for linearly scalable font and glyph metrics.
150 */
151 void setLinearMetrics(bool linearMetrics);
152
153 /** Increases stroke width when creating glyph bitmaps to approximate a bold typeface.
154
155 @param embolden setting for bold approximation
156 */
157 void setEmbolden(bool embolden);
158
159 /** Requests that baselines be snapped to pixels when the current transformation matrix is axis
160 aligned.
161
162 @param baselineSnap setting for baseline snapping to pixels
163 */
164 void setBaselineSnap(bool baselineSnap);
165
166 /** Whether edge pixels draw opaque or with partial transparency.
167 */
168 Edging getEdging() const { return (Edging)fEdging; }
169
170 /** Requests, but does not require, that edge pixels draw opaque or with
171 partial transparency.
172 */
173 void setEdging(Edging edging);
174
175 /** Sets level of glyph outline adjustment.
176 Does not check for valid values of hintingLevel.
177 */
178 void setHinting(SkFontHinting hintingLevel);
179
180 /** Returns level of glyph outline adjustment.
181 */
182 SkFontHinting getHinting() const { return (SkFontHinting)fHinting; }
183
184 /** Returns a font with the same attributes of this font, but with the specified size.
185 Returns nullptr if size is less than zero, infinite, or NaN.
186
187 @param size typographic height of text
188 @return initialized SkFont
189 */
190 SkFont makeWithSize(SkScalar size) const;
191
192 /** Returns SkTypeface if set, or nullptr.
193 Does not alter SkTypeface SkRefCnt.
194
195 @return SkTypeface if previously set, nullptr otherwise
196 */
197 SkTypeface* getTypeface() const {return fTypeface.get(); }
198
199 /** Returns SkTypeface if set, or the default typeface.
200 Does not alter SkTypeface SkRefCnt.
201
202 @return SkTypeface if previously set or, a pointer to the default typeface if not
203 previously set.
204 */
205 SkTypeface* getTypefaceOrDefault() const;
206
207 /** Returns text size in points.
208
209 @return typographic height of text
210 */
211 SkScalar getSize() const { return fSize; }
212
213 /** Returns text scale on x-axis.
214 Default value is 1.
215
216 @return text horizontal scale
217 */
218 SkScalar getScaleX() const { return fScaleX; }
219
220 /** Returns text skew on x-axis.
221 Default value is zero.
222
223 @return additional shear on x-axis relative to y-axis
224 */
225 SkScalar getSkewX() const { return fSkewX; }
226
227 /** Increases SkTypeface SkRefCnt by one.
228
229 @return SkTypeface if previously set, nullptr otherwise
230 */
231 sk_sp<SkTypeface> refTypeface() const { return fTypeface; }
232
233 /** Increases SkTypeface SkRefCnt by one.
234
235 @return SkTypeface if previously set or, a pointer to the default typeface if not
236 previously set.
237 */
238 sk_sp<SkTypeface> refTypefaceOrDefault() const;
239
240 /** Sets SkTypeface to typeface, decreasing SkRefCnt of the previous SkTypeface.
241 Pass nullptr to clear SkTypeface and use the default typeface. Increments
242 tf SkRefCnt by one.
243
244 @param tf font and style used to draw text
245 */
246 void setTypeface(sk_sp<SkTypeface> tf) { fTypeface = tf; }
247
248 /** Sets text size in points.
249 Has no effect if textSize is not greater than or equal to zero.
250
251 @param textSize typographic height of text
252 */
253 void setSize(SkScalar textSize);
254
255 /** Sets text scale on x-axis.
256 Default value is 1.
257
258 @param scaleX text horizontal scale
259 */
260 void setScaleX(SkScalar scaleX);
261
262 /** Sets text skew on x-axis.
263 Default value is zero.
264
265 @param skewX additional shear on x-axis relative to y-axis
266 */
267 void setSkewX(SkScalar skewX);
268
269 /** Converts text into glyph indices.
270 Returns the number of glyph indices represented by text.
271 SkTextEncoding specifies how text represents characters or glyphs.
272 glyphs may be nullptr, to compute the glyph count.
273
274 Does not check text for valid character codes or valid glyph indices.
275
276 If byteLength equals zero, returns zero.
277 If byteLength includes a partial character, the partial character is ignored.
278
279 If encoding is SkTextEncoding::kUTF8 and text contains an invalid UTF-8 sequence,
280 zero is returned.
281
282 When encoding is SkTextEncoding::kUTF8, SkTextEncoding::kUTF16, or
283 SkTextEncoding::kUTF32; then each Unicode codepoint is mapped to a
284 single glyph. This function uses the default character-to-glyph
285 mapping from the SkTypeface and maps characters not found in the
286 SkTypeface to zero.
287
288 If maxGlyphCount is not sufficient to store all the glyphs, no glyphs are copied.
289 The total glyph count is returned for subsequent buffer reallocation.
290
291 @param text character storage encoded with SkTextEncoding
292 @param byteLength length of character storage in bytes
293 @param glyphs storage for glyph indices; may be nullptr
294 @param maxGlyphCount storage capacity
295 @return number of glyphs represented by text of length byteLength
296 */
297 int textToGlyphs(const void* text, size_t byteLength, SkTextEncoding encoding,
298 SkGlyphID glyphs[], int maxGlyphCount) const;
299
300 /** Returns glyph index for Unicode character.
301
302 If the character is not supported by the SkTypeface, returns 0.
303
304 @param uni Unicode character
305 @return glyph index
306 */
307 SkGlyphID unicharToGlyph(SkUnichar uni) const;
308
309 void unicharsToGlyphs(const SkUnichar uni[], int count, SkGlyphID glyphs[]) const;
310
311 /** Returns number of glyphs represented by text.
312
313 If encoding is SkTextEncoding::kUTF8, SkTextEncoding::kUTF16, or
314 SkTextEncoding::kUTF32; then each Unicode codepoint is mapped to a
315 single glyph.
316
317 @param text character storage encoded with SkTextEncoding
318 @param byteLength length of character storage in bytes
319 @return number of glyphs represented by text of length byteLength
320 */
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 bounds returns bounding box relative to (0, 0) if not nullptr
332 @return number of glyphs represented by text of length byteLength
333 */
334 SkScalar measureText(const void* text, size_t byteLength, SkTextEncoding encoding,
335 SkRect* bounds = nullptr) const {
336 return this->measureText(text, byteLength, encoding, bounds, nullptr);
337 }
338
339 /** Returns the advance width of text.
340 The advance is the normal distance to move before drawing additional text.
341 Returns the bounding box of text if bounds is not nullptr. paint
342 stroke width or SkPathEffect may modify the advance with.
343
344 @param text character storage encoded with SkTextEncoding
345 @param byteLength length of character storage in bytes
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 */
364 void getWidths(const SkGlyphID glyphs[], int count, SkScalar widths[], SkRect bounds[]) const {
365 this->getWidthsBounds(glyphs, count, widths, bounds, nullptr);
366 }
367
368 // DEPRECATED
369 void getWidths(const SkGlyphID 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 */
382 void getWidths(const SkGlyphID 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 SkGlyphID 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 */
410 void getBounds(const SkGlyphID 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 SkGlyphID 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 SkGlyphID glyphs[], int count, SkScalar xpos[], SkScalar origin = 0) const;
434
435 /** Modifies path to be the outline of the glyph.
436 If the glyph has an outline, modifies path to be the glyph's outline and returns true.
437 The glyph outline may be empty. Degenerate contours in the glyph outline will be skipped.
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(SkGlyphID 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 SkGlyphID 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 */
478 SkScalar getSpacing() const { return this->getMetrics(nullptr); }
479
480 /** Dumps fields of the font to SkDebugf. May change its output over time, so clients should
481 * not rely on this for anything specific. Used to aid in debugging.
482 */
483 void dump() const;
484
485private:
486 enum PrivFlags {
487 kForceAutoHinting_PrivFlag = 1 << 0,
488 kEmbeddedBitmaps_PrivFlag = 1 << 1,
489 kSubpixel_PrivFlag = 1 << 2,
490 kLinearMetrics_PrivFlag = 1 << 3,
491 kEmbolden_PrivFlag = 1 << 4,
492 kBaselineSnap_PrivFlag = 1 << 5,
493 };
494
495 static constexpr unsigned kAllFlags = kForceAutoHinting_PrivFlag
496 | kEmbeddedBitmaps_PrivFlag
497 | kSubpixel_PrivFlag
498 | kLinearMetrics_PrivFlag
499 | kEmbolden_PrivFlag
500 | kBaselineSnap_PrivFlag;
501
502 sk_sp<SkTypeface> fTypeface;
503 SkScalar fSize;
504 SkScalar fScaleX;
505 SkScalar fSkewX;
506 uint8_t fFlags;
507 uint8_t fEdging;
508 uint8_t fHinting;
509
510 SkScalar setupForAsPaths(SkPaint*);
511 bool hasSomeAntiAliasing() const;
512
513 friend class GrTextBlob;
514 friend class SkFontPriv;
515 friend class SkGlyphRunListPainter;
516 friend class SkTextBlobCacheDiffCanvas;
517 friend class SkStrikeSpec;
518};
519
520#endif
521