1/* 2 * Copyright 2018 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 "SkSGText.h" 9 10#include "SkCanvas.h" 11#include "SkPaint.h" 12#include "SkPath.h" 13#include "SkTArray.h" 14#include "SkTextBlob.h" 15#include "SkTypeface.h" 16 17namespace sksg { 18 19sk_sp<Text> Text::Make(sk_sp<SkTypeface> tf, const SkString& text) { 20 return sk_sp<Text>(new Text(std::move(tf), text)); 21} 22 23Text::Text(sk_sp<SkTypeface> tf, const SkString& text) 24 : fTypeface(std::move(tf)) 25 , fText(text) {} 26 27Text::~Text() = default; 28 29SkRect Text::onRevalidate(InvalidationController*, const SkMatrix&) { 30 // TODO: we could potentially track invals which don't require rebuilding the blob. 31 32 SkPaint font; 33 font.setFlags(fFlags); 34 font.setTypeface(fTypeface); 35 font.setTextSize(fSize); 36 font.setTextScaleX(fScaleX); 37 font.setTextSkewX(fSkewX); 38 font.setTextAlign(fAlign); 39 font.setHinting(fHinting); 40 41 // First, convert to glyphIDs. 42 font.setTextEncoding(SkPaint::kUTF8_TextEncoding); 43 SkSTArray<256, SkGlyphID, true> glyphs; 44 glyphs.reset(font.textToGlyphs(fText.c_str(), fText.size(), nullptr)); 45 SkAssertResult(font.textToGlyphs(fText.c_str(), fText.size(), glyphs.begin()) == glyphs.count()); 46 font.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 47 48 // Next, build the cached blob. 49 SkTextBlobBuilder builder; 50 const auto& buf = builder.allocRun(font, glyphs.count(), 0, 0, nullptr); 51 if (!buf.glyphs) { 52 fBlob.reset(); 53 return SkRect::MakeEmpty(); 54 } 55 56 memcpy(buf.glyphs, glyphs.begin(), glyphs.count() * sizeof(SkGlyphID)); 57 58 fBlob = builder.make(); 59 return fBlob 60 ? fBlob->bounds().makeOffset(fPosition.x(), fPosition.y()) 61 : SkRect::MakeEmpty(); 62} 63 64void Text::onDraw(SkCanvas* canvas, const SkPaint& paint) const { 65 canvas->drawTextBlob(fBlob, fPosition.x(), fPosition.y(), paint); 66} 67 68SkPath Text::onAsPath() const { 69 // TODO 70 return SkPath(); 71} 72 73void Text::onClip(SkCanvas* canvas, bool antiAlias) const { 74 canvas->clipPath(this->asPath(), antiAlias); 75} 76 77} // namespace sksg 78