Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Functions
SkPDFMakeToUnicodeCmap.cpp File Reference
#include "src/pdf/SkPDFMakeToUnicodeCmap.h"
#include "include/private/base/SkTo.h"
#include "src/base/SkUTF.h"
#include "src/pdf/SkPDFUtils.h"

Go to the source code of this file.

Functions

static void append_tounicode_header (SkDynamicMemoryWStream *cmap, bool multibyte)
 
static void append_cmap_footer (SkDynamicMemoryWStream *cmap)
 
static void write_glyph (SkDynamicMemoryWStream *cmap, bool multiByte, SkGlyphID gid)
 
static void append_bfchar_section (const std::vector< BFChar > &bfchar, bool multiByte, SkDynamicMemoryWStream *cmap)
 
static void append_bfrange_section (const std::vector< BFRange > &bfrange, bool multiByte, SkDynamicMemoryWStream *cmap)
 
void SkPDFAppendCmapSections (const SkUnichar *glyphToUnicode, const SkPDFGlyphUse *subset, SkDynamicMemoryWStream *cmap, bool multiByteGlyphs, SkGlyphID firstGlyphID, SkGlyphID lastGlyphID)
 
std::unique_ptr< SkStreamAssetSkPDFMakeToUnicodeCmap (const SkUnichar *glyphToUnicode, const SkPDFGlyphUse *subset, bool multiByteGlyphs, SkGlyphID firstGlyphID, SkGlyphID lastGlyphID)
 

Function Documentation

◆ append_bfchar_section()

static void append_bfchar_section ( const std::vector< BFChar > &  bfchar,
bool  multiByte,
SkDynamicMemoryWStream cmap 
)
static

Definition at line 84 of file SkPDFMakeToUnicodeCmap.cpp.

86 {
87 // PDF spec defines that every bf* list can have at most 100 entries.
88 for (size_t i = 0; i < bfchar.size(); i += 100) {
89 int count = SkToInt(bfchar.size() - i);
90 count = std::min(count, 100);
91 cmap->writeDecAsText(count);
92 cmap->writeText(" beginbfchar\n");
93 for (int j = 0; j < count; ++j) {
94 cmap->writeText("<");
95 write_glyph(cmap, multiByte, bfchar[i + j].fGlyphId);
96 cmap->writeText("> <");
97 SkPDFUtils::WriteUTF16beHex(cmap, bfchar[i + j].fUnicode);
98 cmap->writeText(">\n");
99 }
100 cmap->writeText("endbfchar\n");
101 }
102}
int count
static void write_glyph(SkDynamicMemoryWStream *cmap, bool multiByte, SkGlyphID gid)
constexpr int SkToInt(S x)
Definition SkTo.h:29
bool writeDecAsText(int32_t)
Definition SkStream.cpp:81
bool writeText(const char text[])
Definition SkStream.h:247
void WriteUTF16beHex(SkWStream *wStream, SkUnichar utf32)
Definition SkPDFUtils.h:107

◆ append_bfrange_section()

static void append_bfrange_section ( const std::vector< BFRange > &  bfrange,
bool  multiByte,
SkDynamicMemoryWStream cmap 
)
static

Definition at line 104 of file SkPDFMakeToUnicodeCmap.cpp.

106 {
107 // PDF spec defines that every bf* list can have at most 100 entries.
108 for (size_t i = 0; i < bfrange.size(); i += 100) {
109 int count = SkToInt(bfrange.size() - i);
110 count = std::min(count, 100);
111 cmap->writeDecAsText(count);
112 cmap->writeText(" beginbfrange\n");
113 for (int j = 0; j < count; ++j) {
114 cmap->writeText("<");
115 write_glyph(cmap, multiByte, bfrange[i + j].fStart);
116 cmap->writeText("> <");
117 write_glyph(cmap, multiByte, bfrange[i + j].fEnd);
118 cmap->writeText("> <");
119 SkPDFUtils::WriteUTF16beHex(cmap, bfrange[i + j].fUnicode);
120 cmap->writeText(">\n");
121 }
122 cmap->writeText("endbfrange\n");
123 }
124}

◆ append_cmap_footer()

static void append_cmap_footer ( SkDynamicMemoryWStream cmap)
static

Definition at line 52 of file SkPDFMakeToUnicodeCmap.cpp.

52 {
53 const char kFooter[] =
54 "endcmap\n"
55 "CMapName currentdict /CMap defineresource pop\n"
56 "end\n"
57 "end";
58 cmap->writeText(kFooter);
59}

◆ append_tounicode_header()

static void append_tounicode_header ( SkDynamicMemoryWStream cmap,
bool  multibyte 
)
static

Definition at line 14 of file SkPDFMakeToUnicodeCmap.cpp.

15 {
16 // 12 dict begin: 12 is an Adobe-suggested value. Shall not change.
17 // It's there to prevent old version Adobe Readers from malfunctioning.
18 const char* kHeader =
19 "/CIDInit /ProcSet findresource begin\n"
20 "12 dict begin\n"
21 "begincmap\n";
22 cmap->writeText(kHeader);
23
24 // The /CIDSystemInfo must be consistent to the one in
25 // SkPDFFont::populateCIDFont().
26 // We can not pass over the system info object here because the format is
27 // different. This is not a reference object.
28 const char* kSysInfo =
29 "/CIDSystemInfo\n"
30 "<< /Registry (Adobe)\n"
31 "/Ordering (UCS)\n"
32 "/Supplement 0\n"
33 ">> def\n";
34 cmap->writeText(kSysInfo);
35
36 // The CMapName must be consistent to /CIDSystemInfo above.
37 // /CMapType 2 means ToUnicode.
38 // Codespace range just tells the PDF processor the valid range.
39 const char* kTypeInfoHeader =
40 "/CMapName /Adobe-Identity-UCS def\n"
41 "/CMapType 2 def\n"
42 "1 begincodespacerange\n";
43 cmap->writeText(kTypeInfoHeader);
44 if (multibyte) {
45 cmap->writeText("<0000> <FFFF>\n");
46 } else {
47 cmap->writeText("<00> <FF>\n");
48 }
49 cmap->writeText("endcodespacerange\n");
50}

