From a35f808888428ef09e0c432d049b8d89e34c4880 Mon Sep 17 00:00:00 2001 From: Jeremias Maerki Date: Wed, 24 Aug 2005 20:53:55 +0000 Subject: Improved text painting for PostScript (including letter-space and word-space) Moved text-decoration painting to the common base class and reused the border line painting method for this purpose. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@239925 13f79535-47bb-0310-9956-ffa450edef68 --- .../fop/render/AbstractPathOrientedRenderer.java | 50 ++++++- .../org/apache/fop/render/pdf/PDFRenderer.java | 51 +------ src/java/org/apache/fop/render/ps/PSGenerator.java | 5 +- src/java/org/apache/fop/render/ps/PSRenderer.java | 152 +++++++++++---------- 4 files changed, 139 insertions(+), 119 deletions(-) diff --git a/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java b/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java index 7663b5f2d..d22adb9cb 100644 --- a/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java +++ b/src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java @@ -19,9 +19,7 @@ package org.apache.fop.render; import java.awt.Color; -import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; -import java.util.Iterator; import java.util.List; import org.apache.fop.area.Area; @@ -30,11 +28,12 @@ import org.apache.fop.area.BlockViewport; import org.apache.fop.area.CTM; import org.apache.fop.area.RegionViewport; import org.apache.fop.area.Trait; +import org.apache.fop.area.inline.InlineArea; import org.apache.fop.area.inline.Viewport; import org.apache.fop.datatypes.ColorType; +import org.apache.fop.fo.Constants; +import org.apache.fop.fonts.Typeface; import org.apache.fop.image.FopImage; -import org.apache.fop.pdf.PDFState; -import org.apache.fop.render.pdf.CTMHelper; import org.apache.fop.traits.BorderProps; /** @@ -554,6 +553,49 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { /** Indicates the end of a text object. */ protected abstract void endTextObject(); + /** + * Paints the text decoration marks. + * @param tf Current typeface + * @param fontsize Current font size + * @param inline inline area to paint the marks for + * @param baseline position of the baseline + * @param startx start IPD + */ + protected void renderTextDecoration(Typeface tf, int fontsize, InlineArea inline, + int baseline, int startx) { + boolean hasTextDeco = inline.hasUnderline() + || inline.hasOverline() + || inline.hasLineThrough(); + if (hasTextDeco) { + endTextObject(); + float descender = tf.getDescender(fontsize) / 1000f; + float capHeight = tf.getCapHeight(fontsize) / 1000f; + float halfLineWidth = (descender / -8f) / 2f; + float endx = (startx + inline.getIPD()) / 1000f; + if (inline.hasUnderline()) { + ColorType ct = (ColorType) inline.getTrait(Trait.UNDERLINE_COLOR); + float y = baseline - descender / 2f; + drawBorderLine(startx / 1000f, (y - halfLineWidth) / 1000f, + endx, (y + halfLineWidth) / 1000f, + true, true, Constants.EN_SOLID, ct); + } + if (inline.hasOverline()) { + ColorType ct = (ColorType) inline.getTrait(Trait.OVERLINE_COLOR); + float y = (float)(baseline - (1.1 * capHeight)); + drawBorderLine(startx / 1000f, (y - halfLineWidth) / 1000f, + endx, (y + halfLineWidth) / 1000f, + true, true, Constants.EN_SOLID, ct); + } + if (inline.hasLineThrough()) { + ColorType ct = (ColorType) inline.getTrait(Trait.LINETHROUGH_COLOR); + float y = (float)(baseline - (0.45 * capHeight)); + drawBorderLine(startx / 1000f, (y - halfLineWidth) / 1000f, + endx, (y + halfLineWidth) / 1000f, + true, true, Constants.EN_SOLID, ct); + } + } + } + /** Clip using the current path. */ protected abstract void clip(); diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java index 22e32d7dd..cfb73530f 100644 --- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java @@ -687,6 +687,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { } } + /** @see org.apache.fop.render.AbstractPathOrientedRenderer#updateLineStyle(int) */ private void updateLineStyle(int style) { switch (style) { case Constants.EN_DASHED: @@ -1037,8 +1038,8 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { int size = ((Integer) ch.getTrait(Trait.FONT_SIZE)).intValue(); // This assumes that *all* CIDFonts use a /ToUnicode mapping - Typeface f = (Typeface) fontInfo.getFonts().get(name); - boolean useMultiByte = f.isMultiByte(); + Typeface tf = (Typeface) fontInfo.getFonts().get(name); + boolean useMultiByte = tf.isMultiByte(); // String startText = useMultiByte ? " 0) { - //float f = area.getFontState().getLetterSpacing() - // * 1000 / this.currentFontSize; - float f = area.getFontState().getLetterSpacing(); - psString = (new StringBuffer().append(f).append(" 0.0 (") - .append(sb.toString()).append(") A")).toString(); + int initialSize = text.length(); + initialSize += initialSize / 2; + StringBuffer sb = new StringBuffer(initialSize); + int textLen = text.length(); + if (area.getTextLetterSpaceAdjust() == 0 && area.getTextWordSpaceAdjust() == 0) { + sb.append("("); + for (int i = 0; i < textLen; i++) { + final char c = text.charAt(i); + final char mapped = tf.mapChar(c); + PSGenerator.escapeChar(mapped, sb); + } + sb.append(") t"); } else { - psString = (new StringBuffer("(").append(sb.toString()) - .append(") t")).toString(); + sb.append("("); + int[] offsets = new int[textLen]; + for (int i = 0; i < textLen; i++) { + final char c = text.charAt(i); + final char mapped = tf.mapChar(c); + int wordSpace; + //TODO Synchronize word space behaviour with TextLayoutManager + //Check the other renderers, too! + if (CharUtilities.isAnySpace(mapped) + && mapped != CharUtilities.ZERO_WIDTH_SPACE + && mapped != CharUtilities.ZERO_WIDTH_NOBREAK_SPACE) { + wordSpace = area.getTextWordSpaceAdjust(); + } else { + wordSpace = 0; + } + int cw = tf.getWidth(mapped, fontsize) / 1000; + offsets[i] = cw + area.getTextLetterSpaceAdjust() + wordSpace; + PSGenerator.escapeChar(mapped, sb); + } + sb.append(")" + PSGenerator.LF + "["); + for (int i = 0; i < textLen; i++) { + if (i > 0) { + sb.append(" "); + } + sb.append(gen.formatDouble(offsets[i] / 1000f)); + } + sb.append("]" + PSGenerator.LF + "xshow"); } + writeln(sb.toString()); - - // System.out.println("["+s+"] --> ["+sb.toString()+"]"); - - // comment("% --- InlineArea font-weight="+fontWeight+": " + sb.toString()); - useFont(fs.getFontName(), fs.getFontSize()); - useColor(area.getRed(), area.getGreen(), area.getBlue()); - if (area.getUnderlined() || area.getLineThrough() - || area.getOverlined()) - write("ULS"); - write(psString); - if (area.getUnderlined()) - write("ULE"); - if (area.getLineThrough()) - write("SOE"); - if (area.getOverlined()) - write("OLE"); - this.currentXPosition += area.getContentWidth(); - */ + renderTextDecoration(tf, fontsize, area, bl, rx); super.renderText(area); //Updates IPD } -- cgit v1.2.3