summaryrefslogtreecommitdiffstats
path: root/src/autofit/afcjk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/autofit/afcjk.c')
-rw-r--r--src/autofit/afcjk.c251
1 files changed, 127 insertions, 124 deletions
diff --git a/src/autofit/afcjk.c b/src/autofit/afcjk.c
index 7a6f835..ca7acca 100644
--- a/src/autofit/afcjk.c
+++ b/src/autofit/afcjk.c
@@ -2,9 +2,9 @@
/* */
/* afcjk.c */
/* */
-/* Auto-fitter hinting routines for CJK script (body). */
+/* Auto-fitter hinting routines for CJK writing system (body). */
/* */
-/* Copyright 2006-2013 by */
+/* Copyright 2006-2014 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -27,6 +27,7 @@
#include FT_INTERNAL_DEBUG_H
#include "afglobal.h"
+#include "afpic.h"
#include "aflatin.h"
@@ -74,10 +75,10 @@
FT_TRACE5(( "\n"
- "cjk standard widths computation (script `%s')\n"
- "===============================================\n"
+ "cjk standard widths computation (style `%s')\n"
+ "===================================================\n"
"\n",
- af_script_names[metrics->root.script_class->script] ));
+ af_style_names[metrics->root.style_class->style] ));
af_glyph_hints_init( hints, face->memory );
@@ -86,20 +87,59 @@
{
FT_Error error;
- FT_UInt glyph_index;
+ FT_ULong glyph_index;
+ FT_Long y_offset;
int dim;
AF_CJKMetricsRec dummy[1];
AF_Scaler scaler = &dummy->root.scaler;
+#ifdef FT_CONFIG_OPTION_PIC
+ AF_FaceGlobals globals = metrics->root.globals;
+#endif
- glyph_index = FT_Get_Char_Index(
- face,
- metrics->root.script_class->standard_char );
- if ( glyph_index == 0 )
- goto Exit;
+ AF_StyleClass style_class = metrics->root.style_class;
+ AF_ScriptClass script_class = AF_SCRIPT_CLASSES_GET
+ [style_class->script];
+
+ FT_UInt32 standard_char;
+
+
+ standard_char = script_class->standard_char1;
+ af_get_char_index( &metrics->root,
+ standard_char,
+ &glyph_index,
+ &y_offset );
+ if ( !glyph_index )
+ {
+ if ( script_class->standard_char2 )
+ {
+ standard_char = script_class->standard_char2;
+ af_get_char_index( &metrics->root,
+ standard_char,
+ &glyph_index,
+ &y_offset );
+ if ( !glyph_index )
+ {
+ if ( script_class->standard_char3 )
+ {
+ standard_char = script_class->standard_char3;
+ af_get_char_index( &metrics->root,
+ standard_char,
+ &glyph_index,
+ &y_offset );
+ if ( !glyph_index )
+ goto Exit;
+ }
+ else
+ goto Exit;
+ }
+ }
+ else
+ goto Exit;
+ }
FT_TRACE5(( "standard character: U+%04lX (glyph index %d)\n",
- metrics->root.script_class->standard_char, glyph_index ));
+ standard_char, glyph_index ));
error = FT_Load_Glyph( face, glyph_index, FT_LOAD_NO_SCALE );
if ( error || face->glyph->outline.n_points <= 0 )
@@ -118,7 +158,7 @@
scaler->render_mode = FT_RENDER_MODE_NORMAL;
scaler->flags = 0;
- af_glyph_hints_rescale( hints, (AF_ScriptMetrics)dummy );
+ af_glyph_hints_rescale( hints, (AF_StyleMetrics)dummy );
error = af_glyph_hints_reload( hints, &face->glyph->outline );
if ( error )
@@ -138,6 +178,8 @@
goto Exit;
af_latin_hints_link_segments( hints,
+ 0,
+ NULL,
(AF_Dimension)dim );
seg = axhints->segments;
@@ -221,34 +263,22 @@
FT_Int num_fills;
FT_Int num_flats;
+ FT_Bool fill;
+
AF_CJKBlue blue;
FT_Error error;
AF_CJKAxis axis;
FT_Outline outline;
- AF_Blue_Stringset bss = metrics->root.script_class->blue_stringset;
- const AF_Blue_StringRec* bs = &af_blue_stringsets[bss];
+ AF_StyleClass sc = metrics->root.style_class;
-#ifdef FT_DEBUG_LEVEL_TRACE
- FT_String* cjk_blue_name[4] =
- {
- (FT_String*)"bottom", /* -- , -- */
- (FT_String*)"top", /* -- , TOP */
- (FT_String*)"left", /* HORIZ, -- */
- (FT_String*)"right" /* HORIZ, TOP */
- };
-
- FT_String* cjk_blue_type_name[2] =
- {
- (FT_String*)"unfilled", /* -- */
- (FT_String*)"filled" /* FILL */
- };
-#endif
+ AF_Blue_Stringset bss = sc->blue_stringset;
+ const AF_Blue_StringRec* bs = &af_blue_stringsets[bss];
- /* we walk over the blue character strings as specified in the */
- /* script's entry in the `af_blue_stringset' array, computing its */
- /* extremum points (depending on the string properties) */
+ /* we walk over the blue character strings as specified in the */
+ /* style's entry in the `af_blue_stringset' array, computing its */
+ /* extremum points (depending on the string properties) */
FT_TRACE5(( "cjk blue zones computation\n"
"==========================\n"
@@ -266,20 +296,35 @@
else
axis = &metrics->axis[AF_DIMENSION_VERT];
- FT_TRACE5(( "blue zone %d:\n", axis->blue_count ));
+#ifdef FT_DEBUG_LEVEL_TRACE
+ {
+ FT_String* cjk_blue_name[4] =
+ {
+ (FT_String*)"bottom", /* -- , -- */
+ (FT_String*)"top", /* -- , TOP */
+ (FT_String*)"left", /* HORIZ, -- */
+ (FT_String*)"right" /* HORIZ, TOP */
+ };
+
+
+ FT_TRACE5(( "blue zone %d (%s):\n",
+ axis->blue_count,
+ cjk_blue_name[AF_CJK_IS_HORIZ_BLUE( bs ) |
+ AF_CJK_IS_TOP_BLUE( bs ) ] ));
+ }
+#endif /* FT_DEBUG_LEVEL_TRACE */
num_fills = 0;
num_flats = 0;
- FT_TRACE5(( " cjk blue %s/%s\n",
- cjk_blue_name[AF_CJK_IS_HORIZ_BLUE( bs ) |
- AF_CJK_IS_TOP_BLUE( bs ) ],
- cjk_blue_type_name[!!AF_CJK_IS_FILLED_BLUE( bs )] ));
+ fill = 1; /* start with characters that define fill values */
+ FT_TRACE5(( " [overshoot values]\n" ));
while ( *p )
{
FT_ULong ch;
- FT_UInt glyph_index;
+ FT_ULong glyph_index;
+ FT_Long y_offset;
FT_Pos best_pos; /* same as points.y or points.x, resp. */
FT_Int best_point;
FT_Vector* points;
@@ -287,8 +332,16 @@
GET_UTF8_CHAR( ch, p );
+ /* switch to characters that define flat values */
+ if ( ch == '|' )
+ {
+ fill = 0;
+ FT_TRACE5(( " [reference values]\n" ));
+ continue;
+ }
+
/* load the character in the face -- skip unknown or empty ones */
- glyph_index = FT_Get_Char_Index( face, ch );
+ af_get_char_index( &metrics->root, ch, &glyph_index, &y_offset );
if ( glyph_index == 0 )
{
FT_TRACE5(( " U+%04lX unavailable\n", ch ));
@@ -374,7 +427,7 @@
FT_TRACE5(( " U+%04lX: best_pos = %5ld\n", ch, best_pos ));
}
- if ( AF_CJK_IS_FILLED_BLUE( bs ) )
+ if ( fill )
fills[num_fills++] = best_pos;
else
flats[num_flats++] = best_pos;
@@ -386,15 +439,15 @@
* we couldn't find a single glyph to compute this blue zone,
* we will simply ignore it then
*/
- FT_TRACE5(( " empty\n" ));
+ FT_TRACE5(( " empty\n" ));
continue;
}
- /* we have computed the contents of the `fill' and `flats' tables, */
- /* now determine the reference position of the blue zone -- */
- /* we simply take the median value after a simple sort */
- af_sort_pos( num_flats, flats );
+ /* we have computed the contents of the `fill' and `flats' tables, */
+ /* now determine the reference and overshoot position of the blue -- */
+ /* we simply take the median value after a simple sort */
af_sort_pos( num_fills, fills );
+ af_sort_pos( num_flats, flats );
blue = &axis->blues[axis->blue_count];
blue_ref = &blue->ref.org;
@@ -433,7 +486,7 @@
*blue_ref =
*blue_shoot = ( shoot + ref ) / 2;
- FT_TRACE5(( " [overshoot smaller than reference,"
+ FT_TRACE5(( " [reference smaller than overshoot,"
" taking mean value]\n" ));
}
}
@@ -467,10 +520,11 @@
/* digit `0' is 0x30 in all supported charmaps */
for ( i = 0x30; i <= 0x39; i++ )
{
- FT_UInt glyph_index;
+ FT_ULong glyph_index;
+ FT_Long y_offset;
- glyph_index = FT_Get_Char_Index( face, i );
+ af_get_char_index( &metrics->root, i, &glyph_index, &y_offset );
if ( glyph_index == 0 )
continue;
@@ -1186,8 +1240,10 @@
/* zone, check for left edges */
/* */
/* of course, that's for TrueType */
- is_top_right_blue = FT_BOOL( blue->flags & AF_CJK_BLUE_TOP );
- is_major_dir = FT_BOOL( edge->dir == axis->major_dir );
+ is_top_right_blue =
+ (FT_Byte)( ( blue->flags & AF_CJK_BLUE_TOP ) != 0 );
+ is_major_dir =
+ FT_BOOL( edge->dir == axis->major_dir );
/* if it is a top zone, the edge must be against the major */
/* direction; if it is a bottom zone, it must be in the major */
@@ -1234,7 +1290,7 @@
FT_UInt32 scaler_flags, other_flags;
- af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics );
+ af_glyph_hints_rescale( hints, (AF_StyleMetrics)metrics );
/*
* correct x_scale and y_scale when needed, since they may have
@@ -1484,6 +1540,12 @@
stem_edge->pos = base_edge->pos + fitted_width;
+
+ FT_TRACE5(( " CJKLINK: edge %d @%d (opos=%.2f) linked to %.2f,"
+ " dist was %.2f, now %.2f\n",
+ stem_edge - hints->axis[dim].edges, stem_edge->fpos,
+ stem_edge->opos / 64.0, stem_edge->pos / 64.0,
+ dist / 64.0, fitted_width / 64.0 ));
}
@@ -1665,9 +1727,9 @@
#endif
- FT_TRACE5(( "cjk %s edge hinting (script `%s')\n",
+ FT_TRACE5(( "cjk %s edge hinting (style `%s')\n",
dim == AF_DIMENSION_VERT ? "horizontal" : "vertical",
- af_script_names[hints->metrics->script_class->script] ));
+ af_style_names[hints->metrics->style_class->style] ));
/* we begin by aligning all stems relative to the blue zone */
@@ -2210,60 +2272,18 @@
sizeof ( AF_CJKMetricsRec ),
- (AF_Script_InitMetricsFunc) af_cjk_metrics_init,
- (AF_Script_ScaleMetricsFunc)af_cjk_metrics_scale,
- (AF_Script_DoneMetricsFunc) NULL,
+ (AF_WritingSystem_InitMetricsFunc) af_cjk_metrics_init,
+ (AF_WritingSystem_ScaleMetricsFunc)af_cjk_metrics_scale,
+ (AF_WritingSystem_DoneMetricsFunc) NULL,
- (AF_Script_InitHintsFunc) af_cjk_hints_init,
- (AF_Script_ApplyHintsFunc) af_cjk_hints_apply
+ (AF_WritingSystem_InitHintsFunc) af_cjk_hints_init,
+ (AF_WritingSystem_ApplyHintsFunc) af_cjk_hints_apply
)
- /* this corresponds to Unicode 6.0 */
-
- /* XXX: this should probably fine tuned to differentiate better between */
- /* scripts... */
-
- static const AF_Script_UniRangeRec af_hani_uniranges[] =
- {
- AF_UNIRANGE_REC( 0x1100UL, 0x11FFUL ), /* Hangul Jamo */
- AF_UNIRANGE_REC( 0x2E80UL, 0x2EFFUL ), /* CJK Radicals Supplement */
- AF_UNIRANGE_REC( 0x2F00UL, 0x2FDFUL ), /* Kangxi Radicals */
- AF_UNIRANGE_REC( 0x2FF0UL, 0x2FFFUL ), /* Ideographic Description Characters */
- AF_UNIRANGE_REC( 0x3000UL, 0x303FUL ), /* CJK Symbols and Punctuation */
- AF_UNIRANGE_REC( 0x3040UL, 0x309FUL ), /* Hiragana */
- AF_UNIRANGE_REC( 0x30A0UL, 0x30FFUL ), /* Katakana */
- AF_UNIRANGE_REC( 0x3100UL, 0x312FUL ), /* Bopomofo */
- AF_UNIRANGE_REC( 0x3130UL, 0x318FUL ), /* Hangul Compatibility Jamo */
- AF_UNIRANGE_REC( 0x3190UL, 0x319FUL ), /* Kanbun */
- AF_UNIRANGE_REC( 0x31A0UL, 0x31BFUL ), /* Bopomofo Extended */
- AF_UNIRANGE_REC( 0x31C0UL, 0x31EFUL ), /* CJK Strokes */
- AF_UNIRANGE_REC( 0x31F0UL, 0x31FFUL ), /* Katakana Phonetic Extensions */
- AF_UNIRANGE_REC( 0x3200UL, 0x32FFUL ), /* Enclosed CJK Letters and Months */
- AF_UNIRANGE_REC( 0x3300UL, 0x33FFUL ), /* CJK Compatibility */
- AF_UNIRANGE_REC( 0x3400UL, 0x4DBFUL ), /* CJK Unified Ideographs Extension A */
- AF_UNIRANGE_REC( 0x4DC0UL, 0x4DFFUL ), /* Yijing Hexagram Symbols */
- AF_UNIRANGE_REC( 0x4E00UL, 0x9FFFUL ), /* CJK Unified Ideographs */
- AF_UNIRANGE_REC( 0xA960UL, 0xA97FUL ), /* Hangul Jamo Extended-A */
- AF_UNIRANGE_REC( 0xAC00UL, 0xD7AFUL ), /* Hangul Syllables */
- AF_UNIRANGE_REC( 0xD7B0UL, 0xD7FFUL ), /* Hangul Jamo Extended-B */
- AF_UNIRANGE_REC( 0xF900UL, 0xFAFFUL ), /* CJK Compatibility Ideographs */
- AF_UNIRANGE_REC( 0xFE10UL, 0xFE1FUL ), /* Vertical forms */
- AF_UNIRANGE_REC( 0xFE30UL, 0xFE4FUL ), /* CJK Compatibility Forms */
- AF_UNIRANGE_REC( 0xFF00UL, 0xFFEFUL ), /* Halfwidth and Fullwidth Forms */
- AF_UNIRANGE_REC( 0x1B000UL, 0x1B0FFUL ), /* Kana Supplement */
- AF_UNIRANGE_REC( 0x1D300UL, 0x1D35FUL ), /* Tai Xuan Hing Symbols */
- AF_UNIRANGE_REC( 0x1F200UL, 0x1F2FFUL ), /* Enclosed Ideographic Supplement */
- AF_UNIRANGE_REC( 0x20000UL, 0x2A6DFUL ), /* CJK Unified Ideographs Extension B */
- AF_UNIRANGE_REC( 0x2A700UL, 0x2B73FUL ), /* CJK Unified Ideographs Extension C */
- AF_UNIRANGE_REC( 0x2B740UL, 0x2B81FUL ), /* CJK Unified Ideographs Extension D */
- AF_UNIRANGE_REC( 0x2F800UL, 0x2FA1FUL ), /* CJK Compatibility Ideographs Supplement */
- AF_UNIRANGE_REC( 0UL, 0UL )
- };
-
-
#else /* !AF_CONFIG_OPTION_CJK */
+
AF_DEFINE_WRITING_SYSTEM_CLASS(
af_cjk_writing_system_class,
@@ -2271,33 +2291,16 @@
sizeof ( AF_CJKMetricsRec ),
- (AF_Script_InitMetricsFunc) NULL,
- (AF_Script_ScaleMetricsFunc)NULL,
- (AF_Script_DoneMetricsFunc) NULL,
+ (AF_WritingSystem_InitMetricsFunc) NULL,
+ (AF_WritingSystem_ScaleMetricsFunc)NULL,
+ (AF_WritingSystem_DoneMetricsFunc) NULL,
- (AF_Script_InitHintsFunc) NULL,
- (AF_Script_ApplyHintsFunc) NULL
+ (AF_WritingSystem_InitHintsFunc) NULL,
+ (AF_WritingSystem_ApplyHintsFunc) NULL
)
- static const AF_Script_UniRangeRec af_hani_uniranges[] =
- {
- AF_UNIRANGE_REC( 0UL, 0UL )
- };
-
#endif /* !AF_CONFIG_OPTION_CJK */
- AF_DEFINE_SCRIPT_CLASS(
- af_hani_script_class,
-
- AF_SCRIPT_HANI,
- AF_BLUE_STRINGSET_HANI,
- AF_WRITING_SYSTEM_CJK,
-
- af_hani_uniranges,
- 0x7530 /* 田 */
- )
-
-
/* END */