| 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 |