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