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/SkRect.h" 12 #include "include/core/SkRefCnt.h" 13 #include "include/core/SkScalar.h" 14 #include "include/core/SkTypeface.h" 15 #include "include/core/SkTypes.h" 16 #include "include/private/base/SkTo.h" 17 #include "include/private/base/SkTypeTraits.h" 18 19 #include <cstddef> 20 #include <cstdint> 21 #include <type_traits> 22 #include <vector> 23 24 class SkMatrix; 25 class SkPaint; 26 class SkPath; 27 enum class SkFontHinting; 28 enum class SkTextEncoding; 29 struct SkFontMetrics; 30 struct SkPoint; 31 32 /** \class SkFont 33 SkFont controls options applied when drawing and measuring text. 34 */ 35 class SK_API SkFont { 36 public: 37 /** Whether edge pixels draw opaque or with partial transparency. 38 */ 39 enum class Edging { 40 kAlias, //!< no transparent pixels on glyph edges 41 kAntiAlias, //!< may have transparent pixels on glyph edges 42 kSubpixelAntiAlias, //!< glyph positioned in pixel using transparency 43 }; 44 45 /** Constructs SkFont with default values. 46 47 @return default initialized SkFont 48 */ 49 SkFont(); 50 51 /** Constructs SkFont with default values with SkTypeface and size in points. 52 53 @param typeface font and style used to draw and measure text 54 @param size typographic height of text 55 @return initialized SkFont 56 */ 57 SkFont(sk_sp<SkTypeface> typeface, SkScalar size); 58 59 /** Constructs SkFont with default values with SkTypeface. 60 61 @param typeface font and style used to draw and measure text 62 @return initialized SkFont 63 */ 64 explicit SkFont(sk_sp<SkTypeface> typeface); 65 66 67 /** Constructs SkFont with default values with SkTypeface and size in points, 68 horizontal scale, and horizontal skew. Horizontal scale emulates condensed 69 and expanded fonts. Horizontal skew emulates oblique fonts. 70 71 @param typeface font and style used to draw and measure text 72 @param size typographic height of text 73 @param scaleX text horizontal scale 74 @param skewX additional shear on x-axis relative to y-axis 75 @return initialized SkFont 76 */ 77 SkFont(sk_sp<SkTypeface> typeface, SkScalar size, SkScalar scaleX, SkScalar skewX); 78 79 80 /** Compares SkFont and font, and returns true if they are equivalent. 81 May return false if SkTypeface has identical contents but different pointers. 82 83 @param font font to compare 84 @return true if SkFont pair are equivalent 85 */ 86 bool operator==(const SkFont& font) const; 87 88 /** Compares SkFont and font, and returns true if they are not equivalent. 89 May return true if SkTypeface has identical contents but different pointers. 90 91 @param font font to compare 92 @return true if SkFont pair are not equivalent 93 */ 94 bool operator!=(const SkFont& font) const { return !(*this == font); } 95 96 /** If true, instructs the font manager to always hint glyphs. 97 Returned value is only meaningful if platform uses FreeType as the font manager. 98 99 @return true if all glyphs are hinted 100 */ isForceAutoHinting()101 bool isForceAutoHinting() const { return SkToBool(fFlags & kForceAutoHinting_PrivFlag); } 102 103 /** Returns true if font engine may return glyphs from font bitmaps instead of from outlines. 104 105 @return true if glyphs may be font bitmaps 106 */ isEmbeddedBitmaps()107 bool isEmbeddedBitmaps() const { return SkToBool(fFlags & kEmbeddedBitmaps_PrivFlag); } 108 109 /** Returns true if glyphs may be drawn at sub-pixel offsets. 110 111 @return true if glyphs may be drawn at sub-pixel offsets. 112 */ isSubpixel()113 bool isSubpixel() const { return SkToBool(fFlags & kSubpixel_PrivFlag); } 114 115 /** Returns true if font and glyph metrics are requested to be linearly scalable. 116 117 @return true if font and glyph metrics are requested to be linearly scalable. 118 */ isLinearMetrics()119 bool isLinearMetrics() const { return SkToBool(fFlags & kLinearMetrics_PrivFlag); } 120 121 /** Returns true if bold is approximated by increasing the stroke width when creating glyph 122 bitmaps from outlines. 123 124 @return bold is approximated through stroke width 125 */ isEmbolden()126 bool isEmbolden() const { return SkToBool(fFlags & kEmbolden_PrivFlag); } 127 128 /** Returns true if baselines will be snapped to pixel positions when the current transformation 129 matrix is axis aligned. 130 131 @return baselines may be snapped to pixels 132 */ isBaselineSnap()133 bool isBaselineSnap() const { return SkToBool(fFlags & kBaselineSnap_PrivFlag); } 134 135 /** Sets whether to always hint glyphs. 136 If forceAutoHinting is set, instructs the font manager to always hint glyphs. 137 138 Only affects platforms that use FreeType as the font manager. 139 140 @param forceAutoHinting setting to always hint glyphs 141 */ 142 void setForceAutoHinting(bool forceAutoHinting); 143 144 /** Requests, but does not require, to use bitmaps in fonts instead of outlines. 145 146 @param embeddedBitmaps setting to use bitmaps in fonts 147 */ 148 void setEmbeddedBitmaps(bool embeddedBitmaps); 149 150 /** Requests, but does not require, that glyphs respect sub-pixel positioning. 151 152 @param subpixel setting for sub-pixel positioning 153 */ 154 void setSubpixel(bool subpixel); 155 156 /** Requests, but does not require, linearly scalable font and glyph metrics. 157 158 For outline fonts 'true' means font and glyph metrics should ignore hinting and rounding. 159 Note that some bitmap formats may not be able to scale linearly and will ignore this flag. 160 161 @param linearMetrics setting for linearly scalable font and glyph metrics. 162 */ 163 void setLinearMetrics(bool linearMetrics); 164 165 /** Increases stroke width when creating glyph bitmaps to approximate a bold typeface. 166 167 @param embolden setting for bold approximation 168 */ 169 void setEmbolden(bool embolden); 170 171 /** Requests that baselines be snapped to pixels when the current transformation matrix is axis 172 aligned. 173 174 @param baselineSnap setting for baseline snapping to pixels 175 */ 176 void setBaselineSnap(bool baselineSnap); 177 178 /** Whether edge pixels draw opaque or with partial transparency. 179 */ getEdging()180 Edging getEdging() const { return (Edging)fEdging; } 181 182 /** Requests, but does not require, that edge pixels draw opaque or with 183 partial transparency. 184 */ 185 void setEdging(Edging edging); 186 187 /** Sets level of glyph outline adjustment. 188 Does not check for valid values of hintingLevel. 189 */ 190 void setHinting(SkFontHinting hintingLevel); 191 192 /** Returns level of glyph outline adjustment. 193 */ getHinting()194 SkFontHinting getHinting() const { return (SkFontHinting)fHinting; } 195 196 /** Returns a font with the same attributes of this font, but with the specified size. 197 Returns nullptr if size is less than zero, infinite, or NaN. 198 199 @param size typographic height of text 200 @return initialized SkFont 201 */ 202 SkFont makeWithSize(SkScalar size) const; 203 204 /** Does not alter SkTypeface SkRefCnt. 205 206 @return non-null SkTypeface 207 */ getTypeface()208 SkTypeface* getTypeface() const { 209 SkASSERT(fTypeface); 210 return fTypeface.get(); 211 } 212 213 /** Returns text size in points. 214 215 @return typographic height of text 216 */ getSize()217 SkScalar getSize() const { return fSize; } 218 219 /** Returns text scale on x-axis. 220 Default value is 1. 221 222 @return text horizontal scale 223 */ getScaleX()224 SkScalar getScaleX() const { return fScaleX; } 225 226 /** Returns text skew on x-axis. 227 Default value is zero. 228 229 @return additional shear on x-axis relative to y-axis 230 */ getSkewX()231 SkScalar getSkewX() const { return fSkewX; } 232 233 /** Increases SkTypeface SkRefCnt by one. 234 235 @return A non-null SkTypeface. 236 */ refTypeface()237 sk_sp<SkTypeface> refTypeface() const { 238 SkASSERT(fTypeface); 239 return fTypeface; 240 } 241 242 /** Sets SkTypeface to typeface, decreasing SkRefCnt of the previous SkTypeface. 243 Pass nullptr to clear SkTypeface and use an empty typeface (which draws nothing). 244 Increments tf SkRefCnt by one. 245 246 @param tf font and style used to draw text 247 */ 248 void setTypeface(sk_sp<SkTypeface> 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 the sum of the default advance widths 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 the sum of the default advance widths 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 using sk_is_trivially_relocatable = std::true_type; 502 503 private: 504 enum PrivFlags { 505 kForceAutoHinting_PrivFlag = 1 << 0, 506 kEmbeddedBitmaps_PrivFlag = 1 << 1, 507 kSubpixel_PrivFlag = 1 << 2, 508 kLinearMetrics_PrivFlag = 1 << 3, 509 kEmbolden_PrivFlag = 1 << 4, 510 kBaselineSnap_PrivFlag = 1 << 5, 511 }; 512 513 static constexpr unsigned kAllFlags = kForceAutoHinting_PrivFlag 514 | kEmbeddedBitmaps_PrivFlag 515 | kSubpixel_PrivFlag 516 | kLinearMetrics_PrivFlag 517 | kEmbolden_PrivFlag 518 | kBaselineSnap_PrivFlag; 519 520 sk_sp<SkTypeface> fTypeface; 521 SkScalar fSize; 522 SkScalar fScaleX; 523 SkScalar fSkewX; 524 uint8_t fFlags; 525 uint8_t fEdging; 526 uint8_t fHinting; 527 528 static_assert(::sk_is_trivially_relocatable<decltype(fTypeface)>::value); 529 530 SkScalar setupForAsPaths(SkPaint*); 531 bool hasSomeAntiAliasing() const; 532 533 friend class SkFontPriv; 534 friend class SkGlyphRunListPainterCPU; 535 friend class SkStrikeSpec; 536 friend class SkRemoteGlyphCacheTest; 537 }; 538 539 #endif 540