| Index: tools/SkShaper.cpp
|
| diff --git a/tools/SkShaper.cpp b/tools/SkShaper.cpp
|
| index 377f07c109d5ba69681b5d891c16e55ddcc4782b..44dd8fc7f1bbf0e72c47ffd2c469885ca045d144 100644
|
| --- a/tools/SkShaper.cpp
|
| +++ b/tools/SkShaper.cpp
|
| @@ -14,6 +14,32 @@
|
|
|
| static const int FONT_SIZE_SCALE = 512;
|
|
|
| +namespace {
|
| +struct HBFBlobDel {
|
| + void operator()(hb_blob_t* b) { hb_blob_destroy(b); }
|
| +};
|
| +
|
| +std::unique_ptr<hb_blob_t, HBFBlobDel> stream_to_blob(std::unique_ptr<SkStreamAsset> asset) {
|
| + size_t size = asset->getLength();
|
| + std::unique_ptr<hb_blob_t, HBFBlobDel> blob;
|
| + if (const void* base = asset->getMemoryBase()) {
|
| + blob.reset(hb_blob_create((char*)base, size,
|
| + HB_MEMORY_MODE_READONLY, asset.release(),
|
| + [](void* p) { delete (SkStreamAsset*)p; }));
|
| + } else {
|
| + // SkDebugf("Extra SkStreamAsset copy\n");
|
| + SkAutoMalloc autoMalloc(size);
|
| + asset->read(autoMalloc.get(), size);
|
| + void* ptr = autoMalloc.get();
|
| + blob.reset(hb_blob_create((char*)autoMalloc.release(), size,
|
| + HB_MEMORY_MODE_READONLY, ptr, sk_free));
|
| + }
|
| + SkASSERT(blob);
|
| + hb_blob_make_immutable(blob.get());
|
| + return blob;
|
| +}
|
| +} // namespace
|
| +
|
| struct SkShaper::Impl {
|
| struct HBFontDel {
|
| void operator()(hb_font_t* f) { hb_font_destroy(f); }
|
| @@ -29,22 +55,14 @@ struct SkShaper::Impl {
|
| 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);
|
| -
|
| + std::unique_ptr<hb_blob_t, HBFBlobDel> blob(
|
| + stream_to_blob(std::unique_ptr<SkStreamAsset>(
|
| + fImpl->fTypeface->openStream(&index))));
|
| 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);
|
| + std::unique_ptr<hb_face_t, HBFaceDel> face(
|
| + hb_face_create(blob.get(), (unsigned)index));
|
| SkASSERT(face);
|
| if (!face) {
|
| return;
|
|
|