Implement the first substitute()
This commit is contained in:
parent
ce48f03946
commit
30bd763fa2
|
@ -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), \
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_ {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue