LineHeight.java 10 KB
/*
 * Decompiled with CFR 0_118.
 */
package com.adobe.xfa.text;

import com.adobe.xfa.font.FontInstance;
import com.adobe.xfa.gfx.GFXGlyphOrientation;
import com.adobe.xfa.text.TextAttr;
import com.adobe.xfa.text.TextBaselineShift;
import com.adobe.xfa.text.TextLegacy;
import com.adobe.xfa.text.TextMeasurement;
import com.adobe.xfa.text.Units;
import com.adobe.xfa.ut.UnitSpan;

class LineHeight
extends TextLegacy {
    private TextAttr mpoPrevAttr;
    private int moAscent;
    private int moDescent;
    private int moLineGap;
    private int moSize;
    private int moTextHeight;
    private int moOverride;
    private int moBefore;
    private int moAfter;
    private int moFullHeight;
    private int moLegacySpacing;
    private boolean mbOverrideCancelled;
    private boolean mbHasBaselineShift;
    private boolean mbBaselineShiftStarted;

    LineHeight() {
    }

    LineHeight(int legacyLevel) {
        this.setLegacyLevel(legacyLevel);
    }

    final int ascent() {
        return this.moAscent;
    }

    final int descent() {
        return this.moDescent;
    }

    final int lineGap() {
        return this.moLineGap;
    }

    final int size() {
        return this.moSize;
    }

    final int textOffset(int eGlyphOrientation) {
        int oBottom;
        if (this.hasLegacyPositioning()) {
            oBottom = this.moOverride == 0 ? this.spacing() : (this.moOverride > this.moTextHeight ? this.moOverride : this.moTextHeight);
            oBottom -= this.moDescent;
        } else {
            oBottom = this.moOverride - this.moLineGap;
            if (oBottom < this.moTextHeight) {
                oBottom = this.moTextHeight;
            }
            oBottom = GFXGlyphOrientation.usesHorizontalGlyphs(eGlyphOrientation) ? (oBottom -= this.moDescent) : (oBottom + 1) / 2;
        }
        return this.moBefore + oBottom;
    }

    final int spacing() {
        return this.moOverride > 0 ? this.moOverride : (this.hasLegacyPositioning() ? this.moLegacySpacing : this.moTextHeight + this.moLineGap);
    }

    final int override() {
        return this.moOverride;
    }

    final int fullHeight() {
        return this.moFullHeight;
    }

    final int before() {
        return this.moBefore;
    }

    final void before(int oNewBefore) {
        this.moBefore = oNewBefore;
    }

    final int after() {
        return this.moAfter;
    }

    final void after(int oNewAfter) {
        this.moAfter = oNewAfter;
    }

    final boolean hasBaselineShift() {
        return this.mbHasBaselineShift;
    }

    final void accumulateAscent(int oNewAscent) {
        if (oNewAscent > this.moAscent) {
            this.moAscent = oNewAscent;
        }
    }

    final void accumulateAscent(UnitSpan oNewAscent) {
        this.accumulateAscent(Units.toInt(oNewAscent));
    }

    final void accumulateDescent(int oNewDescent) {
        if (oNewDescent > this.moDescent) {
            this.moDescent = oNewDescent;
        }
    }

    final void accumulateDescent(UnitSpan oNewDescent) {
        this.accumulateDescent(Units.toInt(oNewDescent));
    }

    final void accumulateLineGap(int oNewLineGap) {
        if (oNewLineGap > this.moLineGap) {
            this.moLineGap = oNewLineGap;
        }
    }

    final void accumulateLineGap(UnitSpan oNewLineGap) {
        this.accumulateLineGap(Units.toInt(oNewLineGap));
    }

    final void accumulateSize(int oNewSize) {
        if (oNewSize > this.moSize) {
            this.moSize = oNewSize;
        }
    }

    final void accumulateSize(UnitSpan oNewSize) {
        this.accumulateSize(Units.toInt(oNewSize));
    }

    final void accumulateOverride(int oNewOverride) {
        if (oNewOverride > this.moOverride) {
            this.moOverride = oNewOverride;
        }
    }

    final void accumulateOverride(UnitSpan oNewOverride) {
        this.accumulateOverride(Units.toInt(oNewOverride));
    }

    final void accumulateLegacySpacing(int oNewLegacySpacing) {
        if (oNewLegacySpacing > this.moLegacySpacing) {
            this.moLegacySpacing = oNewLegacySpacing;
        }
    }

    final void accumulateLegacySpacing(int oAscent, int oDescent, int oLineGap) {
        this.accumulateLegacySpacing(oAscent + oDescent + oLineGap);
    }

    final void accumulateAfter(int oNewAfter) {
        if (oNewAfter > this.moAfter) {
            this.moAfter = oNewAfter;
        }
    }

    final void accumulateAfter(UnitSpan oNewAfter) {
        this.accumulateAfter(Units.toInt(oNewAfter));
    }

    final void accumulate(TextAttr poAttr, int eGlyphOrientation, boolean bFirstLineInStream) {
        boolean bBaselineShift;
        HeightInfo info = this.canProcessAttr(poAttr, true);
        if (info == null) {
            return;
        }
        if (GFXGlyphOrientation.usesHorizontalGlyphs(eGlyphOrientation)) {
            this.accumulateAscent(info.ascent);
            this.accumulateDescent(info.descent);
        } else {
            this.accumulateSize(info.size);
        }
        if (!this.hasLegacyPositioning()) {
            this.accumulateLineGap(info.lineGap);
        } else {
            this.accumulateLegacySpacing(info.ascent, info.descent, info.lineGap);
        }
        boolean bl = bBaselineShift = poAttr.baselineShiftEnable() && !poAttr.baselineShift().isNeutral();
        if (bBaselineShift) {
            this.mbHasBaselineShift = true;
        }
        if (poAttr.spacingEnable()) {
            boolean bAccumulateOverride = false;
            UnitSpan spacing = poAttr.spacing().getLength();
            if (!bFirstLineInStream) {
                bAccumulateOverride = true;
            } else {
                int oLineSize = info.size;
                if (!this.hasLegacyPositioning()) {
                    oLineSize += info.lineGap;
                }
                if (spacing.lt(Units.toUnitSpan(oLineSize))) {
                    bAccumulateOverride = true;
                }
            }
            if (bAccumulateOverride) {
                this.accumulateOverride(spacing);
            }
        }
    }

    final void accumulateBaselineShift(TextAttr poAttr) {
        HeightInfo info;
        if (!this.mbBaselineShiftStarted) {
            this.mpoPrevAttr = null;
            if (this.moSize <= 0) {
                this.moSize = this.moAscent + this.moDescent;
            }
            this.mbBaselineShiftStarted = true;
        }
        if ((info = this.canProcessAttr(poAttr, false)) == 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;
            if (this.hasLegacyPositioning()) {
                if (oShift < 0) {
                    this.accumulateLegacySpacing(info.ascent - oShift, info.descent, info.lineGap);
                } else {
                    this.accumulateAfter(oShift);
                }
            } else {
                this.accumulateAscent(info.ascent - oShift);
                this.accumulateDescent(info.descent + oShift);
            }
        }
    }

    final void reconcile() {
        this.moTextHeight = this.moAscent <= 0 && this.moDescent <= 0 ? this.moSize : this.moAscent + this.moDescent;
        if (this.hasLegacyPositioning() && this.moLegacySpacing < this.moTextHeight) {
            this.moLegacySpacing = this.moTextHeight;
        }
        if (this.mbOverrideCancelled) {
            this.moOverride = 0;
        }
        this.moFullHeight = this.moBefore + this.spacing() + this.moAfter;
    }

    final boolean adjustLineSpacing(UnitSpan oTop) {
        if (this.hasLegacyPositioning() || this.moOverride > 0 || oTop.value() >= 0) {
            return false;
        }
        int oDelta = Units.toInt(oTop);
        this.moAscent -= oDelta;
        this.moTextHeight -= oDelta;
        this.moFullHeight -= oDelta;
        return true;
    }

    final void reset() {
        this.moAscent = 0;
        this.moDescent = 0;
        this.moLineGap = 0;
        this.moTextHeight = 0;
        this.moSize = 0;
        this.moOverride = 0;
        this.moBefore = 0;
        this.moAfter = 0;
        this.moLegacySpacing = 0;
        this.mbOverrideCancelled = false;
        this.mbHasBaselineShift = false;
        this.mbBaselineShiftStarted = false;
        this.detach();
    }

    final void cancelOverride() {
        this.mbOverrideCancelled = true;
    }

    final void detach() {
        this.mpoPrevAttr = null;
    }

    private HeightInfo canProcessAttr(TextAttr poAttr, boolean bAccumulateSize) {
        int lineGap;
        int size;
        int ascent;
        int descent;
        if (poAttr == null || poAttr == this.mpoPrevAttr) {
            return null;
        }
        this.mpoPrevAttr = poAttr;
        FontInstance poFontInstance = poAttr.fontInstance();
        if (poFontInstance == null) {
            return null;
        }
        if (this.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) {
                this.accumulateSize(poAttr.size());
            }
        } 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;
        }
    }

}