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 #include "SkDraw.h" 9 #include "SkFontPriv.h" 10 #include "SkPaint.h" 11 #include "SkPaintDefaults.h" 12 #include "SkPath.h" 13 #include "SkScalerContext.h" 14 #include "SkStrike.h" 15 #include "SkStrikeCache.h" 16 #include "SkTo.h" 17 #include "SkTLazy.h" 18 #include "SkTypeface.h" 19 #include "SkUTF.h" 20 #include "SkUtils.h" 21 22 #define kDefault_Size SkPaintDefaults_TextSize 23 #define kDefault_Flags 0 24 #define kDefault_Edging SkFont::Edging::kAntiAlias 25 #define kDefault_Hinting SkPaintDefaults_Hinting 26 27 static inline SkScalar valid_size(SkScalar size) { 28 return SkTMax<SkScalar>(0, size); 29 } 30 31 SkFont::SkFont(sk_sp<SkTypeface> face, SkScalar size, SkScalar scaleX, SkScalar skewX) 32 : fTypeface(std::move(face)) 33 , fSize(valid_size(size)) 34 , fScaleX(scaleX) 35 , fSkewX(skewX) 36 , fFlags(kDefault_Flags) 37 , fEdging(static_cast<unsigned>(kDefault_Edging)) 38 , fHinting(static_cast<unsigned>(kDefault_Hinting)) 39 {} 40 41 SkFont::SkFont(sk_sp<SkTypeface> face, SkScalar size) : SkFont(std::move(face), size, 1, 0) {} 42 43 SkFont::SkFont(sk_sp<SkTypeface> face) : SkFont(std::move(face), kDefault_Size, 1, 0) {} 44 45 SkFont::SkFont() : SkFont(nullptr, kDefault_Size) {} 46 47 bool SkFont::operator==(const SkFont& b) const { 48 return fTypeface.get() == b.fTypeface.get() && 49 fSize == b.fSize && 50 fScaleX == b.fScaleX && 51 fSkewX == b.fSkewX && 52 fFlags == b.fFlags && 53 fEdging == b.fEdging && 54 fHinting == b.fHinting; 55 } 56 57 void SkFont::dump() const { 58 SkDebugf("typeface %p\n", fTypeface.get()); 59 SkDebugf("size %g\n", fSize); 60 SkDebugf("skewx %g\n", fSkewX); 61 SkDebugf("scalex %g\n", fScaleX); 62 SkDebugf("flags 0x%X\n", fFlags); 63 SkDebugf("edging %d\n", (unsigned)fEdging); 64 SkDebugf("hinting %d\n", (unsigned)fHinting); 65 } 66 67 /////////////////////////////////////////////////////////////////////////////////////////////////// 68 69 static inline uint32_t set_clear_mask(uint32_t bits, bool cond, uint32_t mask) { 70 return cond ? bits | mask : bits & ~mask; 71 } 72 73 void SkFont::setForceAutoHinting(bool predicate) { 74 fFlags = set_clear_mask(fFlags, predicate, kForceAutoHinting_PrivFlag); 75 } 76 void SkFont::setEmbeddedBitmaps(bool predicate) { 77 fFlags = set_clear_mask(fFlags, predicate, kEmbeddedBitmaps_PrivFlag); 78 } 79 void SkFont::setSubpixel(bool predicate) { 80 fFlags = set_clear_mask(fFlags, predicate, kSubpixel_PrivFlag); 81 } 82 void SkFont::setLinearMetrics(bool predicate) { 83 fFlags = set_clear_mask(fFlags, predicate, kLinearMetrics_PrivFlag); 84 } 85 void SkFont::setEmbolden(bool predicate) { 86 fFlags = set_clear_mask(fFlags, predicate, kEmbolden_PrivFlag); 87 } 88 89 void SkFont::setEdging(Edging e) { 90 fEdging = SkToU8(e); 91 } 92 93 void SkFont::setHinting(SkFontHinting h) { 94 fHinting = SkToU8(h); 95 } 96 97 void SkFont::setSize(SkScalar size) { 98 fSize = valid_size(size); 99 } 100 void SkFont::setScaleX(SkScalar scale) { 101 fScaleX = scale; 102 } 103 void SkFont::setSkewX(SkScalar skew) { 104 fSkewX = skew; 105 } 106 107 SkFont SkFont::makeWithSize(SkScalar newSize) const { 108 SkFont font = *this; 109 font.setSize(newSize); 110 return font; 111 } 112 113 /////////////////////////////////////////////////////////////////////////////////////////////////// 114 115 SkScalar SkFont::setupForAsPaths(SkPaint* paint) { 116 constexpr uint32_t flagsToIgnore = kLinearMetrics_PrivFlag | 117 kEmbeddedBitmaps_PrivFlag | 118 kForceAutoHinting_PrivFlag; 119 120 fFlags = (fFlags & ~flagsToIgnore) | kSubpixel_PrivFlag; 121 this->setHinting(kNo_SkFontHinting); 122 123 if (this->getEdging() == Edging::kSubpixelAntiAlias) { 124 this->setEdging(Edging::kAntiAlias); 125 } 126 127 if (paint) { 128 paint->setStyle(SkPaint::kFill_Style); 129 paint->setPathEffect(nullptr); 130 } 131 SkScalar textSize = fSize; 132 this->setSize(SkIntToScalar(SkFontPriv::kCanonicalTextSizeForPaths)); 133 return textSize / SkFontPriv::kCanonicalTextSizeForPaths; 134 } 135 136 bool SkFont::hasSomeAntiAliasing() const { 137 Edging edging = this->getEdging(); 138 return edging == SkFont::Edging::kAntiAlias 139 || edging == SkFont::Edging::kSubpixelAntiAlias; 140 } 141 142 class SkCanonicalizeFont { 143 public: 144 SkCanonicalizeFont(const SkFont& font, const SkPaint* paint) : fFont(&font) { 145 if (paint) { 146 fPaint = *paint; 147 } 148 if (font.isLinearMetrics() || 149 SkDraw::ShouldDrawTextAsPaths(font, fPaint, SkMatrix::I())) 150 { 151 SkFont* f = fLazyFont.set(font); 152 fScale = f->setupForAsPaths(nullptr); 153 fFont = f; 154 fPaint.reset(); 155 } 156 } 157 158 const SkFont& getFont() const { return *fFont; } 159 const SkPaint& getPaint() const { return fPaint; } 160 SkScalar getScale() const { return fScale; } 161 162 private: 163 const SkFont* fFont; 164 SkTLazy<SkFont> fLazyFont; 165 SkPaint fPaint; 166 SkScalar fScale = 0; 167 }; 168 169 SkGlyphID SkFont::unicharToGlyph(SkUnichar uni) const { 170 return this->getTypefaceOrDefault()->unicharToGlyph(uni); 171 } 172 173 int SkFont::textToGlyphs(const void* text, size_t byteLength, SkTextEncoding encoding, 174 uint16_t glyphs[], int maxGlyphCount) const { 175 if (0 == byteLength) { 176 return 0; 177 } 178 179 SkASSERT(text); 180 181 int count = SkFontPriv::CountTextElements(text, byteLength, encoding); 182 if (!glyphs || count > maxGlyphCount) { 183 return count; 184 } 185 186 // TODO: unify/eliminate SkTypeface::Encoding with SkTextEncoding 187 SkTypeface::Encoding typefaceEncoding; 188 switch (encoding) { 189 case kUTF8_SkTextEncoding: 190 typefaceEncoding = SkTypeface::kUTF8_Encoding; 191 break; 192 case kUTF16_SkTextEncoding: 193 typefaceEncoding = SkTypeface::kUTF16_Encoding; 194 break; 195 case kUTF32_SkTextEncoding: 196 typefaceEncoding = SkTypeface::kUTF32_Encoding; 197 break; 198 default: 199 SkASSERT(kGlyphID_SkTextEncoding == encoding); 200 // we can early exit, since we already have glyphIDs 201 memcpy(glyphs, text, count << 1); 202 return count; 203 } 204 205 (void) this->getTypefaceOrDefault()->charsToGlyphs(text, typefaceEncoding, glyphs,count); 206 return count; 207 } 208 209 void SkFont::glyphsToUnichars(const SkGlyphID glyphs[], int count, SkUnichar text[]) const { 210 if (count <= 0) { 211 return; 212 } 213 214 auto typeface = this->getTypefaceOrDefault(); 215 const unsigned numGlyphsInTypeface = typeface->countGlyphs(); 216 SkAutoTArray<SkUnichar> unichars(numGlyphsInTypeface); 217 typeface->getGlyphToUnicodeMap(unichars.get()); 218 219 for (int i = 0; i < count; ++i) { 220 unsigned id = glyphs[i]; 221 text[i] = (id < numGlyphsInTypeface) ? unichars[id] : 0xFFFD; 222 } 223 } 224 225 static void set_bounds(const SkGlyph& g, SkRect* bounds) { 226 bounds->set(SkIntToScalar(g.fLeft), 227 SkIntToScalar(g.fTop), 228 SkIntToScalar(g.fLeft + g.fWidth), 229 SkIntToScalar(g.fTop + g.fHeight)); 230 } 231 232 static void join_bounds_x(const SkGlyph& g, SkRect* bounds, SkScalar dx) { 233 bounds->join(SkIntToScalar(g.fLeft) + dx, 234 SkIntToScalar(g.fTop), 235 SkIntToScalar(g.fLeft + g.fWidth) + dx, 236 SkIntToScalar(g.fTop + g.fHeight)); 237 } 238 239 SkScalar SkFont::measureText(const void* text, size_t length, SkTextEncoding encoding, 240 SkRect* bounds, const SkPaint* paint) const { 241 SkCanonicalizeFont canon(*this, paint); 242 const SkFont& font = canon.getFont(); 243 const SkScalar scale = canon.getScale(); 244 245 SkAutoToGlyphs atg(font, text, length, encoding); 246 const int count = atg.count(); 247 if (count == 0) { 248 if (bounds) { 249 bounds->setEmpty(); 250 } 251 return 0; 252 } 253 const uint16_t* glyphs = atg.glyphs(); 254 255 auto cache = SkStrikeCache::FindOrCreateStrikeWithNoDeviceExclusive(font, canon.getPaint()); 256 257 SkScalar width = 0; 258 if (bounds) { 259 const SkGlyph* g = &cache->getGlyphIDMetrics(glyphs[0]); 260 set_bounds(*g, bounds); 261 width = g->fAdvanceX; 262 for (int i = 1; i < count; ++i) { 263 g = &cache->getGlyphIDMetrics(glyphs[i]); 264 join_bounds_x(*g, bounds, width); 265 width += g->fAdvanceX; 266 } 267 } else { 268 for (int i = 0; i < count; ++i) { 269 width += cache->getGlyphIDAdvance(glyphs[i]).fAdvanceX; 270 } 271 } 272 273 if (scale) { 274 width *= scale; 275 if (bounds) { 276 bounds->fLeft *= scale; 277 bounds->fTop *= scale; 278 bounds->fRight *= scale; 279 bounds->fBottom *= scale; 280 } 281 } 282 283 return width; 284 } 285 286 static SkRect make_bounds(const SkGlyph& g, SkScalar scale) { 287 return { 288 g.fLeft * scale, 289 g.fTop * scale, 290 (g.fLeft + g.fWidth) * scale, 291 (g.fTop + g.fHeight) * scale 292 }; 293 } 294 295 template <typename HANDLER> 296 void VisitGlyphs(const SkFont& origFont, const SkPaint* paint, const uint16_t glyphs[], int count, 297 HANDLER handler) { 298 if (count <= 0) { 299 return; 300 } 301 302 SkCanonicalizeFont canon(origFont, paint); 303 const SkFont& font = canon.getFont(); 304 SkScalar scale = canon.getScale(); 305 if (!scale) { 306 scale = 1; 307 } 308 309 auto cache = SkStrikeCache::FindOrCreateStrikeWithNoDeviceExclusive(font, canon.getPaint()); 310 handler(cache.get(), glyphs, count, scale); 311 } 312 313 void SkFont::getWidthsBounds(const uint16_t glyphs[], int count, SkScalar widths[], SkRect bounds[], 314 const SkPaint* paint) const { 315 VisitGlyphs(*this, paint, glyphs, count, [widths, bounds] 316 (SkStrike* cache, const uint16_t glyphs[], int count, SkScalar scale) { 317 for (int i = 0; i < count; ++i) { 318 const SkGlyph* g; 319 if (bounds) { 320 g = &cache->getGlyphIDMetrics(glyphs[i]); 321 bounds[i] = make_bounds(*g, scale); 322 } else { 323 g = &cache->getGlyphIDAdvance(glyphs[i]); 324 } 325 if (widths) { 326 widths[i] = g->fAdvanceX * scale; 327 } 328 } 329 }); 330 } 331 332 void SkFont::getPos(const uint16_t glyphs[], int count, SkPoint pos[], SkPoint origin) const { 333 VisitGlyphs(*this, nullptr, glyphs, count, [pos, origin] 334 (SkStrike* cache, const uint16_t glyphs[], int count, SkScalar scale) { 335 SkPoint loc = origin; 336 for (int i = 0; i < count; ++i) { 337 pos[i] = loc; 338 loc.fX += cache->getGlyphIDAdvance(glyphs[i]).fAdvanceX * scale; 339 } 340 }); 341 } 342 343 void SkFont::getXPos(const uint16_t glyphs[], int count, SkScalar xpos[], SkScalar origin) const { 344 VisitGlyphs(*this, nullptr, glyphs, count, [xpos, origin] 345 (SkStrike* cache, const uint16_t glyphs[], int count, SkScalar scale) { 346 SkScalar x = origin; 347 for (int i = 0; i < count; ++i) { 348 xpos[i] = x; 349 x += cache->getGlyphIDAdvance(glyphs[i]).fAdvanceX * scale; 350 } 351 }); 352 } 353 354 void SkFont::getPaths(const uint16_t glyphs[], int count, 355 void (*proc)(const SkPath*, const SkMatrix&, void*), void* ctx) const { 356 SkFont font(*this); 357 SkScalar scale = font.setupForAsPaths(nullptr); 358 if (!scale) { 359 scale = 1; 360 } 361 const SkMatrix mx = SkMatrix::MakeScale(scale, scale); 362 363 auto exclusive = SkStrikeCache::FindOrCreateStrikeWithNoDeviceExclusive(font); 364 auto cache = exclusive.get(); 365 366 for (int i = 0; i < count; ++i) { 367 proc(cache->findPath(cache->getGlyphIDMetrics(glyphs[i])), mx, ctx); 368 } 369 } 370 371 bool SkFont::getPath(uint16_t glyphID, SkPath* path) const { 372 struct Pair { 373 SkPath* fPath; 374 bool fWasSet; 375 } pair = { path, false }; 376 377 this->getPaths(&glyphID, 1, [](const SkPath* orig, const SkMatrix& mx, void* ctx) { 378 Pair* pair = static_cast<Pair*>(ctx); 379 if (orig) { 380 orig->transform(mx, pair->fPath); 381 pair->fWasSet = true; 382 } 383 }, &pair); 384 return pair.fWasSet; 385 } 386 387 SkScalar SkFont::getMetrics(SkFontMetrics* metrics) const { 388 SkCanonicalizeFont canon(*this, nullptr); 389 const SkFont& font = canon.getFont(); 390 SkScalar scale = canon.getScale(); 391 392 SkFontMetrics storage; 393 if (nullptr == metrics) { 394 metrics = &storage; 395 } 396 397 auto cache = SkStrikeCache::FindOrCreateStrikeWithNoDeviceExclusive(font); 398 *metrics = cache->getFontMetrics(); 399 400 if (scale) { 401 SkFontPriv::ScaleFontMetrics(metrics, scale); 402 } 403 return metrics->fDescent - metrics->fAscent + metrics->fLeading; 404 } 405 406 SkTypeface* SkFont::getTypefaceOrDefault() const { 407 return fTypeface ? fTypeface.get() : SkTypeface::GetDefaultTypeface(); 408 } 409 410 sk_sp<SkTypeface> SkFont::refTypefaceOrDefault() const { 411 return fTypeface ? fTypeface : SkTypeface::MakeDefault(); 412 } 413 414 ////////////////////////////////////////////////////////////////////////////////////////////////// 415 416 int SkFontPriv::ValidCountText(const void* text, size_t length, SkTextEncoding encoding) { 417 switch (encoding) { 418 case kUTF8_SkTextEncoding: return SkUTF::CountUTF8((const char*)text, length); 419 case kUTF16_SkTextEncoding: return SkUTF::CountUTF16((const uint16_t*)text, length); 420 case kUTF32_SkTextEncoding: return SkUTF::CountUTF32((const int32_t*)text, length); 421 case kGlyphID_SkTextEncoding: 422 if (!SkIsAlign2(intptr_t(text)) || !SkIsAlign2(length)) { 423 return -1; 424 } 425 return length >> 1; 426 } 427 return -1; 428 } 429 430 void SkFontPriv::ScaleFontMetrics(SkFontMetrics* metrics, SkScalar scale) { 431 metrics->fTop *= scale; 432 metrics->fAscent *= scale; 433 metrics->fDescent *= scale; 434 metrics->fBottom *= scale; 435 metrics->fLeading *= scale; 436 metrics->fAvgCharWidth *= scale; 437 metrics->fMaxCharWidth *= scale; 438 metrics->fXMin *= scale; 439 metrics->fXMax *= scale; 440 metrics->fXHeight *= scale; 441 metrics->fCapHeight *= scale; 442 metrics->fUnderlineThickness *= scale; 443 metrics->fUnderlinePosition *= scale; 444 metrics->fStrikeoutThickness *= scale; 445 metrics->fStrikeoutPosition *= scale; 446 } 447 448 SkRect SkFontPriv::GetFontBounds(const SkFont& font) { 449 SkMatrix m; 450 m.setScale(font.getSize() * font.getScaleX(), font.getSize()); 451 m.postSkew(font.getSkewX(), 0); 452 453 SkTypeface* typeface = font.getTypefaceOrDefault(); 454 455 SkRect bounds; 456 m.mapRect(&bounds, typeface->getBounds()); 457 return bounds; 458 } 459 460 int SkFontPriv::CountTextElements(const void* text, size_t byteLength, SkTextEncoding encoding) { 461 switch (encoding) { 462 case kUTF8_SkTextEncoding: 463 return SkUTF::CountUTF8(reinterpret_cast<const char*>(text), byteLength); 464 case kUTF16_SkTextEncoding: 465 return SkUTF::CountUTF16(reinterpret_cast<const uint16_t*>(text), byteLength); 466 case kUTF32_SkTextEncoding: 467 return byteLength >> 2; 468 case kGlyphID_SkTextEncoding: 469 return byteLength >> 1; 470 } 471 SkASSERT(false); 472 return 0; 473 } 474 475 void SkFontPriv::GlyphsToUnichars(const SkFont& font, const uint16_t glyphs[], int count, 476 SkUnichar uni[]) { 477 font.glyphsToUnichars(glyphs, count, uni); 478 } 479 480 /////////////////////////////////////////////////////////////////////////////////////////////////// 481 #include "SkReadBuffer.h" 482 #include "SkWriteBuffer.h" 483 484 // packed int at the beginning of the serialized font: 485 // 486 // control_bits:8 size_as_byte:8 flags:12 edging:2 hinting:2 487 488 enum { 489 kSize_Is_Byte_Bit = 1 << 31, 490 kHas_ScaleX_Bit = 1 << 30, 491 kHas_SkewX_Bit = 1 << 29, 492 kHas_Typeface_Bit = 1 << 28, 493 494 kShift_for_Size = 16, 495 kMask_For_Size = 0xFF, 496 497 kShift_For_Flags = 4, 498 kMask_For_Flags = 0xFFF, 499 500 kShift_For_Edging = 2, 501 kMask_For_Edging = 0x3, 502 503 kShift_For_Hinting = 0, 504 kMask_For_Hinting = 0x3 505 }; 506 507 static bool scalar_is_byte(SkScalar x) { 508 int ix = (int)x; 509 return ix == x && ix >= 0 && ix <= kMask_For_Size; 510 } 511 512 void SkFontPriv::Flatten(const SkFont& font, SkWriteBuffer& buffer) { 513 SkASSERT((font.fFlags & ~kMask_For_Flags) == 0); 514 SkASSERT((font.fEdging & ~kMask_For_Edging) == 0); 515 SkASSERT((font.fHinting & ~kMask_For_Hinting) == 0); 516 517 uint32_t packed = 0; 518 packed |= font.fFlags << kShift_For_Flags; 519 packed |= font.fEdging << kShift_For_Edging; 520 packed |= font.fHinting << kShift_For_Hinting; 521 522 if (scalar_is_byte(font.fSize)) { 523 packed |= kSize_Is_Byte_Bit; 524 packed |= (int)font.fSize << kShift_for_Size; 525 } 526 if (font.fScaleX != 1) { 527 packed |= kHas_ScaleX_Bit; 528 } 529 if (font.fSkewX != 0) { 530 packed |= kHas_SkewX_Bit; 531 } 532 if (font.fTypeface) { 533 packed |= kHas_Typeface_Bit; 534 } 535 536 buffer.write32(packed); 537 if (!(packed & kSize_Is_Byte_Bit)) { 538 buffer.writeScalar(font.fSize); 539 } 540 if (packed & kHas_ScaleX_Bit) { 541 buffer.writeScalar(font.fScaleX); 542 } 543 if (packed & kHas_SkewX_Bit) { 544 buffer.writeScalar(font.fSkewX); 545 } 546 if (packed & kHas_Typeface_Bit) { 547 buffer.writeTypeface(font.fTypeface.get()); 548 } 549 } 550 551 bool SkFontPriv::Unflatten(SkFont* font, SkReadBuffer& buffer) { 552 const uint32_t packed = buffer.read32(); 553 554 if (packed & kSize_Is_Byte_Bit) { 555 font->fSize = (packed >> kShift_for_Size) & kMask_For_Size; 556 } else { 557 font->fSize = buffer.readScalar(); 558 } 559 if (packed & kHas_ScaleX_Bit) { 560 font->fScaleX = buffer.readScalar(); 561 } 562 if (packed & kHas_SkewX_Bit) { 563 font->fSkewX = buffer.readScalar(); 564 } 565 if (packed & kHas_Typeface_Bit) { 566 font->fTypeface = buffer.readTypeface(); 567 } 568 569 SkASSERT(SkFont::kAllFlags <= kMask_For_Flags); 570 // we & with kAllFlags, to clear out any unknown flag bits 571 font->fFlags = SkToU8((packed >> kShift_For_Flags) & SkFont::kAllFlags); 572 573 unsigned edging = (packed >> kShift_For_Edging) & kMask_For_Edging; 574 if (edging > (unsigned)SkFont::Edging::kSubpixelAntiAlias) { 575 edging = 0; 576 } 577 font->fEdging = SkToU8(edging); 578 579 unsigned hinting = (packed >> kShift_For_Hinting) & kMask_For_Hinting; 580 if (hinting > (unsigned)kFull_SkFontHinting) { 581 hinting = 0; 582 } 583 font->fHinting = SkToU8(hinting); 584 585 return buffer.isValid(); 586 } 587