aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/batik.jarbin2163538 -> 2265276 bytes
-rw-r--r--src/org/apache/fop/svg/PDFTextPainter.java180
-rw-r--r--src/org/apache/fop/svg/SVGUserAgent.java4
-rw-r--r--status.xml54
4 files changed, 160 insertions, 78 deletions
diff --git a/lib/batik.jar b/lib/batik.jar
index e4b5bb472..a68568266 100644
--- a/lib/batik.jar
+++ b/lib/batik.jar
Binary files differ
diff --git a/src/org/apache/fop/svg/PDFTextPainter.java b/src/org/apache/fop/svg/PDFTextPainter.java
index 6107cf208..d2be59f68 100644
--- a/src/org/apache/fop/svg/PDFTextPainter.java
+++ b/src/org/apache/fop/svg/PDFTextPainter.java
@@ -29,19 +29,33 @@ import org.apache.batik.gvt.*;
import org.apache.batik.gvt.text.*;
import org.apache.batik.gvt.renderer.*;
import org.apache.batik.gvt.font.*;
+import org.apache.batik.bridge.SVGFontFamily;
import org.apache.fop.layout.*;
/**
* Renders the attributed character iterator of a <tt>TextNode</tt>.
+ * This class draws the text directly into the PDFGraphics2D so that
+ * the text is not drawn using shapes which makes the PDF files larger.
+ * If the text is simple enough to draw then it sets the font and calls
+ * 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 {
FontInfo fontInfo;
- protected final static TextPainter proxyPainter
- = StrokingTextPainter.getInstance();
+
+ /**
+ * Use the stroking text painter to get the bounds and shape.
+ * Also used as a fallback to draw the string with strokes.
+ */
+ protected final static TextPainter proxyPainter =
+ StrokingTextPainter.getInstance();
public PDFTextPainter(FontInfo fi) {
fontInfo = fi;
@@ -60,7 +74,7 @@ public class PDFTextPainter implements TextPainter {
Point2D loc = node.getLocation();
AttributedCharacterIterator aci =
- node.getAttributedCharacterIterator();
+ node.getAttributedCharacterIterator();
// reset position to start of char iterator
if (aci.getBeginIndex() == aci.getEndIndex()) {
return;
@@ -69,32 +83,33 @@ public class PDFTextPainter implements TextPainter {
if (ch == AttributedCharacterIterator.DONE) {
return;
}
- TextNode.Anchor anchor =
- (TextNode.Anchor)aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.ANCHOR_TYPE);
-
- Vector gvtFonts =
- (Vector)aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.GVT_FONT_FAMILIES);
- Paint forg = (Paint)aci.getAttribute(TextAttribute.FOREGROUND);
- Paint strokePaint = (Paint)aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.STROKE_PAINT);
- Float size = (Float)aci.getAttribute(TextAttribute.SIZE);
- if(size == null) {
+ TextNode.Anchor anchor = (TextNode.Anchor) aci.getAttribute(
+ GVTAttributedCharacterIterator.TextAttribute.ANCHOR_TYPE);
+
+ Vector gvtFonts = (Vector) aci.getAttribute(
+ GVTAttributedCharacterIterator.TextAttribute.GVT_FONT_FAMILIES);
+ Paint forg = (Paint) aci.getAttribute(TextAttribute.FOREGROUND);
+ Paint strokePaint = (Paint) aci.getAttribute(
+ GVTAttributedCharacterIterator.TextAttribute.STROKE_PAINT);
+ Float size = (Float) aci.getAttribute(TextAttribute.SIZE);
+ if (size == null) {
return;
}
- Stroke stroke =
- (Stroke)aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.STROKE);
- Float xpos =
- (Float)aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.X);
- Float ypos =
- (Float)aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.Y);
+ Stroke stroke = (Stroke) aci.getAttribute(
+ GVTAttributedCharacterIterator.TextAttribute.STROKE);
+ 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);
+ Float posture = (Float) aci.getAttribute(TextAttribute.POSTURE);
+ Float taWeight = (Float) aci.getAttribute(TextAttribute.WEIGHT);
boolean useStrokePainter = false;
if (forg instanceof Color) {
- Color col = (Color)forg;
- if(col.getAlpha() != 255) {
+ Color col = (Color) forg;
+ if (col.getAlpha() != 255) {
useStrokePainter = true;
}
g2d.setColor(col);
@@ -102,31 +117,66 @@ public class PDFTextPainter implements TextPainter {
g2d.setPaint(forg);
g2d.setStroke(stroke);
- if(strokePaint != null) {
+ if (strokePaint != null) {
// need to draw using AttributedCharacterIterator
useStrokePainter = true;
}
- if(useStrokePainter) {
+ Object letSpace = aci.getAttribute(
+ GVTAttributedCharacterIterator.TextAttribute.LETTER_SPACING);
+ if (letSpace != null) {
+ useStrokePainter = true;
+ }
+
+ Object wordSpace = aci.getAttribute(
+ GVTAttributedCharacterIterator.TextAttribute.WORD_SPACING);
+ if (wordSpace != null) {
+ useStrokePainter = true;
+ }
+
+ Object writeMod = aci.getAttribute(
+ GVTAttributedCharacterIterator.TextAttribute.WRITING_MODE);
+ if (!GVTAttributedCharacterIterator.TextAttribute.WRITING_MODE_LTR.equals(
+ writeMod)) {
+ useStrokePainter = true;
+ }
+
+ Object vertOr = aci.getAttribute(
+ GVTAttributedCharacterIterator.TextAttribute.VERTICAL_ORIENTATION);
+ if (GVTAttributedCharacterIterator.TextAttribute.ORIENTATION_ANGLE.equals(
+ vertOr)) {
+ useStrokePainter = true;
+ }
+
+
+
+ if (useStrokePainter) {
proxyPainter.paint(node, g2d);
return;
}
- String style = ((posture != null) && (posture.floatValue() > 0.0))
- ? "italic" : "normal";
- int weight = ((taWeight != null) && (taWeight.floatValue() > 1.0))
- ? FontInfo.BOLD : FontInfo.NORMAL;
+ String style = ((posture != null) && (posture.floatValue() > 0.0)) ?
+ "italic" : "normal";
+ int weight = ((taWeight != null) &&
+ (taWeight.floatValue() > 1.0)) ? FontInfo.BOLD :
+ FontInfo.NORMAL;
FontState fontState = null;
FontInfo fi = fontInfo;
boolean found = false;
String fontFamily = null;
if (gvtFonts != null) {
- for (Enumeration e = gvtFonts.elements(); e.hasMoreElements(); ) {
- GVTFontFamily fam = (GVTFontFamily)e.nextElement();
+ for (Enumeration e = gvtFonts.elements();
+ e.hasMoreElements();) {
+ GVTFontFamily fam = (GVTFontFamily) e.nextElement();
+ if (fam instanceof SVGFontFamily) {
+ proxyPainter.paint(node, g2d);
+ return;
+ }
fontFamily = fam.getFamilyName();
if (fi.hasFont(fontFamily, style, weight)) {
- String fname = fontInfo.fontLookup(fontFamily, style, weight);
+ String fname = fontInfo.fontLookup(fontFamily, style,
+ weight);
FontMetric metrics = fontInfo.getMetricsFor(fname);
int fsize = (int)(size.floatValue() * 1000);
fontState = new FontState(fname, metrics, fsize);
@@ -136,13 +186,14 @@ public class PDFTextPainter implements TextPainter {
}
}
if (!found) {
- String fname = fontInfo.fontLookup("any", style, FontInfo.NORMAL);
+ String fname =
+ fontInfo.fontLookup("any", style, FontInfo.NORMAL);
FontMetric metrics = fontInfo.getMetricsFor(fname);
int fsize = (int)(size.floatValue() * 1000);
fontState = new FontState(fname, metrics, fsize);
} else {
- if(g2d instanceof PDFGraphics2D) {
- ((PDFGraphics2D)g2d).setOverrideFontState(fontState);
+ if (g2d instanceof PDFGraphics2D) {
+ ((PDFGraphics2D) g2d).setOverrideFontState(fontState);
}
}
int fStyle = Font.PLAIN;
@@ -168,11 +219,11 @@ public class PDFTextPainter implements TextPainter {
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;
+ case TextNode.Anchor.ANCHOR_MIDDLE:
+ tx = -advance / 2;
+ break;
+ case TextNode.Anchor.ANCHOR_END:
+ tx = -advance;
}
}
g2d.drawString(txt, (float)(loc.getX() + tx), (float)(loc.getY()));
@@ -197,13 +248,26 @@ public class PDFTextPainter implements TextPainter {
return wordWidth / 1000f;
}
+ public Shape getOutline(TextNode node) {
+ return proxyPainter.getOutline(node);
+ }
+
+ public Rectangle2D getBounds2D(TextNode node) {
+ return proxyPainter.getBounds2D(node);
+ }
+
+ public Rectangle2D getGeometryBounds(TextNode node) {
+ return proxyPainter.getGeometryBounds(node);
+ }
+
+ // Methods that have no purpose for PDF
+
public Mark getMark(TextNode node, int pos, boolean all) {
System.out.println("PDFText getMark");
return null;
}
- public Mark selectAt(double x, double y,
- TextNode node) {
+ public Mark selectAt(double x, double y, TextNode node) {
System.out.println("PDFText selectAt");
return null;
}
@@ -213,12 +277,6 @@ public class PDFTextPainter implements TextPainter {
return null;
}
- public Mark selectAll(double x, double y,
- TextNode node) {
- System.out.println("PDFText selectAll");
- return null;
- }
-
public Mark selectFirst(TextNode node) {
System.out.println("PDFText selectFirst");
return null;
@@ -229,8 +287,7 @@ public class PDFTextPainter implements TextPainter {
return null;
}
- public int[] getSelected(Mark start,
- Mark finish) {
+ public int[] getSelected(Mark start, Mark finish) {
System.out.println("PDFText getSelected");
return null;
}
@@ -240,30 +297,5 @@ public class PDFTextPainter implements TextPainter {
return null;
}
- public Shape getShape(TextNode node) {
- System.out.println("PDFText getShape");
- return proxyPainter.getShape(node);
- }
-
- public Shape getDecoratedShape(TextNode node) {
- //System.out.println("PDFText getDecoratedShape");
- return proxyPainter.getDecoratedShape(node);
- }
-
- public Rectangle2D getBounds(TextNode node) {
- //System.out.println("PDFText getBounds");
- return proxyPainter.getBounds(node);
- }
-
- public Rectangle2D getDecoratedBounds(TextNode node) {
- System.out.println("PDFText getDecoratedBounds");
- return proxyPainter.getDecoratedBounds(node);
- }
-
- public Rectangle2D getPaintedBounds(TextNode node) {
- // System.out.println("PDFText getPaintedBounds");
- return proxyPainter.getPaintedBounds(node);
- }
-
}
diff --git a/src/org/apache/fop/svg/SVGUserAgent.java b/src/org/apache/fop/svg/SVGUserAgent.java
index 899c4c089..f855338d4 100644
--- a/src/org/apache/fop/svg/SVGUserAgent.java
+++ b/src/org/apache/fop/svg/SVGUserAgent.java
@@ -79,10 +79,6 @@ public class SVGUserAgent extends UserAgentAdapter {
/**
* Returns a customized the pixel to mm factor.
*/
- public float getPixelToMM() {
- return userAgent.getPixelToMM();
- }
-
public float getPixelUnitToMillimter() {
return userAgent.getPixelToMM();
}
diff --git a/status.xml b/status.xml
index d25afa614..df9984fe8 100644
--- a/status.xml
+++ b/status.xml
@@ -42,11 +42,61 @@ inactive??
</action>
<action context="code" dev="open">
+ Add static areas to page
+ The static areas will need to be handled in a similar way to the flow
+ except the bpd is unlimited and it will need to reset and repeat for
+ each page.
+ </action>
+ <action context="code" dev="open">
+ Add id areas to page when area added.
+ When the layout managers add an area to the page it can also add the id
+ information.
+ </action>
+ <action context="code" dev="open">
+ Resolve id references on other pages, extensions.
+ When an id is added to a page this will allow id references to be
+ resolved.
+ </action>
+ <action context="code" dev="open">
+ Add markers to page when areas added.
+ When an area is added that is created by an FO that contains markers
+ then the markers can also be added. There are four types of positions
+ for markers.
+ </action>
+ <action context="code" dev="open">
+ Retrieve markers from page.
+ When doing the static areas the markers wil need to be available for
+ retrieving. The marker can then be layed out as normal.
+ </action>
+ <action context="code" dev="open">
+ Calculate line height.
+ The line height needs to be calculated while finding breaks. This needs
+ to include all the alignment and height details of the inline areas.
+ </action>
+ <action context="code" dev="open">
implement the caching mechanism to store pages
when a page contains a forward reference that has not been
resolved then we need to be able to save the page contents to
disk to save memory
</action>
+ <action context="code" dev="open">
+ Implement table layout.
+ The table layout will use the same technique as the block layout. It
+ will locate suitable breaks between rows or inside rows until table
+ finished or end of bpd reached.
+ </action>
+ <action context="code" dev="open">
+ Implement list layout.
+ The list layout like the table layout will be looking for suitable
+ breaks from the child objects. The it will add the appropriate areas to
+ the area tree.
+ </action>
+ <action context="code" dev="open">
+ Get bookmark extension working.
+ Make sure the extension id references are resolved. Once the data is
+ fully resolved then implement a way for the pdf renderer to add the
+ bookmarks. See branch for code how to add bookmarks.
+ </action>
</actions>
@@ -76,6 +126,10 @@ inactive??
<changes>
<release version="?" date="2002">
+ <action dev="KLL" type="update" context="code">
+ Updated batik with change to TextPainter interface and UserAgent.
+ Improved PDFTextPainter to handle more types of text.
+ </action>
<action dev="JM" type="update" context="code"
due-to="Stephen Wolke" due-to-email="smwolke@geistig.com">
Added a RunLengthEncode filter for the PostScript renderer.