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

Side by Side Diff: tools/SkShaper.cpp

Issue 2201153002: SkShaper: optionally disable harfbuzz (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: 2016-08-02 (Tuesday) 18:27:47 EDT Created 4 years, 4 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 unified diff | Download patch
« no previous file with comments | « tools/SkShaper.h ('k') | tools/SkShaper_harfbuzz.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
8 #include <hb-ot.h>
9
10 #include "SkShaper.h"
11 #include "SkStream.h"
12 #include "SkTextBlob.h"
13 #include "SkTypeface.h"
14
15 static const int FONT_SIZE_SCALE = 512;
16
17 namespace {
18 struct HBFBlobDel {
19 void operator()(hb_blob_t* b) { hb_blob_destroy(b); }
20 };
21
22 std::unique_ptr<hb_blob_t, HBFBlobDel> stream_to_blob(std::unique_ptr<SkStreamAs set> asset) {
23 size_t size = asset->getLength();
24 std::unique_ptr<hb_blob_t, HBFBlobDel> blob;
25 if (const void* base = asset->getMemoryBase()) {
26 blob.reset(hb_blob_create((char*)base, size,
27 HB_MEMORY_MODE_READONLY, asset.release(),
28 [](void* p) { delete (SkStreamAsset*)p; }));
29 } else {
30 // SkDebugf("Extra SkStreamAsset copy\n");
31 SkAutoMalloc autoMalloc(size);
32 asset->read(autoMalloc.get(), size);
33 void* ptr = autoMalloc.get();
34 blob.reset(hb_blob_create((char*)autoMalloc.release(), size,
35 HB_MEMORY_MODE_READONLY, ptr, sk_free));
36 }
37 SkASSERT(blob);
38 hb_blob_make_immutable(blob.get());
39 return blob;
40 }
41 } // namespace
42
43 struct SkShaper::Impl {
44 struct HBFontDel {
45 void operator()(hb_font_t* f) { hb_font_destroy(f); }
46 };
47 std::unique_ptr<hb_font_t, HBFontDel> fHarfBuzzFont;
48 struct HBBufDel {
49 void operator()(hb_buffer_t* b) { hb_buffer_destroy(b); }
50 };
51 std::unique_ptr<hb_buffer_t, HBBufDel> fBuffer;
52 sk_sp<SkTypeface> fTypeface;
53 };
54
55 SkShaper::SkShaper(sk_sp<SkTypeface> tf) : fImpl(new Impl) {
56 fImpl->fTypeface = tf ? std::move(tf) : SkTypeface::MakeDefault();
57 int index;
58 std::unique_ptr<hb_blob_t, HBFBlobDel> blob(
59 stream_to_blob(std::unique_ptr<SkStreamAsset>(
60 fImpl->fTypeface->openStream(&index))));
61 struct HBFaceDel {
62 void operator()(hb_face_t* f) { hb_face_destroy(f); }
63 };
64 std::unique_ptr<hb_face_t, HBFaceDel> face(
65 hb_face_create(blob.get(), (unsigned)index));
66 SkASSERT(face);
67 if (!face) {
68 return;
69 }
70 hb_face_set_index(face.get(), (unsigned)index);
71 hb_face_set_upem(face.get(), fImpl->fTypeface->getUnitsPerEm());
72
73 fImpl->fHarfBuzzFont.reset(hb_font_create(face.get()));
74 SkASSERT(fImpl->fHarfBuzzFont);
75 hb_font_set_scale(fImpl->fHarfBuzzFont.get(), FONT_SIZE_SCALE, FONT_SIZE_SCA LE);
76 hb_ot_font_set_funcs(fImpl->fHarfBuzzFont.get());
77
78 fImpl->fBuffer.reset(hb_buffer_create());
79 }
80
81 SkShaper::~SkShaper() {}
82
83 bool SkShaper::good() const { return fImpl->fHarfBuzzFont != nullptr; }
84
85 SkScalar SkShaper::shape(SkTextBlobBuilder* builder,
86 const SkPaint& srcPaint,
87 const char* utf8text,
88 size_t textBytes,
89 SkPoint point) const {
90 SkPaint paint(srcPaint);
91 paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
92 paint.setTypeface(fImpl->fTypeface);
93
94 SkASSERT(builder);
95 hb_buffer_t* buffer = fImpl->fBuffer.get();
96 hb_buffer_add_utf8(buffer, utf8text, -1, 0, -1);
97 hb_buffer_guess_segment_properties(buffer);
98 hb_shape(fImpl->fHarfBuzzFont.get(), buffer, nullptr, 0);
99 unsigned len = hb_buffer_get_length(buffer);
100 if (len == 0) {
101 hb_buffer_clear_contents(buffer);
102 return 0;
103 }
104
105 hb_glyph_info_t* info = hb_buffer_get_glyph_infos(buffer, NULL);
106 hb_glyph_position_t* pos =
107 hb_buffer_get_glyph_positions(buffer, NULL);
108 auto runBuffer = builder->allocRunPos(paint, len);
109
110 double x = point.x();
111 double y = point.y();
112
113 double textSizeY = paint.getTextSize() / (double)FONT_SIZE_SCALE;
114 double textSizeX = textSizeY * paint.getTextScaleX();
115
116 for (unsigned i = 0; i < len; i++) {
117 runBuffer.glyphs[i] = info[i].codepoint;
118 reinterpret_cast<SkPoint*>(runBuffer.pos)[i] =
119 SkPoint::Make(x + pos[i].x_offset * textSizeX,
120 y - pos[i].y_offset * textSizeY);
121 x += pos[i].x_advance * textSizeX;
122 y += pos[i].y_advance * textSizeY;
123 }
124 hb_buffer_clear_contents(buffer);
125 return (SkScalar)x;
126 }
OLDNEW
« no previous file with comments | « tools/SkShaper.h ('k') | tools/SkShaper_harfbuzz.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698