com.adobe.xfa.text.LineHeight Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aem-sdk-api Show documentation
Show all versions of aem-sdk-api Show documentation
The Adobe Experience Manager SDK
package com.adobe.xfa.text;
import com.adobe.xfa.font.FontInstance;
import com.adobe.xfa.gfx.GFXGlyphOrientation;
import com.adobe.xfa.ut.UnitSpan;
/*
* @exclude from published api.
*/
class LineHeight extends TextLegacy {
private TextAttr mpoPrevAttr; // to avoid redundant calcs
private int moAscent; // max ascent
private int moDescent; // max descent
private int moLineGap; // max line gap
private int moSize; // max font Size
private int moTextHeight; // max text height (ascent + descent)
private int moOverride; // line spacing override (if > 0)
private int moBefore; // space before line
private int moAfter; // space after line
private int moFullHeight; // line height with before and after added
private int moLegacySpacing; // 6.0 line spacing
private boolean mbOverrideCancelled;
private boolean mbHasBaselineShift; // any baseline shift found
private boolean mbBaselineShiftStarted; // started accumulating baseline?
LineHeight () {
}
LineHeight (int legacyLevel) {
setLegacyLevel (legacyLevel);
}
final int ascent () {
return moAscent;
}
final int descent () {
return moDescent;
}
final int lineGap () {
return moLineGap;
}
final int size () {
return moSize;
}
// The test offset is actually the baseline offset. It is computed by
// moving up by the maximum descent from the bottom of the line spacing
// (which may have been overridden).
final int textOffset (int eGlyphOrientation) {
int oBottom;
if (hasLegacyPositioning()) {
if (moOverride == 0) {
oBottom = spacing();
} else if (moOverride > moTextHeight) {
oBottom = moOverride;
} else {
oBottom = moTextHeight;
}
oBottom -= moDescent;
} else {
oBottom = moOverride - moLineGap;
if (oBottom < moTextHeight) {
oBottom = moTextHeight;
}
if (GFXGlyphOrientation.usesHorizontalGlyphs (eGlyphOrientation)) {
oBottom -= moDescent;
} else {
oBottom = (oBottom + 1) / 2;
}
}
return moBefore + oBottom;
}
final int spacing () {
// Return spacing override if there is one.
return (moOverride > 0) ? moOverride : (hasLegacyPositioning() ? moLegacySpacing : (moTextHeight + moLineGap));
}
final int override () {
return moOverride;
}
final int fullHeight () {
return moFullHeight;
}
final int before () {
return moBefore;
}
final void before (int oNewBefore) {
moBefore = oNewBefore;
}
final int after () {
return moAfter;
}
final void after (int oNewAfter) {
moAfter = oNewAfter;
}
final boolean hasBaselineShift () {
return mbHasBaselineShift;
}
final void accumulateAscent (int oNewAscent) {
if (oNewAscent > moAscent) {
moAscent = oNewAscent;
}
}
final void accumulateAscent (UnitSpan oNewAscent) {
accumulateAscent (Units.toInt (oNewAscent));
}
final void accumulateDescent (int oNewDescent) {
if (oNewDescent > moDescent) {
moDescent = oNewDescent;
}
}
final void accumulateDescent (UnitSpan oNewDescent) {
accumulateDescent (Units.toInt (oNewDescent));
}
final void accumulateLineGap (int oNewLineGap) {
if (oNewLineGap > moLineGap) {
moLineGap = oNewLineGap;
}
}
final void accumulateLineGap (UnitSpan oNewLineGap) {
accumulateLineGap (Units.toInt (oNewLineGap));
}
final void accumulateSize (int oNewSize) {
if (oNewSize > moSize) {
moSize = oNewSize;
}
}
final void accumulateSize (UnitSpan oNewSize) {
accumulateSize (Units.toInt (oNewSize));
}
final void accumulateOverride (int oNewOverride) {
if (oNewOverride > moOverride) {
moOverride = oNewOverride;
}
}
final void accumulateOverride (UnitSpan oNewOverride) {
accumulateOverride (Units.toInt (oNewOverride));
}
final void accumulateLegacySpacing (int oNewLegacySpacing) {
if (oNewLegacySpacing > moLegacySpacing) {
moLegacySpacing = oNewLegacySpacing;
}
}
final void accumulateLegacySpacing (int oAscent, int oDescent, int oLineGap) {
accumulateLegacySpacing (oAscent + oDescent + oLineGap);
}
final void accumulateAfter (int oNewAfter) {
if (oNewAfter > moAfter) {
moAfter = oNewAfter;
}
}
final void accumulateAfter (UnitSpan oNewAfter) {
accumulateAfter (Units.toInt (oNewAfter));
}
final void accumulate (TextAttr poAttr, int eGlyphOrientation, boolean bFirstLineInStream) {
HeightInfo info = canProcessAttr (poAttr, true);
if (info == null) {
return;
}
if (GFXGlyphOrientation.usesHorizontalGlyphs (eGlyphOrientation)) {
accumulateAscent (info.ascent);
accumulateDescent (info.descent);
} else {
accumulateSize (info.size);
}
if (! hasLegacyPositioning()) {
accumulateLineGap (info.lineGap);
} else {
accumulateLegacySpacing (info.ascent, info.descent, info.lineGap);
}
boolean bBaselineShift = (poAttr.baselineShiftEnable()) && (! poAttr.baselineShift().isNeutral());
if (bBaselineShift) {
mbHasBaselineShift = true;
}
if (poAttr.spacingEnable()) {
boolean bAccumulateOverride = false;
UnitSpan spacing = poAttr.spacing().getLength();
if (! bFirstLineInStream) {
bAccumulateOverride = true;
} else {
int oLineSize = info.size;
if (! hasLegacyPositioning()) {
oLineSize = oLineSize + info.lineGap;
}
if (spacing.lt (Units.toUnitSpan (oLineSize))) {
bAccumulateOverride = true;
}
}
if (bAccumulateOverride) {
accumulateOverride (spacing);
}
}
}
final void accumulateBaselineShift (TextAttr poAttr) {
if (! mbBaselineShiftStarted) {
mpoPrevAttr = null;
if (moSize <= 0) {
moSize = moAscent + moDescent;
}
mbBaselineShiftStarted = true;
}
HeightInfo info = canProcessAttr (poAttr, false);
if (info == null) {
return;
}
if ((poAttr.baselineShiftEnable()) && (! poAttr.baselineShift().isNeutral())) {
UnitSpan us = Units.toUnitSpan (info.size);
us = poAttr.baselineShift().applyShift (us, us);
int oNewBaseline = Units.toInt (us);
int oShift = oNewBaseline - info.size; // +ve is down shift
if (hasLegacyPositioning()) {
if (oShift < 0) {
accumulateLegacySpacing (info.ascent - oShift, info.descent, info.lineGap);
} else {
accumulateAfter (oShift);
}
} else {
accumulateAscent (info.ascent - oShift);
accumulateDescent (info.descent + oShift);
}
}
}
final void reconcile () {
if ((moAscent <= 0) && (moDescent <= 0)) {
moTextHeight = moSize;
} else {
moTextHeight = moAscent + moDescent;
}
if (hasLegacyPositioning() && (moLegacySpacing < moTextHeight)) {
moLegacySpacing = moTextHeight;
}
if (mbOverrideCancelled) {
moOverride = 0;
}
moFullHeight = moBefore + spacing() + moAfter;
}
final boolean adjustLineSpacing (UnitSpan oTop) {
if ((hasLegacyPositioning()) || (moOverride > 0) || (oTop.value() >= 0)) { // legacy positioning; must not adjust // forced line spacing; cannot adjust
return false; // -ve value signals overflow above
}
int oDelta = Units.toInt (oTop);
moAscent -= oDelta;
moTextHeight -= oDelta;
moFullHeight -= oDelta;
return true;
}
final void reset () {
moAscent = 0;
moDescent = 0;
moLineGap = 0;
moTextHeight = 0;
moSize = 0;
moOverride = 0;
moBefore = 0;
moAfter = 0;
moLegacySpacing = 0;
mbOverrideCancelled = false;
mbHasBaselineShift = false;
mbBaselineShiftStarted = false;
detach();
}
final void cancelOverride () {
mbOverrideCancelled = true;
}
final void detach () {
mpoPrevAttr = null; // don't carry dangling reference in case reused
}
private HeightInfo canProcessAttr (TextAttr poAttr, boolean bAccumulateSize) {
if ((poAttr == null) || (poAttr == mpoPrevAttr)) {
return null;
}
mpoPrevAttr = poAttr;
FontInstance poFontInstance = poAttr.fontInstance();
if (poFontInstance == null) {
return null;
}
int ascent, descent, lineGap, size;
if (hasLegacyPositioning()) {
ascent = Units.toInt (poFontInstance.getLegacyAscent());
descent = Units.toInt (poFontInstance.getSize()) - ascent;
lineGap = Units.toInt (poFontInstance.getLegacyLineGap());
} else {
ascent = Units.toInt (poFontInstance.getAscent());
descent = Units.toInt (poFontInstance.getDescent());
lineGap = Units.toInt (poFontInstance.getLineGap());
}
if (poAttr.sizeEnable()) {
size = Units.toInt (poAttr.size());
if (bAccumulateSize) {
accumulateSize (poAttr.size()); // if being called for full accumulation
}
} else {
size = ascent + descent;
}
return new HeightInfo(ascent, descent, size, lineGap);
}
private static class HeightInfo {
final int ascent;
final int descent;
final int size;
final int lineGap;
public HeightInfo(int ascent, int descent, int size, int lineGap) {
this.ascent = ascent;
this.descent = descent;
this.size = size;
this.lineGap = lineGap;
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy