public byte nextChar()

in fop-core/src/main/java/org/apache/fop/text/linebreak/LineBreakStatus.java [84:223]


    public byte nextChar(char c) {

        byte currentClass = LineBreakUtils.getLineBreakProperty(c);

        /* Initial conversions */
        switch (currentClass) {
            case 0: // Unassigned codepoint: same treatment as AI
            case LineBreakUtils.LINE_BREAK_PROPERTY_AI:
            case LineBreakUtils.LINE_BREAK_PROPERTY_SG:
            case LineBreakUtils.LINE_BREAK_PROPERTY_XX:
                // LB 1: Resolve AI, ... SG and XX into other line breaking classes
                //       depending on criteria outside the scope of this algorithm.
                //       In the absence of such criteria, it is recommended that
                //       classes AI, ... SG and XX be resolved to AL
                currentClass = LineBreakUtils.LINE_BREAK_PROPERTY_AL;
                break;

            case LineBreakUtils.LINE_BREAK_PROPERTY_SA:
                // LB 1: Resolve ... SA ... into other line breaking classes
                //       depending on criteria outside the scope of this algorithm.
                //       In the absence of such criteria, it is recommended that
                //       ... SA be resolved to AL, except that characters of
                //       class SA that have General_Category Mn or Mc be resolved to CM
                switch (Character.getType(c)) {
                    case Character.COMBINING_SPACING_MARK: //General_Category "Mc"
                    case Character.NON_SPACING_MARK: //General_Category "Mn"
                        currentClass = LineBreakUtils.LINE_BREAK_PROPERTY_CM;
                        break;
                    default:
                        currentClass = LineBreakUtils.LINE_BREAK_PROPERTY_AL;
                }

            default:
                //nop
        }

        /* Check 1: First character or initial character after a reset/mandatory break? */
        switch (leftClass) {
            case -1:
                //first character or initial character after a reset()
                leftClass = currentClass;
                if (leftClass == LineBreakUtils.LINE_BREAK_PROPERTY_CM) {
                    // LB 10: Treat any remaining combining marks as AL
                    leftClass = LineBreakUtils.LINE_BREAK_PROPERTY_AL;
                }
                // LB 2: Never break at the start of text
                return PROHIBITED_BREAK;

            case LineBreakUtils.LINE_BREAK_PROPERTY_BK:
            case LineBreakUtils.LINE_BREAK_PROPERTY_LF:
            case LineBreakUtils.LINE_BREAK_PROPERTY_NL:
                //first character after mandatory break
                // LB 4: Always break after hard line breaks
                // LB 5: Treat ... LF and NL has hard line breaks
                reset();
                leftClass = currentClass;
                return EXPLICIT_BREAK;

            case LineBreakUtils.LINE_BREAK_PROPERTY_CR:
                //first character after a carriage return:
                // LB 5: Treat CR followed by LF, as well as CR ... as hard line breaks
                // If current is LF, then fall through to Check 2 (see below),
                // and the hard break will be signaled for the character after LF (see above)
                if (currentClass != LineBreakUtils.LINE_BREAK_PROPERTY_LF) {
                    reset();
                    leftClass = currentClass;
                    return EXPLICIT_BREAK;
                }

            default:
                //nop
        }

        /* Check 2: current is a mandatory break or space? */
        switch (currentClass) {
            case LineBreakUtils.LINE_BREAK_PROPERTY_BK:
            case LineBreakUtils.LINE_BREAK_PROPERTY_LF:
            case LineBreakUtils.LINE_BREAK_PROPERTY_NL:
            case LineBreakUtils.LINE_BREAK_PROPERTY_CR:
                // LB 6: Do not break before a hard break
                leftClass = currentClass;
                return PROHIBITED_BREAK;

            case LineBreakUtils.LINE_BREAK_PROPERTY_SP:
                // LB 7: Do not break before spaces ...
                // Zero-width spaces are in the pair-table (see below)
                hadSpace = true;
                return PROHIBITED_BREAK;

            case LineBreakUtils.LINE_BREAK_PROPERTY_JL:
            case LineBreakUtils.LINE_BREAK_PROPERTY_JV:
            case LineBreakUtils.LINE_BREAK_PROPERTY_H2:
            case LineBreakUtils.LINE_BREAK_PROPERTY_H3:
                // LB 26: Do not break a Korean syllable.
                if (!hadSpace) {
                    return PROHIBITED_BREAK;
                }
                break;

            default:
                //nop
        }

        /* Normal treatment, if the first two checks did not return */
        boolean savedHadSpace = hadSpace;
        hadSpace = false;
        byte breakAction = LineBreakUtils.getLineBreakPairProperty(leftClass, currentClass);
        switch (breakAction) {
            case PROHIBITED_BREAK:
            case DIRECT_BREAK:
                leftClass = currentClass;
                return breakAction;

            case INDIRECT_BREAK:
                leftClass = currentClass;
                if (savedHadSpace) {
                    return INDIRECT_BREAK;
                } else {
                    return PROHIBITED_BREAK;
                }

            case COMBINING_INDIRECT_BREAK:
                if (savedHadSpace) {
                    leftClass = currentClass;
                    return COMBINING_INDIRECT_BREAK;
                } else {
                    return PROHIBITED_BREAK;
                }

            case COMBINING_PROHIBITED_BREAK:
                if (savedHadSpace) {
                    leftClass = currentClass;
                }
                return COMBINING_PROHIBITED_BREAK;

            default:
                assert false;
                return breakAction;
        }
    }