OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include <hb-ot.h> | 8 #include <hb-ot.h> |
9 | 9 |
10 #include "SkShaper.h" | 10 #include "SkShaper.h" |
11 #include "SkStream.h" | 11 #include "SkStream.h" |
12 #include "SkTextBlob.h" | 12 #include "SkTextBlob.h" |
13 #include "SkTypeface.h" | 13 #include "SkTypeface.h" |
14 | 14 |
15 static const int FONT_SIZE_SCALE = 512; | 15 static const int FONT_SIZE_SCALE = 512; |
16 | 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 |
17 struct SkShaper::Impl { | 43 struct SkShaper::Impl { |
18 struct HBFontDel { | 44 struct HBFontDel { |
19 void operator()(hb_font_t* f) { hb_font_destroy(f); } | 45 void operator()(hb_font_t* f) { hb_font_destroy(f); } |
20 }; | 46 }; |
21 std::unique_ptr<hb_font_t, HBFontDel> fHarfBuzzFont; | 47 std::unique_ptr<hb_font_t, HBFontDel> fHarfBuzzFont; |
22 struct HBBufDel { | 48 struct HBBufDel { |
23 void operator()(hb_buffer_t* b) { hb_buffer_destroy(b); } | 49 void operator()(hb_buffer_t* b) { hb_buffer_destroy(b); } |
24 }; | 50 }; |
25 std::unique_ptr<hb_buffer_t, HBBufDel> fBuffer; | 51 std::unique_ptr<hb_buffer_t, HBBufDel> fBuffer; |
26 sk_sp<SkTypeface> fTypeface; | 52 sk_sp<SkTypeface> fTypeface; |
27 }; | 53 }; |
28 | 54 |
29 SkShaper::SkShaper(sk_sp<SkTypeface> tf) : fImpl(new Impl) { | 55 SkShaper::SkShaper(sk_sp<SkTypeface> tf) : fImpl(new Impl) { |
30 fImpl->fTypeface = tf ? std::move(tf) : SkTypeface::MakeDefault(); | 56 fImpl->fTypeface = tf ? std::move(tf) : SkTypeface::MakeDefault(); |
31 int index; | 57 int index; |
32 std::unique_ptr<SkStreamAsset> asset(fImpl->fTypeface->openStream(&index)); | 58 std::unique_ptr<hb_blob_t, HBFBlobDel> blob( |
33 size_t size = asset->getLength(); | 59 stream_to_blob(std::unique_ptr<SkStreamAsset>( |
34 SkAutoMalloc autoMalloc(size); // TODO(halcanary): Avoid this malloc+copy. | 60 fImpl->fTypeface->openStream(&index)))); |
35 asset->read(autoMalloc.get(), size); | |
36 asset = nullptr; | |
37 void* ptr = autoMalloc.get(); | |
38 hb_blob_t* blob = hb_blob_create((char*)autoMalloc.release(), size, | |
39 HB_MEMORY_MODE_READONLY, ptr, sk_free); | |
40 SkASSERT(blob); | |
41 hb_blob_make_immutable(blob); | |
42 | |
43 struct HBFaceDel { | 61 struct HBFaceDel { |
44 void operator()(hb_face_t* f) { hb_face_destroy(f); } | 62 void operator()(hb_face_t* f) { hb_face_destroy(f); } |
45 }; | 63 }; |
46 std::unique_ptr<hb_face_t, HBFaceDel> face(hb_face_create(blob, (unsigned)in
dex)); | 64 std::unique_ptr<hb_face_t, HBFaceDel> face( |
47 hb_blob_destroy(blob); | 65 hb_face_create(blob.get(), (unsigned)index)); |
48 SkASSERT(face); | 66 SkASSERT(face); |
49 if (!face) { | 67 if (!face) { |
50 return; | 68 return; |
51 } | 69 } |
52 hb_face_set_index(face.get(), (unsigned)index); | 70 hb_face_set_index(face.get(), (unsigned)index); |
53 hb_face_set_upem(face.get(), fImpl->fTypeface->getUnitsPerEm()); | 71 hb_face_set_upem(face.get(), fImpl->fTypeface->getUnitsPerEm()); |
54 | 72 |
55 fImpl->fHarfBuzzFont.reset(hb_font_create(face.get())); | 73 fImpl->fHarfBuzzFont.reset(hb_font_create(face.get())); |
56 SkASSERT(fImpl->fHarfBuzzFont); | 74 SkASSERT(fImpl->fHarfBuzzFont); |
57 hb_font_set_scale(fImpl->fHarfBuzzFont.get(), FONT_SIZE_SCALE, FONT_SIZE_SCA
LE); | 75 hb_font_set_scale(fImpl->fHarfBuzzFont.get(), FONT_SIZE_SCALE, FONT_SIZE_SCA
LE); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 runBuffer.glyphs[i] = info[i].codepoint; | 117 runBuffer.glyphs[i] = info[i].codepoint; |
100 reinterpret_cast<SkPoint*>(runBuffer.pos)[i] = | 118 reinterpret_cast<SkPoint*>(runBuffer.pos)[i] = |
101 SkPoint::Make(x + pos[i].x_offset * textSizeX, | 119 SkPoint::Make(x + pos[i].x_offset * textSizeX, |
102 y - pos[i].y_offset * textSizeY); | 120 y - pos[i].y_offset * textSizeY); |
103 x += pos[i].x_advance * textSizeX; | 121 x += pos[i].x_advance * textSizeX; |
104 y += pos[i].y_advance * textSizeY; | 122 y += pos[i].y_advance * textSizeY; |
105 } | 123 } |
106 hb_buffer_clear_contents(buffer); | 124 hb_buffer_clear_contents(buffer); |
107 return (SkScalar)x; | 125 return (SkScalar)x; |
108 } | 126 } |
OLD | NEW |