public void produce()

in fop-core/src/main/java/org/apache/fop/render/afp/AFPPainter.java [986:1111]


        public void produce(PtocaBuilder builder) throws IOException {
            Point p = getPaintingState().getPoint(coords[X], coords[Y]);
            builder.setTextOrientation(getPaintingState().getRotation());
            builder.absoluteMoveBaseline(p.y);
            builder.absoluteMoveInline(p.x);

            builder.setExtendedTextColor(state.getTextColor());
            builder.setCodedFont((byte) fontReference);

            int l = text.length();
            int[] dx = IFUtil.convertDPToDX(dp);
            int dxl = (dx != null ? dx.length : 0);
            StringBuffer sb = new StringBuffer();

            if (dxl > 0 && dx[0] != 0) {
                int dxu = Math.round(unitConv.mpt2units(dx[0]));
                builder.relativeMoveInline(-dxu);
            }

            //Following are two variants for glyph placement.
            //SVI does not seem to be implemented in the same way everywhere, so
            //a fallback alternative is preserved here.
            final boolean usePTOCAWordSpacing = true;
            if (usePTOCAWordSpacing) {

                int interCharacterAdjustment = 0;
                if (letterSpacing != 0) {
                    interCharacterAdjustment = Math.round(unitConv.mpt2units(
                            letterSpacing));
                }
                builder.setInterCharacterAdjustment(interCharacterAdjustment);

                int spaceWidth = font.getCharWidth(CharUtilities.SPACE);
                int fixedSpaceCharacterIncrement = Math.round(unitConv.mpt2units(
                        spaceWidth + letterSpacing));
                int varSpaceCharacterIncrement = fixedSpaceCharacterIncrement;
                if (wordSpacing != 0) {
                    varSpaceCharacterIncrement = Math.round(unitConv.mpt2units(
                            spaceWidth + wordSpacing + letterSpacing));
                }
                builder.setVariableSpaceCharacterIncrement(varSpaceCharacterIncrement);

                boolean fixedSpaceMode = false;
                double ttPos = p.x;
                boolean positionByChar = afpFont instanceof AFPFontConfig.AFPTrueTypeFont
                        && ((AFPFontConfig.AFPTrueTypeFont) afpFont).isPositionByChar();
                for (int i = 0; i < l; i++) {
                    char orgChar = text.charAt(i);
                    float glyphAdjust = 0;
                    if (positionByChar) {
                        flushText(builder, sb, charSet);
                        fixedSpaceMode = true;
                        int charWidth = font.getCharWidth(orgChar);
                        sb.append(orgChar);
                        glyphAdjust += charWidth;
                    } else if (CharUtilities.isFixedWidthSpace(orgChar)) {
                        flushText(builder, sb, charSet);
                        builder.setVariableSpaceCharacterIncrement(
                                fixedSpaceCharacterIncrement);
                        fixedSpaceMode = true;
                        sb.append(CharUtilities.SPACE);
                        int charWidth = font.getCharWidth(orgChar);
                        glyphAdjust += (charWidth - spaceWidth);
                    } else {
                        if (fixedSpaceMode) {
                            flushText(builder, sb, charSet);
                            builder.setVariableSpaceCharacterIncrement(
                                    varSpaceCharacterIncrement);
                            fixedSpaceMode = false;
                        }
                        char ch;
                        if (orgChar == CharUtilities.NBSPACE) {
                            ch = ' '; //converted to normal space to allow word spacing
                        } else {
                            ch = orgChar;
                        }
                        sb.append(ch);
                    }

                    if (i < dxl - 1) {
                        glyphAdjust += dx[i + 1];
                    }

                    if (positionByChar) {
                        flushText(builder, sb, charSet);
                        ttPos += unitConv.mpt2units(glyphAdjust);
                        builder.absoluteMoveInline((int) Math.round(ttPos));
                    } else if (glyphAdjust != 0) {
                        flushText(builder, sb, charSet);
                        int increment = Math.round(unitConv.mpt2units(glyphAdjust));
                        builder.relativeMoveInline(increment);
                    }
                }
            } else {
                for (int i = 0; i < l; i++) {
                    char orgChar = text.charAt(i);
                    float glyphAdjust = 0;
                    if (CharUtilities.isFixedWidthSpace(orgChar)) {
                        sb.append(CharUtilities.SPACE);
                        int spaceWidth = font.getCharWidth(CharUtilities.SPACE);
                        int charWidth = font.getCharWidth(orgChar);
                        glyphAdjust += (charWidth - spaceWidth);
                    } else {
                        sb.append(orgChar);
                    }

                    if ((wordSpacing != 0) && CharUtilities.isAdjustableSpace(orgChar)) {
                        glyphAdjust += wordSpacing;
                    }
                    glyphAdjust += letterSpacing;
                    if (i < dxl - 1) {
                        glyphAdjust += dx[i + 1];
                    }

                    if (glyphAdjust != 0) {
                        flushText(builder, sb, charSet);
                        int increment = Math.round(unitConv.mpt2units(glyphAdjust));
                        builder.relativeMoveInline(increment);
                    }
                }
            }
            flushText(builder, sb, charSet);
            if (pto != null) {
                bytesAvailable = pto.getBytesAvailable();
            }
        }