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

import com.adobe.xfa.gfx.GFXMapping;
import com.adobe.xfa.gfx.GFXMappingList;
import com.adobe.xfa.text.TextAttr;
import com.adobe.xfa.text.TextGlyphRun;
import com.adobe.xfa.ut.Storage;
import com.adobe.xfa.ut.UnitSpan;

public class TextLayoutLine {
    public static final int LINE_END_WORD_WRAP = 0;
    public static final int LINE_END_HYPHEN = 1;
    public static final int LINE_END_LAST_WORD = 2;
    public static final int LINE_END_EMERGENCY = 3;
    public static final int LINE_END_FORCED = 4;
    public static final int LINE_END_PARA = 5;
    public static final int LINE_END_ULTIMATE = 6;
    private String msContent = "";
    private int mnChars;
    private final Storage<TextGlyphRun> moRuns = new Storage();
    private int mnGlyphs;
    private GFXMappingList moMappings = new GFXMappingList();
    private Storage<CharRun> moCharRuns = new Storage();
    private int meLineStartState = 0;
    private int meLineEndState = 0;
    private UnitSpan moFullAscent;
    private UnitSpan moFullDescent;

    public TextLayoutLine() {
    }

    public TextLayoutLine(TextLayoutLine oSource) {
        this.copyFrom(oSource);
    }

    public void reset() {
        this.cleanup();
    }

    public TextGlyphRun addRun(TextGlyphRun poRun) {
        TextGlyphRun poCopy = new TextGlyphRun(poRun);
        this.moRuns.add(poCopy);
        this.mnGlyphs += poCopy.getGlyphCount();
        return poCopy;
    }

    public void addRunRef(TextGlyphRun poRun) {
        this.moRuns.add(poRun);
        this.mnGlyphs += poRun.getGlyphCount();
    }

    public int getRunCount() {
        return this.moRuns.size();
    }

    public TextGlyphRun getRun(int nIndex) {
        return this.moRuns.get(nIndex);
    }

    public int getGlyphCount() {
        return this.mnGlyphs;
    }

    public void setContent(String sContent) {
        this.msContent = sContent;
        this.mnChars = sContent.length();
    }

    public String getContent() {
        return this.msContent;
    }

    public int getCharCount() {
        return this.mnChars;
    }

    public void setMappings(GFXMappingList oMappings) {
        this.moMappings = new GFXMappingList(oMappings);
    }

    public GFXMappingList getMappings() {
        return this.moMappings;
    }

    public void addMapping(int nCharIndex, int nGlyphIndex, int nCharLength, int nGlyphLength) {
        if (this.moMappings == null) {
            this.moMappings = new GFXMappingList();
        }
        this.moMappings.addMapping(nCharIndex, nGlyphIndex, nCharLength, nGlyphLength);
    }

    public void addMapping(TextGlyphRun poRun, int nCharIndex, int nGlyphIndex, int nCharLength, int nGlyphLength) {
        TextGlyphRun poTest;
        int i;
        int nOffset = 0;
        for (i = 0; i < this.moRuns.size() && (poTest = this.getRun(i)) != poRun; ++i) {
            nOffset += poRun.getGlyphCount();
        }
        if (i == this.moRuns.size()) {
            return;
        }
        this.addMapping(nCharIndex, nGlyphIndex + nOffset, nCharLength, nGlyphLength);
    }

    public void autoMap() {
        if (this.mnChars != this.mnGlyphs) {
            // empty if block
        }
        this.moMappings.autoMap(this.mnChars);
    }

    public int getMappingCount() {
        return this.moMappings.getMappingCount();
    }

    public GFXMapping getMapping(int nIndex) {
        return this.moMappings.getMapping(nIndex);
    }

    public void setLineStartState(int eState) {
        this.meLineStartState = eState;
    }

    public int getLineStartState() {
        return this.meLineStartState;
    }

    public void setLineEndState(int eState) {
        this.meLineEndState = eState;
    }

    public int getLineEndState() {
        return this.meLineEndState;
    }

    public UnitSpan getFullAscent() {
        return this.moFullAscent;
    }

    public UnitSpan getFullDescent() {
        return this.moFullDescent;
    }

