os/textandloc/fontservices/textshaperplugin/IcuSource/layout/MarkToBasePosnSubtables.cpp
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/textandloc/fontservices/textshaperplugin/IcuSource/layout/MarkToBasePosnSubtables.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,99 @@
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 "MarkToBasePosnSubtables.h"
1.18 +#include "GlyphIterator.h"
1.19 +#include "LESwaps.h"
1.20 +
1.21 +U_NAMESPACE_BEGIN
1.22 +
1.23 +LEGlyphID MarkToBasePositioningSubtable::findBaseGlyph(GlyphIterator *glyphIterator) const
1.24 +{
1.25 + if (glyphIterator->prev()) {
1.26 + return glyphIterator->getCurrGlyphID();
1.27 + }
1.28 +
1.29 + return 0xFFFF;
1.30 +}
1.31 +
1.32 +le_int32 MarkToBasePositioningSubtable::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 + // FIXME: We probably don't want to find a base glyph before a previous ligature...
1.54 + GlyphIterator baseIterator(*glyphIterator, (le_uint16) (lfIgnoreMarks /*| lfIgnoreLigatures*/));
1.55 + LEGlyphID baseGlyph = findBaseGlyph(&baseIterator);
1.56 + le_int32 baseCoverage = getBaseCoverage((LEGlyphID) baseGlyph);
1.57 + const BaseArray *baseArray = (const BaseArray *) ((char *) this + SWAPW(baseArrayOffset));
1.58 + le_uint16 baseCount = SWAPW(baseArray->baseRecordCount);
1.59 +
1.60 + if (baseCoverage < 0 || baseCoverage >= baseCount) {
1.61 + // The base glyph isn't covered, or the coverage
1.62 + // index is too big. The latter means that the
1.63 + // table is mal-formed...
1.64 + return 0;
1.65 + }
1.66 +
1.67 + const BaseRecord *baseRecord = &baseArray->baseRecordArray[baseCoverage * mcCount];
1.68 + Offset anchorTableOffset = SWAPW(baseRecord->baseAnchorTableOffsetArray[markClass]);
1.69 + const AnchorTable *anchorTable = (const AnchorTable *) ((char *) baseArray + anchorTableOffset);
1.70 + LEPoint baseAnchor, markAdvance, pixels;
1.71 +
1.72 + if (anchorTableOffset == 0) {
1.73 + // this means the table is mal-formed...
1.74 + glyphIterator->setCurrGlyphBaseOffset(baseIterator.getCurrStreamPosition());
1.75 + return 0;
1.76 + }
1.77 +
1.78 + anchorTable->getAnchor(baseGlyph, fontInstance, baseAnchor);
1.79 +
1.80 + fontInstance->getGlyphAdvance(markGlyph, pixels);
1.81 + fontInstance->pixelsToUnits(pixels, markAdvance);
1.82 +
1.83 + float anchorDiffX = baseAnchor.fX - markAnchor.fX;
1.84 + float anchorDiffY = baseAnchor.fY - markAnchor.fY;
1.85 +
1.86 + glyphIterator->setCurrGlyphBaseOffset(baseIterator.getCurrStreamPosition());
1.87 +
1.88 + if (glyphIterator->isRightToLeft()) {
1.89 + glyphIterator->setCurrGlyphPositionAdjustment(anchorDiffX, anchorDiffY, -markAdvance.fX, -markAdvance.fY);
1.90 + } else {
1.91 + LEPoint baseAdvance;
1.92 +
1.93 + fontInstance->getGlyphAdvance(baseGlyph, pixels);
1.94 + fontInstance->pixelsToUnits(pixels, baseAdvance);
1.95 +
1.96 + glyphIterator->setCurrGlyphPositionAdjustment(anchorDiffX - baseAdvance.fX, anchorDiffY - baseAdvance.fY, -markAdvance.fX, -markAdvance.fY);
1.97 + }
1.98 +
1.99 + return 1;
1.100 +}
1.101 +
1.102 +U_NAMESPACE_END