Optimize HB memory consumption of PairPos1 in GPOS tables
This is pretty much the same fix as in
be0dfa3473
but for PairPos
format 1 instead of 2.
With very simple GPOS tables we would waste a lot of memory on
caching an uncompressed table, so we now compress it in memory
as well.
Change-Id: I601331b4b83f636dab9e1ac403b343558c15b0de
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
This commit is contained in:
parent
0d43b8c617
commit
4a47187b7a
@ -219,8 +219,12 @@ struct HB_PairSet_
|
|||||||
{
|
{
|
||||||
HB_UShort PairValueCount;
|
HB_UShort PairValueCount;
|
||||||
/* number of PairValueRecord tables */
|
/* number of PairValueRecord tables */
|
||||||
|
#ifndef HB_USE_FLEXIBLE_VALUE_RECORD
|
||||||
HB_PairValueRecord* PairValueRecord;
|
HB_PairValueRecord* PairValueRecord;
|
||||||
/* array of PairValueRecord tables */
|
/* array of PairValueRecord tables */
|
||||||
|
#else
|
||||||
|
HB_Short* ValueRecords;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct HB_PairSet_ HB_PairSet;
|
typedef struct HB_PairSet_ HB_PairSet;
|
||||||
|
125
src/3rdparty/harfbuzz/src/harfbuzz-gpos.c
vendored
125
src/3rdparty/harfbuzz/src/harfbuzz-gpos.c
vendored
@ -185,6 +185,18 @@ HB_Error HB_Done_GPOS_Table( HB_GPOSHeader* gpos )
|
|||||||
return HB_Err_Ok;
|
return HB_Err_Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HB_UInt Calculate_Class2RecordSize(HB_UShort format1, HB_UShort format2)
|
||||||
|
{
|
||||||
|
// Return number of 16 bit values in two value records with given formats
|
||||||
|
return (format1 & 0x01) + (format2 & 0x01)
|
||||||
|
+ ((format1 & 0x02) >> 1) + ((format2 & 0x02) >> 1)
|
||||||
|
+ ((format1 & 0x04) >> 2) + ((format2 & 0x04) >> 2)
|
||||||
|
+ ((format1 & 0x08) >> 3) + ((format2 & 0x08) >> 3)
|
||||||
|
+ ((format1 & 0x10) >> 4) + ((format2 & 0x10) >> 4)
|
||||||
|
+ ((format1 & 0x20) >> 5) + ((format2 & 0x20) >> 5)
|
||||||
|
+ ((format1 & 0x40) >> 6) + ((format2 & 0x40) >> 6)
|
||||||
|
+ ((format1 & 0x80) >> 7) + ((format2 & 0x80) >> 7);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************
|
/*****************************
|
||||||
* SubTable related functions
|
* SubTable related functions
|
||||||
@ -1096,7 +1108,6 @@ static HB_Error Lookup_SinglePos( GPOS_Instance* gpi,
|
|||||||
return HB_Err_Ok;
|
return HB_Err_Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* LookupType 2 */
|
/* LookupType 2 */
|
||||||
|
|
||||||
/* PairSet */
|
/* PairSet */
|
||||||
@ -1111,8 +1122,12 @@ static HB_Error Load_PairSet ( HB_PairSet* ps,
|
|||||||
HB_UShort n, m, count;
|
HB_UShort n, m, count;
|
||||||
HB_UInt base_offset;
|
HB_UInt base_offset;
|
||||||
|
|
||||||
|
#ifdef HB_USE_FLEXIBLE_VALUE_RECORD
|
||||||
|
HB_UInt record_size = 0;
|
||||||
|
HB_Short *vr;
|
||||||
|
#else
|
||||||
HB_PairValueRecord* pvr;
|
HB_PairValueRecord* pvr;
|
||||||
|
#endif
|
||||||
|
|
||||||
base_offset = FILE_Pos();
|
base_offset = FILE_Pos();
|
||||||
|
|
||||||
@ -1123,6 +1138,7 @@ static HB_Error Load_PairSet ( HB_PairSet* ps,
|
|||||||
|
|
||||||
FORGET_Frame();
|
FORGET_Frame();
|
||||||
|
|
||||||
|
#ifndef HB_USE_FLEXIBLE_VALUE_RECORD
|
||||||
ps->PairValueRecord = NULL;
|
ps->PairValueRecord = NULL;
|
||||||
|
|
||||||
if ( ALLOC_ARRAY( ps->PairValueRecord, count, HB_PairValueRecord ) )
|
if ( ALLOC_ARRAY( ps->PairValueRecord, count, HB_PairValueRecord ) )
|
||||||
@ -1142,26 +1158,50 @@ static HB_Error Load_PairSet ( HB_PairSet* ps,
|
|||||||
if ( format1 )
|
if ( format1 )
|
||||||
{
|
{
|
||||||
error = Load_ValueRecord( &pvr[n].Value1, format1,
|
error = Load_ValueRecord( &pvr[n].Value1, format1,
|
||||||
base_offset, stream );
|
base_offset, stream );
|
||||||
if ( error )
|
if ( error )
|
||||||
goto Fail;
|
goto Fail;
|
||||||
}
|
}
|
||||||
if ( format2 )
|
if ( format2 )
|
||||||
{
|
{
|
||||||
error = Load_ValueRecord( &pvr[n].Value2, format2,
|
error = Load_ValueRecord( &pvr[n].Value2, format2,
|
||||||
base_offset, stream );
|
base_offset, stream );
|
||||||
if ( error )
|
if ( error )
|
||||||
{
|
{
|
||||||
if ( format1 )
|
if ( format1 )
|
||||||
Free_ValueRecord( &pvr[n].Value1, format1 );
|
Free_ValueRecord( &pvr[n].Value1, format1 );
|
||||||
goto Fail;
|
goto Fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
ps->ValueRecords = 0;
|
||||||
|
|
||||||
|
// Add one for the SecondGlyph part of each record
|
||||||
|
record_size = Calculate_Class2RecordSize( format1, format2 ) + 1;
|
||||||
|
|
||||||
|
if ( ALLOC_ARRAY( ps->ValueRecords, record_size * count, HB_Short ) )
|
||||||
|
return error;
|
||||||
|
|
||||||
|
vr = ps->ValueRecords;
|
||||||
|
|
||||||
|
for ( n = 0; n < count; n++ )
|
||||||
|
{
|
||||||
|
if ( ACCESS_Frame( 2L ) )
|
||||||
|
goto Fail;
|
||||||
|
|
||||||
|
for ( m = 0; m < record_size; m++ )
|
||||||
|
*(vr++) = GET_Short();
|
||||||
|
|
||||||
|
FORGET_Frame();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
return HB_Err_Ok;
|
return HB_Err_Ok;
|
||||||
|
|
||||||
Fail:
|
Fail:
|
||||||
|
#ifndef HB_USE_FLEXIBLE_VALUE_RECORD
|
||||||
for ( m = 0; m < n; m++ )
|
for ( m = 0; m < n; m++ )
|
||||||
{
|
{
|
||||||
if ( format1 )
|
if ( format1 )
|
||||||
@ -1171,19 +1211,23 @@ Fail:
|
|||||||
}
|
}
|
||||||
|
|
||||||
FREE( pvr );
|
FREE( pvr );
|
||||||
|
#else
|
||||||
|
FREE ( ps->ValueRecords );
|
||||||
|
#endif
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void Free_PairSet( HB_PairSet* ps,
|
static void Free_PairSet( HB_PairSet* ps,
|
||||||
HB_UShort format1,
|
HB_UShort format1,
|
||||||
HB_UShort format2 )
|
HB_UShort format2)
|
||||||
{
|
{
|
||||||
|
#ifndef HB_USE_FLEXIBLE_VALUE_RECORD
|
||||||
HB_UShort n, count;
|
HB_UShort n, count;
|
||||||
|
|
||||||
HB_PairValueRecord* pvr;
|
HB_PairValueRecord* pvr;
|
||||||
|
|
||||||
|
|
||||||
if ( ps->PairValueRecord )
|
if ( ps->PairValueRecord )
|
||||||
{
|
{
|
||||||
count = ps->PairValueCount;
|
count = ps->PairValueCount;
|
||||||
@ -1199,6 +1243,12 @@ static void Free_PairSet( HB_PairSet* ps,
|
|||||||
|
|
||||||
FREE( pvr );
|
FREE( pvr );
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
if ( ps->ValueRecords )
|
||||||
|
{
|
||||||
|
FREE( ps->ValueRecords );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1282,19 +1332,6 @@ static void Free_PairPos1( HB_PairPosFormat1* ppf1,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static HB_UInt Calculate_Class2RecordSize(HB_UShort format1, HB_UShort format2)
|
|
||||||
{
|
|
||||||
// Return number of 16 bit values in two value records with given formats
|
|
||||||
return (format1 & 0x01) + (format2 & 0x01)
|
|
||||||
+ ((format1 & 0x02) >> 1) + ((format2 & 0x02) >> 1)
|
|
||||||
+ ((format1 & 0x04) >> 2) + ((format2 & 0x04) >> 2)
|
|
||||||
+ ((format1 & 0x08) >> 3) + ((format2 & 0x08) >> 3)
|
|
||||||
+ ((format1 & 0x10) >> 4) + ((format2 & 0x10) >> 4)
|
|
||||||
+ ((format1 & 0x20) >> 5) + ((format2 & 0x20) >> 5)
|
|
||||||
+ ((format1 & 0x40) >> 6) + ((format2 & 0x40) >> 6)
|
|
||||||
+ ((format1 & 0x80) >> 7) + ((format2 & 0x80) >> 7);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* PairPosFormat2 */
|
/* PairPosFormat2 */
|
||||||
|
|
||||||
@ -1577,7 +1614,6 @@ static void Free_PairPos( HB_GPOS_SubTable* st )
|
|||||||
_HB_OPEN_Free_Coverage( &pp->Coverage );
|
_HB_OPEN_Free_Coverage( &pp->Coverage );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static HB_Error Lookup_PairPos1( GPOS_Instance* gpi,
|
static HB_Error Lookup_PairPos1( GPOS_Instance* gpi,
|
||||||
HB_PairPosFormat1* ppf1,
|
HB_PairPosFormat1* ppf1,
|
||||||
HB_Buffer buffer,
|
HB_Buffer buffer,
|
||||||
@ -1589,8 +1625,13 @@ static HB_Error Lookup_PairPos1( GPOS_Instance* gpi,
|
|||||||
HB_Error error;
|
HB_Error error;
|
||||||
HB_UShort numpvr, glyph2;
|
HB_UShort numpvr, glyph2;
|
||||||
|
|
||||||
|
#ifndef HB_USE_FLEXIBLE_VALUE_RECORD
|
||||||
HB_PairValueRecord* pvr;
|
HB_PairValueRecord* pvr;
|
||||||
|
#else
|
||||||
|
HB_Short *vr;
|
||||||
|
HB_UShort second_glyph;
|
||||||
|
HB_UInt record_size1, record_size2;
|
||||||
|
#endif
|
||||||
|
|
||||||
if ( index >= ppf1->PairSetCount )
|
if ( index >= ppf1->PairSetCount )
|
||||||
return ERR(HB_Err_Invalid_SubTable);
|
return ERR(HB_Err_Invalid_SubTable);
|
||||||
@ -1598,12 +1639,13 @@ static HB_Error Lookup_PairPos1( GPOS_Instance* gpi,
|
|||||||
if (!ppf1->PairSet[index].PairValueCount)
|
if (!ppf1->PairSet[index].PairValueCount)
|
||||||
return HB_Err_Not_Covered;
|
return HB_Err_Not_Covered;
|
||||||
|
|
||||||
|
glyph2 = IN_CURGLYPH();
|
||||||
|
|
||||||
|
#ifndef HB_USE_FLEXIBLE_VALUE_RECORD
|
||||||
pvr = ppf1->PairSet[index].PairValueRecord;
|
pvr = ppf1->PairSet[index].PairValueRecord;
|
||||||
if ( !pvr )
|
if ( !pvr )
|
||||||
return ERR(HB_Err_Invalid_SubTable);
|
return ERR(HB_Err_Invalid_SubTable);
|
||||||
|
|
||||||
glyph2 = IN_CURGLYPH();
|
|
||||||
|
|
||||||
for ( numpvr = ppf1->PairSet[index].PairValueCount;
|
for ( numpvr = ppf1->PairSet[index].PairValueCount;
|
||||||
numpvr;
|
numpvr;
|
||||||
numpvr--, pvr++ )
|
numpvr--, pvr++ )
|
||||||
@ -1613,11 +1655,38 @@ static HB_Error Lookup_PairPos1( GPOS_Instance* gpi,
|
|||||||
error = Get_ValueRecord( gpi, &pvr->Value1, format1,
|
error = Get_ValueRecord( gpi, &pvr->Value1, format1,
|
||||||
POSITION( first_pos ) );
|
POSITION( first_pos ) );
|
||||||
if ( error )
|
if ( error )
|
||||||
return error;
|
return error;
|
||||||
return Get_ValueRecord( gpi, &pvr->Value2, format2,
|
return Get_ValueRecord( gpi, &pvr->Value2, format2,
|
||||||
POSITION( buffer->in_pos ) );
|
POSITION( buffer->in_pos ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
vr = ppf1->PairSet[index].ValueRecords;
|
||||||
|
if ( !vr )
|
||||||
|
return ERR(HB_Err_Invalid_SubTable);
|
||||||
|
|
||||||
|
record_size1 = Calculate_Class2RecordSize( format1, 0 );
|
||||||
|
record_size2 = Calculate_Class2RecordSize( format2, 0 );
|
||||||
|
|
||||||
|
for ( numpvr = ppf1->PairSet[index].PairValueCount; numpvr; numpvr-- )
|
||||||
|
{
|
||||||
|
second_glyph = *((HB_UShort *)vr);
|
||||||
|
vr++;
|
||||||
|
if ( glyph2 == second_glyph )
|
||||||
|
{
|
||||||
|
error = Get_FlexibleValueRecord( gpi, vr, format1, POSITION( first_pos ) );
|
||||||
|
if ( error )
|
||||||
|
return error;
|
||||||
|
vr += record_size1;
|
||||||
|
|
||||||
|
return Get_FlexibleValueRecord( gpi, vr, format2, POSITION( buffer->in_pos ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vr += record_size1 + record_size2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return HB_Err_Not_Covered;
|
return HB_Err_Not_Covered;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user