Re: Pango Feature Apply Order
- From: Soheil Hassas Yegnaneh <hassas ce sharif edu>
- To: Owen Taylor <otaylor redhat com>
- Cc: gtk-devel-list gnome org
- Subject: Re: Pango Feature Apply Order
- Date: Mon, 29 Dec 2003 18:28:49 +0330
I correct the last patch with an assumption :
Any Shape Engine appends its feature indices to its Rule Set by the
specific order it wants.
like what you've done in the patch of
http://bugzilla.gnome.org/show_bug.cgi?id=122330 I've created a new
attribute ApplyOrder but for FeatureList not LookupList.
Best Regards,
Soheil
On Sun, 2003-12-28 at 17:36, Owen Taylor wrote:
> How does your patch compare to the patch in:
>
> http://bugzilla.gnome.org/show_bug.cgi?id=122330
>
> ?
>
> Thanks,
> Owen
>
> On Sun, Dec 28, 2003 at 05:04:33PM +0330, Soheil Hassas Yegnaneh wrote:
> > Dear All,
> >
> > As OpenType specification says any script has a specific order of
> > features to apply (e.g. in Arabic, lookups of "ccmp" feature has to be
> > applied first and lookups of "dlig" feature has to be applied if user
> > asked for). But, current version of Pango applies lookups by order they
> > came in the font, instead of applying lookups by the order of the
> > features.
> >
> > In order to fix this problem, I've modified TT_(GSUB|GPOS)_Apply_String
> > functions of pango/opentype/ftxg(sub|pos).c.
Index: pango/opentype/ftxgpos.c
===================================================================
RCS file: /usr/local/cvsroot/pango/pango/opentype/ftxgpos.c,v
retrieving revision 1.3
diff -u -d -r1.3 ftxgpos.c
--- pango/opentype/ftxgpos.c 28 Dec 2003 12:25:34 -0000 1.3
+++ pango/opentype/ftxgpos.c 29 Dec 2003 14:29:50 -0000
@@ -6220,6 +6220,11 @@
feature_index >= gpos->FeatureList.FeatureCount )
return TT_Err_Invalid_Argument;
+ /*
+ Filling feature list ApplyCount by order of features listed in the RuleSet
+ */
+ gpos->FeatureList.ApplyOrder[gpos->FeatureList.ApplyCount++] = feature_index;
+
properties = gpos->LookupList.Properties;
feature = gpos->FeatureList.FeatureRecord[feature_index].Feature;
@@ -6228,6 +6233,8 @@
for ( i = 0; i < feature.LookupListCount; i++ )
properties[index[i]] |= property;
+
+
return TT_Err_Ok;
}
@@ -6248,6 +6255,8 @@
for ( i = 0; i < gpos->LookupList.LookupCount; i++ )
properties[i] = 0;
+ gpos->FeatureList.ApplyCount = 0;
+
return TT_Err_Ok;
}
@@ -6295,11 +6304,14 @@
FT_Error error, retError = TTO_Err_Not_Covered;
GPOS_Instance gpi;
- FT_UShort i,
- j;
+ FT_UShort index,
+ i,
+ j;
- FT_UShort* properties;
TTO_Feature feature;
+
+ FT_UShort* properties;
+
if ( !face || !gpos ||
!in || in->length == 0 || in->pos >= in->length )
@@ -6317,25 +6329,29 @@
FREE( *out );
if ( ALLOC_ARRAY( *out, in->length, TTO_GPOS_Data ) )
return error;
- for ( i = 0; i < gpos->FeatureList.FeatureCount; i++)
- {
- feature = gpos->FeatureList.FeatureRecord[i].Feature;
-
- if(feature.LookupListIndex == NULL)
+
+ for ( i = 0; i < gpos->FeatureList.ApplyCount; i++ )
+ {
+ /* index of i'th feature */
+ index = gpos->FeatureList.ApplyOrder[i];
+
+ if( index >= gpos->FeatureList.FeatureCount )
continue;
- for ( j = 0; j < gpos->LookupList.LookupCount; j++ )
- if ( !properties || properties[j] )
+ feature = gpos->FeatureList.FeatureRecord[index].Feature;
+
+ for ( j = 0; j < feature.LookupListCount; j++ )
+ if ( !properties || properties[feature.LookupListIndex[j]] )
{
- error = Do_String_Lookup( &gpi, j, in, *out );
+ error = Do_String_Lookup( &gpi, feature.LookupListIndex[j], in, *out );
if ( error )
- {
+ {
if ( error != TTO_Err_Not_Covered )
return error;
}
else
retError = error;
- }
+ }
}
error = Position_CursiveChain ( *out, in->length );
if ( error )
Index: pango/opentype/ftxgsub.c
===================================================================
RCS file: /usr/local/cvsroot/pango/pango/opentype/ftxgsub.c,v
retrieving revision 1.3
diff -u -d -r1.3 ftxgsub.c
--- pango/opentype/ftxgsub.c 28 Dec 2003 12:25:34 -0000 1.3
+++ pango/opentype/ftxgsub.c 29 Dec 2003 14:29:46 -0000
@@ -521,8 +521,7 @@
error = Coverage_Index( &ss->Coverage, in->string[in->pos], &index );
if ( error )
return error;
-
- printf("glyphID %0x", in->string[in->pos]);
+
switch ( ss->SubstFormat )
{
case 1:
@@ -542,7 +541,7 @@
default:
return TTO_Err_Invalid_GSUB_SubTable;
}
- printf("value[0] %0x\n", value[0]);
+
if ( gdef && gdef->NewGlyphClasses )
{
/* we inherit the old glyph class to the substituted glyph */
@@ -1204,14 +1203,11 @@
return error;
if ( property == TTO_MARK || property & IGNORE_SPECIAL_MARKS )
- first_is_mark = TRUE;
-
+ first_is_mark = TRUE;
+
error = Coverage_Index( &ls->Coverage, in->string[in->pos], &index );
if ( error )
- {
- printf("Error: %xu \n", error);
return error;
- }
if ( index >= ls->LigatureSetCount )
return TTO_Err_Invalid_GSUB_SubTable;
@@ -1252,11 +1248,9 @@
if ( s_in[j] != c[i - 1] )
break;
}
-
- printf("In Ligature Subst %lu %lu\n", i, j);
+
if ( i == lig->ComponentCount )
{
-
if ( gdef && gdef->NewGlyphClasses )
{
/* this is just a guess ... */
@@ -4219,26 +4213,24 @@
lo = &gsub->LookupList.Lookup[lookup_index];
flags = lo->LookupFlag;
+
for ( i = 0; i < lo->SubTableCount; i++ )
{
switch ( lo->LookupType )
{
case GSUB_LOOKUP_SINGLE:
- printf("single\n");
error = Lookup_SingleSubst( &lo->SubTable[i].st.gsub.single,
in, out,
flags, context_length, gsub->gdef );
break;
case GSUB_LOOKUP_MULTIPLE:
- printf("multiple\n");
error = Lookup_MultipleSubst( &lo->SubTable[i].st.gsub.multiple,
in, out,
flags, context_length, gsub->gdef );
break;
case GSUB_LOOKUP_ALTERNATE:
- printf("Alternate\n");
error = Lookup_AlternateSubst( gsub,
&lo->SubTable[i].st.gsub.alternate,
in, out,
@@ -4246,11 +4238,9 @@
break;
case GSUB_LOOKUP_LIGATURE:
- printf("In ligature \n");
error = Lookup_LigatureSubst( &lo->SubTable[i].st.gsub.ligature,
in, out,
flags, context_length, gsub->gdef );
- printf("Out ligature\n");
break;
case GSUB_LOOKUP_CONTEXT:
@@ -4338,11 +4328,16 @@
feature_index >= gsub->FeatureList.FeatureCount )
return TT_Err_Invalid_Argument;
+ /*
+ Filling feature list ApplyCount by order of features listed in the RuleSet
+ */
+ gsub->FeatureList.ApplyOrder[gsub->FeatureList.ApplyCount++] = feature_index;
+
properties = gsub->LookupList.Properties;
feature = gsub->FeatureList.FeatureRecord[feature_index].Feature;
index = feature.LookupListIndex;
-
+
for ( i = 0; i < feature.LookupListCount; i++ )
properties[index[i]] |= property;
@@ -4366,6 +4361,8 @@
for ( i = 0; i < gsub->LookupList.LookupCount; i++ )
properties[i] = 0;
+ gsub->FeatureList.ApplyCount = 0;
+
return TT_Err_Ok;
}
@@ -4463,11 +4460,12 @@
{
FT_Error error, retError = TTO_Err_Not_Covered;
FT_Memory memory = in->memory;
- FT_UShort i,
- j,
- index;
+ FT_UShort index,
+ i,
+ j;
TTO_Feature feature;
+
TTO_GSUB_String tmp1;
TTO_GSUB_String* ptmp1;
TTO_GSUB_String tmp2;
@@ -4476,9 +4474,8 @@
FT_UShort* properties;
-
if ( !gsub ||
- !in || !out || in->length == 0 || in->pos >= in->length )
+ !in || !out || in->length == 0 || in->pos >= in->length || !(gsub->FeatureList.ApplyOrder) )
return TT_Err_Invalid_Argument;
properties = gsub->LookupList.Properties;
@@ -4526,38 +4523,40 @@
goto End;
MEM_Copy( tmp1.logClusters, in->logClusters,
in->length * sizeof( FT_Int ) );
+
+ for ( i = 0; i < gsub->FeatureList.ApplyCount; i++)
+ {
+ /* index of i'th feature */
+ index = gsub->FeatureList.ApplyOrder[i];
+
+ if( index >= gsub->FeatureList.FeatureCount )
+ continue;
-
- for ( i = 0; i < gsub->FeatureList.FeatureCount; i++)
- {
- feature = gsub->FeatureList.FeatureRecord[i].Feature;
-
- if(feature.LookupListIndex == NULL)
- continue;
+ feature = gsub->FeatureList.FeatureRecord[index].Feature;
for ( j = 0; j < feature.LookupListCount; j++ )
- if ( properties[j] )
+ if ( properties[feature.LookupListIndex[j]] )
{
error = Do_String_Lookup( gsub, feature.LookupListIndex[j], ptmp1, ptmp2 );
if ( error )
- {
+ {
if ( error != TTO_Err_Not_Covered )
goto End;
}
else
- retError = error;
-
- /* flipping `in' and `out', preparing the next loop */
+ retError = error;
- ptmp1->pos = in->pos;
- ptmp2->length = ptmp2->pos;
- ptmp2->pos = in->pos;
- ptmp2->max_ligID = ptmp1->max_ligID;
+ /* flipping `in' and `out', preparing the next loop */
+
+ ptmp1->pos = in->pos;
+ ptmp2->length = ptmp2->pos;
+ ptmp2->pos = in->pos;
+ ptmp2->max_ligID = ptmp1->max_ligID;
- t = ptmp2;
- ptmp2 = ptmp1;
- ptmp1 = t;
- }
+ t = ptmp2;
+ ptmp2 = ptmp1;
+ ptmp1 = t;
+ }
}
End:
Index: pango/opentype/ftxopen.c
===================================================================
RCS file: /usr/local/cvsroot/pango/pango/opentype/ftxopen.c,v
retrieving revision 1.2
diff -u -d -r1.2 ftxopen.c
--- pango/opentype/ftxopen.c 28 Dec 2003 12:08:44 -0000 1.2
+++ pango/opentype/ftxopen.c 29 Dec 2003 14:29:17 -0000
@@ -374,6 +374,10 @@
if ( ALLOC_ARRAY( fl->FeatureRecord, count, TTO_FeatureRecord ) )
return error;
+ if ( ALLOC_ARRAY( fl->ApplyOrder, count, FT_UShort ) )
+ goto Fail1;
+ fl->ApplyCount = 0;
+
fr = fl->FeatureRecord;
for ( n = 0; n < count; n++ )
@@ -400,6 +404,9 @@
Free_Feature( &fr[m].Feature, memory );
FREE( fl->FeatureRecord );
+
+ Fail1:
+ FREE( fl->ApplyOrder );
return error;
}
@@ -421,7 +428,10 @@
Free_Feature( &fr[n].Feature, memory );
FREE( fr );
+
}
+ if ( fl->ApplyOrder )
+ FREE(fl->ApplyOrder);
}
@@ -944,7 +954,6 @@
overflow and rounding errors */
middle = max - ( ( max - min ) >> 1 );
- printf("RR1: md%lu mn%lu mx%lu rr%x glyphId%x\n", middle, min, max, array[middle], glyphID );
if ( glyphID == array[middle] )
{
@@ -992,8 +1001,7 @@
overflow and rounding errors */
middle = max - ( ( max - min ) >> 1 );
- if(glyphID == 0x1d2 || glyphID == 0x253 || glyphID == 0x20f || glyphID == 0x1b9)
- printf("RR2: md%lu mn%lu mx%lu rr%x glyphId%x\n", middle, min, max, rr[middle].Start, glyphID );
+
if ( glyphID >= rr[middle].Start && glyphID <= rr[middle].End )
{
*index = rr[middle].StartCoverageIndex + glyphID - rr[middle].Start;
Index: pango/opentype/ftxopen.h
===================================================================
RCS file: /usr/local/cvsroot/pango/pango/opentype/ftxopen.h,v
retrieving revision 1.1.1.1
diff -u -d -r1.1.1.1 ftxopen.h
--- pango/opentype/ftxopen.h 17 Dec 2003 10:53:16 -0000 1.1.1.1
+++ pango/opentype/ftxopen.h 29 Dec 2003 14:29:17 -0000
@@ -117,6 +117,8 @@
{
FT_UShort FeatureCount; /* number of FeatureRecords */
TTO_FeatureRecord* FeatureRecord; /* array of FeatureRecords */
+ FT_UShort* ApplyOrder; /* order to apply features */
+ FT_UShort ApplyCount; /* number of elements in ApplyOrder */
};
typedef struct TTO_FeatureList_ TTO_FeatureList;
[
Date Prev][Date Next] [
Thread Prev][Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]