diff options
author | Igor Melichev <igor.melichev@artifex.com> | 2008-11-09 19:09:30 +0000 |
---|---|---|
committer | Igor Melichev <igor.melichev@artifex.com> | 2008-11-09 19:09:30 +0000 |
commit | b1169da2d6c791b1c3a2ffd27d020fe2ef228a00 (patch) | |
tree | adc82d0116bb6c07549da02deaf63c30eb9e9718 /gs/base/gstype42.c | |
parent | 7b04480cdf6a6593407dcd5264a0f725e8f9d07d (diff) |
Fix (CID font emulation) : CID from another writing mode rendered a wrong
glyph (part 1).
This revision is incomplete due to a commitment error. Please use next
revision.
DETAILS :
This is a second partial fix for Bug 689304
"improper handling of vertical japanese text", related to Comment #30, #31.
When emulating a CID font with an Open Type font, a CID is first
mapped to an OpenType encoding and then to a glyph index.
However OpenType provides same character codes for glyph variants,
which render differently depending on writing mode.
The glyph '(' is an example.
This patch works for OpenType fonts only, which provide a GSUB for vertical
writing mode.
It is not working for True Type collections with no GSUB.
They need a further improvement.
The patch assumes that all interpreters initialize a Type 42 font with
zeroing all its fields.
Postscript interpreter does so since a long ago, but we're not sure about
others.
They may need an improvement.
1. Define a new resource category SubstCID (Resource/Init/gs_ciddc.ps).
2. Provide a tool for generating resources for that category
(toolbin/GenSubstCID).
3. Provide resources for various orderings (Resource/SubstCID/CNS1-WMode,
Resource/SubstCID/GB1-WMode, Resource/SubstCID/Japan1-WMode,
Resource/SubstCID/Korea1-WMode).
4. When loading a TrueType or OpenType font for a CID font emulation,
associate an
appropriate SubstCID resource to it (Resource/Init\gs_cidtt.ps).
(We do associate the resource with TrueType hoping that some
True Type fonts may provide GSUB).
5. Define a new structure gs_subst_CID_on_WMode_s for storing that
information
for the graphics library (base\gxfcid.h), and its garbager descriptor
(base/gsfcid.c).
Since it may duplicate for several fonts, it is shared and
reference-counted.
6. The new function get_subst_CID_on_WMode loads the resource data for the
graphics library
in psi\zfcid1.c . Note it is implemented for PS interpreter only.
7. Generalized gs_type42_substitute_glyph_index_vertical with providing a
CID in base/gstype42.c
and made it be a virtual function of gs_font_type42 (base/gxfont42.c).
We're not sure how other interpreters initialize the font, so
we're checking it for NULL for safety and use
gs_type42_substitute_glyph_index_vertical
as a default implementation.
8. font11_substitute_glyph_index_vertical is another implementation of that
function, which
accounts gs_subst_CID_on_WMode_s data for providing a right glyph depending
on WMode.
Rather a SubstCID resource provides a substitution, currently
we only use the fact that a CID is substituted, and never use
the substituting CID. Nevertheless we prefer to define and store the
resource
in the complete form for possible improvements in future (zfcid1.c).
9. release_subst_CID_on_WMode automatically releases the resource data
when all fonts (that use it) are released.
10. Added SubstCID to the ROM file system in psi/psromfs.mak .
11. Minor unrelated fix : propagate errors from gs_font_notify_register for
(7) in base/gstype42.c .
EXPECTED DIFFERENCES :
None.
git-svn-id: http://svn.ghostscript.com/ghostscript/trunk@9212 a1074d23-0009-0410-80fe-cf8c14f379e6
Diffstat (limited to 'gs/base/gstype42.c')
-rw-r--r-- | gs/base/gstype42.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/gs/base/gstype42.c b/gs/base/gstype42.c index 29d904c47..846bed067 100644 --- a/gs/base/gstype42.c +++ b/gs/base/gstype42.c @@ -309,7 +309,9 @@ gs_type42_font_init(gs_font_type42 * pfont, int subfontID) "gs_type42_font_init"); if (pfont->data.len_glyphs == 0) return_error(gs_error_VMerror); - gs_font_notify_register((gs_font *)pfont, gs_len_glyphs_release, (void *)pfont); + code = gs_font_notify_register((gs_font *)pfont, gs_len_glyphs_release, (void *)pfont); + if (code < 0) + return code; /* The 'loca' may not be in order, so we construct a glyph length array */ /* Since 'loca' is usually sorted, first try the simple linear scan to */ @@ -654,7 +656,8 @@ gs_type42_get_outline_from_TT_file(gs_font_type42 * pfont, stream *s, uint glyph } uint -gs_type42_substitute_glyph_index_vertical(gs_font_type42 *pfont, uint glyph_index) +gs_type42_substitute_glyph_index_vertical(gs_font_type42 *pfont, uint glyph_index, + int WMode, gs_glyph cid) { /* A rough trial implementation, possibly needs improvements or optimization. */ /* Fixme: optimize : Initialize subtable_ptr when the font is defined. */ byte *gsub_ptr = pfont->data.gsub; @@ -740,6 +743,9 @@ gs_type42_substitute_glyph_index_vertical(gs_font_type42 *pfont, uint glyph_inde LookupListTable lookup_list_table; byte *lookup_list_ptr; + if (WMode == 0) + return glyph_index; + /* GSUB header */ gsub.Version = u32(gsub_ptr + offset_of(GSUB, Version)); gsub.ScriptList = U16(gsub_ptr + offset_of(GSUB, ScriptList)); @@ -885,8 +891,12 @@ gs_type42_glyph_outline(gs_font *font, int WMode, gs_glyph glyph, const gs_matri glyph_index = glyph - GS_MIN_GLYPH_INDEX; else { glyph_index = pfont->data.get_glyph_index(pfont, glyph); - if (WMode && pfont->data.gsub_size) - glyph_index = gs_type42_substitute_glyph_index_vertical(pfont, glyph_index); + if (pfont->data.gsub_size) { + if (pfont->data.substitute_glyph_index_vertical != NULL) + glyph_index = pfont->data.substitute_glyph_index_vertical(pfont, glyph_index, WMode, glyph); + else + glyph_index = gs_type42_substitute_glyph_index_vertical(pfont, glyph_index, WMode, glyph); + } } code = gx_lookup_fm_pair(font, pmat, &log2_scale, design_grid, &pair); if (code < 0) @@ -981,8 +991,14 @@ gs_type42_glyph_info(gs_font *font, gs_glyph glyph, const gs_matrix *pmat, glyph_index = pfont->data.get_glyph_index(pfont, glyph); if (glyph_index == GS_NO_GLYPH) return_error(gs_error_undefined); - if ((members & (GLYPH_INFO_WIDTH1 | GLYPH_INFO_VVECTOR1)) && pfont->data.gsub_size) - glyph_index = gs_type42_substitute_glyph_index_vertical(pfont, glyph_index); + if (pfont->data.gsub_size) { + int WMode = ((members & (GLYPH_INFO_WIDTH1 | GLYPH_INFO_VVECTOR1)) ? 1 : 0); + + if (pfont->data.substitute_glyph_index_vertical != NULL) + glyph_index = pfont->data.substitute_glyph_index_vertical(pfont, glyph_index, WMode, glyph); + else + glyph_index = gs_type42_substitute_glyph_index_vertical(pfont, glyph_index, WMode, glyph); + } } return gs_type42_glyph_info_by_gid(font, glyph, pmat, members, info, glyph_index); |