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 /** Returns true if baselines will be snapped to pixel positions when the current transformation 117 matrix is axis aligned. 118 119 @return baselines may be snapped to pixels 120 */ isBaselineSnap()121 bool isBaselineSnap() const { return SkToBool(fFlags & kBaselineSnap_PrivFlag); } 122 123 /** Sets whether to always hint glyphs. 124 If forceAutoHinting is set, instructs the font manager to always hint glyphs. 125 126 Only affects platforms that use FreeType as the font manager. 127 128 @param forceAutoHinting setting to always hint glyphs 129 */ 130 void setForceAutoHinting(bool forceAutoHinting); 131 132 /** Requests, but does not require, to use bitmaps in fonts instead of outlines. 133 134 @param embeddedBitmaps setting to use bitmaps in fonts 135 */ 136 void setEmbeddedBitmaps(bool embeddedBitmaps); 137 138 /** Requests, but does not require, that glyphs respect sub-pixel positioning. 139 140 @param subpixel setting for sub-pixel positioning 141 */ 142 void setSubpixel(bool subpixel); 143 144 /** Requests, but does not require, linearly scalable font and glyph metrics. 145 146 For outline fonts 'true' means font and glyph metrics should ignore hinting and rounding. 147 Note that some bitmap formats may not be able to scale linearly and will ignore this flag. 148 149 @param linearMetrics setting for linearly scalable font and glyph metrics. 150 */ 151 void setLinearMetrics(bool linearMetrics); 152 153 /** Increases stroke width when creating glyph bitmaps to approximate a bold typeface. 154 155 @param embolden setting for bold approximation 156 */ 157 void setEmbolden(bool embolden); 158 159 /** Requests that baselines be snapped to pixels when the current transformation matrix is axis 160 aligned. 161 162 @param baselineSnap setting for baseline snapping to pixels 163 */ 164 void setBaselineSnap(bool baselineSnap); 165 166 /** Whether edge pixels draw opaque or with partial transparency. 167 */ getEdging()168 Edging getEdging() const { return (Edging)fEdging; } 169 170 /** Requests, but does not require, that edge pixels draw opaque or with 171 partial transparency. 172 */ 173 void setEdging(Edging edging); 174 175 /** Sets level of glyph outline adjustment. 176 Does not check for valid values of hintingLevel. 177 */ 178 void setHinting(SkFontHinting hintingLevel); 179 180 /** Returns level of glyph outline adjustment. 181 */ getHinting()182 SkFontHinting getHinting() const { return (SkFontHinting)fHinting; } 183 184 /** Returns a font with the same attributes of this font, but with the specified size. 185 Returns nullptr if size is less than zero, infinite, or NaN. 186 187 @param size typographic height of text 188 @return initialized SkFont 189 */ 190 SkFont makeWithSize(SkScalar size) const; 191 192 /** Returns SkTypeface if set, or nullptr. 193 Does not alter SkTypeface SkRefCnt. 194 195 @return SkTypeface if previously set, nullptr otherwise 196 */ getTypeface()197 SkTypeface* getTypeface() const {return fTypeface.get(); } 198 199 /** Returns SkTypeface if set, or the default typeface. 200 Does not alter SkTypeface SkRefCnt. 201 202 @return SkTypeface if previously set or, a pointer to the default typeface if not 203 previously set. 204 */ 205 SkTypeface* getTypefaceOrDefault() const; 206 207 /** Returns text size in points. 208 209 @return typographic height of text 210 */ getSize()211 SkScalar getSize() const { return fSize; } 212 213 /** Returns text scale on x-axis. 214 Default value is 1. 215 216 @return text horizontal scale 217 */ getScaleX()218 SkScalar getScaleX() const { return fScaleX; } 219 220 /** Returns text skew on x-axis. 221 Default value is zero. 222 223 @return additional shear on x-axis relative to y-axis 224 */ getSkewX()225 SkScalar getSkewX() const { return fSkewX; } 226 227 /** Increases SkTypeface SkRefCnt by one. 228 229 @return SkTypeface if previously set, nullptr otherwise 230 */ refTypeface()231 sk_sp<SkTypeface> refTypeface() const { return fTypeface; } 232 233 /** Increases SkTypeface SkRefCnt by one. 234 235 @return SkTypeface if previously set or, a pointer to the default typeface if not 236 previously set. 237 */ 238 sk_sp<SkTypeface> refTypefaceOrDefault() const; 239 240 /** Sets SkTypeface to typeface, decreasing SkRefCnt of the previous SkTypeface. 241 Pass nullptr to clear SkTypeface and use the default typeface. Increments 242 tf SkRefCnt by one. 243 244 @param tf font and style used to draw text 245 */ setTypeface(sk_sp<SkTypeface> tf)246 void setTypeface(sk_sp<SkTypeface> tf) { fTypeface = tf; } 247 248 /** Sets text size in points. 249 Has no effect if textSize is not greater than or equal to zero. 250 251 @param textSize typographic height of text 252 */ 253 void setSize(SkScalar textSize); 254 255 /** Sets text scale on x-axis. 256 Default value is 1. 257 258 @param scaleX text horizontal scale 259 */ 260 void setScaleX(SkScalar scaleX); 261 262 /** Sets text skew on x-axis. 263 Default value is zero. 264 265 @param skewX additional shear on x-axis relative to y-axis 266 */ 267 void setSkewX(SkScalar skewX); 268 269 /** Converts text into glyph indices. 270 Returns the number of glyph indices represented by text. 271 SkTextEncoding specifies how text represents characters or glyphs. 272 glyphs may be nullptr, to compute the glyph count. 273 274 Does not check text for valid character codes or valid glyph indices. 275 276 If byteLength equals zero, returns zero. 277 If byteLength includes a partial character, the partial character is ignored. 278 279 If encoding is SkTextEncoding::kUTF8 and text contains an invalid UTF-8 sequence, 280 zero is returned. 281 282 When encoding is SkTextEncoding::kUTF8, SkTextEncoding::kUTF16, or 283 SkTextEncoding::kUTF32; then each Unicode codepoint is mapped to a 284 single glyph. This function uses the default character-to-glyph 285 mapping from the SkTypeface and maps characters not found in the 286 SkTypeface to zero. 287 288 If maxGlyphCount is not sufficient to store all the glyphs, no glyphs are copied. 289 The total glyph count is returned for subsequent buffer reallocation. 290 291 @param text character storage encoded with SkTextEncoding 292 @param byteLength length of character storage in bytes 293 @param glyphs storage for glyph indices; may be nullptr 294 @param maxGlyphCount storage capacity 295 @return number of glyphs represented by text of length byteLength 296 */ 297 int textToGlyphs(const void* text, size_t byteLength, SkTextEncoding encoding, 298 SkGlyphID glyphs[], int maxGlyphCount) const; 299 300 /** Returns glyph index for Unicode character. 301 302 If the character is not supported by the SkTypeface, returns 0. 303 304 @param uni Unicode character 305 @return glyph index 306 */ 307 SkGlyphID unicharToGlyph(SkUnichar uni) const; 308 309 void unicharsToGlyphs(const SkUnichar uni[], int count, SkGlyphID glyphs[]) const; 310 311 /** Returns number of glyphs represented by text. 312 313 If encoding is SkTextEncoding::kUTF8, SkTextEncoding::kUTF16, or 314 SkTextEncoding::kUTF32; then each Unicode codepoint is mapped to a 315 single glyph. 316 317 @param text character storage encoded with SkTextEncoding 318 @param byteLength length of character storage in bytes 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 bounds returns bounding box relative to (0, 0) if not nullptr 332 @return number of glyphs represented by text of length byteLength 333 */ 334 SkScalar measureText(const void* text, size_t byteLength, SkTextEncoding encoding, 335 SkRect* bounds = nullptr) const { 336 return this->measureText(text, byteLength, encoding, bounds, nullptr); 337 } 338 339 /** Returns the advance width of text. 340 The advance is the normal distance to move before drawing additional text. 341 Returns the bounding box of text if bounds is not nullptr. The paint 342 stroke settings, mask filter, or path effect may modify the bounds. 343 344 @param text character storage encoded with SkTextEncoding 345 @param byteLength length of character storage in bytes 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 SkGlyphID glyphs[],int count,SkScalar widths[],SkRect bounds[])364 void getWidths(const SkGlyphID glyphs[], int count, SkScalar widths[], SkRect bounds[]) const { 365 this->getWidthsBounds(glyphs, count, widths, bounds, nullptr); 366 } 367 368 // DEPRECATED getWidths(const SkGlyphID glyphs[],int count,SkScalar widths[],std::nullptr_t)369 void getWidths(const SkGlyphID 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 SkGlyphID glyphs[],int count,SkScalar widths[])382 void getWidths(const SkGlyphID 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 SkGlyphID 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 SkGlyphID glyphs[],int count,SkRect bounds[],const SkPaint * paint)410 void getBounds(const SkGlyphID 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 SkGlyphID 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 SkGlyphID glyphs[], int count, SkScalar xpos[], SkScalar origin = 0) const; 434 435 /** Modifies path to be the outline of the glyph. 436 If the glyph has an outline, modifies path to be the glyph's outline and returns true. 437 The glyph outline may be empty. Degenerate contours in the glyph outline will be skipped. 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(SkGlyphID 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 SkGlyphID 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 /** Dumps fields of the font to SkDebugf. May change its output over time, so clients should 481 * not rely on this for anything specific. Used to aid in debugging. 482 */ 483 void dump() const; 484 485 private: 486 enum PrivFlags { 487 kForceAutoHinting_PrivFlag = 1 << 0, 488 kEmbeddedBitmaps_PrivFlag = 1 << 1, 489 kSubpixel_PrivFlag = 1 << 2, 490 kLinearMetrics_PrivFlag = 1 << 3, 491 kEmbolden_PrivFlag = 1 << 4, 492 kBaselineSnap_PrivFlag = 1 << 5, 493 }; 494 495 static constexpr unsigned kAllFlags = kForceAutoHinting_PrivFlag 496 | kEmbeddedBitmaps_PrivFlag 497 | kSubpixel_PrivFlag 498 | kLinearMetrics_PrivFlag 499 | kEmbolden_PrivFlag 500 | kBaselineSnap_PrivFlag; 501 502 sk_sp<SkTypeface> fTypeface; 503 SkScalar fSize; 504 SkScalar fScaleX; 505 SkScalar fSkewX; 506 uint8_t fFlags; 507 uint8_t fEdging; 508 uint8_t fHinting; 509 510 SkScalar setupForAsPaths(SkPaint*); 511 bool hasSomeAntiAliasing() const; 512 513 friend class SkFontPriv; 514 friend class SkGlyphRunListPainter; 515 friend class SkStrikeSpec; 516 }; 517 518 #endif 519