Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(606)

Unified Diff: src/pdf/SkPDFFont.cpp

Issue 23519006: pdf: write only ToUnicode mappings needed by the font, trimming anything out of [firstChar, lastCha… (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/pdf/SkPDFFont.cpp
===================================================================
--- src/pdf/SkPDFFont.cpp (revision 11071)
+++ src/pdf/SkPDFFont.cpp (working copy)
@@ -342,7 +342,9 @@
} // namespace
-static void append_tounicode_header(SkDynamicMemoryWStream* cmap) {
+static void append_tounicode_header(SkDynamicMemoryWStream* cmap,
+ uint16_t firstGlypthID,
+ uint16_t lastGlypthID) {
// 12 dict begin: 12 is an Adobe-suggested value. Shall not change.
// It's there to prevent old version Adobe Readers from malfunctioning.
const char* kHeader =
@@ -365,17 +367,20 @@
// The CMapName must be consistent to /CIDSystemInfo above.
// /CMapType 2 means ToUnicode.
- // We specify codespacerange from 0x0000 to 0xFFFF because we convert our
- // code table from unsigned short (16-bits). Codespace range just tells the
- // PDF processor the valid range. It does not matter whether a complete
- // mapping is provided or not.
- const char* kTypeInfo =
+ // Codespace range just tells the PDF processor the valid range.
+ const char* kTypeInfoHeader =
"/CMapName /Adobe-Identity-UCS def\n"
"/CMapType 2 def\n"
- "1 begincodespacerange\n"
- "<0000> <FFFF>\n"
- "endcodespacerange\n";
- cmap->writeText(kTypeInfo);
+ "1 begincodespacerange\n";
+ cmap->writeText(kTypeInfoHeader);
+
+ // e.g. "<0000> <FFFF>\n"
+ SkString range;
+ range.appendf("<%04X> <%04X>\n", firstGlypthID, lastGlypthID);
+ cmap->writeText(range.c_str());
+
+ const char* kTypeInfoFooter = "endcodespacerange\n";
+ cmap->writeText(kTypeInfoFooter);
}
static void append_cmap_footer(SkDynamicMemoryWStream* cmap) {
@@ -399,11 +404,32 @@
};
static void append_bfchar_section(const SkTDArray<BFChar>& bfchar,
- SkDynamicMemoryWStream* cmap) {
+ SkDynamicMemoryWStream* cmap,
+ uint16_t firstGlypthID,
+ uint16_t lastGlypthID) {
+ int32_t i = 0;
+ while (i < bfchar.count() && bfchar[i].fGlyphId < firstGlypthID) {
vandebo (ex-Chrome) 2013/09/04 22:07:53 While the end point probably doesn't take a lot of
edisonn 2013/09/06 18:54:38 N/A - moved filtering in the caller - fastest way
+ i++;
+ }
+
// PDF spec defines that every bf* list can have at most 100 entries.
- for (int i = 0; i < bfchar.count(); i += 100) {
+ for (; i < bfchar.count(); i += 100) {
+ if (bfchar[i].fGlyphId > lastGlypthID) {
+ return;
+ }
+
int count = bfchar.count() - i;
count = SkMin32(count, 100);
+ // TODO(edisonn): perf, might be better to do a bsearch, but I think
+ // most of the times, we will have enough data to stop imediately.
+ while (count > 0 && bfchar[i + count - 1].fGlyphId > lastGlypthID) {
+ count--;
+ }
+
+ if (count == 0) {
vandebo (ex-Chrome) 2013/09/04 22:07:53 Not possible, count must be >= 1 because of the ch
edisonn 2013/09/06 18:54:38 On 2013/09/04 22:07:53, vandebo wrote: dead code
+ return;
+ }
+
cmap->writeDecAsText(count);
cmap->writeText(" beginbfchar\n");
for (int j = 0; j < count; ++j) {
@@ -418,18 +444,36 @@
}
static void append_bfrange_section(const SkTDArray<BFRange>& bfrange,
- SkDynamicMemoryWStream* cmap) {
+ SkDynamicMemoryWStream* cmap,
+ uint16_t firstGlypthID,
+ uint16_t lastGlypthID) {
+ int32_t i = 0;
+ while (i < bfrange.count() && bfrange[i].fEnd < firstGlypthID) {
vandebo (ex-Chrome) 2013/09/04 22:07:53 Same here re SkTSearch
edisonn 2013/09/06 18:54:38 dead code On 2013/09/04 22:07:53, vandebo wrote:
+ i++;
+ }
+
// PDF spec defines that every bf* list can have at most 100 entries.
- for (int i = 0; i < bfrange.count(); i += 100) {
+ for (; i < bfrange.count(); i += 100) {
+ if (bfrange[i].fStart > lastGlypthID) {
+ return;
+ }
+
int count = bfrange.count() - i;
count = SkMin32(count, 100);
cmap->writeDecAsText(count);
cmap->writeText(" beginbfrange\n");
+
+ // first range might be chopped.
+ uint16_t start = SkMax32(firstGlypthID, bfrange[i].fStart);
+
for (int j = 0; j < count; ++j) {
+ if (bfrange[i + j].fStart > lastGlypthID) {
+ break;
+ }
cmap->writeText("<");
- cmap->writeHexAsText(bfrange[i + j].fStart, 4);
+ cmap->writeHexAsText(j == 0 ? start : bfrange[i + j].fStart, 4);
vandebo (ex-Chrome) 2013/09/04 22:07:53 It's probably the same computational cost to do th
edisonn 2013/09/06 18:54:38 dead code
cmap->writeText("> <");
- cmap->writeHexAsText(bfrange[i + j].fEnd, 4);
+ cmap->writeHexAsText(SkMin32(bfrange[i + j].fEnd, lastGlypthID), 4);
cmap->writeText("> <");
cmap->writeHexAsText(bfrange[i + j].fUnicode, 4);
cmap->writeText(">\n");
@@ -469,11 +513,15 @@
// ( see caller in tests/ToUnicode.cpp )
void append_cmap_sections(const SkTDArray<SkUnichar>& glyphToUnicode,
const SkPDFGlyphSet* subset,
- SkDynamicMemoryWStream* cmap);
+ SkDynamicMemoryWStream* cmap,
+ uint16_t firstGlypthID = 0x0000,
vandebo (ex-Chrome) 2013/09/04 22:07:53 No need for defaults, these args are always passed
edisonn 2013/09/06 18:54:38 Done.
+ uint16_t lastGlypthID = 0xffff);
void append_cmap_sections(const SkTDArray<SkUnichar>& glyphToUnicode,
const SkPDFGlyphSet* subset,
- SkDynamicMemoryWStream* cmap) {
+ SkDynamicMemoryWStream* cmap,
+ uint16_t firstGlypthID,
+ uint16_t lastGlypthID) {
if (glyphToUnicode.isEmpty()) {
return;
}
@@ -520,16 +568,19 @@
// The spec requires all bfchar entries for a font must come before bfrange
// entries.
- append_bfchar_section(bfcharEntries, cmap);
- append_bfrange_section(bfrangeEntries, cmap);
+ append_bfchar_section(bfcharEntries, cmap, firstGlypthID, lastGlypthID);
+ append_bfrange_section(bfrangeEntries, cmap, firstGlypthID, lastGlypthID);
}
static SkPDFStream* generate_tounicode_cmap(
const SkTDArray<SkUnichar>& glyphToUnicode,
- const SkPDFGlyphSet* subset) {
+ const SkPDFGlyphSet* subset,
+ uint16_t firstGlypthID,
+ uint16_t lastGlypthID) {
SkDynamicMemoryWStream cmap;
- append_tounicode_header(&cmap);
- append_cmap_sections(glyphToUnicode, subset, &cmap);
+ append_tounicode_header(&cmap, firstGlypthID, lastGlypthID);
+ append_cmap_sections(glyphToUnicode, subset, &cmap,
+ firstGlypthID, lastGlypthID);
append_cmap_footer(&cmap);
SkAutoTUnref<SkMemoryStream> cmapStream(new SkMemoryStream());
cmapStream->setData(cmap.copyToData())->unref();
@@ -1014,7 +1065,8 @@
return;
}
SkAutoTUnref<SkPDFStream> pdfCmap(
- generate_tounicode_cmap(fFontInfo->fGlyphToUnicode, subset));
+ generate_tounicode_cmap(fFontInfo->fGlyphToUnicode, subset,
+ firstGlyphID(), lastGlyphID()));
addResource(pdfCmap.get());
insert("ToUnicode", new SkPDFObjRef(pdfCmap.get()))->unref();
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698