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