SkFont.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540
  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. #include "include/core/SkPaint.h"
  8. #include "include/core/SkPath.h"
  9. #include "include/core/SkTypeface.h"
  10. #include "include/private/SkTemplates.h"
  11. #include "include/private/SkTo.h"
  12. #include "src/core/SkDraw.h"
  13. #include "src/core/SkFontPriv.h"
  14. #include "src/core/SkPaintDefaults.h"
  15. #include "src/core/SkScalerContext.h"
  16. #include "src/core/SkStrike.h"
  17. #include "src/core/SkStrikeCache.h"
  18. #include "src/core/SkStrikeSpec.h"
  19. #include "src/core/SkTLazy.h"
  20. #include "src/core/SkUtils.h"
  21. #include "src/utils/SkUTF.h"
  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. static inline SkScalar valid_size(SkScalar size) {
  27. return SkTMax<SkScalar>(0, size);
  28. }
  29. SkFont::SkFont(sk_sp<SkTypeface> face, SkScalar size, SkScalar scaleX, SkScalar skewX)
  30. : fTypeface(std::move(face))
  31. , fSize(valid_size(size))
  32. , fScaleX(scaleX)
  33. , fSkewX(skewX)
  34. , fFlags(kDefault_Flags)
  35. , fEdging(static_cast<unsigned>(kDefault_Edging))
  36. , fHinting(static_cast<unsigned>(kDefault_Hinting))
  37. {}
  38. SkFont::SkFont(sk_sp<SkTypeface> face, SkScalar size) : SkFont(std::move(face), size, 1, 0) {}
  39. SkFont::SkFont(sk_sp<SkTypeface> face) : SkFont(std::move(face), kDefault_Size, 1, 0) {}
  40. SkFont::SkFont() : SkFont(nullptr, kDefault_Size) {}
  41. bool SkFont::operator==(const SkFont& b) const {
  42. return fTypeface.get() == b.fTypeface.get() &&
  43. fSize == b.fSize &&
  44. fScaleX == b.fScaleX &&
  45. fSkewX == b.fSkewX &&
  46. fFlags == b.fFlags &&
  47. fEdging == b.fEdging &&
  48. fHinting == b.fHinting;
  49. }
  50. void SkFont::dump() const {
  51. SkDebugf("typeface %p\n", fTypeface.get());
  52. SkDebugf("size %g\n", fSize);
  53. SkDebugf("skewx %g\n", fSkewX);
  54. SkDebugf("scalex %g\n", fScaleX);
  55. SkDebugf("flags 0x%X\n", fFlags);
  56. SkDebugf("edging %d\n", (unsigned)fEdging);
  57. SkDebugf("hinting %d\n", (unsigned)fHinting);
  58. }
  59. ///////////////////////////////////////////////////////////////////////////////////////////////////
  60. static inline uint32_t set_clear_mask(uint32_t bits, bool cond, uint32_t mask) {
  61. return cond ? bits | mask : bits & ~mask;
  62. }
  63. void SkFont::setForceAutoHinting(bool predicate) {
  64. fFlags = set_clear_mask(fFlags, predicate, kForceAutoHinting_PrivFlag);
  65. }
  66. void SkFont::setEmbeddedBitmaps(bool predicate) {
  67. fFlags = set_clear_mask(fFlags, predicate, kEmbeddedBitmaps_PrivFlag);
  68. }
  69. void SkFont::setSubpixel(bool predicate) {
  70. fFlags = set_clear_mask(fFlags, predicate, kSubpixel_PrivFlag);
  71. }
  72. void SkFont::setLinearMetrics(bool predicate) {
  73. fFlags = set_clear_mask(fFlags, predicate, kLinearMetrics_PrivFlag);
  74. }
  75. void SkFont::setEmbolden(bool predicate) {
  76. fFlags = set_clear_mask(fFlags, predicate, kEmbolden_PrivFlag);
  77. }
  78. void SkFont::setEdging(Edging e) {
  79. fEdging = SkToU8(e);
  80. }
  81. void SkFont::setHinting(SkFontHinting h) {
  82. fHinting = SkToU8(h);
  83. }
  84. void SkFont::setSize(SkScalar size) {
  85. fSize = valid_size(size);
  86. }
  87. void SkFont::setScaleX(SkScalar scale) {
  88. fScaleX = scale;
  89. }
  90. void SkFont::setSkewX(SkScalar skew) {
  91. fSkewX = skew;
  92. }
  93. SkFont SkFont::makeWithSize(SkScalar newSize) const {
  94. SkFont font = *this;
  95. font.setSize(newSize);
  96. return font;
  97. }
  98. ///////////////////////////////////////////////////////////////////////////////////////////////////
  99. SkScalar SkFont::setupForAsPaths(SkPaint* paint) {
  100. constexpr uint32_t flagsToIgnore = kEmbeddedBitmaps_PrivFlag |
  101. kForceAutoHinting_PrivFlag;
  102. fFlags = (fFlags & ~flagsToIgnore) | kSubpixel_PrivFlag;
  103. this->setHinting(SkFontHinting::kNone);
  104. if (this->getEdging() == Edging::kSubpixelAntiAlias) {
  105. this->setEdging(Edging::kAntiAlias);
  106. }
  107. if (paint) {
  108. paint->setStyle(SkPaint::kFill_Style);
  109. paint->setPathEffect(nullptr);
  110. }
  111. SkScalar textSize = fSize;
  112. this->setSize(SkIntToScalar(SkFontPriv::kCanonicalTextSizeForPaths));
  113. return textSize / SkFontPriv::kCanonicalTextSizeForPaths;
  114. }
  115. bool SkFont::hasSomeAntiAliasing() const {
  116. Edging edging = this->getEdging();
  117. return edging == SkFont::Edging::kAntiAlias
  118. || edging == SkFont::Edging::kSubpixelAntiAlias;
  119. }
  120. SkGlyphID SkFont::unicharToGlyph(SkUnichar uni) const {
  121. return this->getTypefaceOrDefault()->unicharToGlyph(uni);
  122. }
  123. void SkFont::unicharsToGlyphs(const SkUnichar uni[], int count, SkGlyphID glyphs[]) const {
  124. this->getTypefaceOrDefault()->unicharsToGlyphs(uni, count, glyphs);
  125. }
  126. class SkConvertToUTF32 {
  127. public:
  128. SkConvertToUTF32() {}
  129. const SkUnichar* convert(const void* text, size_t byteLength, SkTextEncoding encoding) {
  130. const SkUnichar* uni;
  131. switch (encoding) {
  132. case SkTextEncoding::kUTF8: {
  133. uni = fStorage.reset(byteLength);
  134. const char* ptr = (const char*)text;
  135. const char* end = ptr + byteLength;
  136. for (int i = 0; ptr < end; ++i) {
  137. fStorage[i] = SkUTF::NextUTF8(&ptr, end);
  138. }
  139. } break;
  140. case SkTextEncoding::kUTF16: {
  141. uni = fStorage.reset(byteLength);
  142. const uint16_t* ptr = (const uint16_t*)text;
  143. const uint16_t* end = ptr + (byteLength >> 1);
  144. for (int i = 0; ptr < end; ++i) {
  145. fStorage[i] = SkUTF::NextUTF16(&ptr, end);
  146. }
  147. } break;
  148. case SkTextEncoding::kUTF32:
  149. uni = (const SkUnichar*)text;
  150. break;
  151. default:
  152. SK_ABORT("unexpected enum");
  153. }
  154. return uni;
  155. }
  156. private:
  157. SkAutoSTMalloc<256, SkUnichar> fStorage;
  158. };
  159. int SkFont::textToGlyphs(const void* text, size_t byteLength, SkTextEncoding encoding,
  160. SkGlyphID glyphs[], int maxGlyphCount) const {
  161. if (0 == byteLength) {
  162. return 0;
  163. }
  164. SkASSERT(text);
  165. int count = SkFontPriv::CountTextElements(text, byteLength, encoding);
  166. if (!glyphs || count > maxGlyphCount) {
  167. return count;
  168. }
  169. if (encoding == SkTextEncoding::kGlyphID) {
  170. memcpy(glyphs, text, count << 1);
  171. return count;
  172. }
  173. SkConvertToUTF32 storage;
  174. const SkUnichar* uni = storage.convert(text, byteLength, encoding);
  175. this->getTypefaceOrDefault()->unicharsToGlyphs(uni, count, glyphs);
  176. return count;
  177. }
  178. SkScalar SkFont::measureText(const void* text, size_t length, SkTextEncoding encoding,
  179. SkRect* bounds, const SkPaint* paint) const {
  180. SkAutoToGlyphs atg(*this, text, length, encoding);
  181. const int glyphCount = atg.count();
  182. if (glyphCount == 0) {
  183. if (bounds) {
  184. bounds->setEmpty();
  185. }
  186. return 0;
  187. }
  188. const SkGlyphID* glyphIDs = atg.glyphs();
  189. SkStrikeSpec strikeSpec = SkStrikeSpec::MakeCanonicalized(*this, paint);
  190. SkBulkGlyphMetrics metrics{strikeSpec};
  191. SkSpan<const SkGlyph*> glyphs = metrics.glyphs(SkMakeSpan(glyphIDs, glyphCount));
  192. SkScalar width = 0;
  193. if (bounds) {
  194. *bounds = glyphs[0]->rect();
  195. width = glyphs[0]->advanceX();
  196. for (int i = 1; i < glyphCount; ++i) {
  197. SkRect r = glyphs[i]->rect();
  198. r.offset(width, 0);
  199. bounds->join(r);
  200. width += glyphs[i]->advanceX();
  201. }
  202. } else {
  203. for (auto glyph : glyphs) {
  204. width += glyph->advanceX();
  205. }
  206. }
  207. const SkScalar scale = strikeSpec.strikeToSourceRatio();
  208. if (scale != 1) {
  209. width *= scale;
  210. if (bounds) {
  211. bounds->fLeft *= scale;
  212. bounds->fTop *= scale;
  213. bounds->fRight *= scale;
  214. bounds->fBottom *= scale;
  215. }
  216. }
  217. return width;
  218. }
  219. void SkFont::getWidthsBounds(const SkGlyphID glyphIDs[],
  220. int count,
  221. SkScalar widths[],
  222. SkRect bounds[],
  223. const SkPaint* paint) const {
  224. SkStrikeSpec strikeSpec = SkStrikeSpec::MakeCanonicalized(*this, paint);
  225. SkBulkGlyphMetrics metrics{strikeSpec};
  226. SkSpan<const SkGlyph*> glyphs = metrics.glyphs(SkMakeSpan(glyphIDs, count));
  227. SkScalar scale = strikeSpec.strikeToSourceRatio();
  228. if (bounds) {
  229. SkMatrix scaleMat = SkMatrix::MakeScale(scale);
  230. SkRect* cursor = bounds;
  231. for (auto glyph : glyphs) {
  232. scaleMat.mapRectScaleTranslate(cursor++, glyph->rect());
  233. }
  234. }
  235. if (widths) {
  236. SkScalar* cursor = widths;
  237. for (auto glyph : glyphs) {
  238. *cursor++ = glyph->advanceX() * scale;
  239. }
  240. }
  241. }
  242. void SkFont::getPos(const SkGlyphID glyphIDs[], int count, SkPoint pos[], SkPoint origin) const {
  243. SkStrikeSpec strikeSpec = SkStrikeSpec::MakeCanonicalized(*this);
  244. SkBulkGlyphMetrics metrics{strikeSpec};
  245. SkSpan<const SkGlyph*> glyphs = metrics.glyphs(SkMakeSpan(glyphIDs, count));
  246. SkPoint sum = origin;
  247. for (auto glyph : glyphs) {
  248. *pos++ = sum;
  249. sum += glyph->advanceVector() * strikeSpec.strikeToSourceRatio();
  250. }
  251. }
  252. void SkFont::getXPos(
  253. const SkGlyphID glyphIDs[], int count, SkScalar xpos[], SkScalar origin) const {
  254. SkStrikeSpec strikeSpec = SkStrikeSpec::MakeCanonicalized(*this);
  255. SkBulkGlyphMetrics metrics{strikeSpec};
  256. SkSpan<const SkGlyph*> glyphs = metrics.glyphs(SkMakeSpan(glyphIDs, count));
  257. SkScalar loc = origin;
  258. SkScalar* cursor = xpos;
  259. for (auto glyph : glyphs) {
  260. *cursor++ = loc;
  261. loc += glyph->advanceX() * strikeSpec.strikeToSourceRatio();
  262. }
  263. }
  264. void SkFont::getPaths(const SkGlyphID glyphIDs[], int count,
  265. void (*proc)(const SkPath*, const SkMatrix&, void*), void* ctx) const {
  266. SkFont font(*this);
  267. SkScalar scale = font.setupForAsPaths(nullptr);
  268. const SkMatrix mx = SkMatrix::MakeScale(scale);
  269. SkStrikeSpec strikeSpec = SkStrikeSpec::MakeWithNoDevice(font);
  270. SkBulkGlyphMetricsAndPaths paths{strikeSpec};
  271. SkSpan<const SkGlyph*> glyphs = paths.glyphs(SkMakeSpan(glyphIDs, count));
  272. for (auto glyph : glyphs) {
  273. proc(glyph->path(), mx, ctx);
  274. }
  275. }
  276. bool SkFont::getPath(SkGlyphID glyphID, SkPath* path) const {
  277. struct Pair {
  278. SkPath* fPath;
  279. bool fWasSet;
  280. } pair = { path, false };
  281. this->getPaths(&glyphID, 1, [](const SkPath* orig, const SkMatrix& mx, void* ctx) {
  282. Pair* pair = static_cast<Pair*>(ctx);
  283. if (orig) {
  284. orig->transform(mx, pair->fPath);
  285. pair->fWasSet = true;
  286. }
  287. }, &pair);
  288. return pair.fWasSet;
  289. }
  290. SkScalar SkFont::getMetrics(SkFontMetrics* metrics) const {
  291. SkStrikeSpec strikeSpec = SkStrikeSpec::MakeCanonicalized(*this, nullptr);
  292. SkFontMetrics storage;
  293. if (nullptr == metrics) {
  294. metrics = &storage;
  295. }
  296. auto cache = strikeSpec.findOrCreateExclusiveStrike();
  297. *metrics = cache->getFontMetrics();
  298. if (strikeSpec.strikeToSourceRatio() != 1) {
  299. SkFontPriv::ScaleFontMetrics(metrics, strikeSpec.strikeToSourceRatio());
  300. }
  301. return metrics->fDescent - metrics->fAscent + metrics->fLeading;
  302. }
  303. SkTypeface* SkFont::getTypefaceOrDefault() const {
  304. return fTypeface ? fTypeface.get() : SkTypeface::GetDefaultTypeface();
  305. }
  306. sk_sp<SkTypeface> SkFont::refTypefaceOrDefault() const {
  307. return fTypeface ? fTypeface : SkTypeface::MakeDefault();
  308. }
  309. //////////////////////////////////////////////////////////////////////////////////////////////////
  310. void SkFontPriv::ScaleFontMetrics(SkFontMetrics* metrics, SkScalar scale) {
  311. metrics->fTop *= scale;
  312. metrics->fAscent *= scale;
  313. metrics->fDescent *= scale;
  314. metrics->fBottom *= scale;
  315. metrics->fLeading *= scale;
  316. metrics->fAvgCharWidth *= scale;
  317. metrics->fMaxCharWidth *= scale;
  318. metrics->fXMin *= scale;
  319. metrics->fXMax *= scale;
  320. metrics->fXHeight *= scale;
  321. metrics->fCapHeight *= scale;
  322. metrics->fUnderlineThickness *= scale;
  323. metrics->fUnderlinePosition *= scale;
  324. metrics->fStrikeoutThickness *= scale;
  325. metrics->fStrikeoutPosition *= scale;
  326. }
  327. SkRect SkFontPriv::GetFontBounds(const SkFont& font) {
  328. SkMatrix m;
  329. m.setScale(font.getSize() * font.getScaleX(), font.getSize());
  330. m.postSkew(font.getSkewX(), 0);
  331. SkTypeface* typeface = font.getTypefaceOrDefault();
  332. SkRect bounds;
  333. m.mapRect(&bounds, typeface->getBounds());
  334. return bounds;
  335. }
  336. int SkFontPriv::CountTextElements(const void* text, size_t byteLength, SkTextEncoding encoding) {
  337. switch (encoding) {
  338. case SkTextEncoding::kUTF8:
  339. return SkUTF::CountUTF8(reinterpret_cast<const char*>(text), byteLength);
  340. case SkTextEncoding::kUTF16:
  341. return SkUTF::CountUTF16(reinterpret_cast<const uint16_t*>(text), byteLength);
  342. case SkTextEncoding::kUTF32:
  343. return byteLength >> 2;
  344. case SkTextEncoding::kGlyphID:
  345. return byteLength >> 1;
  346. }
  347. SkASSERT(false);
  348. return 0;
  349. }
  350. void SkFontPriv::GlyphsToUnichars(const SkFont& font, const SkGlyphID glyphs[], int count,
  351. SkUnichar text[]) {
  352. if (count <= 0) {
  353. return;
  354. }
  355. auto typeface = font.getTypefaceOrDefault();
  356. const unsigned numGlyphsInTypeface = typeface->countGlyphs();
  357. SkAutoTArray<SkUnichar> unichars(numGlyphsInTypeface);
  358. typeface->getGlyphToUnicodeMap(unichars.get());
  359. for (int i = 0; i < count; ++i) {
  360. unsigned id = glyphs[i];
  361. text[i] = (id < numGlyphsInTypeface) ? unichars[id] : 0xFFFD;
  362. }
  363. }
  364. ///////////////////////////////////////////////////////////////////////////////////////////////////
  365. #include "src/core/SkReadBuffer.h"
  366. #include "src/core/SkWriteBuffer.h"
  367. // packed int at the beginning of the serialized font:
  368. //
  369. // control_bits:8 size_as_byte:8 flags:12 edging:2 hinting:2
  370. enum {
  371. kSize_Is_Byte_Bit = 1 << 31,
  372. kHas_ScaleX_Bit = 1 << 30,
  373. kHas_SkewX_Bit = 1 << 29,
  374. kHas_Typeface_Bit = 1 << 28,
  375. kShift_for_Size = 16,
  376. kMask_For_Size = 0xFF,
  377. kShift_For_Flags = 4,
  378. kMask_For_Flags = 0xFFF,
  379. kShift_For_Edging = 2,
  380. kMask_For_Edging = 0x3,
  381. kShift_For_Hinting = 0,
  382. kMask_For_Hinting = 0x3
  383. };
  384. static bool scalar_is_byte(SkScalar x) {
  385. int ix = (int)x;
  386. return ix == x && ix >= 0 && ix <= kMask_For_Size;
  387. }
  388. void SkFontPriv::Flatten(const SkFont& font, SkWriteBuffer& buffer) {
  389. SkASSERT((font.fFlags & ~kMask_For_Flags) == 0);
  390. SkASSERT((font.fEdging & ~kMask_For_Edging) == 0);
  391. SkASSERT((font.fHinting & ~kMask_For_Hinting) == 0);
  392. uint32_t packed = 0;
  393. packed |= font.fFlags << kShift_For_Flags;
  394. packed |= font.fEdging << kShift_For_Edging;
  395. packed |= font.fHinting << kShift_For_Hinting;
  396. if (scalar_is_byte(font.fSize)) {
  397. packed |= kSize_Is_Byte_Bit;
  398. packed |= (int)font.fSize << kShift_for_Size;
  399. }
  400. if (font.fScaleX != 1) {
  401. packed |= kHas_ScaleX_Bit;
  402. }
  403. if (font.fSkewX != 0) {
  404. packed |= kHas_SkewX_Bit;
  405. }
  406. if (font.fTypeface) {
  407. packed |= kHas_Typeface_Bit;
  408. }
  409. buffer.write32(packed);
  410. if (!(packed & kSize_Is_Byte_Bit)) {
  411. buffer.writeScalar(font.fSize);
  412. }
  413. if (packed & kHas_ScaleX_Bit) {
  414. buffer.writeScalar(font.fScaleX);
  415. }
  416. if (packed & kHas_SkewX_Bit) {
  417. buffer.writeScalar(font.fSkewX);
  418. }
  419. if (packed & kHas_Typeface_Bit) {
  420. buffer.writeTypeface(font.fTypeface.get());
  421. }
  422. }
  423. bool SkFontPriv::Unflatten(SkFont* font, SkReadBuffer& buffer) {
  424. const uint32_t packed = buffer.read32();
  425. if (packed & kSize_Is_Byte_Bit) {
  426. font->fSize = (packed >> kShift_for_Size) & kMask_For_Size;
  427. } else {
  428. font->fSize = buffer.readScalar();
  429. }
  430. if (packed & kHas_ScaleX_Bit) {
  431. font->fScaleX = buffer.readScalar();
  432. }
  433. if (packed & kHas_SkewX_Bit) {
  434. font->fSkewX = buffer.readScalar();
  435. }
  436. if (packed & kHas_Typeface_Bit) {
  437. font->fTypeface = buffer.readTypeface();
  438. }
  439. SkASSERT(SkFont::kAllFlags <= kMask_For_Flags);
  440. // we & with kAllFlags, to clear out any unknown flag bits
  441. font->fFlags = SkToU8((packed >> kShift_For_Flags) & SkFont::kAllFlags);
  442. unsigned edging = (packed >> kShift_For_Edging) & kMask_For_Edging;
  443. if (edging > (unsigned)SkFont::Edging::kSubpixelAntiAlias) {
  444. edging = 0;
  445. }
  446. font->fEdging = SkToU8(edging);
  447. unsigned hinting = (packed >> kShift_For_Hinting) & kMask_For_Hinting;
  448. if (hinting > (unsigned)SkFontHinting::kFull) {
  449. hinting = 0;
  450. }
  451. font->fHinting = SkToU8(hinting);
  452. return buffer.isValid();
  453. }