Examples of InlineKnuthSequence


Examples of org.apache.fop.layoutmgr.InlineKnuthSequence

            }
        }
        if (returnedList.size() == 0) {
            //Inline part of the footnote is empty. Need to send back an auxiliary
            //zero-width, zero-height inline box so the footnote gets painted.
            KnuthSequence seq = new InlineKnuthSequence();
            //Need to use an aux. box, otherwise, the line height can't be forced to zero height.
            forcedAnchor = new KnuthInlineBox(0, null, null, true);
            seq.add(forcedAnchor);
            returnedList.add(seq);
        }
        setFinished(true);

        addAnchor(returnedList);
View Full Code Here

Examples of org.apache.fop.layoutmgr.InlineKnuthSequence

        lineStartBAP = context.getLineStartBorderAndPaddingWidth();
        lineEndBAP = context.getLineEndBorderAndPaddingWidth();
        alignmentContext = context.getAlignmentContext();

        LinkedList returnList = new LinkedList();
        KnuthSequence sequence = new InlineKnuthSequence();
        AreaInfo ai = null;
        AreaInfo prevAi = null;
        returnList.add(sequence);

        LineBreakStatus lbs = new LineBreakStatus();
        iThisStart = iNextStart;
        boolean inWord = false;
        boolean inWhitespace = false;
        char ch = 0;
        while (iNextStart < textArray.length) {
            ch = textArray[iNextStart];
            boolean breakOpportunity = false;
            byte breakAction = keepTogether? LineBreakStatus.PROHIBITED_BREAK : lbs.nextChar(ch);
            switch (breakAction) {
                case LineBreakStatus.COMBINING_PROHIBITED_BREAK:
                case LineBreakStatus.PROHIBITED_BREAK:
                    break;
                case LineBreakStatus.EXPLICIT_BREAK:
                    break;
                case LineBreakStatus.COMBINING_INDIRECT_BREAK:
                case LineBreakStatus.DIRECT_BREAK:
                case LineBreakStatus.INDIRECT_BREAK:
                    breakOpportunity = true;
                    break;
                default:
                    log.error("Unexpected breakAction: " + breakAction);
            }
            if (inWord) {
                if (breakOpportunity || isSpace(ch) || ch == NEWLINE) {
                    //Word boundary found, process widths and kerning
                    int lastIndex = iNextStart;
                    while (lastIndex > 0 && textArray[lastIndex - 1] == CharUtilities.SOFT_HYPHEN) {
                        lastIndex--;
                    }
                    int wordLength = lastIndex - iThisStart;
                    boolean kerning = font.hasKerning();
                    MinOptMax wordIPD = new MinOptMax(0);
                    for (int i = iThisStart; i < lastIndex; i++) {
                        char c = textArray[i];

                        //character width
                        int charWidth = font.getCharWidth(c);
                        wordIPD.add(charWidth);

                        //kerning
                        if (kerning) {
                            int kern = 0;
                            if (i > iThisStart) {
                                char previous = textArray[i - 1];
                                kern = font.getKernValue(previous, c) * font.getFontSize() / 1000;
                            } else if (prevAi != null && !prevAi.isSpace && prevAi.iBreakIndex > 0) {
                                char previous = textArray[prevAi.iBreakIndex - 1];
                                kern = font.getKernValue(previous, c) * font.getFontSize() / 1000;
                            }
                            if (kern != 0) {
                                //log.info("Kerning between " + previous + " and " + c + ": " + kern);
                                addToLetterAdjust(i, kern);
                                wordIPD.add(kern);
                            }
                        }
                    }
                    if (kerning && breakOpportunity && !isSpace(ch) && lastIndex > 0 && textArray[lastIndex] == CharUtilities.SOFT_HYPHEN) {
                        int kern = font.getKernValue(textArray[lastIndex - 1], ch) * font.getFontSize() / 1000;
                        if (kern != 0) {
                            addToLetterAdjust(lastIndex, kern);
                        }
                    }
                    int iLetterSpaces = wordLength - 1;
                    // if there is a break opportunity and the next one
                    // is not a space, it could be used as a line end;
                    // add one more letter space, in case other text follows
                    if (breakOpportunity && !isSpace(ch)) {
                        iLetterSpaces++;
                    }
                    wordIPD.add(MinOptMax.multiply(letterSpaceIPD, iLetterSpaces));

                    // create the AreaInfo object
                    ai = new AreaInfo(iThisStart, (short)lastIndex, (short) 0,
                            (short) iLetterSpaces,
                            wordIPD, textArray[lastIndex] == CharUtilities.SOFT_HYPHEN, false, breakOpportunity);
                    vecAreaInfo.add(ai);
                    prevAi = ai;
                    iTempStart = iNextStart;

                    // create the elements
                    sequence.addAll(createElementsForAWordFragment(alignment, ai,
                            vecAreaInfo.size() - 1, letterSpaceIPD));
                    ai = null;

                    iThisStart = iNextStart;
                }
            } else if (inWhitespace) {
                if (ch != CharUtilities.SPACE || breakOpportunity) {
                    // End of whitespace
                    // create the AreaInfo object
                    ai = new AreaInfo(iThisStart, (short) (iNextStart),
                            (short) (iNextStart - iThisStart), (short) 0,
                            MinOptMax.multiply(wordSpaceIPD, iNextStart - iThisStart),
                            false, true, breakOpportunity);
                    vecAreaInfo.add(ai);
                    prevAi = ai;

                    // create the elements
                    sequence.addAll
                        (createElementsForASpace(alignment, ai, vecAreaInfo.size() - 1));
                    ai = null;

                    iThisStart = iNextStart;
                }
            } else {
                if (ai != null) {
                    vecAreaInfo.add(ai);
                    prevAi = ai;
                    ai.breakOppAfter = ch == CharUtilities.SPACE || breakOpportunity;
                    sequence.addAll
                        (createElementsForASpace(alignment, ai, vecAreaInfo.size() - 1));
                    ai = null;
                }
                if (breakAction == LineBreakStatus.EXPLICIT_BREAK) {
                    if (lineEndBAP != 0) {
                        sequence.add
                            (new KnuthGlue(lineEndBAP, 0, 0,
                                           new LeafPosition(this, -1), true));
                    }
                    sequence.endSequence();
                    sequence = new InlineKnuthSequence();
                    returnList.add(sequence);
                }
            }
           
            if ((ch == CharUtilities.SPACE
                    && foText.getWhitespaceTreatment() == Constants.EN_PRESERVE)
                    || ch == CharUtilities.NBSPACE) {
                // preserved space or non-breaking space:
                // create the AreaInfo object
                ai = new AreaInfo(iNextStart, (short) (iNextStart + 1),
                        (short) 1, (short) 0,
                        wordSpaceIPD, false, true, breakOpportunity);
                iThisStart = (short) (iNextStart + 1);
            } else if (CharUtilities.isFixedWidthSpace(ch) || CharUtilities.isZeroWidthSpace(ch)) {
                // create the AreaInfo object
                MinOptMax ipd = new MinOptMax(font.getCharWidth(ch));
                ai = new AreaInfo(iNextStart, (short) (iNextStart + 1),
                        (short) 0, (short) 0,
                        ipd, false, true, breakOpportunity);
                iThisStart = (short) (iNextStart + 1);
            } else if (ch == NEWLINE) {
                // linefeed; this can happen when linefeed-treatment="preserve"
                iThisStart = (short) (iNextStart + 1);
            }
            inWord = !isSpace(ch) && ch != NEWLINE;
            inWhitespace = ch == CharUtilities.SPACE && foText.getWhitespaceTreatment() != Constants.EN_PRESERVE;
            iNextStart++;
        } // end of while
       
        // Process any last elements
        if (inWord) {
            int lastIndex = iNextStart;
            if (textArray[iNextStart - 1] == CharUtilities.SOFT_HYPHEN) {
                lastIndex--;
            }
            int wordLength = lastIndex - iThisStart;
            boolean kerning = font.hasKerning();
            MinOptMax wordIPD = new MinOptMax(0);
            for (int i = iThisStart; i < lastIndex; i++) {
                char c = textArray[i];

                //character width
                int charWidth = font.getCharWidth(c);
                wordIPD.add(charWidth);

                //kerning
                if (kerning) {
                    int kern = 0;
                    if (i > iThisStart) {
                        char previous = textArray[i - 1];
                        kern = font.getKernValue(previous, c) * font.getFontSize() / 1000;
                    } else if (prevAi != null && !prevAi.isSpace) {
                        char previous = textArray[prevAi.iBreakIndex - 1];
                        kern = font.getKernValue(previous, c) * font.getFontSize() / 1000;
                    }
                    if (kern != 0) {
                        //log.info("Kerning between " + previous + " and " + c + ": " + kern);
                        addToLetterAdjust(i, kern);
                        wordIPD.add(kern);
                    }
                }
            }
            int iLetterSpaces = wordLength - 1;
            wordIPD.add(MinOptMax.multiply(letterSpaceIPD, iLetterSpaces));

            // create the AreaInfo object
            ai = new AreaInfo(iThisStart, (short)lastIndex, (short) 0,
                    (short) iLetterSpaces,
                    wordIPD, false, false, false);
            vecAreaInfo.add(ai);
            iTempStart = iNextStart;

            // create the elements
            sequence.addAll(createElementsForAWordFragment(alignment, ai,
                    vecAreaInfo.size() - 1, letterSpaceIPD));
            ai = null;
        } else if (inWhitespace) {
            ai = new AreaInfo(iThisStart, (short) (iNextStart),
                    (short) (iNextStart - iThisStart), (short) 0,
                    MinOptMax.multiply(wordSpaceIPD, iNextStart - iThisStart),
                    false, true, true);
            vecAreaInfo.add(ai);

            // create the elements
            sequence.addAll
                (createElementsForASpace(alignment, ai, vecAreaInfo.size() - 1));
            ai = null;
        } else if (ai != null) {
            vecAreaInfo.add(ai);
            ai.breakOppAfter = ch == CharUtilities.ZERO_WIDTH_SPACE;
            sequence.addAll
                (createElementsForASpace(alignment, ai, vecAreaInfo.size() - 1));
            ai = null;
        } else if (ch == NEWLINE) {
            if (lineEndBAP != 0) {
                sequence.add
                    (new KnuthGlue(lineEndBAP, 0, 0,
                                   new LeafPosition(this, -1), true));
            }
            sequence.endSequence();
            sequence = new InlineKnuthSequence();
            returnList.add(sequence);
        }

        if (((List)returnList.getLast()).size() == 0) {
            //Remove an empty sequence because of a trailing newline
View Full Code Here

Examples of org.apache.fop.layoutmgr.InlineKnuthSequence

    /** @see org.apache.fop.layoutmgr.LayoutManager#getNextKnuthElements(LayoutContext, int) */
    public LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
        MinOptMax ipd;
        curArea = get(context);
        KnuthSequence seq = new InlineKnuthSequence();

        if (curArea == null) {
            setFinished(true);
            return null;
        }

        ipd = new MinOptMax(font.getCharWidth(fobj.getCharacter()));

        curArea.setIPD(ipd.opt);
        curArea.setBPD(font.getAscender() - font.getDescender());

        TraitSetter.addFontTraits(curArea, font);
        curArea.addTrait(Trait.COLOR, fobj.getColor());

        // TODO: may need some special handling for fo:character
        alignmentContext = new AlignmentContext(font
                                    , font.getFontSize()
                                    , fobj.getAlignmentAdjust()
                                    , fobj.getAlignmentBaseline()
                                    , fobj.getBaselineShift()
                                    , fobj.getDominantBaseline()
                                    , context.getAlignmentContext());

        addKnuthElementsForBorderPaddingStart(seq);
       
        // create the AreaInfo object to store the computed values
        areaInfo = new AreaInfo((short) 0, ipd, false, alignmentContext);

        // node is a fo:Character
        if (letterSpaceIPD.min == letterSpaceIPD.max) {
            // constant letter space, only return a box
            seq.add(new KnuthInlineBox(areaInfo.ipdArea.opt, areaInfo.alignmentContext,
                                        notifyPos(new LeafPosition(this, 0)), false));
        } else {
            // adjustable letter space, return a sequence of elements;
            // at the moment the character is supposed to have no letter spaces,
            // but returning this sequence allows us to change only one element
            // if addALetterSpaceTo() is called
            seq.add(new KnuthInlineBox(areaInfo.ipdArea.opt, areaInfo.alignmentContext,
                                        notifyPos(new LeafPosition(this, 0)), false));
            seq.add(new KnuthPenalty(0, KnuthElement.INFINITE, false,
                                            new LeafPosition(this, -1), true));
            seq.add(new KnuthGlue(0, 0, 0,
                                         new LeafPosition(this, -1), true));
            seq.add(new KnuthInlineBox(0, null,
                                        notifyPos(new LeafPosition(this, -1)), true));
        }

        addKnuthElementsForBorderPaddingEnd(seq);

View Full Code Here

Examples of org.apache.fop.layoutmgr.InlineKnuthSequence

        // create the AreaInfo object to store the computed values
        areaInfo = new AreaInfo((short) 0, ipd, false, alignmentContext);

        // node is a fo:ExternalGraphic, fo:InstreamForeignObject,
        // fo:PageNumber or fo:PageNumberCitation
        KnuthSequence seq = new InlineKnuthSequence();

        addKnuthElementsForBorderPaddingStart(seq);
       
        seq.add(new KnuthInlineBox(areaInfo.ipdArea.opt, alignmentContext,
                                    notifyPos(new LeafPosition(this, 0)), false));

        addKnuthElementsForBorderPaddingEnd(seq);
       
        LinkedList returnList = new LinkedList();
View Full Code Here

Examples of org.apache.fop.layoutmgr.InlineKnuthSequence

        // create the AreaInfo object to store the computed values
        areaInfo = new AreaInfo((short) 0, ipd, false, alignmentContext);

        // node is a fo:ExternalGraphic, fo:InstreamForeignObject,
        // fo:PageNumber or fo:PageNumberCitation
        KnuthSequence seq = new InlineKnuthSequence();

        addKnuthElementsForBorderPaddingStart(seq);
       
        seq.add(new KnuthInlineBox(areaInfo.ipdArea.opt, alignmentContext,
                                    notifyPos(new LeafPosition(this, 0)), false));

        addKnuthElementsForBorderPaddingEnd(seq);
       
        LinkedList returnList = new LinkedList();
View Full Code Here

Examples of org.apache.fop.layoutmgr.InlineKnuthSequence

             * if the FO itself is empty, but has an id specified
             * or associated fo:markers, then we still need a dummy
             * sequence to register its position in the area tree
             */
            if (fobj.hasId() || fobj.hasMarkers()) {
                InlineKnuthSequence emptySeq = new InlineKnuthSequence();
                emptySeq.add(new KnuthInlineBox(
                                0,
                                alignmentContext,
                                notifyPos(getAuxiliaryPosition()),
                                true));
                returnList.add(emptySeq);
View Full Code Here

Examples of org.apache.fop.layoutmgr.InlineKnuthSequence

    /** {@inheritDoc} */
    public LinkedList getNextKnuthElements(LayoutContext context,
                                           int alignment) {
        MinOptMax ipd;
        curArea = get(context);
        KnuthSequence seq = new InlineKnuthSequence();

        if (curArea == null) {
            setFinished(true);
            return null;
        }

        alignmentContext = new AlignmentContext(curArea.getBPD()
                                    , fobj.getAlignmentAdjust()
                                    , fobj.getAlignmentBaseline()
                                    , fobj.getBaselineShift()
                                    , fobj.getDominantBaseline()
                                    , context.getAlignmentContext());

        ipd = getAllocationIPD(context.getRefIPD());
        if (fobj.getLeaderPattern() == EN_USECONTENT && curArea instanceof FilledArea) {
            // If we have user supplied content make it fit if we can
            int unitWidth = ((FilledArea)curArea).getUnitWidth();
            if (ipd.opt < unitWidth && ipd.max >= unitWidth) {
                ipd.opt = unitWidth;
            }
        }

        // create the AreaInfo object to store the computed values
        areaInfo = new AreaInfo((short) 0, ipd, false, context.getAlignmentContext());
        curArea.setAdjustingInfo(ipd.max - ipd.opt, ipd.opt - ipd.min, 0);

        addKnuthElementsForBorderPaddingStart(seq);
       
        // node is a fo:Leader
        seq.add(new KnuthInlineBox(0, alignmentContext,
                                    new LeafPosition(this, -1), true));
        seq.add(new KnuthPenalty(0, KnuthElement.INFINITE, false,
                                        new LeafPosition(this, -1), true));
        if (alignment == EN_JUSTIFY || alignment == 0) {
            seq.add
                (new KnuthGlue(areaInfo.ipdArea.opt,
                               areaInfo.ipdArea.max - areaInfo.ipdArea.opt,
                               areaInfo.ipdArea.opt - areaInfo.ipdArea.min,
                               new LeafPosition(this, 0), false));
        } else {
            seq.add
                (new KnuthGlue(areaInfo.ipdArea.opt,
                               0,
                               0,
                               new LeafPosition(this, 0), false));
        }
        seq.add(new KnuthInlineBox(0, alignmentContext,
                                    new LeafPosition(this, -1), true));

        addKnuthElementsForBorderPaddingEnd(seq);
       
        LinkedList returnList = new LinkedList();
View Full Code Here

Examples of org.apache.fop.layoutmgr.InlineKnuthSequence

    /** {@inheritDoc} */
    public LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
        MinOptMax ipd;
        curArea = get(context);
        KnuthSequence seq = new InlineKnuthSequence();

        if (curArea == null) {
            setFinished(true);
            return null;
        }

        ipd = new MinOptMax(font.getCharWidth(fobj.getCharacter()));

        curArea.setIPD(ipd.opt);
        curArea.setBPD(font.getAscender() - font.getDescender());

        TraitSetter.addFontTraits(curArea, font);
        curArea.addTrait(Trait.COLOR, fobj.getColor());

        // TODO: may need some special handling for fo:character
        alignmentContext = new AlignmentContext(font
                                    , font.getFontSize()
                                    , fobj.getAlignmentAdjust()
                                    , fobj.getAlignmentBaseline()
                                    , fobj.getBaselineShift()
                                    , fobj.getDominantBaseline()
                                    , context.getAlignmentContext());

        addKnuthElementsForBorderPaddingStart(seq);
       
        // create the AreaInfo object to store the computed values
        areaInfo = new AreaInfo((short) 0, ipd, false, alignmentContext);

        // node is a fo:Character
        if (letterSpaceIPD.min == letterSpaceIPD.max) {
            // constant letter space, only return a box
            seq.add(new KnuthInlineBox(areaInfo.ipdArea.opt, areaInfo.alignmentContext,
                                        notifyPos(new LeafPosition(this, 0)), false));
        } else {
            // adjustable letter space, return a sequence of elements;
            // at the moment the character is supposed to have no letter spaces,
            // but returning this sequence allows us to change only one element
            // if addALetterSpaceTo() is called
            seq.add(new KnuthInlineBox(areaInfo.ipdArea.opt, areaInfo.alignmentContext,
                                        notifyPos(new LeafPosition(this, 0)), false));
            seq.add(new KnuthPenalty(0, KnuthElement.INFINITE, false,
                                            new LeafPosition(this, -1), true));
            seq.add(new KnuthGlue(0, 0, 0,
                                         new LeafPosition(this, -1), true));
            seq.add(new KnuthInlineBox(0, null,
                                        notifyPos(new LeafPosition(this, -1)), true));
        }

        addKnuthElementsForBorderPaddingEnd(seq);

View Full Code Here

Examples of org.apache.fop.layoutmgr.InlineKnuthSequence

            }
        }
        if (returnedList.size() == 0) {
            //Inline part of the footnote is empty. Need to send back an auxiliary
            //zero-width, zero-height inline box so the footnote gets painted.
            KnuthSequence seq = new InlineKnuthSequence();
            //Need to use an aux. box, otherwise, the line height can't be forced to zero height.
            forcedAnchor = new KnuthInlineBox(0, null, null, true);
            seq.add(forcedAnchor);
            returnedList.add(seq);
        }
        setFinished(true);

        addAnchor(returnedList);
View Full Code Here

Examples of org.apache.fop.layoutmgr.InlineKnuthSequence

        lineStartBAP = context.getLineStartBorderAndPaddingWidth();
        lineEndBAP = context.getLineEndBorderAndPaddingWidth();
        alignmentContext = context.getAlignmentContext();

        LinkedList returnList = new LinkedList();
        KnuthSequence sequence = new InlineKnuthSequence();
        AreaInfo ai = null;
        AreaInfo prevAi = null;
        returnList.add(sequence);

        LineBreakStatus lbs = new LineBreakStatus();
        iThisStart = iNextStart;
        boolean inWord = false;
        boolean inWhitespace = false;
        char ch = 0;
        while (iNextStart < textArray.length) {
            ch = textArray[iNextStart];
            boolean breakOpportunity = false;
            byte breakAction = keepTogether? LineBreakStatus.PROHIBITED_BREAK : lbs.nextChar(ch);
            switch (breakAction) {
                case LineBreakStatus.COMBINING_PROHIBITED_BREAK:
                case LineBreakStatus.PROHIBITED_BREAK:
                    break;
                case LineBreakStatus.EXPLICIT_BREAK:
                    break;
                case LineBreakStatus.COMBINING_INDIRECT_BREAK:
                case LineBreakStatus.DIRECT_BREAK:
                case LineBreakStatus.INDIRECT_BREAK:
                    breakOpportunity = true;
                    break;
                default:
                    log.error("Unexpected breakAction: " + breakAction);
            }
            if (inWord) {
                if (breakOpportunity || isSpace(ch) || ch == NEWLINE) {
                    //Word boundary found, process widths and kerning
                    int lastIndex = iNextStart;
                    while (lastIndex > 0 && textArray[lastIndex - 1] == CharUtilities.SOFT_HYPHEN) {
                        lastIndex--;
                    }
                    int wordLength = lastIndex - iThisStart;
                    boolean kerning = font.hasKerning();
                    MinOptMax wordIPD = new MinOptMax(0);
                    for (int i = iThisStart; i < lastIndex; i++) {
                        char c = textArray[i];

                        //character width
                        int charWidth = font.getCharWidth(c);
                        wordIPD.add(charWidth);

                        //kerning
                        if (kerning) {
                            int kern = 0;
                            if (i > iThisStart) {
                                char previous = textArray[i - 1];
                                kern = font.getKernValue(previous, c) * font.getFontSize() / 1000;
                            } else if (prevAi != null && !prevAi.isSpace && prevAi.iBreakIndex > 0) {
                                char previous = textArray[prevAi.iBreakIndex - 1];
                                kern = font.getKernValue(previous, c) * font.getFontSize() / 1000;
                            }
                            if (kern != 0) {
                                //log.info("Kerning between " + previous + " and " + c + ": " + kern);
                                addToLetterAdjust(i, kern);
                                wordIPD.add(kern);
                            }
                        }
                    }
                    if (kerning && breakOpportunity && !isSpace(ch) && lastIndex > 0 && textArray[lastIndex] == CharUtilities.SOFT_HYPHEN) {
                        int kern = font.getKernValue(textArray[lastIndex - 1], ch) * font.getFontSize() / 1000;
                        if (kern != 0) {
                            addToLetterAdjust(lastIndex, kern);
                        }
                    }
                    int iLetterSpaces = wordLength - 1;
                    // if there is a break opportunity and the next one
                    // is not a space, it could be used as a line end;
                    // add one more letter space, in case other text follows
                    if (breakOpportunity && !isSpace(ch)) {
                        iLetterSpaces++;
                    }
                    wordIPD.add(MinOptMax.multiply(letterSpaceIPD, iLetterSpaces));

                    // create the AreaInfo object
                    ai = new AreaInfo(iThisStart, (short)lastIndex, (short) 0,
                            (short) iLetterSpaces,
                            wordIPD, textArray[lastIndex] == CharUtilities.SOFT_HYPHEN, false, breakOpportunity);
                    vecAreaInfo.add(ai);
                    prevAi = ai;
                    iTempStart = iNextStart;

                    // create the elements
                    sequence.addAll(createElementsForAWordFragment(alignment, ai,
                            vecAreaInfo.size() - 1, letterSpaceIPD));
                    ai = null;

                    iThisStart = iNextStart;
                }
            } else if (inWhitespace) {
                if (ch != CharUtilities.SPACE || breakOpportunity) {
                    // End of whitespace
                    // create the AreaInfo object
                    ai = new AreaInfo(iThisStart, (short) (iNextStart),
                            (short) (iNextStart - iThisStart), (short) 0,
                            MinOptMax.multiply(wordSpaceIPD, iNextStart - iThisStart),
                            false, true, breakOpportunity);
                    vecAreaInfo.add(ai);
                    prevAi = ai;

                    // create the elements
                    sequence.addAll
                        (createElementsForASpace(alignment, ai, vecAreaInfo.size() - 1));
                    ai = null;

                    iThisStart = iNextStart;
                }
            } else {
                if (ai != null) {
                    vecAreaInfo.add(ai);
                    prevAi = ai;
                    ai.breakOppAfter = ch == CharUtilities.SPACE || breakOpportunity;
                    sequence.addAll
                        (createElementsForASpace(alignment, ai, vecAreaInfo.size() - 1));
                    ai = null;
                }
                if (breakAction == LineBreakStatus.EXPLICIT_BREAK) {
                    if (lineEndBAP != 0) {
                        sequence.add
                            (new KnuthGlue(lineEndBAP, 0, 0,
                                           new LeafPosition(this, -1), true));
                    }
                    sequence.endSequence();
                    sequence = new InlineKnuthSequence();
                    returnList.add(sequence);
                }
            }
           
            if ((ch == CharUtilities.SPACE
                    && foText.getWhitespaceTreatment() == Constants.EN_PRESERVE)
                    || ch == CharUtilities.NBSPACE) {
                // preserved space or non-breaking space:
                // create the AreaInfo object
                ai = new AreaInfo(iNextStart, (short) (iNextStart + 1),
                        (short) 1, (short) 0,
                        wordSpaceIPD, false, true, breakOpportunity);
                iThisStart = (short) (iNextStart + 1);
            } else if (CharUtilities.isFixedWidthSpace(ch) || CharUtilities.isZeroWidthSpace(ch)) {
                // create the AreaInfo object
                MinOptMax ipd = new MinOptMax(font.getCharWidth(ch));
                ai = new AreaInfo(iNextStart, (short) (iNextStart + 1),
                        (short) 0, (short) 0,
                        ipd, false, true, breakOpportunity);
                iThisStart = (short) (iNextStart + 1);
            } else if (ch == NEWLINE) {
                // linefeed; this can happen when linefeed-treatment="preserve"
                iThisStart = (short) (iNextStart + 1);
            }
            inWord = !isSpace(ch) && ch != NEWLINE;
            inWhitespace = ch == CharUtilities.SPACE && foText.getWhitespaceTreatment() != Constants.EN_PRESERVE;
            iNextStart++;
        } // end of while
       
        // Process any last elements
        if (inWord) {
            int lastIndex = iNextStart;
            if (textArray[iNextStart - 1] == CharUtilities.SOFT_HYPHEN) {
                lastIndex--;
            }
            int wordLength = lastIndex - iThisStart;
            boolean kerning = font.hasKerning();
            MinOptMax wordIPD = new MinOptMax(0);
            for (int i = iThisStart; i < lastIndex; i++) {
                char c = textArray[i];

                //character width
                int charWidth = font.getCharWidth(c);
                wordIPD.add(charWidth);

                //kerning
                if (kerning) {
                    int kern = 0;
                    if (i > iThisStart) {
                        char previous = textArray[i - 1];
                        kern = font.getKernValue(previous, c) * font.getFontSize() / 1000;
                    } else if (prevAi != null && !prevAi.isSpace) {
                        char previous = textArray[prevAi.iBreakIndex - 1];
                        kern = font.getKernValue(previous, c) * font.getFontSize() / 1000;
                    }
                    if (kern != 0) {
                        //log.info("Kerning between " + previous + " and " + c + ": " + kern);
                        addToLetterAdjust(i, kern);
                        wordIPD.add(kern);
                    }
                }
            }
            int iLetterSpaces = wordLength - 1;
            wordIPD.add(MinOptMax.multiply(letterSpaceIPD, iLetterSpaces));

            // create the AreaInfo object
            ai = new AreaInfo(iThisStart, (short)lastIndex, (short) 0,
                    (short) iLetterSpaces,
                    wordIPD, false, false, false);
            vecAreaInfo.add(ai);
            iTempStart = iNextStart;

            // create the elements
            sequence.addAll(createElementsForAWordFragment(alignment, ai,
                    vecAreaInfo.size() - 1, letterSpaceIPD));
            ai = null;
        } else if (inWhitespace) {
            ai = new AreaInfo(iThisStart, (short) (iNextStart),
                    (short) (iNextStart - iThisStart), (short) 0,
                    MinOptMax.multiply(wordSpaceIPD, iNextStart - iThisStart),
                    false, true, true);
            vecAreaInfo.add(ai);

            // create the elements
            sequence.addAll
                (createElementsForASpace(alignment, ai, vecAreaInfo.size() - 1));
            ai = null;
        } else if (ai != null) {
            vecAreaInfo.add(ai);
            ai.breakOppAfter = ch == CharUtilities.ZERO_WIDTH_SPACE;
            sequence.addAll
                (createElementsForASpace(alignment, ai, vecAreaInfo.size() - 1));
            ai = null;
        } else if (ch == NEWLINE) {
            if (lineEndBAP != 0) {
                sequence.add
                    (new KnuthGlue(lineEndBAP, 0, 0,
                                   new LeafPosition(this, -1), true));
            }
            sequence.endSequence();
            sequence = new InlineKnuthSequence();
            returnList.add(sequence);
        }

        if (((List)returnList.getLast()).size() == 0) {
            //Remove an empty sequence because of a trailing newline
View Full Code Here
TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.