3  * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved 
   8 #include "LEFontInstance.h" 
   9 #include "OpenTypeTables.h" 
  10 #include "GlyphPositioningTables.h" 
  11 #include "PairPositioningSubtables.h" 
  12 #include "ValueRecords.h" 
  13 #include "GlyphIterator.h" 
  14 #include "OpenTypeUtilities.h" 
  19 le_uint32 
PairPositioningSubtable::process(const LEReferenceTo
<PairPositioningSubtable
> &base
, GlyphIterator 
*glyphIterator
, const LEFontInstance 
*fontInstance
, LEErrorCode 
&success
) const 
  21     switch(SWAPW(subtableFormat
)) 
  28       const LEReferenceTo
<PairPositioningFormat1Subtable
> subtable(base
, success
, (const PairPositioningFormat1Subtable 
*) this); 
  30       if(LE_SUCCESS(success
)) 
  31       return subtable
->process(subtable
, glyphIterator
, fontInstance
, success
); 
  38       const LEReferenceTo
<PairPositioningFormat2Subtable
> subtable(base
, success
, (const PairPositioningFormat2Subtable 
*) this); 
  40       if(LE_SUCCESS(success
)) 
  41       return subtable
->process(subtable
, glyphIterator
, fontInstance
, success
); 
  50 le_uint32 
PairPositioningFormat1Subtable::process(const LEReferenceTo
<PairPositioningFormat1Subtable
> &base
, GlyphIterator 
*glyphIterator
, const LEFontInstance 
*fontInstance
, LEErrorCode 
&success
) const 
  52     LEGlyphID firstGlyph 
= glyphIterator
->getCurrGlyphID(); 
  53     le_int32 coverageIndex 
= getGlyphCoverage(base
, firstGlyph
, success
); 
  54     GlyphIterator 
