Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(231)

Unified Diff: tools/SkShaper.cpp

Issue 2138133002: tools/SkShaper: factor shaping out of using_skia_and_harfbuzz (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: 2016-07-11 (Monday) 15:42:21 EDT Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/SkShaper.h ('k') | tools/using_skia_and_harfbuzz.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/SkShaper.cpp
diff --git a/tools/SkShaper.cpp b/tools/SkShaper.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..377f07c109d5ba69681b5d891c16e55ddcc4782b
--- /dev/null
+++ b/tools/SkShaper.cpp
@@ -0,0 +1,108 @@
+/*
+ * 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 <hb-ot.h>
+
+#include "SkShaper.h"
+#include "SkStream.h"
+#include "SkTextBlob.h"
+#include "SkTypeface.h"
+
+static const int FONT_SIZE_SCALE = 512;
+
+struct SkShaper::Impl {
+ struct HBFontDel {
+ void operator()(hb_font_t* f) { hb_font_destroy(f); }
+ };
+ std::unique_ptr<hb_font_t, HBFontDel> fHarfBuzzFont;
+ struct HBBufDel {
+ void operator()(hb_buffer_t* b) { hb_buffer_destroy(b); }
+ };
+ std::unique_ptr<hb_buffer_t, HBBufDel> fBuffer;
+ sk_sp<SkTypeface> fTypeface;
+};
+
+SkShaper::SkShaper(sk_sp<SkTypeface> tf) : fImpl(new Impl) {
+ fImpl->fTypeface = tf ? std::move(tf) : SkTypeface::MakeDefault();
+ int index;
+ std::unique_ptr<SkStreamAsset> asset(fImpl->fTypeface->openStream(&index));
+ size_t size = asset->getLength();
+ SkAutoMalloc autoMalloc(size); // TODO(halcanary): Avoid this malloc+copy.
+ asset->read(autoMalloc.get(), size);
+ asset = nullptr;
+ void* ptr = autoMalloc.get();
+ hb_blob_t* blob = hb_blob_create((char*)autoMalloc.release(), size,
+ HB_MEMORY_MODE_READONLY, ptr, sk_free);
+ SkASSERT(blob);
+ hb_blob_make_immutable(blob);
+
+ struct HBFaceDel {
+ void operator()(hb_face_t* f) { hb_face_destroy(f); }
+ };
+ std::unique_ptr<hb_face_t, HBFaceDel> face(hb_face_create(blob, (unsigned)index));
+ hb_blob_destroy(blob);
+ SkASSERT(face);
+ if (!face) {
+ return;
+ }
+ hb_face_set_index(face.get(), (unsigned)index);
+ hb_face_set_upem(face.get(), fImpl->fTypeface->getUnitsPerEm());
+
+ fImpl->fHarfBuzzFont.reset(hb_font_create(face.get()));
+ SkASSERT(fImpl->fHarfBuzzFont);
+ hb_font_set_scale(fImpl->fHarfBuzzFont.get(), FONT_SIZE_SCALE, FONT_SIZE_SCALE);
+ hb_ot_font_set_funcs(fImpl->fHarfBuzzFont.get());
+
+ fImpl->fBuffer.reset(hb_buffer_create());
+}
+
+SkShaper::~SkShaper() {}
+
+bool SkShaper::good() const { return fImpl->fHarfBuzzFont != nullptr; }
+
+SkScalar SkShaper::shape(SkTextBlobBuilder* builder,
+ const SkPaint& srcPaint,
+ const char* utf8text,
+ size_t textBytes,
+ SkPoint point) const {
+ SkPaint paint(srcPaint);
+ paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
+ paint.setTypeface(fImpl->fTypeface);
+
+ SkASSERT(builder);
+ hb_buffer_t* buffer = fImpl->fBuffer.get();
+ hb_buffer_add_utf8(buffer, utf8text, -1, 0, -1);
+ hb_buffer_guess_segment_properties(buffer);
+ hb_shape(fImpl->fHarfBuzzFont.get(), buffer, nullptr, 0);
+ unsigned len = hb_buffer_get_length(buffer);
+ if (len == 0) {
+ hb_buffer_clear_contents(buffer);
+ return 0;
+ }
+
+ hb_glyph_info_t* info = hb_buffer_get_glyph_infos(buffer, NULL);
+ hb_glyph_position_t* pos =
+ hb_buffer_get_glyph_positions(buffer, NULL);
+ auto runBuffer = builder->allocRunPos(paint, len);
+
+ double x = point.x();
+ double y = point.y();
+
+ double textSizeY = paint.getTextSize() / (double)FONT_SIZE_SCALE;
+ double textSizeX = textSizeY * paint.getTextScaleX();
+
+ for (unsigned i = 0; i < len; i++) {
+ runBuffer.glyphs[i] = info[i].codepoint;
+ reinterpret_cast<SkPoint*>(runBuffer.pos)[i] =
+ SkPoint::Make(x + pos[i].x_offset * textSizeX,
+ y - pos[i].y_offset * textSizeY);
+ x += pos[i].x_advance * textSizeX;
+ y += pos[i].y_advance * textSizeY;
+ }
+ hb_buffer_clear_contents(buffer);
+ return (SkScalar)x;
+}
« no previous file with comments | « tools/SkShaper.h ('k') | tools/using_skia_and_harfbuzz.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698