in modules/awt/src/main/java/common/org/apache/harmony/awt/gl/font/TextRunSegmentImpl.java [602:789]
float doJustification(TextRunBreaker.JustificationInfo jInfos[]) {
int lastPriority =
jInfos[jInfos.length-1] == null ?
-1 : jInfos[jInfos.length-1].priority;
// Get the highest priority
int highestPriority = 0;
for (; highestPriority<jInfos.length; highestPriority++) {
if (jInfos[highestPriority] != null) {
break;
}
}
if (highestPriority == jInfos.length) {
return 0;
}
TextRunBreaker.JustificationInfo firstInfo = jInfos[highestPriority];
TextRunBreaker.JustificationInfo lastInfo =
lastPriority > 0 ? jInfos[lastPriority] : null;
boolean haveFirst = info.start <= firstInfo.firstIdx;
boolean haveLast = info.end >= (firstInfo.lastIdx + 1);
// Here we suppose that GLYPHS are ordered LEFT TO RIGHT
int firstGlyph = haveFirst ?
getChar2Glyph()[firstInfo.firstIdx - info.start] :
getChar2Glyph()[0];
int lastGlyph = haveLast ?
getChar2Glyph()[firstInfo.lastIdx - info.start] :
getChar2Glyph()[info.length - 1];
if (haveLast) {
lastGlyph--;
}
TextRunBreaker.JustificationInfo currInfo;
float glyphOffset = 0;
float positionIncrement = 0;
float sideIncrement = 0;
if (haveFirst) { // Don't add padding before first char
GlyphJustificationInfo gji = getGlyphJustificationInfos()[firstGlyph];
currInfo = jInfos[gji.growPriority];
if (currInfo != null) {
if (currInfo.useLimits) {
if (currInfo.absorb) {
glyphOffset += gji.weight * currInfo.absorbedGapPerUnit;
} else if (
lastInfo != null &&
lastInfo.priority == currInfo.priority
) {
glyphOffset += gji.weight * lastInfo.absorbedGapPerUnit;
}
glyphOffset +=
firstInfo.grow ?
gji.growRightLimit :
-gji.shrinkRightLimit;
} else {
glyphOffset += gji.weight * currInfo.gapPerUnit;
}
}
firstGlyph++;
}
if (firstInfo.grow) {
for (int i=firstGlyph; i<=lastGlyph; i++) {
GlyphJustificationInfo gji = getGlyphJustificationInfos()[i];
currInfo = jInfos[gji.growPriority];
if (currInfo == null) {
// We still have to increment glyph position
Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
glyphPos.setLocation(glyphPos.getX() + glyphOffset, glyphPos.getY());
getGlyphVector().setGlyphPosition(i, glyphPos);
continue;
}
if (currInfo.useLimits) {
glyphOffset += gji.growLeftLimit;
if (currInfo.absorb) {
sideIncrement = gji.weight * currInfo.absorbedGapPerUnit;
glyphOffset += sideIncrement;
positionIncrement = glyphOffset;
glyphOffset += sideIncrement;
} else if (lastInfo != null && lastInfo.priority == currInfo.priority) {
sideIncrement = gji.weight * lastInfo.absorbedGapPerUnit;
glyphOffset += sideIncrement;
positionIncrement = glyphOffset;
glyphOffset += sideIncrement;
} else {
positionIncrement = glyphOffset;
}
glyphOffset += gji.growRightLimit;
} else {
sideIncrement = gji.weight * currInfo.gapPerUnit;
glyphOffset += sideIncrement;
positionIncrement = glyphOffset;
glyphOffset += sideIncrement;
}
Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
glyphPos.setLocation(glyphPos.getX() + positionIncrement, glyphPos.getY());
getGlyphVector().setGlyphPosition(i, glyphPos);
}
} else {
for (int i=firstGlyph; i<=lastGlyph; i++) {
GlyphJustificationInfo gji = getGlyphJustificationInfos()[i];
currInfo = jInfos[gji.shrinkPriority];
if (currInfo == null) {
// We still have to increment glyph position
Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
glyphPos.setLocation(glyphPos.getX() + glyphOffset, glyphPos.getY());
getGlyphVector().setGlyphPosition(i, glyphPos);
continue;
}
if (currInfo.useLimits) {
glyphOffset -= gji.shrinkLeftLimit;
if (currInfo.absorb) {
sideIncrement = gji.weight * currInfo.absorbedGapPerUnit;
glyphOffset += sideIncrement;
positionIncrement = glyphOffset;
glyphOffset += sideIncrement;
} else if (lastInfo != null && lastInfo.priority == currInfo.priority) {
sideIncrement = gji.weight * lastInfo.absorbedGapPerUnit;
glyphOffset += sideIncrement;
positionIncrement = glyphOffset;
glyphOffset += sideIncrement;
} else {
positionIncrement = glyphOffset;
}
glyphOffset -= gji.shrinkRightLimit;
} else {
sideIncrement = gji.weight * currInfo.gapPerUnit;
glyphOffset += sideIncrement;
positionIncrement = glyphOffset;
glyphOffset += sideIncrement;
}
Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
glyphPos.setLocation(glyphPos.getX() + positionIncrement, glyphPos.getY());
getGlyphVector().setGlyphPosition(i, glyphPos);
}
}
if (haveLast) { // Don't add padding after last char
lastGlyph++;
GlyphJustificationInfo gji = getGlyphJustificationInfos()[lastGlyph];
currInfo = jInfos[gji.growPriority];
if (currInfo != null) {
if (currInfo.useLimits) {
glyphOffset += firstInfo.grow ? gji.growLeftLimit : -gji.shrinkLeftLimit;
if (currInfo.absorb) {
glyphOffset += gji.weight * currInfo.absorbedGapPerUnit;
} else if (lastInfo != null && lastInfo.priority == currInfo.priority) {
glyphOffset += gji.weight * lastInfo.absorbedGapPerUnit;
}
} else {
glyphOffset += gji.weight * currInfo.gapPerUnit;
}
}
// Ajust positions of all glyphs after last glyph
for (int i=lastGlyph; i<getGlyphVector().getNumGlyphs()+1; i++) {
Point2D glyphPos = getGlyphVector().getGlyphPosition(i);
glyphPos.setLocation(glyphPos.getX() + glyphOffset, glyphPos.getY());
getGlyphVector().setGlyphPosition(i, glyphPos);
}
} else { // Update position after last glyph in glyph vector -
// to get correct advance for it
Point2D glyphPos = getGlyphVector().getGlyphPosition(lastGlyph+1);
glyphPos.setLocation(glyphPos.getX() + glyphOffset, glyphPos.getY());
getGlyphVector().setGlyphPosition(lastGlyph+1, glyphPos);
}
gjis = null; // We don't need justification infos any more
// Also we have to reset cached bounds and metrics
this.visualBounds = null;
this.logicalBounds = null;
return glyphOffset; // How much our segment grown or shrunk
}