tempIterator(*glyphIterator
); 
  56     if (coverageIndex 
>= 0 && glyphIterator
->next()) { 
  57         Offset pairSetTableOffset 
= SWAPW(pairSetTableOffsetArray
[coverageIndex
]); 
  58         PairSetTable 
*pairSetTable 
= (PairSetTable 
*) ((char *) this + pairSetTableOffset
); 
  59         le_uint16 pairValueCount 
= SWAPW(pairSetTable
->pairValueCount
); 
  60         le_int16 valueRecord1Size 
= ValueRecord::getSize(SWAPW(valueFormat1
)); 
  61         le_int16 valueRecord2Size 
= ValueRecord::getSize(SWAPW(valueFormat2
)); 
  62         le_int16 recordSize 
= sizeof(PairValueRecord
) - sizeof(ValueRecord
) + valueRecord1Size 
+ valueRecord2Size
; 
  63         LEGlyphID secondGlyph 
= glyphIterator
->getCurrGlyphID(); 
  64         const PairValueRecord 
*pairValueRecord 
= NULL
; 
  66         if (pairValueCount 
!= 0) { 
  67             pairValueRecord 
= findPairValueRecord((TTGlyphID
) LE_GET_GLYPH(secondGlyph
), pairSetTable
->pairValueRecordArray
, pairValueCount
, recordSize
); 
  70         if (pairValueRecord 
== NULL
) { 
  74         if (valueFormat1 
!= 0) { 
  75             pairValueRecord
->valueRecord1
.adjustPosition(SWAPW(valueFormat1
), (char *) this, tempIterator
, fontInstance
); 
  78         if (valueFormat2 
!= 0) { 
  79             const ValueRecord 
*valueRecord2 
= (const ValueRecord 
*) ((char *) &pairValueRecord
->valueRecord1 
+ valueRecord1Size
); 
  81             valueRecord2
->adjustPosition(SWAPW(valueFormat2
), (char *) this, *glyphIterator
, fontInstance
); 
  84         // back up glyphIterator so second glyph can be 
  85         // first glyph in the next pair 
  86         glyphIterator
->prev(); 
  93 le_uint32 
PairPositioningFormat2Subtable::process(const LEReferenceTo
<PairPositioningFormat2Subtable
> &base
, GlyphIterator 
*glyphIterator
, const LEFontInstance 
*fontInstance
, LEErrorCode 
&success
) const 
  95     LEGlyphID firstGlyph 
= glyphIterator
->getCurrGlyphID(); 
  96     le_int32 coverageIndex 
= getGlyphCoverage(base
, firstGlyph
, success
); 
  97     GlyphIterator 
tempIterator(*glyphIterator
); 
  99     if (coverageIndex 
>= 0 && glyphIterator
->next()) { 
 100         LEGlyphID secondGlyph 
= glyphIterator
->getCurrGlyphID(); 
 101         const ClassDefinitionTable 
*classDef1 
= (const ClassDefinitionTable 
*) ((char *) this + SWAPW(classDef1Offset
)); 
 102         const ClassDefinitionTable 
*classDef2 
= (const ClassDefinitionTable 
*) ((char *) this + SWAPW(classDef2Offset
)); 
 103         le_int32 class1 
= classDef1
->getGlyphClass(firstGlyph
); 
 104         le_int32 class2 
= classDef2
->getGlyphClass(secondGlyph
); 
 105         le_int16 valueRecord1Size 
= ValueRecord::getSize(SWAPW(valueFormat1
)); 
 106         le_int16 valueRecord2Size 
= ValueRecord::getSize(SWAPW(valueFormat2
)); 
 107         le_int16 class2RecordSize 
= valueRecord1Size 
+ valueRecord2Size
; 
 108         le_int16 class1RecordSize 
= class2RecordSize 
* SWAPW(class2Count
); 
 109         const Class1Record 
*class1Record 
= (const Class1Record 
*) ((char *) class1RecordArray 
+ (class1RecordSize 
* class1
)); 
 110         const Class2Record 
*class2Record 
= (const Class2Record 
*) ((char *) class1Record
->class2RecordArray 
+ (class2RecordSize 
* class2
)); 
 113         if (valueFormat1 
!= 0) { 
 114             class2Record
->valueRecord1
.adjustPosition(SWAPW(valueFormat1
), (char *) this, tempIterator
, fontInstance
); 
 117         if (valueFormat2 
!= 0) { 
 118             const ValueRecord 
*valueRecord2 
= (const ValueRecord 
*) ((char *) &class2Record
->valueRecord1 
+ valueRecord1Size
); 
 120             valueRecord2
->adjustPosition(SWAPW(valueFormat2
), (const char *) this, *glyphIterator
, fontInstance
); 
 123         // back up glyphIterator so second glyph can be 
 124         // first glyph in the next pair 
 125         glyphIterator
->prev(); 
 132 const PairValueRecord 
*PairPositioningFormat1Subtable::findPairValueRecord(TTGlyphID glyphID
, const PairValueRecord 
*records
, le_uint16 recordCount
, le_uint16 recordSize
) const 
 135         // The OpenType spec. says that the ValueRecord table is 
 136         // sorted by secondGlyph. Unfortunately, there are fonts 
 137         // around that have an unsorted ValueRecord table. 
 138         const PairValueRecord 
*record 
= records
; 
 140         for(le_int32 r 
= 0; r 
< recordCount
; r 
+= 1) { 
 141                 if (SWAPW(record
->secondGlyph
) == glyphID
) { 
 145                 record 
= (const PairValueRecord 
*) ((char *) record 
+ recordSize
); 
 148     le_uint8 bit 
= OpenTypeUtilities::highBit(recordCount
); 
 149     le_uint16 power 
= 1 << bit
; 
 150     le_uint16 extra 
= (recordCount 
- power
) * recordSize
; 
 151     le_uint16 probe 
= power 
* recordSize
; 
 152     const PairValueRecord 
*record 
= records
; 
 153     const PairValueRecord 
*trial 
= (const PairValueRecord 
*) ((char *) record 
+ extra
); 
 155     if (SWAPW(trial
->secondGlyph
) <= glyphID
) { 
 159     while (probe 
> recordSize
) { 
 161         trial 
= (const PairValueRecord 
*) ((char *) record 
+ probe
); 
 163         if (SWAPW(trial
->secondGlyph
) <= glyphID
) { 
 168     if (SWAPW(record
->secondGlyph
) == glyphID
) {