    public void copyFrom(TextLayoutLine oSource) {
        if (this != oSource) {
            this.cleanup();
            this.msContent = oSource.msContent;
            this.moRuns.setSize(oSource.moRuns.size());
            for (int i = 0; i < this.moRuns.size(); ++i) {
                this.moRuns.set(i, oSource.getRun(i));
            }
            this.moMappings.copyFrom(oSource.moMappings);
            this.mnChars = oSource.mnChars;
            this.mnGlyphs = oSource.mnGlyphs;
            this.meLineStartState = oSource.meLineStartState;
            this.meLineEndState = oSource.meLineEndState;
            this.moFullAscent = oSource.moFullAscent;
            this.moFullDescent = oSource.moFullDescent;
            this.moCharRuns = null;
        }
    }

    void reconcile() {
        this.forceReconcile();
    }

    int getCharRunCount() {
        this.reconcile();
        return this.moCharRuns.size();
    }

    CharRun getCharRun(int nIndex) {
        this.reconcile();
        return this.moCharRuns.get(nIndex);
    }

    public void setFullAscent(UnitSpan oAscent) {
        this.moFullAscent = oAscent;
    }

    public void setFullDescent(UnitSpan oDescent) {
        this.moFullDescent = oDescent;
    }

    private void forceReconcile() {
        if (this.moCharRuns != null) {
            return;
        }
        this.moCharRuns = new Storage();
        this.moMappings.validate(this.mnChars, this.mnGlyphs);
        TextGlyphRun poPrevRun = null;
        int nPrevRunIndex = 0;
        int nCharLimit = 0;
        this.moMappings.orderByCharacter();
        for (int nMap = 0; nMap < this.moMappings.getMappingCount(); ++nMap) {
            GFXMapping oMapping = this.moMappings.getMapping(nMap);
            int nCharStart = oMapping.getLowestCharIndex();
            assert (nCharStart == nCharLimit);
            nCharLimit = oMapping.getHighestCharIndex() + 1;
            assert (nCharLimit <= this.mnChars);
            int nGlyphStart = oMapping.getLowestGlyphIndex();
            TextGlyphRun poRun = null;
            int nRunOffset = 0;
            for (int i = 0; i < this.moRuns.size() && poRun == null; ++i) {
                TextGlyphRun poTest = this.getRun(i);
                int nRunLimit = nRunOffset + poTest.getGlyphCount();
                if (nGlyphStart < nRunLimit) {
                    poRun = poTest;
                }
                nRunOffset = nRunLimit;
            }
            assert (poRun != null);
            if (poRun == poPrevRun) continue;
            if (nCharStart > nPrevRunIndex) {
                this.moCharRuns.add(new CharRun(poPrevRun.getAttr(), poPrevRun, nPrevRunIndex, nCharStart - nPrevRunIndex));
            }
            poPrevRun = poRun;
            nPrevRunIndex = nCharStart;
        }
        assert (nCharLimit == this.mnChars);
        if (nPrevRunIndex < this.mnChars) {
            this.moCharRuns.add(new CharRun(poPrevRun.getAttr(), poPrevRun, nPrevRunIndex, this.mnChars - nPrevRunIndex));
        }
    }

    private void cleanup() {
        this.moRuns.setSize(0);
        this.msContent = "";
        this.moMappings.reset();
        this.moCharRuns.setSize(0);
        this.mnChars = 0;
        this.mnGlyphs = 0;
        this.meLineStartState = 0;
        this.meLineEndState = 0;
        this.moFullAscent = UnitSpan.ZERO;
        this.moFullDescent = UnitSpan.ZERO;
    }

    static class CharRun {
        final TextAttr mpoAttr;
        final TextGlyphRun mpoGlyphRun;
        final int mnCharIndex;
        final int mnCharLength;

        public CharRun(TextAttr poAttr, TextGlyphRun poGlyphRun, int nCharIndex, int nCharLength) {
            this.mpoAttr = poAttr;
            this.mpoGlyphRun = poGlyphRun;
            this.mnCharIndex = nCharIndex;
            this.mnCharLength = nCharLength;
        }
    }

}