diff -r 000000000000 -r bde4ae8d615e os/textandloc/fontservices/textshaperplugin/IcuSource/layout/GlyphPositionAdjustments.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/textandloc/fontservices/textshaperplugin/IcuSource/layout/GlyphPositionAdjustments.cpp Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,166 @@ +/* + * + * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved + * + */ + +#include "LETypes.h" +#include "GlyphPositionAdjustments.h" +#include "LEGlyphStorage.h" +#include "LEFontInstance.h" + +U_NAMESPACE_BEGIN + +#define CHECK_ALLOCATE_ARRAY(array, type, size) \ + if (array == NULL) { \ + array = (type *) new type[size]; \ + } + +GlyphPositionAdjustments::GlyphPositionAdjustments(le_int32 glyphCount) + : fGlyphCount(glyphCount), fEntryExitPoints(NULL), fAdjustments(NULL) +{ + fAdjustments = (Adjustment *) new Adjustment[glyphCount]; +} + +GlyphPositionAdjustments::~GlyphPositionAdjustments() +{ + delete[] fEntryExitPoints; + delete[] fAdjustments; +} + +const LEPoint *GlyphPositionAdjustments::getEntryPoint(le_int32 index, LEPoint &entryPoint) const +{ + if (fEntryExitPoints == NULL) { + return NULL; + } + + return fEntryExitPoints[index].getEntryPoint(entryPoint); +} + +const LEPoint *GlyphPositionAdjustments::getExitPoint(le_int32 index, LEPoint &exitPoint)const +{ + if (fEntryExitPoints == NULL) { + return NULL; + } + + return fEntryExitPoints[index].getExitPoint(exitPoint); +} + +void GlyphPositionAdjustments::setEntryPoint(le_int32 index, LEPoint &newEntryPoint, le_bool baselineIsLogicalEnd) +{ + CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount); + + fEntryExitPoints[index].setEntryPoint(newEntryPoint, baselineIsLogicalEnd); +} + +void GlyphPositionAdjustments::setExitPoint(le_int32 index, LEPoint &newExitPoint, le_bool baselineIsLogicalEnd) +{ + CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount); + + fEntryExitPoints[index].setExitPoint(newExitPoint, baselineIsLogicalEnd); +} + +void GlyphPositionAdjustments::setCursiveGlyph(le_int32 index, le_bool baselineIsLogicalEnd) +{ + CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount); + + fEntryExitPoints[index].setCursiveGlyph(baselineIsLogicalEnd); +} + +void GlyphPositionAdjustments::applyCursiveAdjustments(LEGlyphStorage &glyphStorage, le_bool rightToLeft, const LEFontInstance *fontInstance) +{ + if (! hasCursiveGlyphs()) { + return; + } + + le_int32 start = 0, end = fGlyphCount, dir = 1; + le_int32 firstExitPoint = -1, lastExitPoint = -1; + LEPoint entryAnchor, exitAnchor, pixels; + LEGlyphID lastExitGlyphID = 0; + float baselineAdjustment = 0; + + // This removes a possible warning about + // using exitAnchor before it's been initialized. + exitAnchor.fX = exitAnchor.fY = 0; + + if (rightToLeft) { + start = fGlyphCount - 1; + end = -1; + dir = -1; + } + + for (le_int32 i = start; i != end; i += dir) { + LEGlyphID glyphID = glyphStorage[i]; + + if (isCursiveGlyph(i)) { + if (lastExitPoint >= 0 && getEntryPoint(i, entryAnchor) != NULL) { + float anchorDiffX = exitAnchor.fX - entryAnchor.fX; + float anchorDiffY = exitAnchor.fY - entryAnchor.fY; + + baselineAdjustment += anchorDiffY; + adjustYPlacement(i, baselineAdjustment); + + if (rightToLeft) { + LEPoint secondAdvance; + + fontInstance->getGlyphAdvance(glyphID, pixels); + fontInstance->pixelsToUnits(pixels, secondAdvance); + + adjustXAdvance(i, -(anchorDiffX + secondAdvance.fX)); + } else { + LEPoint firstAdvance; + + fontInstance->getGlyphAdvance(lastExitGlyphID, pixels); + fontInstance->pixelsToUnits(pixels, firstAdvance); + + adjustXAdvance(lastExitPoint, anchorDiffX - firstAdvance.fX); + } + } + + lastExitPoint = i; + + if (getExitPoint(i, exitAnchor) != NULL) { + if (firstExitPoint < 0) { + firstExitPoint = i; + } + + lastExitGlyphID = glyphID; + } else { + if (baselineIsLogicalEnd(i) && firstExitPoint >= 0 && lastExitPoint >= 0) { + le_int32 limit = lastExitPoint + dir; + + for (le_int32 j = firstExitPoint; j != limit; j += dir) { + if (isCursiveGlyph(j)) { + adjustYPlacement(j, -baselineAdjustment); + } + } + } + + firstExitPoint = lastExitPoint = -1; + baselineAdjustment = 0; + } + } + } +} + +LEPoint *GlyphPositionAdjustments::EntryExitPoint::getEntryPoint(LEPoint &entryPoint) const +{ + if (fFlags & EEF_HAS_ENTRY_POINT) { + entryPoint = fEntryPoint; + return &entryPoint; + } + + return NULL; +} + +LEPoint *GlyphPositionAdjustments::EntryExitPoint::getExitPoint(LEPoint &exitPoint) const +{ + if (fFlags & EEF_HAS_EXIT_POINT) { + exitPoint = fExitPoint; + return &exitPoint; + } + + return NULL; +} + +U_NAMESPACE_END