From a25fbef56a4e70192b0b322b6d87b78839fab0e5 Mon Sep 17 00:00:00 2001 From: Ben Wagner Date: Wed, 30 Aug 2017 13:56:19 -0400 Subject: Add bidi to SkShaper. Change-Id: Iaab9a1d5091a3b157a582b7e8c3261a6c3283ffc Reviewed-on: https://skia-review.googlesource.com/40778 Reviewed-by: Derek Sollenberger Commit-Queue: Ben Wagner --- tools/shape/SkShaper_primitive.cpp | 70 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 tools/shape/SkShaper_primitive.cpp (limited to 'tools/shape/SkShaper_primitive.cpp') diff --git a/tools/shape/SkShaper_primitive.cpp b/tools/shape/SkShaper_primitive.cpp new file mode 100644 index 0000000000..750c51621e --- /dev/null +++ b/tools/shape/SkShaper_primitive.cpp @@ -0,0 +1,70 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "SkShaper.h" +#include "SkStream.h" +#include "SkTextBlob.h" +#include "SkTypeface.h" + +struct SkShaper::Impl { + sk_sp fTypeface; +}; + +SkShaper::SkShaper(sk_sp tf) : fImpl(new Impl) { + fImpl->fTypeface = tf ? std::move(tf) : SkTypeface::MakeDefault(); +} + +SkShaper::~SkShaper() {} + +bool SkShaper::good() const { return true; } + +// This example only uses public API, so we don't use SkUTF8_NextUnichar. +unsigned utf8_lead_byte_to_count(const char* ptr) { + uint8_t c = *(const uint8_t*)ptr; + SkASSERT(c <= 0xF7); + SkASSERT((c & 0xC0) != 0x80); + return (((0xE5 << 24) >> ((unsigned)c >> 4 << 1)) & 3) + 1; +} + +SkScalar SkShaper::shape(SkTextBlobBuilder* builder, + const SkPaint& srcPaint, + const char* utf8text, + size_t textBytes, + bool leftToRight, + SkPoint point) const { + sk_ignore_unused_variable(leftToRight); + + SkPaint paint(srcPaint); + paint.setTypeface(fImpl->fTypeface); + paint.setTextEncoding(SkPaint::kUTF8_TextEncoding); + int glyphCount = paint.countText(utf8text, textBytes); + if (glyphCount <= 0) { + return 0; + } + SkRect bounds; + (void)paint.measureText(utf8text, textBytes, &bounds); + paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); + const SkTextBlobBuilder::RunBuffer& runBuffer = + builder->allocRunTextPosH(paint, glyphCount, point.y(), textBytes, SkString(), &bounds); + memcpy(runBuffer.utf8text, utf8text, textBytes); + const char* txtPtr = utf8text; + for (int i = 0; i < glyphCount; ++i) { + // Each charater maps to exactly one glyph via SkGlyphCache::unicharToGlyph(). + runBuffer.clusters[i] = SkToU32(txtPtr - utf8text); + txtPtr += utf8_lead_byte_to_count(txtPtr); + SkASSERT(txtPtr <= utf8text + textBytes); + } + paint.setTextEncoding(SkPaint::kUTF8_TextEncoding); + (void)paint.textToGlyphs(utf8text, textBytes, runBuffer.glyphs); + (void)paint.getTextWidths(utf8text, textBytes, runBuffer.pos); + SkScalar x = point.x(); + for (int i = 0; i < glyphCount; ++i) { + SkScalar w = runBuffer.pos[i]; + runBuffer.pos[i] = x; + x += w; + } + return (SkScalar)x; +} -- cgit v1.2.3