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