Flutter Engine
The Flutter Engine
Functions
SkPDFMakeToUnicodeCmap.cpp File Reference
#include "src/pdf/SkPDFMakeToUnicodeCmap.h"
#include "include/core/SkStream.h"
#include "include/private/base/SkTo.h"
#include "src/base/SkUTF.h"
#include "src/pdf/SkPDFGlyphUse.h"
#include "src/pdf/SkPDFUtils.h"
#include <algorithm>
#include <cstddef>
#include <vector>

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 90 of file SkPDFMakeToUnicodeCmap.cpp.

92 {
93 // PDF spec defines that every bf* list can have at most 100 entries.
94 for (size_t i = 0; i < bfchar.size(); i += 100) {
95 int count = SkToInt(bfchar.size() - i);
96 count = std::min(count, 100);
97 cmap->writeDecAsText(count);
98 cmap->writeText(" beginbfchar\n");
99 for (int j = 0; j < count; ++j) {
100 cmap->writeText("<");
101 write_glyph(cmap, multiByte, bfchar[i + j].fGlyphId);
102 cmap->writeText("> <");
103 SkPDFUtils::WriteUTF16beHex(cmap, bfchar[i + j].fUnicode);
104 cmap->writeText(">\n");
105 }
106 cmap->writeText("endbfchar\n");
107 }
108}
int count
Definition: FontMgrTest.cpp:50
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
static float min(float r, float g, float b)
Definition: hsl.cpp:48
void WriteUTF16beHex(SkWStream *wStream, SkUnichar utf32)
Definition: SkPDFUtils.h:119

◆ append_bfrange_section()

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

Definition at line 110 of file SkPDFMakeToUnicodeCmap.cpp.

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

◆ append_cmap_footer()

static void append_cmap_footer ( SkDynamicMemoryWStream cmap)
static

Definition at line 58 of file SkPDFMakeToUnicodeCmap.cpp.

58 {
59 const char kFooter[] =
60 "endcmap\n"
61 "CMapName currentdict /CMap defineresource pop\n"
62 "end\n"
63 "end";
64 cmap->writeText(kFooter);
65}

◆ append_tounicode_header()

static void append_tounicode_header ( SkDynamicMemoryWStream cmap,
bool  multibyte 
)
static

Definition at line 20 of file SkPDFMakeToUnicodeCmap.cpp.

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

◆ SkPDFAppendCmapSections()

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

Definition at line 158 of file SkPDFMakeToUnicodeCmap.cpp.

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

◆ SkPDFMakeToUnicodeCmap()

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

Definition at line 214 of file SkPDFMakeToUnicodeCmap.cpp.

219 {
221 append_tounicode_header(&cmap, multiByteGlyphs);
222 SkPDFAppendCmapSections(glyphToUnicode, subset, &cmap, multiByteGlyphs,
223 firstGlyphID, lastGlyphID);
224 append_cmap_footer(&cmap);
225 return cmap.detachAsStream();
226}
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 80 of file SkPDFMakeToUnicodeCmap.cpp.

82 {
83 if (multiByte) {
85 } else {
87 }
88}
constexpr uint8_t SkToU8(S x)
Definition: SkTo.h:22
void WriteUInt8(SkWStream *wStream, uint8_t value)
Definition: SkPDFUtils.h:113
void WriteUInt16BE(SkWStream *wStream, uint16_t value)
Definition: SkPDFUtils.h:105