diff options
author | Ken Sharp <ken.sharp@artifex.com> | 2009-07-03 09:27:02 +0000 |
---|---|---|
committer | Ken Sharp <ken.sharp@artifex.com> | 2009-07-03 09:27:02 +0000 |
commit | b7eb1aba93b3ac2d705e4aad3246c5f76fce80c6 (patch) | |
tree | 714b8edf063377cfedda18886d9f94ddf1954000 | |
parent | f92746838339eef73b05653e5a9890d321948a46 (diff) |
Enhancement (TrueType fonts): Add support for Adobe's use of Identity CMap in PDF files,
when substituting a TrueType font, mapped as a CIDFont from disk, for a missing CIDFont.
Details:
bug #688515 "Need method to map CIDFonts to TrueType fonts when Ordering is Identity"
This issue also covers issues #689499, #688813, #689623 and #690483.
When using a native TrueType font from disk as a replacement for a CIDFont, GS needs a
way to convert the character code used in the input file (either PostScript or PDF) into
a TrueType glyph ID (GID).
When the TrueType font is declared (in cidfmap), the CSI entry contains an Ordering, this is concatenated with the CMAP declared in the actual TrueType font. This
information is used to create a CIDDecoding resource, certain combinations (defined in
.CMapChooser) create CIDDecoding resources 'on the fly'.
A CIDDecoding resource simply maps a character code directly to a GID. Normally this
resource, when automatically created, is manufactured by converting the character code
to an internal code (using the declared CMap from cidfmap) and then converting the
internal code to a GID using the TrueType CMAP table. Most often the internal code
is a Unicode code point.
The investigation in 688515 makes it clear that when we have an Identity CMap in a
PDF file the character code should be treated as the GID. This makes it very easy for
us to construct a CIDDecoding resource, its a simple one-to-one. Unfortunately the
existing machinery relies upon a CMap, and there is already a mapping for
Identity.Symbol (An Identity CMap with a font whose CMAP table is a Symbol table).
We don't want to break this existing functionality, so the new code adds an entry
in .CMapChooser for Identity.Unicode (only to avoid errors) and then in the
function which actually loads the TT font (load_sfnts in gs_cidtt.ps) we check
specifically for an Identity.Unicode Decoding. If we find one then we call a new
routine to create an Identity mapping (CIDMap) from character code to GID.
Expected Differences
None
git-svn-id: http://svn.ghostscript.com/ghostscript/trunk@9834 a1074d23-0009-0410-80fe-cf8c14f379e6
-rw-r--r-- | gs/Resource/Init/gs_ciddc.ps | 1 | ||||
-rw-r--r-- | gs/Resource/Init/gs_cidtt.ps | 16 | ||||
-rw-r--r-- | gs/psi/icid.h | 2 | ||||
-rw-r--r-- | gs/psi/zcid.c | 31 | ||||
-rw-r--r-- | gs/psi/zfcid1.c | 15 |
5 files changed, 63 insertions, 2 deletions
diff --git a/gs/Resource/Init/gs_ciddc.ps b/gs/Resource/Init/gs_ciddc.ps index 222b570d2..2949677a2 100644 --- a/gs/Resource/Init/gs_ciddc.ps +++ b/gs/Resource/Init/gs_ciddc.ps @@ -170,6 +170,7 @@ begin /Korea1.Unicode [ /UniKS-UCS2-H /UniKS-UCS2-V ] /Identity.Symbol [ /Identity-H /Identity-V ] /Unicode.Unicode [ /Identity-UTF16-H ] + /Identity.Unicode [ /Identity-UTF16-H ] >> def /.MakeInstance % <name> .MakeInstance <inst> diff --git a/gs/Resource/Init/gs_cidtt.ps b/gs/Resource/Init/gs_cidtt.ps index 295d95b08..d912ee53e 100644 --- a/gs/Resource/Init/gs_cidtt.ps +++ b/gs/Resource/Init/gs_cidtt.ps @@ -55,6 +55,13 @@ currentdict /super.complete_instance currentdict /complete_instance get put currentdict end } bind def +/GenerateIdentityCIDMap % <font> GenerateCIDMap <font> +{ begin + /CIDMap [ 44000 string 44000 string 44000 string] def + CIDMap .fillIdentityCIDMap + currentdict end +} bind def + /load_sfnts % <FontDict> load_sfnts <FontDict> { % Read the True Type file from the path /Path, and buld /sfnts, % skipping glyf and loca. @@ -83,8 +90,13 @@ currentdict /super.complete_instance currentdict /complete_instance get put } { pop pop pop } ifelse - //ChooseDecoding exec % <font> - //GenerateCIDMap exec % <font> + dup /Decoding get /Identity.Unicode eq { + //ChooseDecoding exec % <font> + //GenerateIdentityCIDMap exec % <font> + } { + //ChooseDecoding exec % <font> + //GenerateCIDMap exec % <font> + } ifelse } bind def %-----------TrueType-specific methods for category redefinition : ----------- diff --git a/gs/psi/icid.h b/gs/psi/icid.h index 8c108e3f7..4bdf5ff0b 100644 --- a/gs/psi/icid.h +++ b/gs/psi/icid.h @@ -35,6 +35,8 @@ int cid_to_TT_charcode(const gs_memory_t *mem, /* Create a CIDMap from a True Type cmap, Decoding and SubstNWP. */ int cid_fill_CIDMap(const gs_memory_t *mem, const ref *Decoding, const ref *TT_cmap, const ref *SubstNWP, int GDBytes, ref *CIDMap); +/* Create an identity CIDMap. */ +int cid_fill_Identity_CIDMap(const gs_memory_t *mem, ref *CIDMap); /* <cid9font> <cid> .type9mapcid <charstring> <font_index> */ int ztype9mapcid(i_ctx_t *i_ctx_p); diff --git a/gs/psi/zcid.c b/gs/psi/zcid.c index 33c3bdc46..05ed5ec56 100644 --- a/gs/psi/zcid.c +++ b/gs/psi/zcid.c @@ -21,6 +21,7 @@ #include "idparam.h" #include "store.h" #include "oper.h" +#include "gserrors.h" /* Get the information from a CIDSystemInfo dictionary. */ int @@ -212,3 +213,33 @@ cid_fill_CIDMap(const gs_memory_t *mem, } return 0; } + +int +cid_fill_Identity_CIDMap(const gs_memory_t *mem, + ref *CIDMap) +{ int dict_enum; + ref el[2]; + int count, i; + + count = r_size(CIDMap); + if (count != 3) + return_error(gs_error_rangecheck); + + /* Checking the CIDMap structure correctness : */ + for (i = 0; i < count; i++) { + ref s; + int code = array_get(mem, CIDMap, i, &s); + + if (code < 0) + return code; + check_type(s, t_string); /* fixme : optimize with moving to TT_char_code_from_CID. */ + } + for (i=0; i < 255*255; i++) { + int code; + + code = set_CIDMap_element(mem, CIDMap, i, i); + if (code < 0) + return code; + } + return 0; +} diff --git a/gs/psi/zfcid1.c b/gs/psi/zfcid1.c index b4f393574..0b8c7380b 100644 --- a/gs/psi/zfcid1.c +++ b/gs/psi/zfcid1.c @@ -550,6 +550,20 @@ zfillCIDMap(i_ctx_t *i_ctx_p) return code; } +static int +zfillIdentityCIDMap(i_ctx_t *i_ctx_p) +{ + os_ptr op = osp; + ref *Decoding = op - 4, *TT_cmap = op - 3, *SubstNWP = op - 2, + *GDBytes = op - 1, *CIDMap = op; + int code; + + check_type(*CIDMap, t_array); + code = cid_fill_Identity_CIDMap(imemory, CIDMap); + pop(1); + return code; +} + /* ------ Initialization procedure ------ */ const op_def zfcid1_op_defs[] = @@ -558,5 +572,6 @@ const op_def zfcid1_op_defs[] = {"2.buildfont11", zbuildfont11}, {"2.type11mapcid", ztype11mapcid}, {"2.fillCIDMap", zfillCIDMap}, + {"2.fillIdentityCIDMap", zfillIdentityCIDMap}, op_def_end(0) }; |