summaryrefslogtreecommitdiff
path: root/Build/source/libs/icu/icu-4.6/layout/GlyphPositionAdjustments.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/icu/icu-4.6/layout/GlyphPositionAdjustments.cpp')
-rw-r--r--Build/source/libs/icu/icu-4.6/layout/GlyphPositionAdjustments.cpp185
1 files changed, 185 insertions, 0 deletions
diff --git a/Build/source/libs/icu/icu-4.6/layout/GlyphPositionAdjustments.cpp b/Build/source/libs/icu/icu-4.6/layout/GlyphPositionAdjustments.cpp
new file mode 100644
index 00000000000..900e1aeecef
--- /dev/null
+++ b/Build/source/libs/icu/icu-4.6/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