diff options
author | Jjgod Jiang <gzjjgod@gmail.com> | 2014-08-04 07:29:07 +0000 |
---|---|---|
committer | Jjgod Jiang <gzjjgod@gmail.com> | 2014-08-04 07:29:07 +0000 |
commit | 9e295194f1137856c64809a484b41306473d7a89 (patch) | |
tree | a0f9a63f20aa60fe06c216a40a1c75dae96551e8 /Build/source/texk/dvipdfm-x/cmap.c | |
parent | e93685e85b3f0bff2eb571e79d77dccddd1cb2ed (diff) |
Fix ToUnicode with reverse CMap lookup
When dvipdfmx is provided a regular CMap in the following format:
<unicode codepoint> cid
We can try to utilize the data and do a reverse lookup when all we
know is the cids used.
Initially, when parsing the cmap specified, we build a reverseMap
which maps CID to the first Unicode codepoint it corresponds to.
(Which is pretty much the reverse of CMap_decode().)
Since this cmap is already parsed when we create the fontmap cache,
we can just pass the cmap_id all the way down to
otf_create_ToUnicode_stream() and get CMap* back from this cmap_id.
Second, we refactor create_ToUnicode_cmap{4, 12}() functions into
one create_ToUnicode_cmap() and combine the common code.
In the third step, in create_ToUnicode_cmap() we try to see if the
font is indeed a CFF font (with CID-keyed), and we do have a cmap,
we can use the newly added CMap_reverse_decode() to convert all
used cids back to Unicode codepoints. With that mapping information
we can successfully create the ToUnicode PDF stream we needed.
git-svn-id: svn://tug.org/texlive/trunk@34831 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/dvipdfm-x/cmap.c')
-rw-r--r-- | Build/source/texk/dvipdfm-x/cmap.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/Build/source/texk/dvipdfm-x/cmap.c b/Build/source/texk/dvipdfm-x/cmap.c index 0629ac1cc49..d5c909cda01 100644 --- a/Build/source/texk/dvipdfm-x/cmap.c +++ b/Build/source/texk/dvipdfm-x/cmap.c @@ -109,6 +109,9 @@ CMap_new (void) cmap->mapData->pos = 0; cmap->mapData->data = NEW(MEM_ALLOC_SIZE, unsigned char); + cmap->reverseMap = NEW(65536, int); + memset(cmap->reverseMap, 0, 65536 * sizeof(int)); + return cmap; } @@ -140,6 +143,9 @@ CMap_release (CMap *cmap) } } + if (cmap->reverseMap) + RELEASE(cmap->reverseMap); + RELEASE(cmap); } @@ -359,6 +365,14 @@ CMap_decode (CMap *cmap, return count; } +int +CMap_reverse_decode(CMap *cmap, CID cid) { + int ch = cmap->reverseMap ? cmap->reverseMap[cid] : -1; + if (ch == 0 && cmap->useCMap) + return CMap_reverse_decode(cmap->useCMap, cid); + return ch; +} + char * CMap_get_name (CMap *cmap) { @@ -664,7 +678,7 @@ int CMap_add_cidrange (CMap *cmap, const unsigned char *srclo, const unsigned char *srchi, int srcdim, CID base) { - int c; + int i, c, v; mapDef *cur; ASSERT(cmap); @@ -679,6 +693,11 @@ CMap_add_cidrange (CMap *cmap, if (locate_tbl(&cur, srclo, srcdim) < 0) return -1; + for (v = 0, i = 0; i < srcdim - 1; i++) + v = (v << 8) + srclo[i]; + + cmap->reverseMap[base] = v; + for (c = srclo[srcdim-1]; c <= srchi[srcdim-1]; c++) { if (cur[c].flag != 0) { if (!__silent) @@ -689,6 +708,8 @@ CMap_add_cidrange (CMap *cmap, cur[c].code = get_mem(cmap, 2); cur[c].code[0] = base >> 8; cur[c].code[1] = base & 0xff; + + cmap->reverseMap[base] = (v << 8) + c; } if (base >= CID_MAX) WARN("CID number too large."); |