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