Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkPDFSubsetFont.cpp
Go to the documentation of this file.
1// Copyright 2018 Google LLC.
2// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
3
5
6#if defined(SK_PDF_USE_HARFBUZZ_SUBSET)
7
11
12#include "hb.h" // NO_G3_REWRITE
13#include "hb-subset.h" // NO_G3_REWRITE
14
15using HBBlob = std::unique_ptr<hb_blob_t, SkFunctionObject<hb_blob_destroy>>;
16using HBFace = std::unique_ptr<hb_face_t, SkFunctionObject<hb_face_destroy>>;
17using HBSubsetInput = std::unique_ptr<hb_subset_input_t, SkFunctionObject<hb_subset_input_destroy>>;
18using HBSet = std::unique_ptr<hb_set_t, SkFunctionObject<hb_set_destroy>>;
19
20static HBBlob to_blob(sk_sp<SkData> data) {
21 using blob_size_t = SkCallableTraits<decltype(hb_blob_create)>::argument<1>::type;
22 if (!SkTFitsIn<blob_size_t>(data->size())) {
23 return nullptr;
24 }
25 const char* blobData = static_cast<const char*>(data->data());
26 blob_size_t blobSize = SkTo<blob_size_t>(data->size());
27 return HBBlob(hb_blob_create(blobData, blobSize,
28 HB_MEMORY_MODE_READONLY,
29 data.release(), [](void* p){ ((SkData*)p)->unref(); }));
30}
31
32static sk_sp<SkData> to_data(HBBlob blob) {
33 if (!blob) {
34 return nullptr;
35 }
36 unsigned int length;
37 const char* data = hb_blob_get_data(blob.get(), &length);
38 if (!data || !length) {
39 return nullptr;
40 }
42 [](const void*, void* ctx) { hb_blob_destroy((hb_blob_t*)ctx); },
43 blob.release());
44}
45
46static HBFace make_subset(hb_subset_input_t* input, hb_face_t* face, bool retainZeroGlyph) {
47 // TODO: When possible, check if a font is 'tricky' with FT_IS_TRICKY.
48 // If it isn't known if a font is 'tricky', retain the hints.
49 unsigned int flags = HB_SUBSET_FLAGS_RETAIN_GIDS;
50 if (retainZeroGlyph) {
51 flags |= HB_SUBSET_FLAGS_NOTDEF_OUTLINE;
52 }
53 hb_subset_input_set_flags(input, flags);
54 return HBFace(hb_subset_or_fail(face, input));
55}
56
57static sk_sp<SkData> subset_harfbuzz(sk_sp<SkData> fontData,
58 const SkPDFGlyphUse& glyphUsage,
59 int ttcIndex) {
60 if (!fontData) {
61 return nullptr;
62 }
63 HBFace face(hb_face_create(to_blob(std::move(fontData)).get(), ttcIndex));
64 SkASSERT(face);
65
66 HBSubsetInput input(hb_subset_input_create_or_fail());
67 SkASSERT(input);
68 if (!face || !input) {
69 return nullptr;
70 }
71 hb_set_t* glyphs = hb_subset_input_glyph_set(input.get());
72 glyphUsage.getSetValues([&glyphs](unsigned gid) { hb_set_add(glyphs, gid);});
73
74 HBFace subset = make_subset(input.get(), face.get(), glyphUsage.has(0));
75 if (!subset) {
76 return nullptr;
77 }
78 HBBlob result(hb_face_reference_blob(subset.get()));
79 return to_data(std::move(result));
80}
81
83 const SkPDFGlyphUse& glyphUsage,
85 int ttcIndex) {
86 return subset_harfbuzz(std::move(fontData), glyphUsage, ttcIndex);
87}
88
89#else
90
94#endif // defined(SK_PDF_USE_HARFBUZZ_SUBSET)
uint16_t glyphs[5]
#define SkASSERT(cond)
Definition SkAssert.h:116
sk_sp< SkData > SkPDFSubsetFont(sk_sp< SkData >, const SkPDFGlyphUse &, SkPDF::Metadata::Subsetter, int)
constexpr size_t SkToSizeT(S x)
Definition SkTo.h:31
static sk_sp< SkData > MakeWithProc(const void *ptr, size_t length, ReleaseProc proc, void *ctx)
Definition SkData.cpp:128
bool has(SkGlyphID gid) const
void getSetValues(FN f) const
FlutterSemanticsFlag flags
GAsyncResult * result
size_t length
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switches.h:41
const myers::Point & get(const myers::Segment &)