summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Sharp <ken.sharp@artifex.com>2009-07-03 09:27:02 +0000
committerKen Sharp <ken.sharp@artifex.com>2009-07-03 09:27:02 +0000
commitb7eb1aba93b3ac2d705e4aad3246c5f76fce80c6 (patch)
tree714b8edf063377cfedda18886d9f94ddf1954000
parentf92746838339eef73b05653e5a9890d321948a46 (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.ps1
-rw-r--r--gs/Resource/Init/gs_cidtt.ps16
-rw-r--r--gs/psi/icid.h2
-rw-r--r--gs/psi/zcid.c31
-rw-r--r--gs/psi/zfcid1.c15
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)
};