ICU-3294 Save entry/exit points when processing cursive attachment subtables, position glyphs after GPOS processing.
X-SVN-Rev: 17123
This commit is contained in:
parent
bd1d7fd662
commit
573c7a46d0
162
icu4c/source/layout/GlyphPositionAdjustments.cpp
Normal file
162
icu4c/source/layout/GlyphPositionAdjustments.cpp
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
*
|
||||
* (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)
|
||||
{
|
||||
CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount);
|
||||
|
||||
fEntryExitPoints[index].setEntryPoint(newEntryPoint);
|
||||
}
|
||||
|
||||
void GlyphPositionAdjustments::setExitPoint(le_int32 index, LEPoint &newExitPoint)
|
||||
{
|
||||
CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount);
|
||||
|
||||
fEntryExitPoints[index].setExitPoint(newExitPoint);
|
||||
}
|
||||
|
||||
void GlyphPositionAdjustments::setCursiveGlyph(le_int32 index)
|
||||
{
|
||||
CHECK_ALLOCATE_ARRAY(fEntryExitPoints, EntryExitPoint, fGlyphCount);
|
||||
|
||||
fEntryExitPoints[index].setCursiveGlyph();
|
||||
}
|
||||
|
||||
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;
|
||||
float baselineAdjustment = 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 &&*/ 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
|
Loading…
Reference in New Issue
Block a user