• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 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 "SkShaper.h"
8 #include "SkStream.h"
9 #include "SkTextBlob.h"
10 #include "SkTypeface.h"
11 
12 struct SkShaper::Impl {
13     sk_sp<SkTypeface> fTypeface;
14 };
15 
SkShaper(sk_sp<SkTypeface> tf)16 SkShaper::SkShaper(sk_sp<SkTypeface> tf) : fImpl(new Impl) {
17     fImpl->fTypeface = tf ? std::move(tf) : SkTypeface::MakeDefault();
18 }
19 
~SkShaper()20 SkShaper::~SkShaper() {}
21 
good() const22 bool SkShaper::good() const { return true; }
23 
24 // This example only uses public API, so we don't use SkUTF8_NextUnichar.
utf8_lead_byte_to_count(const char * ptr)25 unsigned utf8_lead_byte_to_count(const char* ptr) {
26     uint8_t c = *(const uint8_t*)ptr;
27     SkASSERT(c <= 0xF7);
28     SkASSERT((c & 0xC0) != 0x80);
29     return (((0xE5 << 24) >> ((unsigned)c >> 4 << 1)) & 3) + 1;
30 }
31 
shape(SkTextBlobBuilder * builder,const SkPaint & srcPaint,const char * utf8text,size_t textBytes,SkPoint point) const32 SkScalar SkShaper::shape(SkTextBlobBuilder* builder,
33                          const SkPaint& srcPaint,
34                          const char* utf8text,
35                          size_t textBytes,
36                          SkPoint point) const {
37     SkPaint paint(srcPaint);
38     paint.setTypeface(fImpl->fTypeface);
39     paint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
40     int glyphCount = paint.countText(utf8text, textBytes);
41     if (glyphCount <= 0) {
42         return 0;
43     }
44     SkRect bounds;
45     (void)paint.measureText(utf8text, textBytes, &bounds);
46     paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
47     const SkTextBlobBuilder::RunBuffer& runBuffer =
48         builder->allocRunTextPosH(paint, glyphCount, point.y(), textBytes, SkString(), &bounds);
49     memcpy(runBuffer.utf8text, utf8text, textBytes);
50     const char* txtPtr = utf8text;
51     for (int i = 0; i < glyphCount; ++i) {
52         // Each charater maps to exactly one glyph via SkGlyphCache::unicharToGlyph().
53         runBuffer.clusters[i] = SkToU32(txtPtr - utf8text);
54         txtPtr += utf8_lead_byte_to_count(txtPtr);
55         SkASSERT(txtPtr <= utf8text + textBytes);
56     }
57     paint.setTextEncoding(SkPaint::kUTF8_TextEncoding);
58     (void)paint.textToGlyphs(utf8text, textBytes, runBuffer.glyphs);
59     (void)paint.getTextWidths(utf8text, textBytes, runBuffer.pos);
60     SkScalar x = point.x();
61     for (int i = 0; i < glyphCount; ++i) {
62         SkScalar w = runBuffer.pos[i];
63         runBuffer.pos[i] = x;
64         x += w;
65     }
66     return (SkScalar)x;
67 }
68