keiron 01/08/15 03:33:35 Modified: src/org/apache/fop/svg PDFGraphics2D.java PDFTextPainter.java Log: added support for embedded fonts for svg text, also added proper escaping Revision Changes Path 1.15 +136 -20 xml-fop/src/org/apache/fop/svg/PDFGraphics2D.java Index: PDFGraphics2D.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/svg/PDFGraphics2D.java,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- PDFGraphics2D.java 2001/08/14 14:50:30 1.14 +++ PDFGraphics2D.java 2001/08/15 10:33:34 1.15 @@ -1,5 +1,5 @@ /* - * $Id: PDFGraphics2D.java,v 1.14 2001/08/14 14:50:30 keiron Exp $ + * $Id: PDFGraphics2D.java,v 1.15 2001/08/15 10:33:34 keiron Exp $ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. * For details on use and redistribution please refer to the * LICENSE file included with these sources. @@ -13,6 +13,8 @@ import org.apache.fop.render.pdf.*; import org.apache.fop.image.*; import org.apache.fop.datatypes.ColorSpace; +import org.apache.fop.render.pdf.CIDFont; +import org.apache.fop.render.pdf.fonts.LazyFont; import org.apache.batik.ext.awt.g2d.*; import org.apache.batik.ext.awt.image.GraphicsUtil; @@ -30,6 +32,7 @@ import java.util.Map; import java.util.Vector; +import java.util.Hashtable; /** * This concrete implementation of <tt>AbstractGraphics2D</tt> is a @@ -40,7 +43,7 @@ * implementing a <tt>Graphic2D</tt> piece-meal. * * @author <a href="mailto:[EMAIL PROTECTED]">Keiron Liddle</a> - * @version $Id: PDFGraphics2D.java,v 1.14 2001/08/14 14:50:30 keiron Exp $ + * @version $Id: PDFGraphics2D.java,v 1.15 2001/08/15 10:33:34 keiron Exp $ * @see org.apache.batik.ext.awt.g2d.AbstractGraphics2D */ public class PDFGraphics2D extends AbstractGraphics2D { @@ -57,6 +60,7 @@ PDFAnnotList currentAnnotList = null; protected FontState fontState; + protected FontState ovFontState = null; /** * the current stream to add PDF commands to @@ -116,6 +120,10 @@ gc = c; } + public void setOverrideFontState(FontState infont) { + ovFontState = infont; + } + /** * This constructor supports the create method */ @@ -787,25 +795,30 @@ currentStream.write("BT\n"); - Font gFont = getFont(); - String name = gFont.getName(); - if (name.equals("sanserif")) { - name = "sans-serif"; - } - int size = gFont.getSize(); - String style = gFont.isItalic() ? "italic" : "normal"; - String weight = gFont.isBold() ? "bold" : "normal"; - try { - fontState = new FontState(fontState.getFontInfo(), name, style, - weight, size * 1000, 0); - } catch (org.apache.fop.apps.FOPException fope) { - fope.printStackTrace(); + if(ovFontState == null) { + Font gFont = getFont(); + String n = gFont.getFamily(); + if (n.equals("sanserif")) { + n = "sans-serif"; + } + int siz = gFont.getSize(); + String style = gFont.isItalic() ? "italic" : "normal"; + String weight = gFont.isBold() ? "bold" : "normal"; + try { + fontState = new FontState(fontState.getFontInfo(), n, style, + weight, siz * 1000, 0); + } catch (org.apache.fop.apps.FOPException fope) { + fope.printStackTrace(); + } + } else { + fontState = ovFontState; + ovFontState = null; } + String name; + int size; name = fontState.getFontName(); size = fontState.getFontSize() / 1000; - // System.out.println("ffn:" + gFont.getFontName() + "fn:" + gFont.getName() + " ff:" + gFont.getFamily() + " fs:" + fontState.getFontName()); - if ((!name.equals(this.currentFontName)) || (size != this.currentFontSize)) { this.currentFontName = name; @@ -813,6 +826,31 @@ currentStream.write("/" + name + " " + size + " Tf\n"); } + + Hashtable kerning = null; + boolean kerningAvailable = false; + + kerning = fontState.getKerning(); + if (kerning != null &&!kerning.isEmpty()) { + kerningAvailable = true; + } + + // This assumes that *all* CIDFonts use a /ToUnicode mapping + boolean useMultiByte = false; + org.apache.fop.render.pdf.Font f = + (org.apache.fop.render.pdf.Font)fontState.getFontInfo().getFonts().get(name); + if (f instanceof LazyFont){ + if(((LazyFont) f).getRealFont() instanceof CIDFont){ + useMultiByte = true; + } + } else if (f instanceof CIDFont){ + useMultiByte = true; + } + + // String startText = useMultiByte ? "<FEFF" : "("; + String startText = useMultiByte ? "<" : "("; + String endText = useMultiByte ? "> " : ") "; + AffineTransform trans = getTransform(); trans.translate(x, y); double[] vals = new double[6]; @@ -823,13 +861,90 @@ + PDFNumber.doubleOut(vals[2]) + " " + PDFNumber.doubleOut(-vals[3]) + " " + PDFNumber.doubleOut(vals[4]) + " " - + PDFNumber.doubleOut(vals[5]) + " Tm (" + s - + ") Tj\n"); + + PDFNumber.doubleOut(vals[5]) + " Tm [" + startText); + + int l = s.length(); + + for (int i = 0; i < l; i++) { + char ch = fontState.mapChar(s.charAt(i)); + + if (!useMultiByte) { + if (ch > 127) { + currentStream.write("\\"); + currentStream.write(Integer.toOctalString((int)ch)); + } else { + switch (ch) { + case '(': + case ')': + case '\\': + currentStream.write("\\"); + break; + } + currentStream.write(ch); + } + } else { + currentStream.write(getUnicodeString(ch)); + } + + if (kerningAvailable && (i + 1) < l) { + addKerning(currentStream, (new Integer((int)ch)), + (new Integer((int)fontState.mapChar(s.charAt(i + 1)))), + kerning, startText, endText); + } + } + currentStream.write(endText); + + + currentStream.write("] TJ\n"); + currentStream.write("ET\n"); } + private void addKerning(StringWriter buf, Integer ch1, Integer ch2, + Hashtable kerning, String startText, + String endText) { + Hashtable kernPair = (Hashtable)kerning.get(ch1); + + if (kernPair != null) { + Integer width = (Integer)kernPair.get(ch2); + if (width != null) { + currentStream.write(endText + (-width.intValue()) + " " + startText); + } + } + } + /** + * Convert a char to a multibyte hex representation + */ + private String getUnicodeString(char c) { + + StringBuffer buf = new StringBuffer(4); + byte[] uniBytes = null; + try { + char[] a = { + c + }; + uniBytes = new String(a).getBytes("UnicodeBigUnmarked"); + } catch (Exception e) { + // This should never fail + } + + for (int i = 0; i < uniBytes.length; i++) { + int b = (uniBytes[i] < 0) ? (int)(256 + uniBytes[i]) + : (int)uniBytes[i]; + + String hexString = Integer.toHexString(b); + if (hexString.length() == 1) + buf = buf.append("0" + hexString); + else + buf = buf.append(hexString); + } + + return buf.toString(); + } + + /** * Renders the text of the specified iterator, using the * <code>Graphics2D</code> context's current <code>Paint</code>. The * iterator must specify a font @@ -856,13 +971,14 @@ float y) { System.err.println("drawString(AttributedCharacterIterator)"); - currentStream.write("BT\n"); Shape imclip = getClip(); writeClip(imclip); Color c = getColor(); applyColor(c, true); c = getBackground(); applyColor(c, false); + + currentStream.write("BT\n"); AffineTransform trans = getTransform(); trans.translate(x, y); 1.5 +6 -2 xml-fop/src/org/apache/fop/svg/PDFTextPainter.java Index: PDFTextPainter.java =================================================================== RCS file: /home/cvs/xml-fop/src/org/apache/fop/svg/PDFTextPainter.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- PDFTextPainter.java 2001/07/30 20:29:34 1.4 +++ PDFTextPainter.java 2001/08/15 10:33:34 1.5 @@ -1,5 +1,5 @@ /* - * $Id: PDFTextPainter.java,v 1.4 2001/07/30 20:29:34 tore Exp $ + * $Id: PDFTextPainter.java,v 1.5 2001/08/15 10:33:34 keiron Exp $ * Copyright (C) 2001 The Apache Software Foundation. All rights reserved. * For details on use and redistribution please refer to the * LICENSE file included with these sources. @@ -37,7 +37,7 @@ * Renders the attributed character iterator of a <tt>TextNode</tt>. * * @author <a href="mailto:[EMAIL PROTECTED]">Keiron Liddle</a> - * @version $Id: PDFTextPainter.java,v 1.4 2001/07/30 20:29:34 tore Exp $ + * @version $Id: PDFTextPainter.java,v 1.5 2001/08/15 10:33:34 keiron Exp $ */ public class PDFTextPainter implements TextPainter { FontState fontState; @@ -124,6 +124,10 @@ style, weight, fsize * 1000, 0); } catch (org.apache.fop.apps.FOPException fope) { fope.printStackTrace(); + } + } else { + if(g2d instanceof PDFGraphics2D) { + ((PDFGraphics2D)g2d).setOverrideFontState(fontState); } } int fStyle = Font.PLAIN; --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]