diff options
author | Peter Breitenlohner <peb@mppmu.mpg.de> | 2011-08-10 12:03:08 +0000 |
---|---|---|
committer | Peter Breitenlohner <peb@mppmu.mpg.de> | 2011-08-10 12:03:08 +0000 |
commit | 79b8b3a76d8eda7372bb4dedae0ec7aebdaebc12 (patch) | |
tree | 9e4992c8719febb576deb6120740611380d71f7a /Build/source/libs/icu/icu-4.8.1/layout/GlyphPositionAdjustments.cpp | |
parent | 8cd13eb8f4bb7b92c6d9bb50aff9a62c37df026c (diff) |
icu 4.8.1
git-svn-id: svn://tug.org/texlive/trunk@23480 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/icu/icu-4.8.1/layout/GlyphPositionAdjustments.cpp')
-rw-r--r-- | Build/source/libs/icu/icu-4.8.1/layout/GlyphPositionAdjustments.cpp | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/Build/source/libs/icu/icu-4.8.1/layout/GlyphPositionAdjustments.cpp b/Build/source/libs/icu/icu-4.8.1/layout/GlyphPositionAdjustments.cpp new file mode 100644 index 00000000000..900e1aeecef --- /dev/null +++ b/Build/source/libs/icu/icu-4.8.1/layout/GlyphPositionAdjustments.cpp @@ -0,0 +1,185 @@ +/* + * + * (C) Copyright IBM Corp. 1998-2008 - 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::clearEntryPoint(le_int32 index) +{ + CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount); + + fEntryExitPoints[index].clearEntryPoint(); +} + +void GlyphPositionAdjustments::clearExitPoint(le_int32 index) +{ + CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount); + + fEntryExitPoints[index].clearExitPoint(); +} + +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*/; + LEPoint dummyAnchor; + + if (getEntryPoint(i, dummyAnchor) != NULL) { + limit += 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 |