◆ SkPDFAppendCmapSections()

void SkPDFAppendCmapSections ( const SkUnichar glyphToUnicode,
const SkPDFGlyphUse subset,
SkDynamicMemoryWStream cmap,
bool  multiByteGlyphs,
SkGlyphID  firstGlyphID,
SkGlyphID  lastGlyphID 
)

Definition at line 152 of file SkPDFMakeToUnicodeCmap.cpp.

157 {
158 int glyphOffset = 0;
159 if (!multiByteGlyphs) {
160 glyphOffset = firstGlyphID - 1;
161 }
162
163 std::vector<BFChar> bfcharEntries;
164 std::vector<BFRange> bfrangeEntries;
165
166 BFRange currentRangeEntry = {0, 0, 0};
167 bool rangeEmpty = true;
168 const int limit = (int)lastGlyphID + 1 - glyphOffset;
169
170 for (int i = firstGlyphID - glyphOffset; i < limit + 1; ++i) {
171 SkGlyphID gid = i + glyphOffset;
172 bool inSubset = i < limit && (subset == nullptr || subset->has(gid));
173 if (!rangeEmpty) {
174 // PDF spec requires bfrange not changing the higher byte,
175 // e.g. <1035> <10FF> <2222> is ok, but
176 // <1035> <1100> <2222> is no good
177 bool inRange =
178 i == currentRangeEntry.fEnd + 1 &&
179 i >> 8 == currentRangeEntry.fStart >> 8 &&
180 i < limit &&
181 glyphToUnicode[gid] ==
182 currentRangeEntry.fUnicode + i - currentRangeEntry.fStart;
183 if (!inSubset || !inRange) {
184 if (currentRangeEntry.fEnd > currentRangeEntry.fStart) {
185 bfrangeEntries.push_back(currentRangeEntry);
186 } else {
187 bfcharEntries.push_back({currentRangeEntry.fStart, currentRangeEntry.fUnicode});
188 }
189 rangeEmpty = true;
190 }
191 }
192 if (inSubset) {
193 currentRangeEntry.fEnd = i;
194 if (rangeEmpty) {
195 currentRangeEntry.fStart = i;
196 currentRangeEntry.fUnicode = glyphToUnicode[gid];
197 rangeEmpty = false;
198 }
199 }
200 }
201
202 // The spec requires all bfchar entries for a font must come before bfrange
203 // entries.
204 append_bfchar_section(bfcharEntries, multiByteGlyphs, cmap);
205 append_bfrange_section(bfrangeEntries, multiByteGlyphs, cmap);
206}
static void append_bfrange_section(const std::vector< BFRange > &bfrange, bool multiByte, SkDynamicMemoryWStream *cmap)
static void append_bfchar_section(const std::vector< BFChar > &bfchar, bool multiByte, SkDynamicMemoryWStream *cmap)
uint16_t SkGlyphID
Definition SkTypes.h:179
Type::kYUV Type::kRGBA() int(0.7 *637)
bool has(SkGlyphID gid) const

◆ SkPDFMakeToUnicodeCmap()

std::unique_ptr< SkStreamAsset > SkPDFMakeToUnicodeCmap ( const SkUnichar glyphToUnicode,
const SkPDFGlyphUse subset,
bool  multiByteGlyphs,
SkGlyphID  firstGlyphID,
SkGlyphID  lastGlyphID 
)

Definition at line 208 of file SkPDFMakeToUnicodeCmap.cpp.

213 {
215 append_tounicode_header(&cmap, multiByteGlyphs);
216 SkPDFAppendCmapSections(glyphToUnicode, subset, &cmap, multiByteGlyphs,
217 firstGlyphID, lastGlyphID);
218 append_cmap_footer(&cmap);
219 return cmap.detachAsStream();
220}
static void append_cmap_footer(SkDynamicMemoryWStream *cmap)
static void append_tounicode_header(SkDynamicMemoryWStream *cmap, bool multibyte)
void SkPDFAppendCmapSections(const SkUnichar *glyphToUnicode, const SkPDFGlyphUse *subset, SkDynamicMemoryWStream *cmap, bool multiByteGlyphs, SkGlyphID firstGlyphID, SkGlyphID lastGlyphID)
std::unique_ptr< SkStreamAsset > detachAsStream()
Definition SkStream.cpp:876

◆ write_glyph()

static void write_glyph ( SkDynamicMemoryWStream cmap,
bool  multiByte,
SkGlyphID  gid 
)
static

Definition at line 74 of file SkPDFMakeToUnicodeCmap.cpp.

76 {
77 if (multiByte) {
79 } else {
81 }
82}
constexpr uint8_t SkToU8(S x)
Definition SkTo.h:22
void WriteUInt8(SkWStream *wStream, uint8_t value)
Definition SkPDFUtils.h:101
void WriteUInt16BE(SkWStream *wStream, uint16_t value)
Definition SkPDFUtils.h:93