os/textandloc/fontservices/textshaperplugin/IcuSource/layout/MarkToMarkPosnSubtables.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/textandloc/fontservices/textshaperplugin/IcuSource/layout/MarkToMarkPosnSubtables.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,92 @@
1.4 +/*
1.5 + *
1.6 + * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
1.7 + *
1.8 + */
1.9 +
1.10 +#include "LETypes.h"
1.11 +#include "LEFontInstance.h"
1.12 +#include "OpenTypeTables.h"
1.13 +#include "AnchorTables.h"
1.14 +#include "MarkArrays.h"
1.15 +#include "GlyphPositioningTables.h"
1.16 +#include "AttachmentPosnSubtables.h"
1.17 +#include "MarkToMarkPosnSubtables.h"
1.18 +#include "GlyphIterator.h"
1.19 +#include "LESwaps.h"
1.20 +
1.21 +U_NAMESPACE_BEGIN
1.22 +
1.23 +LEGlyphID MarkToMarkPositioningSubtable::findMark2Glyph(GlyphIterator *glyphIterator) const
1.24 +{
1.25 + if (glyphIterator->findMark2Glyph()) {
1.26 + return glyphIterator->getCurrGlyphID();
1.27 + }
1.28 +
1.29 + return 0xFFFF;
1.30 +}
1.31 +
1.32 +le_int32 MarkToMarkPositioningSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const
1.33 +{
1.34 + LEGlyphID markGlyph = glyphIterator->getCurrGlyphID();
1.35 + le_int32 markCoverage = getGlyphCoverage((LEGlyphID) markGlyph);
1.36 +
1.37 + if (markCoverage < 0) {
1.38 + // markGlyph isn't a covered mark glyph
1.39 + return 0;
1.40 + }
1.41 +
1.42 + LEPoint markAnchor;
1.43 + const MarkArray *markArray = (const MarkArray *) ((char *) this + SWAPW(markArrayOffset));
1.44 + le_int32 markClass = markArray->getMarkClass(markGlyph, markCoverage, fontInstance, markAnchor);
1.45 + le_uint16 mcCount = SWAPW(classCount);
1.46 +
1.47 + if (markClass < 0 || markClass >= mcCount) {
1.48 + // markGlyph isn't in the mark array or its
1.49 + // mark class is too big. The table is mal-formed!
1.50 + return 0;
1.51 + }
1.52 +
1.53 + GlyphIterator mark2Iterator(*glyphIterator);
1.54 + LEGlyphID mark2Glyph = findMark2Glyph(&mark2Iterator);
1.55 + le_int32 mark2Coverage = getBaseCoverage((LEGlyphID) mark2Glyph);
1.56 + const Mark2Array *mark2Array = (const Mark2Array *) ((char *) this + SWAPW(baseArrayOffset));
1.57 + le_uint16 mark2Count = SWAPW(mark2Array->mark2RecordCount);
1.58 +
1.59 + if (mark2Coverage < 0 || mark2Coverage >= mark2Count) {
1.60 + // The mark2 glyph isn't covered, or the coverage
1.61 + // index is too big. The latter means that the
1.62 + // table is mal-formed...
1.63 + return 0;
1.64 + }
1.65 +
1.66 + const Mark2Record *mark2Record = &mark2Array->mark2RecordArray[mark2Coverage * mcCount];
1.67 + Offset anchorTableOffset = SWAPW(mark2Record->mark2AnchorTableOffsetArray[markClass]);
1.68 + const AnchorTable *anchorTable = (const AnchorTable *) ((char *) mark2Array + anchorTableOffset);
1.69 + LEPoint mark2Anchor, markAdvance, pixels;
1.70 +
1.71 + anchorTable->getAnchor(mark2Glyph, fontInstance, mark2Anchor);
1.72 +
1.73 + fontInstance->getGlyphAdvance(markGlyph, pixels);
1.74 + fontInstance->pixelsToUnits(pixels, markAdvance);
1.75 +
1.76 + float anchorDiffX = mark2Anchor.fX - markAnchor.fX;
1.77 + float anchorDiffY = mark2Anchor.fY - markAnchor.fY;
1.78 +
1.79 + glyphIterator->setCurrGlyphBaseOffset(mark2Iterator.getCurrStreamPosition());
1.80 +
1.81 + if (glyphIterator->isRightToLeft()) {
1.82 + glyphIterator->setCurrGlyphPositionAdjustment(anchorDiffX, anchorDiffY, -markAdvance.fX, -markAdvance.fY);
1.83 + } else {
1.84 + LEPoint mark2Advance;
1.85 +
1.86 + fontInstance->getGlyphAdvance(mark2Glyph, pixels);
1.87 + fontInstance->pixelsToUnits(pixels, mark2Advance);
1.88 +
1.89 + glyphIterator->setCurrGlyphPositionAdjustment(anchorDiffX - mark2Advance.fX, anchorDiffY - mark2Advance.fY, -markAdvance.fX, -markAdvance.fY);
1.90 + }
1.91 +
1.92 + return 1;
1.93 +}
1.94 +
1.95 +U_NAMESPACE_END