You are viewing a plain text version of this content. The canonical link for it is here.
Posted to fop-commits@xmlgraphics.apache.org by sp...@apache.org on 2007/11/08 22:27:35 UTC
svn commit: r593328 [5/7] - in
/xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking: ./
src/codegen/fonts/ src/documentation/ src/documentation/content/xdocs/
src/documentation/content/xdocs/dev/ src/documentation/content/xdocs/trunk/
src/java...
Modified: xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/AbstractFOPTranscoder.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/AbstractFOPTranscoder.java?rev=593328&r1=593327&r2=593328&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/AbstractFOPTranscoder.java (original)
+++ xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/AbstractFOPTranscoder.java Thu Nov 8 13:27:19 2007
@@ -19,27 +19,25 @@
package org.apache.fop.svg;
-import org.xml.sax.EntityResolver;
-
-import org.apache.commons.logging.impl.SimpleLog;
-import org.apache.commons.logging.Log;
import org.apache.batik.bridge.UserAgent;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.dom.util.DocumentFactory;
import org.apache.batik.transcoder.ErrorHandler;
+import org.apache.batik.transcoder.SVGAbstractTranscoder;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscodingHints;
-import org.apache.batik.transcoder.SVGAbstractTranscoder;
import org.apache.batik.transcoder.image.ImageTranscoder;
import org.apache.batik.transcoder.keys.BooleanKey;
import org.apache.batik.util.SVGConstants;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.impl.SimpleLog;
import org.w3c.dom.DOMImplementation;
+import org.xml.sax.EntityResolver;
/**
* This is the common base class of all of FOP's transcoders.
*/
-public abstract class AbstractFOPTranscoder extends SVGAbstractTranscoder
- {
+public abstract class AbstractFOPTranscoder extends SVGAbstractTranscoder {
/**
* The key to specify whether to stroke text instead of using text
@@ -81,6 +79,9 @@
return new FOPTranscoderUserAgent();
}
+ /**
+ * @param logger
+ */
public void setLogger(Log logger) {
this.logger = logger;
}
@@ -125,6 +126,22 @@
return factory;
}
+ /**
+ * Indicates whether text should be stroked rather than painted using text operators. Stroking
+ * text (also referred to as "painting as shapes") can used in situations where the quality of
+ * text output is not satisfying. The downside of the work-around: The generated file will
+ * likely become bigger and you will lose copy/paste functionality for certain output formats
+ * such as PDF.
+ * @return true if text should be stroked rather than painted using text operators
+ */
+ protected boolean isTextStroked() {
+ boolean stroke = false;
+ if (hints.containsKey(KEY_STROKE_TEXT)) {
+ stroke = ((Boolean)hints.get(KEY_STROKE_TEXT)).booleanValue();
+ }
+ return stroke;
+ }
+
// --------------------------------------------------------------------
// FOP's default error handler (for transcoders)
// --------------------------------------------------------------------
Modified: xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/PDFBridgeContext.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/PDFBridgeContext.java?rev=593328&r1=593327&r2=593328&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/PDFBridgeContext.java (original)
+++ xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/PDFBridgeContext.java Thu Nov 8 13:27:19 2007
@@ -20,7 +20,9 @@
package org.apache.fop.svg;
import java.awt.geom.AffineTransform;
+import java.lang.reflect.Constructor;
+import org.apache.batik.bridge.Bridge;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.DocumentLoader;
import org.apache.batik.bridge.UserAgent;
@@ -62,8 +64,9 @@
* @param linkTransform AffineTransform to properly place links,
* may be null
*/
- public PDFBridgeContext(UserAgent userAgent, FontInfo fontInfo,
- AffineTransform linkTransform) {
+ public PDFBridgeContext(UserAgent userAgent,
+ FontInfo fontInfo,
+ AffineTransform linkTransform) {
super(userAgent);
this.fontInfo = fontInfo;
this.linkTransform = linkTransform;
@@ -79,12 +82,43 @@
this(userAgent, fontInfo, null);
}
+ private void putPDFElementBridgeConditional(String className, String testFor) {
+ try {
+ Class.forName(testFor);
+ //if we get here the test class is available
+
+ Class clazz = Class.forName(className);
+ Constructor constructor = clazz.getConstructor(new Class[] {FontInfo.class});
+ putBridge((Bridge)constructor.newInstance(new Object[] {fontInfo}));
+ } catch (Throwable t) {
+ //simply ignore (bridges instantiated over this method are optional)
+ }
+ }
+
/** {@inheritDoc} */
public void registerSVGBridges() {
super.registerSVGBridges();
if (fontInfo != null) {
- putBridge(new PDFTextElementBridge(fontInfo));
+ PDFTextElementBridge textElementBridge = new PDFTextElementBridge(fontInfo);
+ putBridge(textElementBridge);
+
+ //Batik flow text extension (may not always be available)
+ //putBridge(new PDFBatikFlowTextElementBridge(fontInfo);
+ putPDFElementBridgeConditional(
+ "org.apache.fop.svg.PDFBatikFlowTextElementBridge",
+ "org.apache.batik.extension.svg.BatikFlowTextElementBridge");
+
+ //SVG 1.2 flow text support
+ //putBridge(new PDFSVG12TextElementBridge(fontInfo)); //-->Batik 1.7
+ putPDFElementBridgeConditional(
+ "org.apache.fop.svg.PDFSVG12TextElementBridge",
+ "org.apache.batik.bridge.svg12.SVG12TextElementBridge");
+
+ //putBridge(new PDFSVGFlowRootElementBridge(fontInfo));
+ putPDFElementBridgeConditional(
+ "org.apache.fop.svg.PDFSVGFlowRootElementBridge",
+ "org.apache.batik.bridge.svg12.SVGFlowRootElementBridge");
}
PDFAElementBridge pdfAElementBridge = new PDFAElementBridge();
@@ -99,8 +133,10 @@
}
// Make sure any 'sub bridge contexts' also have our bridges.
+ //TODO There's no matching method in the super-class here
public BridgeContext createBridgeContext() {
return new PDFBridgeContext(getUserAgent(), getDocumentLoader(),
fontInfo, linkTransform);
}
+
}
Modified: xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java?rev=593328&r1=593327&r2=593328&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java (original)
+++ xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/PDFDocumentGraphics2DConfigurator.java Thu Nov 8 13:27:19 2007
@@ -24,6 +24,7 @@
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.fop.apps.FOPException;
+import org.apache.fop.fonts.FontCache;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontResolver;
import org.apache.fop.fonts.FontSetup;
@@ -53,8 +54,14 @@
//Fonts
try {
FontResolver fontResolver = FontSetup.createMinimalFontResolver();
+ //TODO The following could be optimized by retaining the FontCache somewhere
+ FontCache fontCache = FontCache.load();
+ if (fontCache == null) {
+ fontCache = new FontCache();
+ }
List fontList = PrintRendererConfigurator.buildFontListFromConfiguration(
- cfg, null, fontResolver, false, null);
+ cfg, null, fontResolver, false, fontCache);
+ fontCache.save();
FontInfo fontInfo = new FontInfo();
FontSetup.setup(fontInfo, fontList, fontResolver);
graphics.setFontInfo(fontInfo);
Modified: xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/PDFGraphics2D.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/PDFGraphics2D.java?rev=593328&r1=593327&r2=593328&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/PDFGraphics2D.java (original)
+++ xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/PDFGraphics2D.java Thu Nov 8 13:27:19 2007
@@ -19,80 +19,77 @@
package org.apache.fop.svg;
-import org.apache.fop.pdf.PDFConformanceException;
-import org.apache.fop.pdf.PDFResourceContext;
-import org.apache.fop.pdf.PDFResources;
-import org.apache.fop.pdf.PDFGState;
-import org.apache.fop.pdf.PDFDeviceColorSpace;
-import org.apache.fop.pdf.PDFColor;
-import org.apache.fop.pdf.PDFState;
-import org.apache.fop.pdf.PDFNumber;
-import org.apache.fop.pdf.PDFText;
-import org.apache.fop.pdf.PDFXObject;
-import org.apache.fop.pdf.PDFPattern;
-import org.apache.fop.pdf.PDFDocument;
-import org.apache.fop.pdf.PDFLink;
-import org.apache.fop.pdf.PDFAnnotList;
-import org.apache.fop.pdf.BitmapImage;
-import org.apache.fop.fonts.FontInfo;
-import org.apache.fop.fonts.Font;
-import org.apache.fop.fonts.FontSetup;
-import org.apache.fop.fonts.FontTriplet;
-import org.apache.fop.fonts.LazyFont;
-import org.apache.fop.image.JpegImage;
-import org.apache.fop.fonts.CIDFont;
-import org.apache.fop.render.pdf.FopPDFImage;
-import org.apache.fop.util.ColorExt;
-
-import org.apache.xmlgraphics.java2d.AbstractGraphics2D;
-import org.apache.xmlgraphics.java2d.GraphicContext;
-
-import org.apache.batik.ext.awt.RadialGradientPaint;
-import org.apache.batik.ext.awt.LinearGradientPaint;
-import org.apache.batik.ext.awt.MultipleGradientPaint;
-import org.apache.batik.ext.awt.RenderingHintsKeyExt;
-import org.apache.batik.gvt.PatternPaint;
-import org.apache.batik.gvt.GraphicsNode;
-
-import java.text.AttributedCharacterIterator;
-import java.text.CharacterIterator;
+import java.awt.AlphaComposite;
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
-import java.awt.Color;
import java.awt.GraphicsConfiguration;
-/* java.awt.Font is not imported to avoid confusion with
- org.apache.fop.fonts.Font */
-import java.awt.GradientPaint;
import java.awt.Image;
-import java.awt.Shape;
-import java.awt.Stroke;
import java.awt.Paint;
import java.awt.PaintContext;
import java.awt.Rectangle;
-import java.awt.Dimension;
-import java.awt.BasicStroke;
-import java.awt.AlphaComposite;
-import java.awt.geom.AffineTransform;
+import java.awt.Shape;
+import java.awt.Stroke;
import java.awt.color.ColorSpace;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.PathIterator;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
-import java.awt.image.DirectColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferInt;
+import java.awt.image.DirectColorModel;
import java.awt.image.ImageObserver;
-import java.awt.image.RenderedImage;
import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
import java.awt.image.WritableRaster;
import java.awt.image.renderable.RenderableImage;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-import java.io.StringWriter;
import java.io.IOException;
import java.io.OutputStream;
-
-import java.util.Map;
+import java.io.StringWriter;
+import java.text.AttributedCharacterIterator;
+import java.text.CharacterIterator;
import java.util.List;
+import java.util.Map;
+
+import org.apache.batik.ext.awt.LinearGradientPaint;
+import org.apache.batik.ext.awt.MultipleGradientPaint;
+import org.apache.batik.ext.awt.RadialGradientPaint;
+import org.apache.batik.ext.awt.RenderingHintsKeyExt;
+import org.apache.batik.gvt.GraphicsNode;
+import org.apache.batik.gvt.PatternPaint;
+import org.apache.fop.fonts.CIDFont;
+import org.apache.fop.fonts.Font;
+import org.apache.fop.fonts.FontInfo;
+import org.apache.fop.fonts.FontSetup;
+import org.apache.fop.fonts.FontTriplet;
+import org.apache.fop.fonts.LazyFont;
+import org.apache.fop.image.JpegImage;
+import org.apache.fop.pdf.BitmapImage;
+import org.apache.fop.pdf.PDFAnnotList;
+import org.apache.fop.pdf.PDFColor;
+import org.apache.fop.pdf.PDFConformanceException;
+import org.apache.fop.pdf.PDFDeviceColorSpace;
+import org.apache.fop.pdf.PDFDocument;
+import org.apache.fop.pdf.PDFGState;
+import org.apache.fop.pdf.PDFImageXObject;
+import org.apache.fop.pdf.PDFLink;
+import org.apache.fop.pdf.PDFName;
+import org.apache.fop.pdf.PDFNumber;
+import org.apache.fop.pdf.PDFPattern;
+import org.apache.fop.pdf.PDFResourceContext;
+import org.apache.fop.pdf.PDFResources;
+import org.apache.fop.pdf.PDFState;
+import org.apache.fop.pdf.PDFText;
+import org.apache.fop.pdf.PDFXObject;
+import org.apache.fop.render.pdf.FopPDFImage;
+import org.apache.fop.util.ColorExt;
+import org.apache.xmlgraphics.java2d.AbstractGraphics2D;
+import org.apache.xmlgraphics.java2d.GraphicContext;
/**
* PDF Graphics 2D.
@@ -109,6 +106,9 @@
/** The number of decimal places. */
private static final int DEC = 8;
+
+ /** Convenience constant for full opacity */
+ static final int OPAQUE = 255;
/**
* the PDF Document being created
@@ -406,8 +406,8 @@
String key = "__AddJPEG_" + hashCode() + "_" + jpegCount[0];
jpegCount[0]++;
FopPDFImage fopimage = new FopPDFImage(jpeg, key);
- int xObjectNum = this.pdfDoc.addImage(resourceContext,
- fopimage).getXNumber();
+ PDFName imageName = this.pdfDoc.addImage(resourceContext,
+ fopimage).getName();
AffineTransform at = getTransform();
double[] matrix = new double[6];
at.getMatrix(matrix);
@@ -421,8 +421,8 @@
currentStream.write("" + width + " 0 0 "
+ (-height) + " "
+ x + " "
- + (y + height) + " cm\n" + "/Im"
- + xObjectNum + " Do\nQ\n");
+ + (y + height) + " cm\n"
+ + imageName + " Do\nQ\n");
if (outputStream != null) {
try {
@@ -518,7 +518,7 @@
// the pdf document. If so, we just reuse the reference;
// otherwise we have to build a FopImage and add it to the pdf
// document
- PDFXObject imageInfo = pdfDoc.getImage("TempImage:" + img.toString());
+ PDFXObject imageInfo = pdfDoc.getXObject("TempImage:" + img.toString());
if (imageInfo == null) {
// OK, have to build and add a PDF image
@@ -579,7 +579,7 @@
+ img.toString(), buf.getWidth(),
buf.getHeight(), mask, null);
fopimg.setColorSpace(new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_GRAY));
- PDFXObject xobj = pdfDoc.addImage(resourceContext, fopimg);
+ PDFImageXObject xobj = pdfDoc.addImage(resourceContext, fopimg);
ref = xobj.referencePDF();
if (outputStream != null) {
@@ -622,8 +622,8 @@
Shape imclip = getClip();
writeClip(imclip);
currentStream.write("" + width + " 0 0 " + (-height) + " " + x
- + " " + (y + height) + " cm\n" + "/Im"
- + imageInfo.getXNumber() + " Do\nQ\n");
+ + " " + (y + height) + " cm\n"
+ + imageInfo.getName() + " Do\nQ\n");
return true;
}
@@ -707,16 +707,7 @@
}
}
- if (c.getAlpha() != 255) {
- checkTransparencyAllowed();
- Map vals = new java.util.HashMap();
- vals.put(PDFGState.GSTATE_ALPHA_STROKE,
- new Float(c.getAlpha() / 255f));
- PDFGState gstate = pdfDoc.getFactory().makeGState(
- vals, graphicsState.getGState());
- resourceContext.addGState(gstate);
- currentStream.write("/" + gstate.getName() + " gs\n");
- }
+ applyAlpha(OPAQUE, c.getAlpha());
c = getColor();
applyColor(c, false);
@@ -1057,12 +1048,12 @@
private boolean createPattern(PatternPaint pp, boolean fill) {
preparePainting();
- FontInfo fontInfo = new FontInfo();
- FontSetup.setup(fontInfo, null, null);
+ FontInfo specialFontInfo = new FontInfo();
+ FontSetup.setup(specialFontInfo, null, null);
PDFResources res = pdfDoc.getFactory().makeResources();
PDFResourceContext context = new PDFResourceContext(res);
- PDFGraphics2D pattGraphic = new PDFGraphics2D(textAsShapes, fontInfo,
+ PDFGraphics2D pattGraphic = new PDFGraphics2D(textAsShapes, specialFontInfo,
pdfDoc, context, pageRef,
"", 0);
pattGraphic.setGraphicContext(new GraphicContext());
@@ -1128,7 +1119,7 @@
/** @todo see if pdfDoc and res can be linked here,
(currently res <> PDFDocument's resources) so addFonts()
can be moved to PDFDocument class */
- res.addFonts(pdfDoc, fontInfo);
+ res.addFonts(pdfDoc, specialFontInfo);
PDFPattern myPat = pdfDoc.getFactory().makePattern(
resourceContext, 1, res, 1, 1, bbox,
@@ -1159,11 +1150,13 @@
Shape clip = getClip();
Rectangle2D usrClipBounds, usrBounds;
usrBounds = shape.getBounds2D();
- usrClipBounds = clip.getBounds2D();
- if (!usrClipBounds.intersects(usrBounds)) {
- return true;
+ if (clip != null) {
+ usrClipBounds = clip.getBounds2D();
+ if (!usrClipBounds.intersects(usrBounds)) {
+ return true;
+ }
+ Rectangle2D.intersect(usrBounds, usrClipBounds, usrBounds);
}
- Rectangle2D.intersect(usrBounds, usrClipBounds, usrBounds);
double usrX = usrBounds.getX();
double usrY = usrBounds.getY();
double usrW = usrBounds.getWidth();
@@ -1172,11 +1165,15 @@
Rectangle devShapeBounds, devClipBounds, devBounds;
AffineTransform at = getTransform();
devShapeBounds = at.createTransformedShape(shape).getBounds();
- devClipBounds = at.createTransformedShape(clip).getBounds();
- if (!devClipBounds.intersects(devShapeBounds)) {
- return true;
+ if (clip != null) {
+ devClipBounds = at.createTransformedShape(clip).getBounds();
+ if (!devClipBounds.intersects(devShapeBounds)) {
+ return true;
+ }
+ devBounds = devShapeBounds.intersection(devClipBounds);
+ } else {
+ devBounds = devShapeBounds;
}
- devBounds = devShapeBounds.intersection(devClipBounds);
int devX = devBounds.x;
int devY = devBounds.y;
int devW = devBounds.width;
@@ -1189,7 +1186,7 @@
PaintContext pctx = paint.createContext(rgbCM, devBounds, usrBounds,
at, getRenderingHints());
- PDFXObject imageInfo = pdfDoc.getImage
+ PDFXObject imageInfo = pdfDoc.getXObject
("TempImage:" + pctx.toString());
if (imageInfo != null) {
resourceContext.getPDFResources().addXObject(imageInfo);
@@ -1237,7 +1234,7 @@
BitmapImage fopimg = new BitmapImage
("TempImageMask:" + pctx.toString(), devW, devH, mask, null);
fopimg.setColorSpace(new PDFDeviceColorSpace(PDFDeviceColorSpace.DEVICE_GRAY));
- PDFXObject xobj = pdfDoc.addImage(resourceContext, fopimg);
+ PDFImageXObject xobj = pdfDoc.addImage(resourceContext, fopimg);
maskRef = xobj.referencePDF();
if (outputStream != null) {
@@ -1265,8 +1262,8 @@
currentStream.write("q\n");
writeClip(shape);
currentStream.write("" + usrW + " 0 0 " + (-usrH) + " " + usrX
- + " " + (usrY + usrH) + " cm\n" + "/Im"
- + imageInfo.getXNumber() + " Do\nQ\n");
+ + " " + (usrY + usrH) + " cm\n"
+ + imageInfo.getName() + " Do\nQ\n");
return true;
}
@@ -1419,69 +1416,25 @@
if (ovFontState == null) {
java.awt.Font gFont = getFont();
fontTransform = gFont.getTransform();
- String n = gFont.getFamily();
- if (n.equals("sanserif")) {
- n = "sans-serif";
- }
- float siz = gFont.getSize2D();
- String style = gFont.isItalic() ? "italic" : "normal";
- int weight = gFont.isBold() ? Font.WEIGHT_BOLD : Font.WEIGHT_NORMAL;
- FontTriplet triplet = fontInfo.fontLookup(n, style, weight);
- fontState = fontInfo.getFontInstance(triplet, (int)(siz * 1000 + 0.5));
+ fontState = getInternalFontForAWTFont(gFont);
} else {
fontState = fontInfo.getFontInstance(
ovFontState.getFontTriplet(), ovFontState.getFontSize());
ovFontState = null;
}
- String name;
- float size;
- name = fontState.getFontName();
- size = (float)fontState.getFontSize() / 1000f;
-
- if ((!name.equals(this.currentFontName))
- || (size != this.currentFontSize)) {
- this.currentFontName = name;
- this.currentFontSize = size;
- currentStream.write("/" + name + " " + size + " Tf\n");
-
- }
+ updateCurrentFont(fontState);
currentStream.write("q\n");
Color c = getColor();
applyColor(c, true);
applyPaint(getPaint(), true);
- int salpha = c.getAlpha();
-
- if (salpha != 255) {
- checkTransparencyAllowed();
- Map vals = new java.util.HashMap();
- vals.put(PDFGState.GSTATE_ALPHA_NONSTROKE, new Float(salpha / 255f));
- PDFGState gstate = pdfDoc.getFactory().makeGState(
- vals, graphicsState.getGState());
- resourceContext.addGState(gstate);
- currentStream.write("/" + gstate.getName() + " gs\n");
- }
-
- Map kerning = null;
- boolean kerningAvailable = false;
+ applyAlpha(c.getAlpha(), OPAQUE);
- kerning = fontState.getKerning();
- if (kerning != null && !kerning.isEmpty()) {
- kerningAvailable = true;
- }
+ Map kerning = fontState.getKerning();
+ boolean kerningAvailable = (kerning != null && !kerning.isEmpty());
- // This assumes that *all* CIDFonts use a /ToUnicode mapping
- boolean useMultiByte = false;
- org.apache.fop.fonts.Typeface f =
- (org.apache.fop.fonts.Typeface)fontInfo.getFonts().get(name);
- if (f instanceof LazyFont) {
- if (((LazyFont) f).getRealFont() instanceof CIDFont) {
- useMultiByte = true;
- }
- } else if (f instanceof CIDFont) {
- useMultiByte = true;
- }
+ boolean useMultiByte = isMultiByteFont(currentFontName);
// String startText = useMultiByte ? "<FEFF" : "(";
String startText = useMultiByte ? "<" : "(";
@@ -1527,6 +1480,7 @@
case '\\':
currentStream.write("\\");
break;
+ default:
}
currentStream.write(ch);
}
@@ -1543,13 +1497,88 @@
}
currentStream.write(endText);
-
currentStream.write("] TJ\n");
-
currentStream.write("ET\n");
currentStream.write("Q\n");
}
+ /**
+ * Applies the given alpha values for filling and stroking.
+ * @param fillAlpha A value between 0 and 255 (=OPAQUE) for filling
+ * @param strokeAlpha A value between 0 and 255 (=OPAQUE) for stroking
+ */
+ protected void applyAlpha(int fillAlpha, int strokeAlpha) {
+ if (fillAlpha != OPAQUE || strokeAlpha != OPAQUE) {
+ checkTransparencyAllowed();
+ Map vals = new java.util.HashMap();
+ if (fillAlpha != OPAQUE) {
+ vals.put(PDFGState.GSTATE_ALPHA_NONSTROKE, new Float(fillAlpha / 255f));
+ }
+ if (strokeAlpha != OPAQUE) {
+ vals.put(PDFGState.GSTATE_ALPHA_STROKE, new Float(strokeAlpha / 255f));
+ }
+ PDFGState gstate = pdfDoc.getFactory().makeGState(
+ vals, graphicsState.getGState());
+ resourceContext.addGState(gstate);
+ currentStream.write("/" + gstate.getName() + " gs\n");
+ }
+ }
+
+ /**
+ * Updates the currently selected font.
+ * @param font the new font to use
+ */
+ protected void updateCurrentFont(Font font) {
+ String name = font.getFontName();
+ float size = (float)font.getFontSize() / 1000f;
+
+ //Only update if necessary
+ if ((!name.equals(this.currentFontName))
+ || (size != this.currentFontSize)) {
+ this.currentFontName = name;
+ this.currentFontSize = size;
+ currentStream.write("/" + name + " " + size + " Tf\n");
+ }
+ }
+
+ /**
+ * Returns a suitable internal font given an AWT Font instance.
+ * @param awtFont the AWT font
+ * @return the internal Font
+ */
+ protected Font getInternalFontForAWTFont(java.awt.Font awtFont) {
+ Font fontState;
+ String n = awtFont.getFamily();
+ if (n.equals("sanserif")) {
+ n = "sans-serif";
+ }
+ float siz = awtFont.getSize2D();
+ String style = awtFont.isItalic() ? "italic" : "normal";
+ int weight = awtFont.isBold() ? Font.WEIGHT_BOLD : Font.WEIGHT_NORMAL;
+ FontTriplet triplet = fontInfo.fontLookup(n, style, weight);
+ fontState = fontInfo.getFontInstance(triplet, (int)(siz * 1000 + 0.5));
+ return fontState;
+ }
+
+ /**
+ * Determines whether the font with the given name is a multi-byte font.
+ * @param name the name of the font
+ * @return true if it's a multi-byte font
+ */
+ protected boolean isMultiByteFont(String name) {
+ // This assumes that *all* CIDFonts use a /ToUnicode mapping
+ org.apache.fop.fonts.Typeface f
+ = (org.apache.fop.fonts.Typeface)fontInfo.getFonts().get(name);
+ if (f instanceof LazyFont) {
+ if (((LazyFont) f).getRealFont() instanceof CIDFont) {
+ return true;
+ }
+ } else if (f instanceof CIDFont) {
+ return true;
+ }
+ return false;
+ }
+
private void addKerning(StringWriter buf, Integer ch1, Integer ch2,
Map kerning, String startText,
String endText) {
@@ -1702,16 +1731,7 @@
}
}
- if (c.getAlpha() != 255) {
- checkTransparencyAllowed();
- Map vals = new java.util.HashMap();
- vals.put(PDFGState.GSTATE_ALPHA_NONSTROKE,
- new Float(c.getAlpha() / 255f));
- PDFGState gstate = pdfDoc.getFactory().makeGState(
- vals, graphicsState.getGState());
- resourceContext.addGState(gstate);
- currentStream.write("/" + gstate.getName() + " gs\n");
- }
+ applyAlpha(c.getAlpha(), OPAQUE);
c = getColor();
applyColor(c, true);
Modified: xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/PDFTextElementBridge.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/PDFTextElementBridge.java?rev=593328&r1=593327&r2=593328&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/PDFTextElementBridge.java (original)
+++ xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/PDFTextElementBridge.java Thu Nov 8 13:27:19 2007
@@ -19,15 +19,13 @@
package org.apache.fop.svg;
-import org.apache.batik.gvt.TextNode;
-import org.apache.batik.bridge.SVGTextElementBridge;
import org.apache.batik.bridge.BridgeContext;
+import org.apache.batik.bridge.SVGTextElementBridge;
import org.apache.batik.gvt.GraphicsNode;
-
+import org.apache.batik.gvt.TextNode;
+import org.apache.batik.gvt.TextPainter;
import org.apache.fop.fonts.FontInfo;
-
import org.w3c.dom.Element;
-import org.w3c.dom.Node;
/**
* Bridge class for the <text> element.
@@ -37,11 +35,12 @@
* @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a>
*/
public class PDFTextElementBridge extends SVGTextElementBridge {
+
private PDFTextPainter pdfTextPainter;
/**
* Constructs a new bridge for the <text> element.
- * @param fi the font infomration
+ * @param fi the font information
*/
public PDFTextElementBridge(FontInfo fi) {
pdfTextPainter = new PDFTextPainter(fi);
@@ -56,71 +55,20 @@
*/
public GraphicsNode createGraphicsNode(BridgeContext ctx, Element e) {
GraphicsNode node = super.createGraphicsNode(ctx, e);
- if (node != null && isSimple(ctx, e, node)) {
+ if (node != null) {
+ //Set our own text painter
((TextNode)node).setTextPainter(getTextPainter());
}
return node;
}
- private PDFTextPainter getTextPainter() {
- return pdfTextPainter;
- }
-
/**
- * Check if text element contains simple text.
- * This checks the children of the text element to determine
- * if the text is simple. The text is simple if it can be rendered
- * with basic text drawing algorithms. This means there are no
- * alternate characters, the font is known and there are no effects
- * applied to the text.
- *
- * @param ctx the bridge context
- * @param element the svg text element
- * @param node the graphics node
- * @return true if this text is simple of false if it cannot be
- * easily rendered using normal drawString on the PDFGraphics2D
+ * Returns the TextPainter instance used by this bridge.
+ * @return the text painter
*/
- private boolean isSimple(BridgeContext ctx, Element element, GraphicsNode node) {
- /* I cannot find any reference that 36pt is the maximum font size in PDF. Tests show
- * no such restriction (jeremias, 28.5.2007)
- *
- // Font size, in user space units.
- float fs = TextUtilities.convertFontSize(element).floatValue();
- // PDF cannot display fonts over 36pt
- if (fs > 36) {
- return false;
- }
- */
-
- Element nodeElement;
- for (Node n = element.getFirstChild();
- n != null;
- n = n.getNextSibling()) {
-
- switch (n.getNodeType()) {
- case Node.ELEMENT_NODE:
-
- nodeElement = (Element)n;
-
- if (n.getLocalName().equals(SVG_TSPAN_TAG)
- || n.getLocalName().equals(SVG_ALT_GLYPH_TAG)) {
- return false;
- } else if (n.getLocalName().equals(SVG_TEXT_PATH_TAG)) {
- return false;
- } else if (n.getLocalName().equals(SVG_TREF_TAG)) {
- return false;
- }
- break;
- case Node.TEXT_NODE:
- case Node.CDATA_SECTION_NODE:
- }
- }
-
- /*if (CSSUtilities.convertFilter(element, node, ctx) != null) {
- return false;
- }*/
-
- return true;
+ public TextPainter getTextPainter() {
+ return pdfTextPainter;
}
+
}
Modified: xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/PDFTextPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/PDFTextPainter.java?rev=593328&r1=593327&r2=593328&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/PDFTextPainter.java (original)
+++ xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/PDFTextPainter.java Thu Nov 8 13:27:19 2007
@@ -19,32 +19,34 @@
package org.apache.fop.svg;
+import java.awt.BasicStroke;
+import java.awt.Color;
import java.awt.Graphics2D;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-/* java.awt.Font is not imported to avoid confusion with
- org.apache.fop.fonts.Font */
-import java.text.AttributedCharacterIterator;
-import java.awt.font.TextAttribute;
-import java.awt.Shape;
import java.awt.Paint;
+import java.awt.Shape;
import java.awt.Stroke;
-import java.awt.Color;
-import java.util.List;
+import java.awt.font.TextAttribute;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.Point2D;
+import java.lang.reflect.Method;
+import java.text.AttributedCharacterIterator;
import java.util.Iterator;
+import java.util.List;
-import org.apache.batik.gvt.text.Mark;
-import org.apache.batik.gvt.TextPainter;
-import org.apache.batik.gvt.TextNode;
-import org.apache.batik.gvt.text.GVTAttributedCharacterIterator;
-import org.apache.batik.gvt.text.TextPaintInfo;
-import org.apache.batik.gvt.font.GVTFontFamily;
import org.apache.batik.bridge.SVGFontFamily;
+import org.apache.batik.gvt.font.GVTFont;
+import org.apache.batik.gvt.font.GVTFontFamily;
+import org.apache.batik.gvt.font.GVTGlyphVector;
import org.apache.batik.gvt.renderer.StrokingTextPainter;
-
+import org.apache.batik.gvt.text.GVTAttributedCharacterIterator;
+import org.apache.batik.gvt.text.TextPaintInfo;
+import org.apache.batik.gvt.text.TextSpanLayout;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.fonts.FontTriplet;
+import org.apache.fop.util.CharUtilities;
/**
* Renders the attributed character iterator of a <tt>TextNode</tt>.
@@ -54,108 +56,221 @@
* drawString. If the text is complex or the cannot be translated
* into a simple drawString the StrokingTextPainter is used instead.
*
- * (todo) handle underline, overline and strikethrough
- * (todo) use drawString(AttributedCharacterIterator iterator...) for some
- *
- * @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a>
* @version $Id$
*/
-public class PDFTextPainter implements TextPainter {
- private FontInfo fontInfo;
+public class PDFTextPainter extends StrokingTextPainter {
- /**
- * Use the stroking text painter to get the bounds and shape.
- * Also used as a fallback to draw the string with strokes.
- */
- protected static final TextPainter PROXY_PAINTER =
- StrokingTextPainter.getInstance();
+ private static final boolean DEBUG = false;
+
+ private boolean strokeText = false;
+ private FontInfo fontInfo;
/**
* Create a new PDF text painter with the given font information.
- * @param fi the fint info
+ * @param fi the font info
*/
public PDFTextPainter(FontInfo fi) {
fontInfo = fi;
}
- /**
- * Paints the specified attributed character iterator using the
- * specified Graphics2D and context and font context.
- * @param node the TextNode to paint
- * @param g2d the Graphics2D to use
- */
- public void paint(TextNode node, Graphics2D g2d) {
- String txt = node.getText();
- Point2D loc = node.getLocation();
-
- AttributedCharacterIterator aci =
- node.getAttributedCharacterIterator();
- // reset position to start of char iterator
- if (aci.getBeginIndex() == aci.getEndIndex()) {
- return;
- }
- char ch = aci.first();
- if (ch == AttributedCharacterIterator.DONE) {
- return;
+ /** {@inheritDoc} */
+ protected void paintTextRuns(List textRuns, Graphics2D g2d) {
+ if (DEBUG) {
+ System.out.println("paintTextRuns: count = " + textRuns.size());
+ //fontInfo.dumpAllTripletsToSystemOut();
}
- TextNode.Anchor anchor;
- anchor = (TextNode.Anchor) aci.getAttribute(
- GVTAttributedCharacterIterator.TextAttribute.ANCHOR_TYPE);
-
- List gvtFonts;
- gvtFonts = (List) aci.getAttribute(
- GVTAttributedCharacterIterator.TextAttribute.GVT_FONT_FAMILIES);
-
- TextPaintInfo tpi = (TextPaintInfo) aci.getAttribute(
- GVTAttributedCharacterIterator.TextAttribute.PAINT_INFO);
-
- if (tpi == null) {
- return;
- }
-
- Paint forg = tpi.fillPaint;
- Paint strokePaint = tpi.strokePaint;
- Float size = (Float) aci.getAttribute(TextAttribute.SIZE);
- if (size == null) {
+ if (!(g2d instanceof PDFGraphics2D) || strokeText) {
+ super.paintTextRuns(textRuns, g2d);
return;
}
- Stroke stroke = tpi.strokeStroke;
- /*
- Float xpos = (Float) aci.getAttribute(
- GVTAttributedCharacterIterator.TextAttribute.X);
- Float ypos = (Float) aci.getAttribute(
- GVTAttributedCharacterIterator.TextAttribute.Y);
- */
-
- Float posture = (Float) aci.getAttribute(TextAttribute.POSTURE);
- Float taWeight = (Float) aci.getAttribute(TextAttribute.WEIGHT);
+ PDFGraphics2D pdf = (PDFGraphics2D)g2d;
+ PDFTextUtil textUtil = new PDFTextUtil(pdf);
+ for (int i = 0; i < textRuns.size(); i++) {
+ TextRun textRun = (TextRun)textRuns.get(i);
+ AttributedCharacterIterator runaci = textRun.getACI();
+ runaci.first();
+
+ TextPaintInfo tpi = (TextPaintInfo)runaci.getAttribute(PAINT_INFO);
+ if (tpi == null || !tpi.visible) {
+ continue;
+ }
+ if ((tpi != null) && (tpi.composite != null)) {
+ g2d.setComposite(tpi.composite);
+ }
+
+ //------------------------------------
+ TextSpanLayout layout = textRun.getLayout();
+ if (DEBUG) {
+ int charCount = runaci.getEndIndex() - runaci.getBeginIndex();
+ System.out.println("================================================");
+ System.out.println("New text run:");
+ System.out.println("char count: " + charCount);
+ System.out.println("range: "
+ + runaci.getBeginIndex() + " - " + runaci.getEndIndex());
+ System.out.println("glyph count: " + layout.getGlyphCount()); //=getNumGlyphs()
+ }
+ //Gather all characters of the run
+ StringBuffer chars = new StringBuffer();
+ for (runaci.first(); runaci.getIndex() < runaci.getEndIndex();) {
+ chars.append(runaci.current());
+ runaci.next();
+ }
+ runaci.first();
+ if (DEBUG) {
+ System.out.println("Text: " + chars);
+ pdf.currentStream.write("%Text: " + chars + "\n");
+ }
+
+ GeneralPath debugShapes = null;
+ if (DEBUG) {
+ debugShapes = new GeneralPath();
+ }
+
+ Font[] fonts = findFonts(runaci);
+ if (fonts == null || fonts.length == 0) {
+ //Draw using Java2D
+ textRun.getLayout().draw(g2d);
+ continue;
+ }
+
+ textUtil.saveGraphicsState();
+ textUtil.concatMatrixCurrentTransform();
+ Shape imclip = g2d.getClip();
+ pdf.writeClip(imclip);
+
+ applyColorAndPaint(tpi, pdf);
+
+ textUtil.beginTextObject();
+ textUtil.setFonts(fonts);
+ textUtil.setTextRenderingMode(tpi.fillPaint != null, tpi.strokePaint != null, false);
+
+ AffineTransform localTransform = new AffineTransform();
+ Point2D prevPos = null;
+ double prevVisibleCharWidth = 0.0;
+ GVTGlyphVector gv = layout.getGlyphVector();
+ for (int index = 0, c = gv.getNumGlyphs(); index < c; index++) {
+ char ch = chars.charAt(index);
+ boolean visibleChar = gv.isGlyphVisible(index)
+ || (CharUtilities.isAnySpace(ch) && !CharUtilities.isZeroWidthSpace(ch));
+ if (DEBUG) {
+ System.out.println("glyph " + index
+ + " -> " + layout.getGlyphIndex(index) + " => " + ch);
+ if (CharUtilities.isAnySpace(ch) && ch != 32) {
+ System.out.println("Space found: " + Integer.toHexString(ch));
+ }
+ if (ch == CharUtilities.ZERO_WIDTH_JOINER) {
+ System.out.println("ZWJ found: " + Integer.toHexString(ch));
+ }
+ if (ch == CharUtilities.SOFT_HYPHEN) {
+ System.out.println("Soft hyphen found: " + Integer.toHexString(ch));
+ }
+ if (!visibleChar) {
+ System.out.println("Invisible glyph found: " + Integer.toHexString(ch));
+ }
+ }
+ if (!visibleChar) {
+ continue;
+ }
+ Point2D p = gv.getGlyphPosition(index);
- boolean useStrokePainter = false;
+ AffineTransform glyphTransform = gv.getGlyphTransform(index);
+ //TODO Glyph transforms could be refined so not every char has to be painted
+ //with its own TJ command (stretch/squeeze case could be optimized)
+ if (DEBUG) {
+ System.out.println("pos " + p + ", transform " + glyphTransform);
+ Shape sh;
+ sh = gv.getGlyphLogicalBounds(index);
+ if (sh == null) {
+ sh = new Ellipse2D.Double(p.getX(), p.getY(), 2, 2);
+ }
+ debugShapes.append(sh, false);
+ }
- if (forg instanceof Color) {
- Color col = (Color) forg;
- if (col.getAlpha() != 255) {
- useStrokePainter = true;
+ //Exact position of the glyph
+ localTransform.setToIdentity();
+ localTransform.translate(p.getX(), p.getY());
+ if (glyphTransform != null) {
+ localTransform.concatenate(glyphTransform);
+ }
+ localTransform.scale(1, -1);
+
+ boolean yPosChanged = (prevPos == null
+ || prevPos.getY() != p.getY()
+ || glyphTransform != null);
+ if (yPosChanged) {
+ if (index > 0) {
+ textUtil.writeTJ();
+ textUtil.writeTextMatrix(localTransform);
+ }
+ } else {
+ double xdiff = p.getX() - prevPos.getX();
+ //Width of previous character
+ Font font = textUtil.getCurrentFont();
+ double cw = prevVisibleCharWidth;
+ double effxdiff = (1000 * xdiff) - cw;
+ if (effxdiff != 0) {
+ double adjust = (-effxdiff / font.getFontSize());
+ textUtil.adjustGlyphTJ(adjust * 1000);
+ }
+ if (DEBUG) {
+ System.out.println("==> x diff: " + xdiff + ", " + effxdiff
+ + ", charWidth: " + cw);
+ }
+ }
+ Font f = textUtil.selectFontForChar(ch);
+ if (f != textUtil.getCurrentFont()) {
+ textUtil.writeTJ();
+ textUtil.setCurrentFont(f);
+ textUtil.writeTf(f);
+ textUtil.writeTextMatrix(localTransform);
+ }
+ char paintChar = (CharUtilities.isAnySpace(ch) ? ' ' : ch);
+ textUtil.writeTJChar(paintChar);
+
+ //Update last position
+ prevPos = p;
+ prevVisibleCharWidth = textUtil.getCurrentFont().getCharWidth(chars.charAt(index));
+ }
+ textUtil.writeTJ();
+ textUtil.endTextObject();
+ textUtil.restoreGraphicsState();
+ if (DEBUG) {
+ g2d.setStroke(new BasicStroke(0));
+ g2d.setColor(Color.LIGHT_GRAY);
+ g2d.draw(debugShapes);
}
- g2d.setColor(col);
- }
- g2d.setPaint(forg);
- g2d.setStroke(stroke);
-
- if (strokePaint != null) {
- // need to draw using AttributedCharacterIterator
- useStrokePainter = true;
}
+ }
- if (hasUnsupportedAttributes(aci)) {
- useStrokePainter = true;
+ private void applyColorAndPaint(TextPaintInfo tpi, PDFGraphics2D pdf) {
+ Paint fillPaint = tpi.fillPaint;
+ Paint strokePaint = tpi.strokePaint;
+ Stroke stroke = tpi.strokeStroke;
+ int fillAlpha = PDFGraphics2D.OPAQUE;
+ if (fillPaint instanceof Color) {
+ Color col = (Color)fillPaint;
+ pdf.applyColor(col, true);
+ fillAlpha = col.getAlpha();
+ }
+ if (strokePaint instanceof Color) {
+ Color col = (Color)strokePaint;
+ pdf.applyColor(col, false);
}
-
- // text contains unsupported information
- if (useStrokePainter) {
- PROXY_PAINTER.paint(node, g2d);
- return;
+ pdf.applyPaint(fillPaint, true);
+ pdf.applyStroke(stroke);
+ if (strokePaint != null) {
+ pdf.applyPaint(strokePaint, false);
}
+ pdf.applyAlpha(fillAlpha, PDFGraphics2D.OPAQUE);
+ }
+
+ private Font[] findFonts(AttributedCharacterIterator aci) {
+ List fonts = new java.util.ArrayList();
+ List gvtFonts = (List) aci.getAttribute(
+ GVTAttributedCharacterIterator.TextAttribute.GVT_FONT_FAMILIES);
+ Float posture = (Float) aci.getAttribute(TextAttribute.POSTURE);
+ Float taWeight = (Float) aci.getAttribute(TextAttribute.WEIGHT);
+ Float fontSize = (Float) aci.getAttribute(TextAttribute.SIZE);
String style = ((posture != null) && (posture.floatValue() > 0.0))
? "italic" : "normal";
@@ -163,236 +278,65 @@
&& (taWeight.floatValue() > 1.0)) ? Font.WEIGHT_BOLD
: Font.WEIGHT_NORMAL;
- Font fontState = null;
- FontInfo fi = fontInfo;
- boolean found = false;
String fontFamily = null;
+
+ //GVT_FONT can sometimes be different from the fonts in GVT_FONT_FAMILIES
+ //or GVT_FONT_FAMILIES can even be empty and only GVT_FONT is set
+ /* The following code section is not available until Batik 1.7 is released. */
+ GVTFont gvtFont = (GVTFont)aci.getAttribute(
+ GVTAttributedCharacterIterator.TextAttribute.GVT_FONT);
+ if (gvtFont != null) {
+ try {
+ Method method = gvtFont.getClass().getMethod("getFamilyName", null);
+ String gvtFontFamily = (String)method.invoke(gvtFont, null);
+ //TODO Uncomment the following line when Batik 1.7 is shipped with FOP
+ //String gvtFontFamily = gvtFont.getFamilyName(); //Not available in Batik 1.6
+ if (DEBUG) {
+ System.out.print(gvtFontFamily + ", ");
+ }
+ if (fontInfo.hasFont(gvtFontFamily, style, weight)) {
+ FontTriplet triplet = fontInfo.fontLookup(gvtFontFamily, style,
+ weight);
+ int fsize = (int)(fontSize.floatValue() * 1000);
+ fonts.add(fontInfo.getFontInstance(triplet, fsize));
+ }
+ } catch (Exception e) {
+ //Most likely NoSuchMethodError here when using Batik 1.6
+ //Just skip this section in this case
+ }
+ }
+
if (gvtFonts != null) {
Iterator i = gvtFonts.iterator();
while (i.hasNext()) {
GVTFontFamily fam = (GVTFontFamily) i.next();
if (fam instanceof SVGFontFamily) {
- PROXY_PAINTER.paint(node, g2d);
- return;
+ return null; //Let Batik paint this text!
}
fontFamily = fam.getFamilyName();
- if (fi.hasFont(fontFamily, style, weight)) {
+ if (DEBUG) {
+ System.out.print(fontFamily + ", ");
+ }
+ if (fontInfo.hasFont(fontFamily, style, weight)) {
FontTriplet triplet = fontInfo.fontLookup(fontFamily, style,
weight);
- int fsize = (int)(size.floatValue() * 1000);
- fontState = fontInfo.getFontInstance(triplet, fsize);
- found = true;
- break;
+ int fsize = (int)(fontSize.floatValue() * 1000);
+ fonts.add(fontInfo.getFontInstance(triplet, fsize));
}
}
}
- if (!found) {
+ if (fonts.size() == 0) {
FontTriplet triplet = fontInfo.fontLookup("any", style, Font.WEIGHT_NORMAL);
- int fsize = (int)(size.floatValue() * 1000);
- fontState = fontInfo.getFontInstance(triplet, fsize);
- } else {
- if (g2d instanceof PDFGraphics2D) {
- ((PDFGraphics2D) g2d).setOverrideFontState(fontState);
- }
- }
- int fStyle = java.awt.Font.PLAIN;
- if (weight == Font.WEIGHT_BOLD) {
- if (style.equals("italic")) {
- fStyle = java.awt.Font.BOLD | java.awt.Font.ITALIC;
- } else {
- fStyle = java.awt.Font.BOLD;
- }
- } else {
- if (style.equals("italic")) {
- fStyle = java.awt.Font.ITALIC;
- } else {
- fStyle = java.awt.Font.PLAIN;
- }
- }
- java.awt.Font font = new java.awt.Font(fontFamily, fStyle,
- (int)(fontState.getFontSize() / 1000));
-
- g2d.setFont(font);
-
- float advance = getStringWidth(txt, fontState);
- float tx = 0;
- if (anchor != null) {
- switch (anchor.getType()) {
- case TextNode.Anchor.ANCHOR_MIDDLE:
- tx = -advance / 2;
- break;
- case TextNode.Anchor.ANCHOR_END:
- tx = -advance;
+ int fsize = (int)(fontSize.floatValue() * 1000);
+ fonts.add(fontInfo.getFontInstance(triplet, fsize));
+ if (DEBUG) {
+ System.out.print("fallback to 'any' font");
}
}
- g2d.drawString(txt, (float)(loc.getX() + tx), (float)(loc.getY()));
- }
-
- private boolean hasUnsupportedAttributes(AttributedCharacterIterator aci) {
- boolean hasunsupported = false;
- Object letSpace = aci.getAttribute(
- GVTAttributedCharacterIterator.TextAttribute.LETTER_SPACING);
- if (letSpace != null) {
- hasunsupported = true;
- }
-
- Object wordSpace = aci.getAttribute(
- GVTAttributedCharacterIterator.TextAttribute.WORD_SPACING);
- if (wordSpace != null) {
- hasunsupported = true;
- }
-
- AttributedCharacterIterator.Attribute key;
- key = GVTAttributedCharacterIterator.TextAttribute.WRITING_MODE;
- Object writeMod = aci.getAttribute(key);
- if (!GVTAttributedCharacterIterator.TextAttribute.WRITING_MODE_LTR.equals(
- writeMod)) {
- hasunsupported = true;
- }
-
- Object vertOr = aci.getAttribute(
- GVTAttributedCharacterIterator.TextAttribute.VERTICAL_ORIENTATION);
- if (GVTAttributedCharacterIterator.TextAttribute.ORIENTATION_ANGLE.equals(
- vertOr)) {
- hasunsupported = true;
+ if (DEBUG) {
+ System.out.println();
}
- return hasunsupported;
+ return (Font[])fonts.toArray(new Font[fonts.size()]);
}
-
- private float getStringWidth(String str, Font fontState) {
- float wordWidth = 0;
- float whitespaceWidth = fontState.getWidth(fontState.mapChar(' '));
-
- for (int i = 0; i < str.length(); i++) {
- float charWidth;
- char c = str.charAt(i);
- if (!((c == ' ') || (c == '\n') || (c == '\r') || (c == '\t'))) {
- charWidth = fontState.getWidth(fontState.mapChar(c));
- if (charWidth <= 0) {
- charWidth = whitespaceWidth;
- }
- } else {
- charWidth = whitespaceWidth;
- }
- wordWidth += charWidth;
- }
- return wordWidth / 1000f;
- }
-
- /**
- * Get the outline shape of the text characters.
- * This uses the StrokingTextPainter to get the outline
- * shape since in theory it should be the same.
- *
- * @param node the text node
- * @return the outline shape of the text characters
- */
- public Shape getOutline(TextNode node) {
- return PROXY_PAINTER.getOutline(node);
- }
-
- /**
- * Get the bounds.
- * This uses the StrokingTextPainter to get the bounds
- * since in theory it should be the same.
- *
- * @param node the text node
- * @return the bounds of the text
- */
- public Rectangle2D getBounds2D(TextNode node) {
- return PROXY_PAINTER.getBounds2D(node);
- }
-
- /**
- * Get the geometry bounds.
- * This uses the StrokingTextPainter to get the bounds
- * since in theory it should be the same.
- * @param node the text node
- * @return the bounds of the text
- */
- public Rectangle2D getGeometryBounds(TextNode node) {
- return PROXY_PAINTER.getGeometryBounds(node);
- }
-
- // Methods that have no purpose for PDF
-
- /**
- * Get the mark.
- * This does nothing since the output is pdf and not interactive.
- * @param node the text node
- * @param pos the position
- * @param all select all
- * @return null
- */
- public Mark getMark(TextNode node, int pos, boolean all) {
- return null;
- }
-
- /**
- * Select at.
- * This does nothing since the output is pdf and not interactive.
- * @param x the x position
- * @param y the y position
- * @param node the text node
- * @return null
- */
- public Mark selectAt(double x, double y, TextNode node) {
- return null;
- }
-
- /**
- * Select to.
- * This does nothing since the output is pdf and not interactive.
- * @param x the x position
- * @param y the y position
- * @param beginMark the start mark
- * @return null
- */
- public Mark selectTo(double x, double y, Mark beginMark) {
- return null;
- }
-
- /**
- * Selec first.
- * This does nothing since the output is pdf and not interactive.
- * @param node the text node
- * @return null
- */
- public Mark selectFirst(TextNode node) {
- return null;
- }
-
- /**
- * Select last.
- * This does nothing since the output is pdf and not interactive.
- * @param node the text node
- * @return null
- */
- public Mark selectLast(TextNode node) {
- return null;
- }
-
- /**
- * Get selected.
- * This does nothing since the output is pdf and not interactive.
- * @param start the start mark
- * @param finish the finish mark
- * @return null
- */
- public int[] getSelected(Mark start, Mark finish) {
- return null;
- }
-
- /**
- * Get the highlighted shape.
- * This does nothing since the output is pdf and not interactive.
- * @param beginMark the start mark
- * @param endMark the end mark
- * @return null
- */
- public Shape getHighlightShape(Mark beginMark, Mark endMark) {
- return null;
- }
-
-}
-
+
+}
\ No newline at end of file
Modified: xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/PDFTranscoder.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/PDFTranscoder.java?rev=593328&r1=593327&r2=593328&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/PDFTranscoder.java (original)
+++ xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/svg/PDFTranscoder.java Thu Nov 8 13:27:19 2007
@@ -25,6 +25,7 @@
import org.apache.avalon.framework.configuration.Configurable;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.configuration.DefaultConfiguration;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.UnitProcessor;
import org.apache.batik.bridge.UserAgent;
@@ -33,10 +34,10 @@
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.TranscodingHints;
import org.apache.batik.transcoder.image.ImageTranscoder;
+import org.apache.batik.transcoder.keys.BooleanKey;
import org.apache.batik.transcoder.keys.FloatKey;
import org.apache.fop.Version;
import org.apache.fop.fonts.FontInfo;
-import org.apache.fop.fonts.FontSetup;
import org.w3c.dom.Document;
import org.w3c.dom.svg.SVGLength;
@@ -63,6 +64,12 @@
* <tt>KEY_USER_STYLESHEET_URI</tt> to fix the URI of a user
* stylesheet, and <tt>KEY_PIXEL_TO_MM</tt> to specify the pixel to
* millimeter conversion factor.
+ *
+ * <p><tt>KEY_AUTO_FONTS</tt> to disable the auto-detection of fonts installed in the system.
+ * The PDF Transcoder cannot use AWT's font subsystem and that's why the fonts have to be
+ * configured differently. By default, font auto-detection is enabled to match the behaviour
+ * of the other transcoders, but this may be associated with a price in the form of a small
+ * performance penalty. If font auto-detection is not desired, it can be disable using this key.
*
* @author <a href="mailto:keiron@aftexsw.com">Keiron Liddle</a>
* @version $Id$
@@ -76,13 +83,20 @@
*/
public static final TranscodingHints.Key KEY_DEVICE_RESOLUTION = new FloatKey();
+ /**
+ * The key is used to specify whether the available fonts should be automatically
+ * detected. The alternative is to configure the transcoder manually using a configuration
+ * file.
+ */
+ public static final TranscodingHints.Key KEY_AUTO_FONTS = new BooleanKey();
+
private Configuration cfg = null;
/** Graphics2D instance that is used to paint to */
protected PDFDocumentGraphics2D graphics = null;
/**
- * Constructs a new <tt>ImageTranscoder</tt>.
+ * Constructs a new <tt>PDFTranscoder</tt>.
*/
public PDFTranscoder() {
super();
@@ -102,9 +116,7 @@
};
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void configure(Configuration cfg) throws ConfigurationException {
this.cfg = cfg;
}
@@ -121,16 +133,35 @@
TranscoderOutput output)
throws TranscoderException {
- graphics = new PDFDocumentGraphics2D();
+ graphics = new PDFDocumentGraphics2D(isTextStroked());
graphics.getPDFDocument().getInfo().setProducer("Apache FOP Version "
+ Version.getVersion()
+ ": PDF Transcoder for Batik");
try {
- if (this.cfg != null) {
+ Configuration effCfg = this.cfg;
+ if (effCfg == null) {
+ //By default, enable font auto-detection if no cfg is given
+ boolean autoFonts = true;
+ if (hints.containsKey(KEY_AUTO_FONTS)) {
+ autoFonts = ((Boolean)hints.get(KEY_AUTO_FONTS)).booleanValue();
+ }
+ if (autoFonts) {
+ DefaultConfiguration c = new DefaultConfiguration("pdf-transcoder");
+ DefaultConfiguration fonts = new DefaultConfiguration("fonts");
+ c.addChild(fonts);
+ DefaultConfiguration autodetect = new DefaultConfiguration("auto-detect");
+ fonts.addChild(autodetect);
+ effCfg = c;
+ }
+ }
+
+ if (effCfg != null) {
PDFDocumentGraphics2DConfigurator configurator
= new PDFDocumentGraphics2DConfigurator();
- configurator.configure(graphics, this.cfg);
+ configurator.configure(graphics, effCfg);
+ } else {
+ graphics.setupDefaultFontInfo();
}
} catch (Exception e) {
throw new TranscoderException(
@@ -190,8 +221,18 @@
/** {@inheritDoc} */
protected BridgeContext createBridgeContext() {
- BridgeContext ctx = new PDFBridgeContext(userAgent, graphics.getFontInfo());
- return ctx;
+ //For compatibility with Batik 1.6
+ return createBridgeContext("1.x");
}
+ /** {@inheritDoc} */
+ public BridgeContext createBridgeContext(String version) {
+ FontInfo fontInfo = graphics.getFontInfo();
+ if (isTextStroked()) {
+ fontInfo = null;
+ }
+ BridgeContext ctx = new PDFBridgeContext(userAgent, fontInfo);
+ return ctx;
+ }
+
}
Modified: xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/util/CharUtilities.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/util/CharUtilities.java?rev=593328&r1=593327&r2=593328&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/util/CharUtilities.java (original)
+++ xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/util/CharUtilities.java Thu Nov 8 13:27:19 2007
@@ -62,6 +62,8 @@
public static final char ZERO_WIDTH_SPACE = '\u200B';
/** word joiner */
public static final char WORD_JOINER = '\u2060';
+ /** zero-width joiner */
+ public static final char ZERO_WIDTH_JOINER = '\u200D';
/** zero-width no-break space (= byte order mark) */
public static final char ZERO_WIDTH_NOBREAK_SPACE = '\uFEFF';
/** soft hyphen */
Modified: xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/util/UnitConv.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/util/UnitConv.java?rev=593328&r1=593327&r2=593328&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/util/UnitConv.java (original)
+++ xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/java/org/apache/fop/util/UnitConv.java Thu Nov 8 13:27:19 2007
@@ -88,6 +88,15 @@
}
/**
+ * Converts inches (in) to points (pt)
+ * @param in the value in inches
+ * @return the value in pt
+ */
+ public static double in2pt(double in) {
+ return in * IN2PT;
+ }
+
+ /**
* Converts millipoints (mpt) to inches (in)
* @param mpt the value in mpt
* @return the value in inches
Modified: xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/sandbox/org/apache/fop/render/mif/MIFHandler.java
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/sandbox/org/apache/fop/render/mif/MIFHandler.java?rev=593328&r1=593327&r2=593328&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/sandbox/org/apache/fop/render/mif/MIFHandler.java (original)
+++ xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/src/sandbox/org/apache/fop/render/mif/MIFHandler.java Thu Nov 8 13:27:19 2007
@@ -32,17 +32,17 @@
import org.apache.fop.fo.flow.ExternalGraphic;
import org.apache.fop.fo.flow.Footnote;
import org.apache.fop.fo.flow.FootnoteBody;
-import org.apache.fop.fo.flow.InstreamForeignObject;
import org.apache.fop.fo.flow.Inline;
+import org.apache.fop.fo.flow.InstreamForeignObject;
import org.apache.fop.fo.flow.Leader;
import org.apache.fop.fo.flow.ListBlock;
import org.apache.fop.fo.flow.ListItem;
import org.apache.fop.fo.flow.PageNumber;
-import org.apache.fop.fo.flow.Table;
-import org.apache.fop.fo.flow.TableBody;
-import org.apache.fop.fo.flow.TableCell;
-import org.apache.fop.fo.flow.TableColumn;
-import org.apache.fop.fo.flow.TableRow;
+import org.apache.fop.fo.flow.table.Table;
+import org.apache.fop.fo.flow.table.TableBody;
+import org.apache.fop.fo.flow.table.TableCell;
+import org.apache.fop.fo.flow.table.TableColumn;
+import org.apache.fop.fo.flow.table.TableRow;
import org.apache.fop.fo.pagination.Flow;
import org.apache.fop.fo.pagination.PageSequence;
import org.apache.fop.fo.pagination.PageSequenceMaster;
Modified: xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/status.xml
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/status.xml?rev=593328&r1=593327&r2=593328&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/status.xml (original)
+++ xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/status.xml Thu Nov 8 13:27:19 2007
@@ -28,6 +28,63 @@
<changes>
<release version="FOP Trunk">
+ <action context="Code" dev="JM" type="fix">
+ Made the way TrueType fonts are embedded in PDF compliant to the
+ specification so viewers correctly identify subset fonts.
+ </action>
+ <action context="Code" dev="JM" type="fix">
+ Fixed font-autodetection so fonts with uppercase extensions are
+ detected, too.
+ </action>
+ <action context="Code" dev="JM" type="update">
+ Improved font auto-detection and handling of AWT-supplied fonts in order
+ to achieve better results when using multiple output formats. Whenever
+ possible, the font names appearing in the operating system can also
+ be used in XSL-FO.
+ </action>
+ <action context="Code" dev="JM" type="fix">
+ Fixed regression: transparent-page-background was not recognized for PNG output.
+ </action>
+ <action context="Code" dev="VH" type="add">
+ Added check for table-cells which span more rows than available in their parent element
+ (table-header/footer/body).
+ </action>
+ <action context="Code" dev="AD" type="add">
+ Added support for fo:markers in fo:inline and fo:basic-link.
+ </action>
+ <action context="Code" dev="JM" type="update">
+ PDF Transcoder (SVG) text painting has been completely rewritten.
+ Except for some special cases (with filters for example), all text
+ (including flow text) is now painted using PDF text operators.
+ </action>
+ <action context="Code" dev="AD" type="add" fixes-bug="42748">
+ Added support for ids on empty fo:inlines.
+ </action>
+ <action context="Code" dev="AC" type="add" fixes-bug="42982" due-to="Max Berger">
+ Add Font support in jar files.
+ </action>
+ <action context="Code" dev="AC" type="fix" fixes-bug="43042" due-to="Andrejus Chaliapinas">
+ Postscript extension cleanup.
+ </action>
+ <action context="Code" dev="AC" type="fix" fixes-bug="43587">
+ Fix to avoid ClassCastException where multiple ps:ps-comments are declared within fo:declarations.
+ </action>
+ <action context="Code" dev="AC" type="fix" fixes-bug="43143">
+ Fix to avoid NullPointerException when parsing ExpertEncoded and ExpertSubsetEncoded Type 1 fonts.
+ </action>
+ <action context="Code" dev="AC" type="fix" fixes-bug="43439">
+ Fixes missing TLE value attribute when using AreaTree input with the AFP renderer.
+ </action>
+ <action context="Code" dev="JM" type="add">
+ Added generic structures to the PDF library in order to support PDF
+ file in fo:external-graphic later.
+ </action>
+ <action context="Code" dev="JM" type="add" fixes-bug="43597" due-to="Max Berger">
+ Added support for SVGZ.
+ </action>
+ <action context="Code" dev="JM" type="fix">
+ Bugfix for NPE with empty table-row (regression from 0.93).
+ </action>
<action context="Code" dev="JM" type="add">
Added a configuration setting to the PCL renderer to disable PJL commands.
</action>
Modified: xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/test/fotree/testcases/column-number_cells_body.fo
URL: http://svn.apache.org/viewvc/xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/test/fotree/testcases/column-number_cells_body.fo?rev=593328&r1=593327&r2=593328&view=diff
==============================================================================
--- xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/test/fotree/testcases/column-number_cells_body.fo (original)
+++ xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/test/fotree/testcases/column-number_cells_body.fo Thu Nov 8 13:27:19 2007
@@ -1,162 +1,162 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<!--
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<!-- $Id$ -->
-<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
- xmlns:test="http://xmlgraphics.apache.org/fop/test">
- <fo:layout-master-set>
- <fo:simple-page-master master-name="normal" page-width="5in" page-height="2in"
- margin="20pt">
- <fo:region-body />
- </fo:simple-page-master>
- </fo:layout-master-set>
- <fo:page-sequence master-reference="normal">
- <fo:flow flow-name="xsl-region-body">
- <!-- table with explicit columns -->
- <fo:table table-layout="fixed" border-collapse="separate">
- <fo:table-column column-width="proportional-column-width(1)">
- <test:assert property="column-number" expected="1" />
- </fo:table-column>
- <fo:table-column column-width="proportional-column-width(2)">
- <test:assert property="column-number" expected="2" />
- </fo:table-column>
- <fo:table-column column-width="proportional-column-width(1)">
- <test:assert property="column-number" expected="3" />
- </fo:table-column>
- <fo:table-header>
- <fo:table-cell number-columns-spanned="3" starts-row="true" ends-row="true">
- <test:assert property="column-number" expected="1" />
- <fo:block>header cell</fo:block>
- </fo:table-cell>
- </fo:table-header>
- <fo:table-footer>
- <fo:table-cell starts-row="true">
- <test:assert property="column-number" expected="1" />
- <fo:block>footer cell 1</fo:block>
- </fo:table-cell>
- <fo:table-cell>
- <test:assert property="column-number" expected="2" />
- <fo:block>footer cell 2</fo:block>
- </fo:table-cell>
- <fo:table-cell ends-row="true">
- <test:assert property="column-number" expected="3" />
- <fo:block>footer cell 3</fo:block>
- </fo:table-cell>
- </fo:table-footer>
- <fo:table-body>
- <fo:table-cell number-columns-spanned="2" starts-row="true">
- <test:assert property="column-number" expected="1" />
- <fo:block>cell-content</fo:block>
- </fo:table-cell>
- <fo:table-cell>
- <test:assert property="column-number" expected="3" />
- <fo:block>cell-content</fo:block>
- </fo:table-cell>
- <fo:table-cell number-rows-spanned="2" starts-row="true">
- <test:assert property="column-number" expected="1" />
- <fo:block>cell-content</fo:block>
- </fo:table-cell>
- <fo:table-cell>
- <test:assert property="column-number" expected="2" />
- <fo:block>cell-content</fo:block>
- </fo:table-cell>
- <fo:table-cell ends-row="true">
- <test:assert property="column-number" expected="3" />
- <fo:block>cell-content</fo:block>
- </fo:table-cell>
- <fo:table-cell number-rows-spanned="2" starts-row="true">
- <test:assert property="column-number" expected="2" />
- <fo:block>cell-content</fo:block>
- </fo:table-cell>
- <fo:table-cell ends-row="true">
- <test:assert property="column-number" expected="3" />
- <fo:block>cell-content</fo:block>
- </fo:table-cell>
- <fo:table-cell starts-row="true">
- <test:assert property="column-number" expected="1" />
- <fo:block>cell-content</fo:block>
- </fo:table-cell>
- <fo:table-cell ends-row="true">
- <test:assert property="column-number" expected="3" />
- <fo:block>cell-content</fo:block>
- </fo:table-cell>
- </fo:table-body>
- </fo:table>
- <!-- table with implicit columns. -->
- <fo:table table-layout="fixed" border-collapse="separate">
- <fo:table-header>
- <fo:table-cell number-columns-spanned="3" starts-row="true" ends-row="true">
- <test:assert property="column-number" expected="1" />
- <fo:block>header cell</fo:block>
- </fo:table-cell>
- </fo:table-header>
- <fo:table-footer>
- <fo:table-cell starts-row="true">
- <test:assert property="column-number" expected="1" />
- <fo:block>footer cell 1</fo:block>
- </fo:table-cell>
- <fo:table-cell>
- <test:assert property="column-number" expected="2" />
- <fo:block>footer cell 2</fo:block>
- </fo:table-cell>
- <fo:table-cell ends-row="true">
- <test:assert property="column-number" expected="3" />
- <fo:block>footer cell 3</fo:block>
- </fo:table-cell>
- </fo:table-footer>
- <fo:table-body>
- <fo:table-cell number-columns-spanned="2" starts-row="true">
- <test:assert property="column-number" expected="1" />
- <fo:block>cell-content</fo:block>
- </fo:table-cell>
- <fo:table-cell ends-row="true">
- <test:assert property="column-number" expected="3" />
- <fo:block>cell-content</fo:block>
- </fo:table-cell>
- <fo:table-cell number-rows-spanned="2" starts-row="true">
- <test:assert property="column-number" expected="1" />
- <fo:block>cell-content</fo:block>
- </fo:table-cell>
- <fo:table-cell>
- <test:assert property="column-number" expected="2" />
- <fo:block>cell-content</fo:block>
- </fo:table-cell>
- <fo:table-cell ends-row="true">
- <test:assert property="column-number" expected="3" />
- <fo:block>cell-content</fo:block>
- </fo:table-cell>
- <fo:table-cell number-rows-spanned="2" starts-row="true">
- <test:assert property="column-number" expected="2" />
- <fo:block>cell-content</fo:block>
- </fo:table-cell>
- <fo:table-cell ends-row="true">
- <test:assert property="column-number" expected="3" />
- <fo:block>cell-content</fo:block>
- </fo:table-cell>
- <fo:table-cell starts-row="true">
- <test:assert property="column-number" expected="1" />
- <fo:block>cell-content</fo:block>
- </fo:table-cell>
- <fo:table-cell ends-row="true">
- <test:assert property="column-number" expected="3" />
- <fo:block>cell-content</fo:block>
- </fo:table-cell>
- </fo:table-body>
- </fo:table>
- </fo:flow>
- </fo:page-sequence>
-</fo:root>
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id$ -->
+<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"
+ xmlns:test="http://xmlgraphics.apache.org/fop/test">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="normal" page-width="5in" page-height="2in"
+ margin="20pt">
+ <fo:region-body />
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+ <fo:page-sequence master-reference="normal">
+ <fo:flow flow-name="xsl-region-body">
+ <!-- table with explicit columns -->
+ <fo:table table-layout="fixed" border-collapse="separate">
+ <fo:table-column column-width="proportional-column-width(1)">
+ <test:assert property="column-number" expected="1" />
+ </fo:table-column>
+ <fo:table-column column-width="proportional-column-width(2)">
+ <test:assert property="column-number" expected="2" />
+ </fo:table-column>
+ <fo:table-column column-width="proportional-column-width(1)">
+ <test:assert property="column-number" expected="3" />
+ </fo:table-column>
+ <fo:table-header>
+ <fo:table-cell number-columns-spanned="3" starts-row="true" ends-row="true">
+ <test:assert property="column-number" expected="1" />
+ <fo:block>header cell</fo:block>
+ </fo:table-cell>
+ </fo:table-header>
+ <fo:table-footer>
+ <fo:table-cell starts-row="true">
+ <test:assert property="column-number" expected="1" />
+ <fo:block>footer cell 1</fo:block>
+ </fo:table-cell>
+ <fo:table-cell>
+ <test:assert property="column-number" expected="2" />
+ <fo:block>footer cell 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell ends-row="true">
+ <test:assert property="column-number" expected="3" />
+ <fo:block>footer cell 3</fo:block>
+ </fo:table-cell>
+ </fo:table-footer>
+ <fo:table-body>
+ <fo:table-cell number-columns-spanned="2" starts-row="true">
+ <test:assert property="column-number" expected="1" />
+ <fo:block>cell-content</fo:block>
+ </fo:table-cell>
+ <fo:table-cell>
+ <test:assert property="column-number" expected="3" />
+ <fo:block>cell-content</fo:block>
+ </fo:table-cell>
+ <fo:table-cell number-rows-spanned="2" starts-row="true">
+ <test:assert property="column-number" expected="1" />
+ <fo:block>cell-content</fo:block>
+ </fo:table-cell>
+ <fo:table-cell>
+ <test:assert property="column-number" expected="2" />
+ <fo:block>cell-content</fo:block>
+ </fo:table-cell>
+ <fo:table-cell ends-row="true">
+ <test:assert property="column-number" expected="3" />
+ <fo:block>cell-content</fo:block>
+ </fo:table-cell>
+ <fo:table-cell number-rows-spanned="2" starts-row="true">
+ <test:assert property="column-number" expected="2" />
+ <fo:block>cell-content</fo:block>
+ </fo:table-cell>
+ <fo:table-cell ends-row="true">
+ <test:assert property="column-number" expected="3" />
+ <fo:block>cell-content</fo:block>
+ </fo:table-cell>
+ <fo:table-cell starts-row="true">
+ <test:assert property="column-number" expected="1" />
+ <fo:block>cell-content</fo:block>
+ </fo:table-cell>
+ <fo:table-cell ends-row="true">
+ <test:assert property="column-number" expected="3" />
+ <fo:block>cell-content</fo:block>
+ </fo:table-cell>
+ </fo:table-body>
+ </fo:table>
+ <!-- table with implicit columns. -->
+ <fo:table table-layout="fixed" border-collapse="separate">
+ <fo:table-header>
+ <fo:table-cell number-columns-spanned="3" starts-row="true" ends-row="true">
+ <test:assert property="column-number" expected="1" />
+ <fo:block>header cell</fo:block>
+ </fo:table-cell>
+ </fo:table-header>
+ <fo:table-footer>
+ <fo:table-cell starts-row="true">
+ <test:assert property="column-number" expected="1" />
+ <fo:block>footer cell 1</fo:block>
+ </fo:table-cell>
+ <fo:table-cell>
+ <test:assert property="column-number" expected="2" />
+ <fo:block>footer cell 2</fo:block>
+ </fo:table-cell>
+ <fo:table-cell ends-row="true">
+ <test:assert property="column-number" expected="3" />
+ <fo:block>footer cell 3</fo:block>
+ </fo:table-cell>
+ </fo:table-footer>
+ <fo:table-body>
+ <fo:table-cell number-columns-spanned="2" starts-row="true">
+ <test:assert property="column-number" expected="1" />
+ <fo:block>cell-content</fo:block>
+ </fo:table-cell>
+ <fo:table-cell ends-row="true">
+ <test:assert property="column-number" expected="3" />
+ <fo:block>cell-content</fo:block>
+ </fo:table-cell>
+ <fo:table-cell number-rows-spanned="2" starts-row="true">
+ <test:assert property="column-number" expected="1" />
+ <fo:block>cell-content</fo:block>
+ </fo:table-cell>
+ <fo:table-cell>
+ <test:assert property="column-number" expected="2" />
+ <fo:block>cell-content</fo:block>
+ </fo:table-cell>
+ <fo:table-cell ends-row="true">
+ <test:assert property="column-number" expected="3" />
+ <fo:block>cell-content</fo:block>
+ </fo:table-cell>
+ <fo:table-cell number-rows-spanned="2" starts-row="true">
+ <test:assert property="column-number" expected="2" />
+ <fo:block>cell-content</fo:block>
+ </fo:table-cell>
+ <fo:table-cell ends-row="true">
+ <test:assert property="column-number" expected="3" />
+ <fo:block>cell-content</fo:block>
+ </fo:table-cell>
+ <fo:table-cell starts-row="true">
+ <test:assert property="column-number" expected="1" />
+ <fo:block>cell-content</fo:block>
+ </fo:table-cell>
+ <fo:table-cell ends-row="true">
+ <test:assert property="column-number" expected="3" />
+ <fo:block>cell-content</fo:block>
+ </fo:table-cell>
+ </fo:table-body>
+ </fo:table>
+ </fo:flow>
+ </fo:page-sequence>
+</fo:root>
Propchange: xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/test/fotree/testcases/column-number_cells_body.fo
('svn:eol' removed)
Propchange: xmlgraphics/fop/branches/Temp_Interleaved_Page_Line_Breaking/test/fotree/testcases/column-number_cells_body.fo
------------------------------------------------------------------------------
svn:eol-style = native
---------------------------------------------------------------------
To unsubscribe, e-mail: fop-commits-unsubscribe@xmlgraphics.apache.org
For additional commands, e-mail: fop-commits-help@xmlgraphics.apache.org