Implement the first substitute()

This commit is contained in:
Behdad Esfahbod 2009-04-15 22:56:15 -04:00
parent ce48f03946
commit 30bd763fa2
14 changed files with 151 additions and 56 deletions

View File

@ -33,7 +33,7 @@
HB_BEGIN_HEADER
#define HB_GLYPH_PROPERTIES_UNKNOWN 0xFFFF
#define HB_GLYPH_PROPERTY_UNKNOWN 0xFFFF
HB_INTERNAL void
_hb_buffer_swap( HB_Buffer buffer );
@ -83,9 +83,9 @@ _hb_buffer_allocate_ligid( HB_Buffer buffer );
#define OUT_GLYPH( pos ) (buffer->out_string[(pos)].gindex)
#define OUT_ITEM( pos ) (&buffer->out_string[(pos)])
#define CHECK_Property( layout, index, flags, property ) \
(error = _hb_ot_layout_check_glyph_properties((layout), (index), (flags), (property)) \
? HB_Err_Ok : HB_Err_Not_Covered)
#define CHECK_Property( layout, index, flags, properties ) \
({unsigned int _p; error = _hb_ot_layout_check_glyph_property((layout), (index), (flags), (&_p)) \
? HB_Err_Ok : HB_Err_Not_Covered, *(properties) = _p; error;})
#define ADD_String( buffer, num_in, num_out, glyph_data, component, ligID ) \
( ( error = _hb_buffer_add_output_glyphs( (buffer), \

View File

@ -187,7 +187,7 @@ hb_buffer_add_glyph( HB_Buffer buffer,
glyph->cluster = cluster;
glyph->component = 0;
glyph->ligID = 0;
glyph->gproperties = HB_GLYPH_PROPERTIES_UNKNOWN;
glyph->gproperty = HB_GLYPH_PROPERTY_UNKNOWN;
buffer->in_length++;
@ -304,7 +304,7 @@ _hb_buffer_add_output_glyphs( HB_Buffer buffer,
item->cluster = cluster;
item->component = component;
item->ligID = ligID;
item->gproperties = HB_GLYPH_PROPERTIES_UNKNOWN;
item->gproperty = HB_GLYPH_PROPERTY_UNKNOWN;
}
buffer->in_pos += num_in;

View File

@ -38,7 +38,7 @@ typedef struct HB_GlyphItemRec_ {
HB_UInt cluster;
HB_UShort component;
HB_UShort ligID;
HB_UShort gproperties;
HB_UShort gproperty;
} HB_GlyphItemRec, *HB_GlyphItem;
typedef struct HB_PositionRec_ {

View File

@ -105,13 +105,13 @@ struct HB_LigGlyph_
HB_INTERNAL HB_Error
_HB_GDEF_Add_Glyph_Property( HB_GDEFHeader* gdef,
HB_UShort glyphID,
HB_UShort property );
HB_UShort properties );
HB_INTERNAL HB_Error
_HB_GDEF_Check_Property( HB_GDEFHeader* gdef,
HB_GlyphItem item,
HB_UShort flags,
HB_UShort* property );
HB_UShort* properties );
HB_INTERNAL HB_Error
_HB_GDEF_LoadMarkAttachClassDef_From_LookupFlags( HB_GDEFHeader* gdef,

View File

@ -1074,14 +1074,14 @@ _HB_GDEF_Check_Property( HB_GDEFHeader* gdef,
HB_UShort basic_glyph_class;
HB_UShort desired_attachment_class;
if ( gitem->gproperties == HB_GLYPH_PROPERTIES_UNKNOWN )
if ( gitem->gproperty == HB_GLYPH_PROPERTY_UNKNOWN )
{
error = HB_GDEF_Get_Glyph_Property( gdef, gitem->gindex, &gitem->gproperties );
error = HB_GDEF_Get_Glyph_Property( gdef, gitem->gindex, &gitem->gproperty );
if ( error )
return error;
}
*property = gitem->gproperties;
*property = gitem->gproperty;
/* If the glyph was found in the MarkAttachmentClass table,
* then that class value is the high byte of the result,

View File

@ -121,7 +121,7 @@ HB_Error HB_Done_GDEF_Table ( HB_GDEFHeader* gdef );
HB_Error HB_GDEF_Get_Glyph_Property( HB_GDEFHeader* gdef,
HB_UShort glyphID,
HB_UShort* property );
HB_UShort* properties );
HB_Error HB_GDEF_Build_ClassDefinition( HB_GDEFHeader* gdef,
HB_UShort num_glyphs,

View File

@ -1783,7 +1783,7 @@ static HB_Error Lookup_CursivePos( GPOS_Instance* gpi,
return HB_Err_Not_Covered;
}
/* Glyphs not having the right GDEF properties will be ignored, i.e.,
/* Glyphs not having the right GDEF property will be ignored, i.e.,
gpi->last won't be reset (contrary to user defined properties). */
if ( CHECK_Property( gpos->layout, IN_CURITEM(), flags, &property ) )
@ -2224,7 +2224,7 @@ static HB_Error Lookup_MarkBasePos( GPOS_Instance* gpi,
while ( i <= buffer->in_pos )
{
property = _hb_ot_layout_get_glyph_properties (gpos->layout, IN_GLYPH(j));
property = _hb_ot_layout_get_glyph_property (gpos->layout, IN_GLYPH(j));
if ( !property )
return HB_Err_Not_Covered;
@ -2633,7 +2633,7 @@ static HB_Error Lookup_MarkLigPos( GPOS_Instance* gpi,
while ( i <= buffer->in_pos )
{
property = _hb_ot_layout_get_glyph_properties (gpos->layout, IN_GLYPH(j));
property = _hb_ot_layout_get_glyph_property (gpos->layout, IN_GLYPH(j));
if ( !property )
return HB_Err_Not_Covered;
@ -2960,7 +2960,7 @@ static HB_Error Lookup_MarkMarkPos( GPOS_Instance* gpi,
j = buffer->in_pos - 1;
while ( i <= buffer->in_pos )
{
property = _hb_ot_layout_get_glyph_properties (gpos->layout, IN_GLYPH(j));
property = _hb_ot_layout_get_glyph_property (gpos->layout, IN_GLYPH(j));
if ( !property )
return HB_Err_Not_Covered;

View File

@ -145,7 +145,7 @@ HB_Error HB_GPOS_Query_Features( HB_GPOSHeader* gpos,
HB_Error HB_GPOS_Add_Feature( HB_GPOSHeader* gpos,
HB_UShort feature_index,
HB_UInt property );
HB_UInt properties );
HB_Error HB_GPOS_Clear_Features( HB_GPOSHeader* gpos );

View File

@ -121,7 +121,7 @@ HB_Error HB_GSUB_Query_Features( HB_GSUBHeader* gsub,
HB_Error HB_GSUB_Add_Feature( HB_GSUBHeader* gsub,
HB_UShort feature_index,
HB_UInt property );
HB_UInt properties );
HB_Error HB_GSUB_Clear_Features( HB_GSUBHeader* gsub );

View File

@ -32,20 +32,90 @@
#include "hb-ot-layout-open-private.h"
#include "hb-ot-layout-gdef-private.h"
#include "harfbuzz-buffer-private.h" /* XXX */
#define DEFINE_GET_GLYPH_COVERAGE(name) \
inline hb_ot_layout_coverage_t get_##name (hb_codepoint_t glyph) const { \
const Coverage &c = get_coverage (); \
return c.get_coverage (glyph); \
}
#define SUBTABLE_SUBSTITUTE \
bool substitute (hb_ot_layout_t *layout, \
hb_buffer_t *buffer, \
unsigned int context_length, \
unsigned int nesting_level_left, \
unsigned int lookup_flag) const
struct SingleSubstFormat1 {
friend struct SingleSubst;
private:
inline bool substitute (hb_ot_layout_t *layout,
hb_buffer_t *buffer,
unsigned int context_length,
unsigned int nesting_level_left) const {
// if (get_coverage (IN_CURGLYPH()))
// return ;
DEFINE_GET_ACCESSOR (Coverage, coverage, coverage);
DEFINE_GET_GLYPH_COVERAGE (glyph_coverage);
inline SUBTABLE_SUBSTITUTE {
hb_codepoint_t glyph_id;
hb_ot_layout_coverage_t index;
unsigned int property;
HB_UNUSED (nesting_level_left);
if (HB_UNLIKELY (context_length < 1))
return false;
if (!_hb_ot_layout_check_glyph_property (layout, IN_CURITEM (), lookup_flag, &property))
return false;
glyph_id = IN_CURGLYPH ();
index = get_glyph_coverage (glyph_id);
if (-1 == index)
return false;
glyph_id += deltaGlyphID;
_hb_buffer_replace_output_glyph (buffer, glyph_id, context_length == NO_CONTEXT);
if ( _hb_ot_layout_has_new_glyph_classes (layout) )
{
/* we inherit the old glyph class to the substituted glyph */
_hb_ot_layout_set_glyph_property (layout, glyph_id, property);
}
return true;
}
#if 0
switch ( ss->SubstFormat )
{
case 1:
value = (IN_CURGLYPH() + ss->ssf.ssf1.DeltaGlyphID ) & 0xFFFF;
if ( REPLACE_Glyph( buffer, value, nesting_level ) )
return error;
break;
case 2:
if ( index >= ss->ssf.ssf2.GlyphCount )
return ERR(HB_Err_Invalid_SubTable);
value = ss->ssf.ssf2.Substitute[index];
if ( REPLACE_Glyph( buffer, value, nesting_level ) )
return error;
break;
default:
return ERR(HB_Err_Invalid_SubTable);
}
if ( _hb_ot_layout_has_new_glyph_classes (layout) )
{
/* we inherit the old glyph class to the substituted glyph */
hb_ot_layout_set_glyph_class (layout, value, properties);
}
#endif
private:
USHORT substFormat; /* Format identifier--format = 1 */
Offset coverage; /* Offset to Coverage table--from
@ -490,7 +560,8 @@ struct SubstLookupSubTable {
hb_buffer_t *buffer,
unsigned int context_length,
unsigned int nesting_level_left,
unsigned int lookup_type) const {
unsigned int lookup_type,
unsigned int lookup_flag) const {
}
private:
@ -545,6 +616,7 @@ struct SubstLookup : Lookup {
unsigned int context_length,
unsigned int nesting_level_left) const {
unsigned int lookup_type = get_type ();
unsigned int lookup_flag = get_flag ();
if (HB_UNLIKELY (nesting_level_left == 0))
return false;
@ -553,7 +625,7 @@ struct SubstLookup : Lookup {
for (unsigned int i = 0; i < get_subtable_count (); i++)
if (get_subtable (i).substitute (layout, buffer,
context_length, nesting_level_left,
lookup_type))
lookup_type, lookup_flag))
return true;
return false;

View File

@ -671,7 +671,7 @@ struct Lookup {
inline bool ignore_base_glyphs(void) const { return lookupFlag & LookupFlag::IgnoreBaseGlyphs; }
inline bool ignore_ligatures (void) const { return lookupFlag & LookupFlag::IgnoreLigatures; }
inline bool ignore_marks (void) const { return lookupFlag & LookupFlag::IgnoreMarks; }
inline bool get_mark_attachment_type (void) const { return lookupFlag & LookupFlag::MarkAttachmentType; }
inline unsigned int get_mark_attachment_type (void) const { return lookupFlag & LookupFlag::MarkAttachmentType; }
inline unsigned int get_type (void) const { return lookupType; }
inline unsigned int get_flag (void) const { return lookupFlag; }

View File

@ -34,9 +34,7 @@
#include "harfbuzz-buffer.h"
typedef uint16_t hb_ot_layout_class_t;
typedef uint16_t hb_ot_layout_glyph_properties_t;
typedef uint16_t hb_ot_layout_lookup_flags_t;
typedef unsigned int hb_ot_layout_class_t;
typedef int hb_ot_layout_coverage_t; /* -1 is not covered, >= 0 otherwise */
/* XXX #define HB_OT_LAYOUT_INTERNAL static */
@ -51,15 +49,20 @@ HB_BEGIN_DECLS();
HB_OT_LAYOUT_INTERNAL hb_bool_t
_hb_ot_layout_has_new_glyph_classes (hb_ot_layout_t *layout);
HB_OT_LAYOUT_INTERNAL hb_ot_layout_glyph_properties_t
_hb_ot_layout_get_glyph_properties (hb_ot_layout_t *layout,
hb_codepoint_t glyph);
HB_OT_LAYOUT_INTERNAL unsigned int
_hb_ot_layout_get_glyph_property (hb_ot_layout_t *layout,
hb_codepoint_t glyph);
HB_OT_LAYOUT_INTERNAL void
_hb_ot_layout_set_glyph_property (hb_ot_layout_t *layout,
hb_codepoint_t glyph,
unsigned int property);
HB_OT_LAYOUT_INTERNAL hb_bool_t
_hb_ot_layout_check_glyph_properties (hb_ot_layout_t *layout,
HB_GlyphItem gitem,
hb_ot_layout_lookup_flags_t lookup_flags,
hb_ot_layout_glyph_properties_t *property);
_hb_ot_layout_check_glyph_property (hb_ot_layout_t *layout,
HB_GlyphItem gitem,
unsigned int lookup_flags,
unsigned int *property);
HB_END_DECLS();

View File

@ -98,6 +98,8 @@ hb_ot_layout_destroy (hb_ot_layout_t *layout)
* GDEF
*/
/* XXX the public class_t is a mess */
hb_bool_t
hb_ot_layout_has_font_glyph_classes (hb_ot_layout_t *layout)
{
@ -110,9 +112,9 @@ _hb_ot_layout_has_new_glyph_classes (hb_ot_layout_t *layout)
return layout->new_gdef.len > 0;
}
HB_OT_LAYOUT_INTERNAL hb_ot_layout_glyph_properties_t
_hb_ot_layout_get_glyph_properties (hb_ot_layout_t *layout,
hb_codepoint_t glyph)
HB_OT_LAYOUT_INTERNAL unsigned int
_hb_ot_layout_get_glyph_property (hb_ot_layout_t *layout,
hb_codepoint_t glyph)
{
hb_ot_layout_class_t klass;
@ -138,22 +140,22 @@ _hb_ot_layout_get_glyph_properties (hb_ot_layout_t *layout,
}
HB_OT_LAYOUT_INTERNAL hb_bool_t
_hb_ot_layout_check_glyph_properties (hb_ot_layout_t *layout,
HB_GlyphItem gitem,
hb_ot_layout_lookup_flags_t lookup_flags,
hb_ot_layout_glyph_properties_t *property)
_hb_ot_layout_check_glyph_property (hb_ot_layout_t *layout,
HB_GlyphItem gitem,
unsigned int lookup_flags,
unsigned int *property)
{
hb_ot_layout_glyph_class_t basic_glyph_class;
hb_ot_layout_glyph_properties_t desired_attachment_class;
unsigned int desired_attachment_class;
if (gitem->gproperties == HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN)
if (gitem->gproperty == HB_BUFFER_GLYPH_PROPERTIES_UNKNOWN)
{
gitem->gproperties = *property = _hb_ot_layout_get_glyph_properties (layout, gitem->gindex);
if (gitem->gproperties == HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED)
gitem->gproperty = *property = _hb_ot_layout_get_glyph_property (layout, gitem->gindex);
if (gitem->gproperty == HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED)
return false;
}
*property = gitem->gproperties;
*property = gitem->gproperty;
/* If the glyph was found in the MarkAttachmentClass table,
* then that class value is the high byte of the result,
@ -179,27 +181,42 @@ _hb_ot_layout_check_glyph_properties (hb_ot_layout_t *layout,
if (desired_attachment_class)
{
if (basic_glyph_class == HB_OT_LAYOUT_GLYPH_CLASS_MARK &&
*property != desired_attachment_class )
*property != desired_attachment_class)
return false;
}
return true;
}
HB_OT_LAYOUT_INTERNAL void
_hb_ot_layout_set_glyph_property (hb_ot_layout_t *layout,
hb_codepoint_t glyph,
unsigned int property)
{
hb_ot_layout_glyph_class_t klass;
if (property & LookupFlag::MarkAttachmentType)
klass = HB_OT_LAYOUT_GLYPH_CLASS_MARK;
else
klass = (hb_ot_layout_glyph_class_t) property;
hb_ot_layout_set_glyph_class (layout, glyph, klass);
}
hb_ot_layout_glyph_class_t
hb_ot_layout_get_glyph_class (hb_ot_layout_t *layout,
hb_codepoint_t glyph)
{
hb_ot_layout_glyph_properties_t properties;
unsigned int property;
hb_ot_layout_class_t klass;
properties = _hb_ot_layout_get_glyph_properties (layout, glyph);
property = _hb_ot_layout_get_glyph_property (layout, glyph);
if (properties & 0xFF00)
if (property & LookupFlag::MarkAttachmentType)
return HB_OT_LAYOUT_GLYPH_CLASS_MARK;
return (hb_ot_layout_glyph_class_t) properties;
return (hb_ot_layout_glyph_class_t) property;
}
void
@ -212,6 +229,9 @@ hb_ot_layout_set_glyph_class (hb_ot_layout_t *layout,
hb_ot_layout_class_t gdef_klass;
int len = layout->new_gdef.len;
if (G_UNLIKELY (glyph > 65535))
return;
if (glyph >= len) {
int new_len;
unsigned char *new_klasses;

View File

@ -91,7 +91,7 @@ typedef enum {
HB_OT_LAYOUT_TABLE_TYPE_NONE
} hb_ot_layout_table_type_t;
typedef uint16_t hb_ot_layout_feature_mask_t;
typedef uint32_t hb_ot_layout_feature_mask_t;
#define HB_OT_LAYOUT_MAX_NESTING_LEVEL 100