Home | History | Annotate | Download | only in layout
      1 /*
      2  *
      3  * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
      4  *
      5  */
      6 
      7 #include "LETypes.h"
      8 #include "LEFontInstance.h"
      9 #include "OpenTypeTables.h"
     10 #include "AnchorTables.h"
     11 #include "MarkArrays.h"
     12 #include "GlyphPositioningTables.h"
     13 #include "AttachmentPosnSubtables.h"
     14 #include "MarkToMarkPosnSubtables.h"
     15 #include "GlyphIterator.h"
     16 #include "LESwaps.h"
     17 
     18 U_NAMESPACE_BEGIN
     19 
     20 LEGlyphID MarkToMarkPositioningSubtable::findMark2Glyph(GlyphIterator *glyphIterator) const
     21 {
     22     if (glyphIterator->findMark2Glyph()) {
     23         return glyphIterator->getCurrGlyphID();
     24     }
     25 
     26     return 0xFFFF;
     27 }
     28 
     29 le_int32 MarkToMarkPositioningSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const
     30 {
     31     LEGlyphID markGlyph = glyphIterator->getCurrGlyphID();
     32     le_int32 markCoverage = getGlyphCoverage((LEGlyphID) markGlyph);
     33 
     34     if (markCoverage < 0) {
     35         // markGlyph isn't a covered mark glyph
     36         return 0;
     37     }
     38 
     39     LEPoint markAnchor;
     40     const MarkArray *markArray = (const MarkArray *) ((char *) this + SWAPW(markArrayOffset));
     41     le_int32 markClass = markArray->getMarkClass(markGlyph, markCoverage, fontInstance, markAnchor);
     42     le_uint16 mcCount = SWAPW(classCount);
     43 
     44     if (markClass < 0 || markClass >= mcCount) {
     45         // markGlyph isn't in the mark array or its
     46         // mark class is too big. The table is mal-formed!
     47         return 0;
     48     }
     49 
     50     GlyphIterator mark2Iterator(*glyphIterator);
     51     LEGlyphID mark2Glyph = findMark2Glyph(&mark2Iterator);
     52     le_int32 mark2Coverage = getBaseCoverage((LEGlyphID) mark2Glyph);
     53     const Mark2Array *mark2Array = (const Mark2Array *) ((char *) this + SWAPW(baseArrayOffset));
     54     le_uint16 mark2Count = SWAPW(mark2Array->mark2RecordCount);
     55 
     56     if (mark2Coverage < 0 || mark2Coverage >= mark2Count) {
     57         // The mark2 glyph isn't covered, or the coverage
     58         // index is too big. The latter means that the
     59         // table is mal-formed...
     60         return 0;
     61     }
     62 
     63     const Mark2Record *mark2Record = &mark2Array->mark2RecordArray[mark2Coverage * mcCount];
     64     Offset anchorTableOffset = SWAPW(mark2Record->mark2AnchorTableOffsetArray[markClass]);
     65     const AnchorTable *anchorTable = (const AnchorTable *) ((char *) mark2Array + anchorTableOffset);
     66     LEPoint mark2Anchor, markAdvance, pixels;
     67 
     68     if (anchorTableOffset == 0) {
     69         // this seems to mean that the marks don't attach...
     70         return 0;
     71     }
     72 
     73     anchorTable->getAnchor(mark2Glyph, fontInstance, mark2Anchor);
     74 
     75     fontInstance->getGlyphAdvance(markGlyph, pixels);
     76     fontInstance->pixelsToUnits(pixels, markAdvance);
     77 
     78     float anchorDiffX = mark2Anchor.fX - markAnchor.fX;
     79     float anchorDiffY = mark2Anchor.fY - markAnchor.fY;
     80 
     81     glyphIterator->setCurrGlyphBaseOffset(mark2Iterator.getCurrStreamPosition());
     82 
     83     if (glyphIterator->isRightToLeft()) {
     84         glyphIterator->setCurrGlyphPositionAdjustment(anchorDiffX, anchorDiffY, -markAdvance.fX, -markAdvance.fY);
     85     } else {
     86         LEPoint mark2Advance;
     87 
     88         fontInstance->getGlyphAdvance(mark2Glyph, pixels);
     89         fontInstance->pixelsToUnits(pixels, mark2Advance);
     90 
     91         glyphIterator->setCurrGlyphPositionAdjustment(anchorDiffX - mark2Advance.fX, anchorDiffY - mark2Advance.fY, -markAdvance.fX, -markAdvance.fY);
     92     }
     93 
     94     return 1;
     95 }
     96 
     97 U_NAMESPACE_END
     98