import org.apache.fop.layout.*;
import org.apache.fop.image.*;
+import org.w3c.dom.*;
import org.w3c.dom.svg.*;
+import org.w3c.dom.css.*;
import org.w3c.dom.svg.SVGLength;
import org.apache.fop.dom.svg.*;
+ "Q\nBT\n");
}
- /**
- * add a line to the current stream
- *
- * @param x1 the start x location in millipoints
- * @param y1 the start y location in millipoints
- * @param x2 the end x location in millipoints
- * @param y2 the end y location in millipoints
- * @param th the thickness in millipoints
- * @param r the red component
- * @param g the green component
- * @param b the blue component
- */
- protected void addLine(float x1, float y1, float x2, float y2, DrawingInstruction di)
- {
- String str;
- str = "" + x1 + " " + y1 + " m "
- + x2 + " " + y2 + " l";
- if(di != null && di.fill)
- currentStream.add(str + " f\n"); // ??
- currentStream.add(str + " S\n");
- }
-
- protected void addCircle(float cx, float cy, float r, DrawingInstruction di)
- {
- String str;
- str = "" + cx + " " + (cy - r) + " m\n"
- + "" + (cx + 21 * r / 40f) + " " + (cy - r) + " " + (cx + r) + " " + (cy - 21 * r / 40f) + " " + (cx + r) + " " + cy + " c\n"
- + "" + (cx + r) + " " + (cy + 21 * r / 40f) + " " + (cx + 21 * r / 40f) + " " + (cy + r) + " " + cx + " " + (cy + r) + " c\n"
- + "" + (cx - 21 * r / 40f) + " " + (cy + r) + " " + (cx - r) + " " + (cy + 21 * r / 40f) + " " + (cx - r) + " " + cy + " c\n"
- + "" + (cx - r) + " " + (cy - 21 * r / 40f) + " " + (cx - 21 * r / 40f) + " " + (cy - r) + " " + cx + " " + (cy - r) + " c\n";
-
- currentStream.add(str);
- doDrawing(di);
- }
-
- protected void addEllipse(float cx, float cy, float rx, float ry, DrawingInstruction di)
- {
- String str;
- str = "" + cx + " " + (cy - ry) + " m\n"
- + "" + (cx + 21 * rx / 40f) + " " + (cy - ry) + " " + (cx + rx) + " " + (cy - 21 * ry / 40f) + " " + (cx + rx) + " " + cy + " c\n"
- + "" + (cx + rx) + " " + (cy + 21 * ry / 40f) + " " + (cx + 21 * rx / 40f) + " " + (cy + ry) + " " + cx + " " + (cy + ry) + " c\n"
- + "" + (cx - 21 * rx / 40f) + " " + (cy + ry) + " " + (cx - rx) + " " + (cy + 21 * ry / 40f) + " " + (cx - rx) + " " + cy + " c\n"
- + "" + (cx - rx) + " " + (cy - 21 * ry / 40f) + " " + (cx - 21 * rx / 40f) + " " + (cy - ry) + " " + cx + " " + (cy - ry) + " c\n";
- currentStream.add(str);
- doDrawing(di);
- }
-
- /**
- * add a filled rectangle to the current stream
- *
- * @param x the x position of left edge in millipoints
- * @param y the y position of top edge in millipoints
- * @param w the width in millipoints
- * @param h the height in millipoints
- * @param r the red component of edges
- * @param g the green component of edges
- * @param b the blue component of edges
- * @param fr the red component of the fill
- * @param fg the green component of the fill
- * @param fb the blue component of the fill
- */
- protected void addRect(float x, float y, float w, float h, float rx, float ry, DrawingInstruction di)
- {
- String str = "";
- if(rx == 0.0 && ry == 0.0) {
- str = "" + x + " " + y + " " + w + " " + h + " re\n";
- } else {
- str = "" + (x + rx) + " " + y + " m\n";
- str += "" + (x + w - rx) + " " + y + " l\n";
- str += "" + (x + w) + " " + y + " " + (x + w) + " " + y + " " + (x + w) + " " + (y + ry) + " c\n";
- str += "" + (x + w) + " " + (y + h - ry) + " l\n";
- str += "" + (x + w) + " " + (y + h) + " " + (x + w) + " " + (y + h) + " " + (x + w - rx) + " " + (y + h) + " c\n";
- str += "" + (x + rx) + " " + (y + h) + " l\n";
- str += "" + x + " " + (y + h) + " " + x + " " + (y + h) + " " + x + " " + (y + h - ry) + " c\n";
- str += "" + x + " " + (y + ry) + " l\n";
- str += "" + x + " " + y + " " + x + " " + y + " " + (x + rx) + " " + y + " c\n";
- }
- currentStream.add(str);
- doDrawing(di);
- }
-
/**
* add a rectangle to the current stream
*
+ "Q\nBT\n");
}
- protected void addPath(Vector points, int posx, int posy, DrawingInstruction di)
- {
- SVGPathSegImpl pathmoveto = null;
- float lastx = 0;
- float lasty = 0;
- for(Enumeration e = points.elements(); e.hasMoreElements(); ) {
- SVGPathSegImpl pc = (SVGPathSegImpl)e.nextElement();
- float[] vals = pc.getValues();
- float lastcx = 0;
- float lastcy = 0;
- switch(pc.getPathSegType()) {
- case SVGPathSeg.PATHSEG_MOVETO_ABS:
- pathmoveto = pc;
- lastx = vals[0];
- lasty = vals[1];
- currentStream.add(lastx + " " + lasty + " m\n");
- break;
- case SVGPathSeg.PATHSEG_MOVETO_REL:
- if(pathmoveto == null) {
- lastx = vals[0];
- lasty = vals[1];
- pathmoveto = pc;
- currentStream.add(lastx + " " + lasty + " m\n");
- } else {
- lastx += vals[0];
- lasty += vals[1];
- currentStream.add(lastx + " " + lasty + " l\n");
- }
- break;
- case SVGPathSeg.PATHSEG_LINETO_ABS:
- lastx = vals[0];
- lasty = vals[1];
- currentStream.add(lastx + " " + lasty + " l\n");
- break;
- case SVGPathSeg.PATHSEG_LINETO_REL:
- lastx += vals[0];
- lasty += vals[1];
- currentStream.add(lastx + " " + lasty + " l\n");
- break;
- case SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:
- lasty = vals[0];
- currentStream.add(lastx + " " + lasty + " l\n");
- break;
- case SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:
- lasty += vals[0];
- currentStream.add(lastx + " " + lasty + " l\n");
- break;
- case SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:
- lastx = vals[0];
- currentStream.add(lastx + " " + lasty + " l\n");
- break;
- case SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:
- lastx += vals[0];
- currentStream.add(lastx + " " + lasty + " l\n");
- break;
- case SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:
- lastx = vals[4];
- lasty = vals[5];
- lastcx = vals[2];
- lastcy = vals[3];
- currentStream.add((vals[0]) + " " + (vals[1]) + " " +
- (vals[2]) + " " + (vals[3]) + " " +
- lastx + " " + lasty +
- " c\n");
- break;
- case SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:
- currentStream.add((vals[0] + lastx) + " " + (vals[1] + lasty) + " " +
- (vals[2] + lastx) + " " + (vals[3] + lasty) + " " +
- (vals[4] + lastx) + " " + (vals[5] + lasty) +
- " c\n");
- lastcx = vals[2] + lastx;
- lastcy = vals[3] + lasty;
- lastx += vals[4];
- lasty += vals[5];
- break;
- case SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
- if(lastcx == 0) {
- lastcx = lastx;
- }
- if(lastcy == 0) {
- lastcy = lasty;
- }
- lastx = vals[2];
- lasty = vals[3];
- currentStream.add(lastcx + " " + lastcy + " " +
- (vals[0]) + " " + (vals[1]) + " " +
- lastx + " " + lasty +
- " c\n");
- break;
- case SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
- if(lastcx == 0) {
- lastcx = lastx;
- }
- if(lastcy == 0) {
- lastcy = lasty;
- }
- currentStream.add(lastcx + " " + lastcy + " " +
- (vals[0] + lastx) + " " + (vals[1] + lasty) + " " +
- (vals[2] + lastx) + " " + (vals[3] + lasty) +
- " c\n");
- lastx += vals[2];
- lasty += vals[3];
- break;
- case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:
- if(lastcx == 0) {
- lastcx = lastx;
- }
- if(lastcy == 0) {
- lastcy = lasty;
- }
- lastx = vals[0];
- lasty = vals[1];
- lastcx = 0;
- lastcy = 0;
- currentStream.add(lastcx + " " + lastcy + " " +
- lastx + " " + lasty +
- " y\n");
- break;
- case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:
- if(lastcx == 0) {
- lastcx = lastx;
- }
- if(lastcy == 0) {
- lastcy = lasty;
- }
- currentStream.add(lastcx + " " + lastcy + " " +
- (vals[0] + lastx) + " " + (vals[1] + lasty) +
- " y\n");
- lastcx = 0;
- lastcy = 0;
- lastx += vals[0];
- lasty += vals[1];
- break;
- // get angle between the two points
- // then get angle of points to centre (ie. both points are on the
- // apogee and perigee of the ellipse)
- // then work out the direction from flags
- case SVGPathSeg.PATHSEG_ARC_ABS:
- {
- double rx = vals[0];
- double ry = vals[1];
- double theta = vals[2];
- boolean largearcflag = (vals[3] == 1.0);
- boolean sweepflag = (vals[4] == 1.0);
-
- double angle = Math.atan((vals[6] - lasty) / (vals[5] - lastx));
- double relangle = Math.acos(rx / Math.sqrt((vals[6] - lasty) * (vals[6] - lasty) + (vals[5] - lastx) * (vals[5] - lastx)));
- double absangle = angle + relangle;
- // change sign depending on flags
- double contrx1;
- double contry1;
- double contrx2;
- double contry2;
- if(largearcflag) {
- if(sweepflag) {
- contrx1 = lastx - rx * Math.cos(absangle);
- contry1 = lasty + rx * Math.sin(absangle);
- contrx2 = vals[5] + ry * Math.cos(absangle);
- contry2 = vals[6] + ry * Math.sin(absangle);
- } else {
- contrx1 = lastx - rx * Math.cos(absangle);
- contry1 = lasty - rx * Math.sin(absangle);
- contrx2 = vals[5] + ry * Math.cos(absangle);
- contry2 = vals[6] - ry * Math.sin(absangle);
- }
- } else {
- if(sweepflag) {
- contrx1 = lastx + rx * Math.cos(absangle);
- contry1 = lasty + rx * Math.sin(absangle);
- contrx2 = contrx1;
- contry2 = contry1;
- } else {
- contrx1 = lastx + ry * Math.cos(absangle);
- contry1 = lasty - ry * Math.sin(absangle);
- contrx2 = contrx1;
- contry2 = contry1;
- }
- }
-
- double cx = lastx;
- double cy = lasty;
- currentStream.add(contrx1 + " " + contry1 + " " +
- contrx2 + " " + contry2 + " " +
- vals[5] + " " + vals[6] +
- " c\n");
- lastcx = 0; //??
- lastcy = 0; //??
- lastx = vals[5];
- lasty = vals[6];
- }
- break;
- case SVGPathSeg.PATHSEG_ARC_REL:
- {
- double rx = vals[0];
- double ry = vals[1];
- double theta = vals[2];
- boolean largearcflag = (vals[3] == 1.0);
- boolean sweepflag = (vals[4] == 1.0);
-
- double angle = Math.atan(vals[6] / vals[5]);
- double relangle = Math.atan(ry / rx);
-// System.out.println((theta * Math.PI / 180f) + ":" + relangle + ":" + largearcflag + ":" + sweepflag);
- double absangle = (theta * Math.PI / 180f);//angle + relangle;
- // change sign depending on flags
- double contrx1;
- double contry1;
- double contrx2;
- double contry2;
- if(largearcflag) {
- // in a large arc we need to do at least 2 and a bit
- // segments or curves.
- if(sweepflag) {
- contrx1 = lastx + rx * Math.cos(absangle);
- contry1 = lasty + rx * Math.sin(absangle);
- contrx2 = lastx + vals[5] + ry * Math.cos(absangle);
- contry2 = lasty + vals[6] - ry * Math.sin(absangle);
- } else {
- contrx1 = lastx + rx * Math.sin(absangle);
- contry1 = lasty + rx * Math.cos(absangle);
- contrx2 = lastx + vals[5] + ry * Math.cos(absangle);
- contry2 = lasty + vals[6] + ry * Math.sin(absangle);
- }
- } else {
- // only need at most two segments
- if(sweepflag) {
- contrx1 = lastx + rx * Math.cos(absangle);
- contry1 = lasty - rx * Math.sin(absangle);
- contrx2 = contrx1;
- contry2 = contry1;
- } else {
- contrx1 = lastx - ry * Math.cos(absangle);
- contry1 = lasty + ry * Math.sin(absangle);
- contrx2 = contrx1;
- contry2 = contry1;
- }
- }
- //System.out.println(contrx1 + ":" + contry1 + ":" + contrx2 + ":" + contry2);
-
- double cx = lastx;
- double cy = lasty;
- currentStream.add(contrx1 + " " + contry1 + " " +
- contrx2 + " " + contry2 + " " +
- (vals[5] + lastx) + " " + (vals[6] + lasty) +
- " c\n");
-
- lastcx = 0; //??
- lastcy = 0; //??
- lastx += vals[5];
- lasty += vals[6];
- }
- break;
- case SVGPathSeg.PATHSEG_CLOSEPATH:
- currentStream.add("h\n");
- break;
- }
- }
- doDrawing(di);
- }
-
- protected void addPolyline(Vector points, int posx, int posy, DrawingInstruction di, boolean close)
- {
- PathPoint pc;
- float lastx = 0;
- float lasty = 0;
- Enumeration e = points.elements();
- if(e.hasMoreElements()) {
- pc = (PathPoint)e.nextElement();
- lastx = pc.x;
- lasty = pc.y;
- currentStream.add(lastx + " " + lasty + " m\n");
- }
- while(e.hasMoreElements()) {
- pc = (PathPoint)e.nextElement();
- lastx = pc.x;
- lasty = pc.y;
- currentStream.add(lastx + " " + lasty + " l\n");
- }
- if(close)
- currentStream.add("h\n");
- doDrawing(di);
- }
-
- protected void doDrawing(DrawingInstruction di)
- {
- if(di == null) {
- currentStream.add("S\n");
- } else {
- if(di.fill) {
- if(di.stroke) {
- if(!di.nonzero)
- currentStream.add("B*\n");
- else
- currentStream.add("B\n");
- } else {
- if(!di.nonzero)
- currentStream.add("f*\n");
- else
- currentStream.add("f\n");
- }
- } else {
-// if(di.stroke)
- currentStream.add("S\n");
- }
- }
- }
-
- /**
- * render area container to PDF
- *
- * @param area the area container to render
- */
- public void renderAreaContainer(AreaContainer area) {
-
- int saveY = this.currentYPosition;
- int saveX = this.currentAreaContainerXPosition;
-
- if (area.getPosition() == Position.ABSOLUTE) {
- // Y position is computed assuming positive Y axis, adjust for negative postscript one
- this.currentYPosition = area.getYPosition() - 2 * area.getPaddingTop() - 2 * area.borderWidthTop;
- this.currentAreaContainerXPosition = area.getXPosition();
- } else if (area.getPosition() == Position.RELATIVE) {
- this.currentYPosition -= area.getYPosition();
- this.currentAreaContainerXPosition += area.getXPosition();
- } else if (area.getPosition() == Position.STATIC) {
- this.currentYPosition -= area.getPaddingTop() + area.borderWidthTop;
- this.currentAreaContainerXPosition += area.getPaddingLeft() + area.borderWidthLeft;
- }
+ /**
+ * render area container to PDF
+ *
+ * @param area the area container to render
+ */
+ public void renderAreaContainer(AreaContainer area) {
+
+ int saveY = this.currentYPosition;
+ int saveX = this.currentAreaContainerXPosition;
+
+ if (area.getPosition() == Position.ABSOLUTE) {
+ // Y position is computed assuming positive Y axis, adjust for negative postscript one
+ this.currentYPosition = area.getYPosition() - 2 * area.getPaddingTop() - 2 * area.borderWidthTop;
+ this.currentAreaContainerXPosition = area.getXPosition();
+ } else if (area.getPosition() == Position.RELATIVE) {
+ this.currentYPosition -= area.getYPosition();
+ this.currentAreaContainerXPosition += area.getXPosition();
+ } else if (area.getPosition() == Position.STATIC) {
+ this.currentYPosition -= area.getPaddingTop() + area.borderWidthTop;
+ this.currentAreaContainerXPosition += area.getPaddingLeft() + area.borderWidthLeft;
+ }
doFrame(area);
(((float) (y - h)) / 1000f) + " cm\n" +
"/Im" + xObjectNum + " Do\nQ\nBT\n");
}
-
- public void renderImage(String href, float x, float y, float width, float height)
- {
- try {
- if(href.indexOf(":") == -1) {
- href = "file:" + href;
- }
- FopImage img = FopImageFactory.Make(href);
- if(img != null) {
- int xObjectNum = this.pdfDoc.addImage(img);
- currentStream.add("q\n1 0 0 -1 " + 0
- + " " + (y + height) + " cm\n" + width + " 0 0 " +
- height + " " +
- x + " " +
- y + " cm\n" +
- "/Im" + xObjectNum + " Do\nQ\n");
-// img.close();
- }
- } catch(Exception e) {
- System.err.println("could not add image to SVG: " + href);
- }
- }
/** render a foreign object area */
public void renderForeignObjectArea(ForeignObjectArea area)
public void renderSVGArea(SVGArea area) {
int x = this.currentAreaContainerXPosition;
int y = this.currentYPosition;
- int w = area.getContentWidth();
- int h = area.getHeight();
+ SVGSVGElement svg = area.getSVGDocument().getRootElement();
+ int w = (int)(svg.getWidth().getBaseVal().getValue() * 1000);
+ int h = (int)(svg.getHeight().getBaseVal().getValue() * 1000);
/*
* Clip to the svg area.
// TODO - translate and clip to viewbox
- Enumeration e = area.getChildren().elements();
- while (e.hasMoreElements()) {
- Object o = e.nextElement();
- if(o instanceof GraphicImpl) {
- renderElement(area, (GraphicImpl)o, x, y);
- }
- }
+ renderSVG(area.getFontState(), svg, x, y);
currentStream.add("Q\n");
}
- void handleGradient(String sp, boolean fill, GraphicImpl area)
- {
- // should be a url to a gradient
- String url = (String)sp;
- if(url.startsWith("url(")) {
- String address;
- int b1 = url.indexOf("(");
- int b2 = url.indexOf(")");
- address = url.substring(b1 + 1, b2);
- address = address.trim();
- // local reference
- if(address.startsWith("#")) {
- // find the gradient element
- GraphicImpl gi = area.locateDef(address.substring(1, address.length()));
-// System.out.println(gi + ":" + address.substring(1, address.length()));
- if(gi instanceof SVGLinearGradientElement) {
- SVGLinearGradientElement linear = (SVGLinearGradientElement)gi;
+ /**
+ * render inline area to PDF
+ *
+ * @param area inline area to render
+ */
+ public void renderInlineArea(InlineArea area) {
+ char ch;
+ StringBuffer pdf = new StringBuffer();
+
+ String name = area.getFontState().getFontName();
+ int size = area.getFontState().getFontSize();
+
+ PDFColor theAreaColor = new PDFColor(
+ (double)area.getRed(),
+ (double)area.getGreen(),
+ (double)area.getBlue() );
+
+ if ((!name.equals(this.currentFontName))
+ || (size != this.currentFontSize)) {
+ this.currentFontName = name;
+ this.currentFontSize = size;
+ pdf = pdf.append("/" + name + " " + (size/1000) + " Tf\n");
+ }
- Vector theCoords = new Vector();
- theCoords.addElement(new Double(linear.getX1().getBaseVal().getValue()));
- theCoords.addElement(new Double(linear.getY1().getBaseVal().getValue()));
- theCoords.addElement(new Double(linear.getX2().getBaseVal().getValue()));
- theCoords.addElement(new Double(linear.getY2().getBaseVal().getValue()));
+ //if (theAreaColor.isEquivalent(this.currentFill)) {
+ this.currentFill = theAreaColor;
+
+ pdf = pdf.append(this.currentFill.getColorSpaceOut(true));
+ //}
+
+ int rx = this.currentXPosition;
+ int bl = this.currentYPosition;
- Vector theExtend = new Vector();
- theExtend.addElement(new Boolean(true));
- theExtend.addElement(new Boolean(true));
+ pdf = pdf.append("1 0 0 1 "
+ +(rx/1000f) + " " + (bl/1000f)
+ + " Tm (");
- Vector theDomain = new Vector();
- theDomain.addElement(new Double(0));
- theDomain.addElement(new Double(1));
+ String s;
+ if ( area.getPageNumberID()!=null ) { // this text is a page number, so resolve it
+ s = idReferences.getPageNumber(area.getPageNumberID());
+ if(s==null)
+ {
+ s="";
+ }
+ }
+ else {
+ s = area.getText();
+ }
+
+ int l = s.length();
+
+ for (int i=0; i < l; i++) {
+ ch = s.charAt(i);
+ if (ch > 127) {
+ pdf = pdf.append("\\");
+ pdf = pdf.append(Integer.toOctalString((int)ch));
+ } else {
+ switch (ch) {
+ case '(' : pdf = pdf.append("\\("); break;
+ case ')' : pdf = pdf.append("\\)"); break;
+ case '\\' : pdf = pdf.append("\\\\"); break;
+ default : pdf = pdf.append(ch); break;
+ }
+ }
+ }
+ pdf = pdf.append(") Tj\n");
+
+ currentStream.add(pdf.toString());
+
+ this.currentXPosition += area.getContentWidth();
+ }
+
+ /**
+ * render inline space to PDF
+ *
+ * @param space space to render
+ */
+ public void renderInlineSpace(InlineSpace space) {
+ this.currentXPosition += space.getSize();
+ }
+
+ /**
+ * render line area to PDF
+ *
+ * @param area area to render
+ */
+ public void renderLineArea(LineArea area) {
+ int rx = this.currentAreaContainerXPosition
+ + area.getStartIndent();
+ int ry = this.currentYPosition;
+ int w = area.getContentWidth();
+ int h = area.getHeight();
+
+ this.currentYPosition -= area.getPlacementOffset();
+ this.currentXPosition = rx;
+
+ int bl = this.currentYPosition;
+
+ Enumeration e = area.getChildren().elements();
+ while (e.hasMoreElements()) {
+ Box b = (Box) e.nextElement();
+ b.render(this);
+ }
+
+ this.currentYPosition = ry-h;
+ }
+
+ /**
+ * render page into PDF
+ *
+ * @param page page to render
+ */
+ public void renderPage(Page page) {
+ AreaContainer body, before, after;
+
+ currentStream = this.pdfDoc.makeStream();
+ body = page.getBody();
+ before = page.getBefore();
+ after = page.getAfter();
+
+ this.currentFontName = "";
+ this.currentFontSize = 0;
+
+ currentStream.add("BT\n");
+ renderAreaContainer(body);
+
+ if (before != null) {
+ renderAreaContainer(before);
+ }
+
+ if (after != null) {
+ renderAreaContainer(after);
+ }
+
+ currentStream.add("ET\n");
+
+ currentPage = this.pdfDoc.makePage(this.pdfResources, currentStream,
+ page.getWidth()/1000,
+ page.getHeight()/1000, page);
+
+ if (page.hasLinks()) {
+ currentAnnotList = this.pdfDoc.makeAnnotList();
+ currentPage.setAnnotList(currentAnnotList);
+
+ Enumeration e = page.getLinkSets().elements();
+ while (e.hasMoreElements()) {
+ LinkSet linkSet = (LinkSet) e.nextElement();
+
+ linkSet.align();
+ String dest = linkSet.getDest();
+ int linkType = linkSet.getLinkType();
+ Enumeration f = linkSet.getRects().elements();
+ while (f.hasMoreElements()) {
+ LinkedRectangle lrect = (LinkedRectangle) f.nextElement();
+ currentAnnotList.addLink(
+ this.pdfDoc.makeLink(lrect.getRectangle(), dest, linkType));
+ }
+ }
+ } else {
+ // just to be on the safe side
+ currentAnnotList = null;
+ }
+ }
+
+ /**
+ * render rule area into PDF
+ *
+ * @param area area to render
+ */
+ public void renderRuleArea(RuleArea area) {
+ int rx = this.currentAreaContainerXPosition
+ + area.getStartIndent();
+ int ry = this.currentYPosition;
+ int w = area.getContentWidth();
+ int h = area.getHeight();
+ int th = area.getRuleThickness();
+
+ addLine(rx, ry, rx+w, ry, th, new PDFColor(area.getRed(), area.getGreen(),area.getBlue()));
+ }
+
+ /**
+ * set up the font info
+ *
+ * @param fontInfo font info to set up
+ */
+ public void setupFontInfo(FontInfo fontInfo) {
+ FontSetup.setup(fontInfo);
+ FontSetup.addToResources(this.pdfDoc, fontInfo);
+ }
+
+ // SVG Stuff
+
+ public void renderGArea(FontState fontState, SVGGElement area, int posx, int posy)
+ {
+ NodeList nl = area.getChildNodes();
+ for(int count = 0; count < nl.getLength(); count++) {
+ Node n = nl.item(count);
+ if(n instanceof SVGElement) {
+ renderElement(fontState, (SVGElement)n, posx, posy);
+ }
+ }
+ }
+
+ void handleSwitchElement(FontState fontState, int posx, int posy, SVGSwitchElement ael)
+ {
+ SVGList relist = ael.getRequiredExtensions();
+ SVGList rflist = ael.getRequiredFeatures();
+ SVGList sllist = ael.getSystemLanguage();
+ org.w3c.dom.NodeList nl = ael.getChildNodes();
+ for(int count = 0; count < nl.getLength(); count++) {
+ org.w3c.dom.Node n = nl.item(count);
+ // only render the first child that has a valid
+ // test data
+ if(n instanceof GraphicElement) {
+ GraphicElement graphic = (GraphicElement)n;
+ SVGList grelist = graphic.getRequiredExtensions();
+ // if null it evaluates to true
+ if(grelist != null) {
+ for(int i = 0; i < grelist.getNumberOfItems(); i++) {
+ String str = (String)grelist.getItem(i);
+ if(relist == null) {
+ // use default extension set
+ // currently no extensions are supported
+// if(!(str.equals("http:// ??"))) {
+ continue;
+// }
+ } else {
+ }
+ }
+ }
+ SVGList grflist = graphic.getRequiredFeatures();
+ if(grflist != null) {
+ for(int i = 0; i < grflist.getNumberOfItems(); i++) {
+ String str = (String)grflist.getItem(i);
+ if(rflist == null) {
+ // use default feature set
+ if(!(str.equals("org.w3c.svg.static")
+ || str.equals("org.w3c.dom.svg.all"))) {
+ continue;
+ }
+ } else {
+ boolean found = false;
+ for(int j = 0; j < rflist.getNumberOfItems(); j++) {
+ if(rflist.getItem(j).equals(str)) {
+ found = true;
+ break;
+ }
+ }
+ if(!found)
+ continue;
+ }
+ }
+ }
+ SVGList gsllist = graphic.getSystemLanguage();
+ if(gsllist != null) {
+ for(int i = 0; i < gsllist.getNumberOfItems(); i++) {
+ String str = (String)gsllist.getItem(i);
+ if(sllist == null) {
+ // use default feature set
+ if(!(str.equals("en"))) {
+ continue;
+ }
+ } else {
+ boolean found = false;
+ for(int j = 0; j < sllist.getNumberOfItems(); j++) {
+ if(sllist.getItem(j).equals(str)) {
+ found = true;
+ break;
+ }
+ }
+ if(!found)
+ continue;
+ }
+ }
+ }
+ renderElement(fontState, (SVGElement)n, posx, posy);
+ // only render the first valid one
+ break;
+ }
+ }
+ }
+
+ /**
+ * add a line to the current stream
+ *
+ * @param x1 the start x location in millipoints
+ * @param y1 the start y location in millipoints
+ * @param x2 the end x location in millipoints
+ * @param y2 the end y location in millipoints
+ * @param th the thickness in millipoints
+ * @param r the red component
+ * @param g the green component
+ * @param b the blue component
+ */
+ protected void addLine(float x1, float y1, float x2, float y2, DrawingInstruction di)
+ {
+ String str;
+ str = "" + x1 + " " + y1 + " m "
+ + x2 + " " + y2 + " l";
+ if(di != null && di.fill)
+ currentStream.add(str + " f\n"); // ??
+ currentStream.add(str + " S\n");
+ }
+
+ protected void addCircle(float cx, float cy, float r, DrawingInstruction di)
+ {
+ String str;
+ str = "" + cx + " " + (cy - r) + " m\n"
+ + "" + (cx + 21 * r / 40f) + " " + (cy - r) + " " + (cx + r) + " " + (cy - 21 * r / 40f) + " " + (cx + r) + " " + cy + " c\n"
+ + "" + (cx + r) + " " + (cy + 21 * r / 40f) + " " + (cx + 21 * r / 40f) + " " + (cy + r) + " " + cx + " " + (cy + r) + " c\n"
+ + "" + (cx - 21 * r / 40f) + " " + (cy + r) + " " + (cx - r) + " " + (cy + 21 * r / 40f) + " " + (cx - r) + " " + cy + " c\n"
+ + "" + (cx - r) + " " + (cy - 21 * r / 40f) + " " + (cx - 21 * r / 40f) + " " + (cy - r) + " " + cx + " " + (cy - r) + " c\n";
+
+ currentStream.add(str);
+ doDrawing(di);
+ }
+
+ protected void addEllipse(float cx, float cy, float rx, float ry, DrawingInstruction di)
+ {
+ String str;
+ str = "" + cx + " " + (cy - ry) + " m\n"
+ + "" + (cx + 21 * rx / 40f) + " " + (cy - ry) + " " + (cx + rx) + " " + (cy - 21 * ry / 40f) + " " + (cx + rx) + " " + cy + " c\n"
+ + "" + (cx + rx) + " " + (cy + 21 * ry / 40f) + " " + (cx + 21 * rx / 40f) + " " + (cy + ry) + " " + cx + " " + (cy + ry) + " c\n"
+ + "" + (cx - 21 * rx / 40f) + " " + (cy + ry) + " " + (cx - rx) + " " + (cy + 21 * ry / 40f) + " " + (cx - rx) + " " + cy + " c\n"
+ + "" + (cx - rx) + " " + (cy - 21 * ry / 40f) + " " + (cx - 21 * rx / 40f) + " " + (cy - ry) + " " + cx + " " + (cy - ry) + " c\n";
+ currentStream.add(str);
+ doDrawing(di);
+ }
+
+ /**
+ * add a filled rectangle to the current stream
+ *
+ * @param x the x position of left edge in millipoints
+ * @param y the y position of top edge in millipoints
+ * @param w the width in millipoints
+ * @param h the height in millipoints
+ * @param r the red component of edges
+ * @param g the green component of edges
+ * @param b the blue component of edges
+ * @param fr the red component of the fill
+ * @param fg the green component of the fill
+ * @param fb the blue component of the fill
+ */
+ protected void addRect(float x, float y, float w, float h, float rx, float ry, DrawingInstruction di)
+ {
+ String str = "";
+ if(rx == 0.0 && ry == 0.0) {
+ str = "" + x + " " + y + " " + w + " " + h + " re\n";
+ } else {
+ str = "" + (x + rx) + " " + y + " m\n";
+ str += "" + (x + w - rx) + " " + y + " l\n";
+ str += "" + (x + w) + " " + y + " " + (x + w) + " " + y + " " + (x + w) + " " + (y + ry) + " c\n";
+ str += "" + (x + w) + " " + (y + h - ry) + " l\n";
+ str += "" + (x + w) + " " + (y + h) + " " + (x + w) + " " + (y + h) + " " + (x + w - rx) + " " + (y + h) + " c\n";
+ str += "" + (x + rx) + " " + (y + h) + " l\n";
+ str += "" + x + " " + (y + h) + " " + x + " " + (y + h) + " " + x + " " + (y + h - ry) + " c\n";
+ str += "" + x + " " + (y + ry) + " l\n";
+ str += "" + x + " " + y + " " + x + " " + y + " " + (x + rx) + " " + y + " c\n";
+ }
+ currentStream.add(str);
+ doDrawing(di);
+ }
+
+ protected void addPath(Vector points, int posx, int posy, DrawingInstruction di)
+ {
+ SVGPathSegImpl pathmoveto = null;
+ float lastx = 0;
+ float lasty = 0;
+ for(Enumeration e = points.elements(); e.hasMoreElements(); ) {
+ SVGPathSegImpl pc = (SVGPathSegImpl)e.nextElement();
+ float[] vals = pc.getValues();
+ float lastcx = 0;
+ float lastcy = 0;
+ switch(pc.getPathSegType()) {
+ case SVGPathSeg.PATHSEG_MOVETO_ABS:
+ pathmoveto = pc;
+ lastx = vals[0];
+ lasty = vals[1];
+ currentStream.add(lastx + " " + lasty + " m\n");
+ break;
+ case SVGPathSeg.PATHSEG_MOVETO_REL:
+ if(pathmoveto == null) {
+ lastx = vals[0];
+ lasty = vals[1];
+ pathmoveto = pc;
+ currentStream.add(lastx + " " + lasty + " m\n");
+ } else {
+ lastx += vals[0];
+ lasty += vals[1];
+ currentStream.add(lastx + " " + lasty + " l\n");
+ }
+ break;
+ case SVGPathSeg.PATHSEG_LINETO_ABS:
+ lastx = vals[0];
+ lasty = vals[1];
+ currentStream.add(lastx + " " + lasty + " l\n");
+ break;
+ case SVGPathSeg.PATHSEG_LINETO_REL:
+ lastx += vals[0];
+ lasty += vals[1];
+ currentStream.add(lastx + " " + lasty + " l\n");
+ break;
+ case SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:
+ lasty = vals[0];
+ currentStream.add(lastx + " " + lasty + " l\n");
+ break;
+ case SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:
+ lasty += vals[0];
+ currentStream.add(lastx + " " + lasty + " l\n");
+ break;
+ case SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:
+ lastx = vals[0];
+ currentStream.add(lastx + " " + lasty + " l\n");
+ break;
+ case SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:
+ lastx += vals[0];
+ currentStream.add(lastx + " " + lasty + " l\n");
+ break;
+ case SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:
+ lastx = vals[4];
+ lasty = vals[5];
+ lastcx = vals[2];
+ lastcy = vals[3];
+ currentStream.add((vals[0]) + " " + (vals[1]) + " " +
+ (vals[2]) + " " + (vals[3]) + " " +
+ lastx + " " + lasty +
+ " c\n");
+ break;
+ case SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:
+ currentStream.add((vals[0] + lastx) + " " + (vals[1] + lasty) + " " +
+ (vals[2] + lastx) + " " + (vals[3] + lasty) + " " +
+ (vals[4] + lastx) + " " + (vals[5] + lasty) +
+ " c\n");
+ lastcx = vals[2] + lastx;
+ lastcy = vals[3] + lasty;
+ lastx += vals[4];
+ lasty += vals[5];
+ break;
+ case SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
+ if(lastcx == 0) {
+ lastcx = lastx;
+ }
+ if(lastcy == 0) {
+ lastcy = lasty;
+ }
+ lastx = vals[2];
+ lasty = vals[3];
+ currentStream.add(lastcx + " " + lastcy + " " +
+ (vals[0]) + " " + (vals[1]) + " " +
+ lastx + " " + lasty +
+ " c\n");
+ break;
+ case SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
+ if(lastcx == 0) {
+ lastcx = lastx;
+ }
+ if(lastcy == 0) {
+ lastcy = lasty;
+ }
+ currentStream.add(lastcx + " " + lastcy + " " +
+ (vals[0] + lastx) + " " + (vals[1] + lasty) + " " +
+ (vals[2] + lastx) + " " + (vals[3] + lasty) +
+ " c\n");
+ lastx += vals[2];
+ lasty += vals[3];
+ break;
+ case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:
+ if(lastcx == 0) {
+ lastcx = lastx;
+ }
+ if(lastcy == 0) {
+ lastcy = lasty;
+ }
+ lastx = vals[0];
+ lasty = vals[1];
+ lastcx = 0;
+ lastcy = 0;
+ currentStream.add(lastcx + " " + lastcy + " " +
+ lastx + " " + lasty +
+ " y\n");
+ break;
+ case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:
+ if(lastcx == 0) {
+ lastcx = lastx;
+ }
+ if(lastcy == 0) {
+ lastcy = lasty;
+ }
+ currentStream.add(lastcx + " " + lastcy + " " +
+ (vals[0] + lastx) + " " + (vals[1] + lasty) +
+ " y\n");
+ lastcx = 0;
+ lastcy = 0;
+ lastx += vals[0];
+ lasty += vals[1];
+ break;
+ // get angle between the two points
+ // then get angle of points to centre (ie. both points are on the
+ // apogee and perigee of the ellipse)
+ // then work out the direction from flags
+ case SVGPathSeg.PATHSEG_ARC_ABS:
+ {
+ double rx = vals[0];
+ double ry = vals[1];
+ double theta = vals[2];
+ boolean largearcflag = (vals[3] == 1.0);
+ boolean sweepflag = (vals[4] == 1.0);
+
+ double angle = Math.atan((vals[6] - lasty) / (vals[5] - lastx));
+ double relangle = Math.acos(rx / Math.sqrt((vals[6] - lasty) * (vals[6] - lasty) + (vals[5] - lastx) * (vals[5] - lastx)));
+ double absangle = angle + relangle;
+ // change sign depending on flags
+ double contrx1;
+ double contry1;
+ double contrx2;
+ double contry2;
+ if(largearcflag) {
+ if(sweepflag) {
+ contrx1 = lastx - rx * Math.cos(absangle);
+ contry1 = lasty + rx * Math.sin(absangle);
+ contrx2 = vals[5] + ry * Math.cos(absangle);
+ contry2 = vals[6] + ry * Math.sin(absangle);
+ } else {
+ contrx1 = lastx - rx * Math.cos(absangle);
+ contry1 = lasty - rx * Math.sin(absangle);
+ contrx2 = vals[5] + ry * Math.cos(absangle);
+ contry2 = vals[6] - ry * Math.sin(absangle);
+ }
+ } else {
+ if(sweepflag) {
+ contrx1 = lastx + rx * Math.cos(absangle);
+ contry1 = lasty + rx * Math.sin(absangle);
+ contrx2 = contrx1;
+ contry2 = contry1;
+ } else {
+ contrx1 = lastx + ry * Math.cos(absangle);
+ contry1 = lasty - ry * Math.sin(absangle);
+ contrx2 = contrx1;
+ contry2 = contry1;
+ }
+ }
+
+ double cx = lastx;
+ double cy = lasty;
+ currentStream.add(contrx1 + " " + contry1 + " " +
+ contrx2 + " " + contry2 + " " +
+ vals[5] + " " + vals[6] +
+ " c\n");
+ lastcx = 0; //??
+ lastcy = 0; //??
+ lastx = vals[5];
+ lasty = vals[6];
+ }
+ break;
+ case SVGPathSeg.PATHSEG_ARC_REL:
+ {
+ double rx = vals[0];
+ double ry = vals[1];
+ double theta = vals[2];
+ boolean largearcflag = (vals[3] == 1.0);
+ boolean sweepflag = (vals[4] == 1.0);
+
+ double angle = Math.atan(vals[6] / vals[5]);
+ double relangle = Math.atan(ry / rx);
+// System.out.println((theta * Math.PI / 180f) + ":" + relangle + ":" + largearcflag + ":" + sweepflag);
+ double absangle = (theta * Math.PI / 180f);//angle + relangle;
+ // change sign depending on flags
+ double contrx1;
+ double contry1;
+ double contrx2;
+ double contry2;
+ if(largearcflag) {
+ // in a large arc we need to do at least 2 and a bit
+ // segments or curves.
+ if(sweepflag) {
+ contrx1 = lastx + rx * Math.cos(absangle);
+ contry1 = lasty + rx * Math.sin(absangle);
+ contrx2 = lastx + vals[5] + ry * Math.cos(absangle);
+ contry2 = lasty + vals[6] - ry * Math.sin(absangle);
+ } else {
+ contrx1 = lastx + rx * Math.sin(absangle);
+ contry1 = lasty + rx * Math.cos(absangle);
+ contrx2 = lastx + vals[5] + ry * Math.cos(absangle);
+ contry2 = lasty + vals[6] + ry * Math.sin(absangle);
+ }
+ } else {
+ // only need at most two segments
+ if(sweepflag) {
+ contrx1 = lastx + rx * Math.cos(absangle);
+ contry1 = lasty - rx * Math.sin(absangle);
+ contrx2 = contrx1;
+ contry2 = contry1;
+ } else {
+ contrx1 = lastx - ry * Math.cos(absangle);
+ contry1 = lasty + ry * Math.sin(absangle);
+ contrx2 = contrx1;
+ contry2 = contry1;
+ }
+ }
+ //System.out.println(contrx1 + ":" + contry1 + ":" + contrx2 + ":" + contry2);
+
+ double cx = lastx;
+ double cy = lasty;
+ currentStream.add(contrx1 + " " + contry1 + " " +
+ contrx2 + " " + contry2 + " " +
+ (vals[5] + lastx) + " " + (vals[6] + lasty) +
+ " c\n");
+
+ lastcx = 0; //??
+ lastcy = 0; //??
+ lastx += vals[5];
+ lasty += vals[6];
+ }
+ break;
+ case SVGPathSeg.PATHSEG_CLOSEPATH:
+ currentStream.add("h\n");
+ break;
+ }
+ }
+ doDrawing(di);
+ }
+
+ protected void addPolyline(Vector points, int posx, int posy, DrawingInstruction di, boolean close)
+ {
+ PathPoint pc;
+ float lastx = 0;
+ float lasty = 0;
+ Enumeration e = points.elements();
+ if(e.hasMoreElements()) {
+ pc = (PathPoint)e.nextElement();
+ lastx = pc.x;
+ lasty = pc.y;
+ currentStream.add(lastx + " " + lasty + " m\n");
+ }
+ while(e.hasMoreElements()) {
+ pc = (PathPoint)e.nextElement();
+ lastx = pc.x;
+ lasty = pc.y;
+ currentStream.add(lastx + " " + lasty + " l\n");
+ }
+ if(close)
+ currentStream.add("h\n");
+ doDrawing(di);
+ }
+
+ protected void doDrawing(DrawingInstruction di)
+ {
+ if(di == null) {
+ currentStream.add("S\n");
+ } else {
+ if(di.fill) {
+ if(di.stroke) {
+ if(!di.nonzero)
+ currentStream.add("B*\n");
+ else
+ currentStream.add("B\n");
+ } else {
+ if(!di.nonzero)
+ currentStream.add("f*\n");
+ else
+ currentStream.add("f\n");
+ }
+ } else {
+// if(di.stroke)
+ currentStream.add("S\n");
+ }
+ }
+ }
+
+ public void renderImage(FontState fontState, String href, float x, float y, float width, float height)
+ {
+ try {
+ if(href.indexOf(":") == -1) {
+ href = "file:" + href;
+ }
+ FopImage img = FopImageFactory.Make(href);
+ if(img instanceof SVGImage) {
+ SVGSVGElement svg = ((SVGImage)img).getSVGDocument().getRootElement();
+ currentStream.add("q\n" + width / svg.getWidth().getBaseVal().getValue() + " 0 0 " + height / svg.getHeight().getBaseVal().getValue() + " 0 0 cm\n");
+ renderSVG(fontState, svg, (int)x * 1000, (int)y * 1000);
+ currentStream.add("Q\n");
+// renderSVG(svg);
+ } else if(img != null) {
+ int xObjectNum = this.pdfDoc.addImage(img);
+ currentStream.add("q\n1 0 0 -1 " + 0
+ + " " + (2 * y + height) + " cm\n" + width + " 0 0 " +
+ height + " " +
+ x + " " +
+ y + " cm\n" +
+ "/Im" + xObjectNum + " Do\nQ\n");
+// img.close();
+ }
+ } catch(Exception e) {
+e.printStackTrace();
+ System.err.println("could not add image to SVG: " + href);
+ }
+ }
+
+ void renderSVG(FontState fontState, SVGSVGElement svg, int x, int y)
+ {
+ NodeList nl = svg.getChildNodes();
+ for(int count = 0; count < nl.getLength(); count++) {
+ Node n = nl.item(count);
+ if(n instanceof SVGElement) {
+ renderElement(fontState, (SVGElement)n, x, y);
+ }
+ }
+ }
+
+ void handleGradient(String sp, boolean fill, SVGElement area)
+ {
+ // should be a url to a gradient
+ String url = (String)sp;
+ if(url.startsWith("url(")) {
+ String address;
+ int b1 = url.indexOf("(");
+ int b2 = url.indexOf(")");
+ address = url.substring(b1 + 1, b2);
+ address = address.trim();
+ // local reference
+ if(address.startsWith("#")) {
+ // find the gradient element
+ SVGElement gi = null;
+// gi = area.locateDef(address.substring(1, address.length()));
+// System.out.println(gi + ":" + address.substring(1, address.length()));
+ if(gi instanceof SVGLinearGradientElement) {
+ SVGLinearGradientElement linear = (SVGLinearGradientElement)gi;
+
+ Vector theCoords = new Vector();
+ theCoords.addElement(new Double(linear.getX1().getBaseVal().getValue()));
+ theCoords.addElement(new Double(linear.getY1().getBaseVal().getValue()));
+ theCoords.addElement(new Double(linear.getX2().getBaseVal().getValue()));
+ theCoords.addElement(new Double(linear.getY2().getBaseVal().getValue()));
+
+ Vector theExtend = new Vector();
+ theExtend.addElement(new Boolean(true));
+ theExtend.addElement(new Boolean(true));
+
+ Vector theDomain = new Vector();
+ theDomain.addElement(new Double(0));
+ theDomain.addElement(new Double(1));
Vector theEncode = new Vector();
theEncode.addElement(new Double(0));
Vector theFunctions = new Vector();
- org.w3c.dom.NodeList nl = linear.getChildNodes();
+ NodeList nl = linear.getChildNodes();
Vector someColors = new Vector();
float lastoffset = 0;
Vector lastVector = null;
SVGStopElementImpl stop;
- Hashtable table;
+ Hashtable table = null;
for(int count = 0; count < nl.getLength(); count++) {
stop = (SVGStopElementImpl)nl.item(count);
- table = stop.oldgetStyle();
+// table = stop.oldgetStyle();
ColorType sc = (ColorType)table.get("stop-color");
if(sc == null) {
// maybe using color
ColorSpace aColorSpace = new ColorSpace(ColorSpace.DEVICE_RGB);
org.w3c.dom.NodeList nl = radial.getChildNodes();
SVGStopElementImpl stop;
- Hashtable table;
+ Hashtable table = null;
Vector someColors = new Vector();
Vector theCoords = new Vector();
Vector theBounds = new Vector();
float lastoffset = 0;
for(int count = 0; count < nl.getLength(); count++) {
stop = (SVGStopElementImpl)nl.item(count);
- table = stop.oldgetStyle();
+// table = stop.oldgetStyle();
ColorType sc = (ColorType)table.get("stop-color");
if(sc == null) {
// maybe using color
int linejoin = 0; // miter
int miterwidth = 8;
}
- protected DrawingInstruction applyStyle(GraphicImpl area, Hashtable style)
+ protected DrawingInstruction applyStyle(SVGElement area, CSSStyleDeclaration style)
{
DrawingInstruction di = new DrawingInstruction();
- Object sp;
- sp = style.get("fill");
+ CSSValue sp;
+ sp = style.getPropertyCSSValue("fill");
if(sp != null) {
- di.fill = true;
- if(sp instanceof ColorType) {
+ if(sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+ if(((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_RGBCOLOR) {
+ RGBColor col = ((CSSPrimitiveValue)sp).getRGBColorValue();
+ CSSPrimitiveValue val;
+ val = col.getRed();
+ float red = val.getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
+ val = col.getGreen();
+ float green = val.getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
+ val = col.getBlue();
+ float blue = val.getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
+ PDFColor fillColour = new PDFColor(red, green, blue);
+ currentStream.add(fillColour.getColorSpaceOut(true));
+ di.fill = true;
+ }
+ }
+/* if(sp instanceof ColorType) {
ColorType ct = (ColorType)sp;
PDFColor fillColour = new PDFColor(ct.red(), ct.green(), ct.blue());
currentStream.add(fillColour.getColorSpaceOut(true));
} else {
handleGradient((String)sp, true, area);
}
- }
+ }*/
} else {
}
- sp = style.get("fill-rule");
+ sp = style.getPropertyCSSValue("fill-rule");
if(sp != null) {
- if(sp.equals("nonzero")) {
- di.nonzero = true;
- }
+ if(sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+ if(((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_STRING) {
+ if(sp.getCssText().equals("nonzero")) {
+ di.nonzero = true;
+ }
+ }
+ }
} else {
}
- sp = style.get("stroke");
+ sp = style.getPropertyCSSValue("stroke");
if(sp != null) {
- di.stroke = true;
- if(sp instanceof ColorType) {
+ if(sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+ if(((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_RGBCOLOR) {
+ RGBColor col = ((CSSPrimitiveValue)sp).getRGBColorValue();
+ CSSPrimitiveValue val;
+ val = col.getRed();
+ float red = val.getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
+ val = col.getGreen();
+ float green = val.getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
+ val = col.getBlue();
+ float blue = val.getFloatValue(CSSPrimitiveValue.CSS_NUMBER);
+ PDFColor fillColour = new PDFColor(red, green, blue);
+ currentStream.add(fillColour.getColorSpaceOut(false));
+ di.stroke = true;
+ }
+ }
+/* if(sp instanceof ColorType) {
ColorType ct = (ColorType)sp;
PDFColor fillColour = new PDFColor(ct.red(), ct.green(), ct.blue());
- currentStream.add(fillColour.getColorSpaceOut(false));
- } else if(sp instanceof String) {
- if(sp.equals("none")) {
- di.stroke = false;
- } else {
- handleGradient((String)sp, false, area);
- }
- }
- } else {
- }
- sp = style.get("stroke-linecap");
- if(sp != null) {
- // butt, round ,square
- if(sp.equals("butt")) {
- currentStream.add(0 + " J\n");
- } else if(sp.equals("round")) {
- currentStream.add(1 + " J\n");
- } else if(sp.equals("square")) {
- currentStream.add(2 + " J\n");
- }
- } else {
- }
- sp = style.get("stroke-linejoin");
- if(sp != null) {
- if(sp.equals("miter")) {
- currentStream.add(0 + " j\n");
- } else if(sp.equals("round")) {
- currentStream.add(1 + " j\n");
- } else if(sp.equals("bevel")) {
- currentStream.add(2 + " j\n");
- }
- } else {
- }
- sp = style.get("stroke-miterlimit");
- if(sp != null) {
- float width;
- width = ((SVGLengthImpl)sp).getValue();
- PDFNumber pdfNumber = new PDFNumber();
- currentStream.add(pdfNumber.doubleOut(width) + " M\n");
- } else {
- }
- sp = style.get("stroke-width");
- if(sp != null) {
- float width;
- width = ((SVGLengthImpl)sp).getValue();
- PDFNumber pdfNumber = new PDFNumber();
- currentStream.add(pdfNumber.doubleOut(width) + " w\n");
- }
- sp = style.get("stroke-dasharray");
- if(sp != null) {
- Vector list;
- list = (Vector)sp;
- currentStream.add("[ ");
- for(Enumeration e = list.elements(); e.hasMoreElements(); ) {
- Integer val = (Integer)e.nextElement();
- currentStream.add(val.intValue() + " ");
- }
- sp = style.get("stroke-offset");
- if(sp != null) {
- float width;
- width = ((SVGLengthImpl)sp).getValue();
- PDFNumber pdfNumber = new PDFNumber();
- currentStream.add("] " + pdfNumber.doubleOut(width) + " d\n");
- } else {
- currentStream.add("] 0 d\n");
- }
-
- }
- sp = style.get("mask");
- if(sp != null) {
- String maskurl;
- maskurl = (String)sp;
-// System.out.println("mask: " + maskurl);
- maskurl = maskurl.substring(1, maskurl.length());
- // get def of mask and set mask
- GraphicImpl graph = null;
- graph = area.locateDef(maskurl);
- if(graph != null) {
-// System.out.println("mask: " + graph);
- GraphicImpl parent = graph.getGraphicParent();
- graph.setParent(area);
-// renderElement(svgarea, graph, posx, posy);
- graph.setParent(parent);
- }
- }
- return di;
- }
-
- // need to transform about the origin of the current object
- protected void applyTransform(Vector trans)
- {
- PDFNumber pdfNumber = new PDFNumber();
- for(Enumeration e = trans.elements(); e.hasMoreElements(); ) {
- SVGTransform t = (SVGTransform)e.nextElement();
- SVGMatrix matrix = t.getMatrix();
- currentStream.add(pdfNumber.doubleOut(matrix.getA()) + " " + pdfNumber.doubleOut(matrix.getB()) + " " + pdfNumber.doubleOut(matrix.getC())
- + " " + pdfNumber.doubleOut(matrix.getD()) + " " + pdfNumber.doubleOut(matrix.getE()) + " " + pdfNumber.doubleOut(matrix.getF()) + " cm\n");
- }
- }
-
- public void renderElement(SVGArea svgarea, GraphicImpl area, int posx, int posy)
- {
- int x = posx;
- int y = posy;
- Hashtable style = area.oldgetStyle();
- DrawingInstruction di = null;
-
- currentStream.add("q\n");
- Vector trans = area.oldgetTransform();
- if(trans != null) {
- applyTransform(trans);
- }
-
- if(style != null) {
- di = applyStyle(area, style);
- }
-
- if (area instanceof SVGRectElement) {
- SVGRectElement rg = (SVGRectElement)area;
- float rectx = rg.getX().getBaseVal().getValue();
- float recty = rg.getY().getBaseVal().getValue();
- float rx = rg.getRx().getBaseVal().getValue();
- float ry = rg.getRy().getBaseVal().getValue();
- float rw = rg.getWidth().getBaseVal().getValue();
- float rh = rg.getHeight().getBaseVal().getValue();
- addRect(rectx, recty, rw, rh, rx, ry, di);
- } else if (area instanceof SVGLineElement) {
- SVGLineElement lg = (SVGLineElement)area;
- float x1 = lg.getX1().getBaseVal().getValue();
- float y1 = lg.getY1().getBaseVal().getValue();
- float x2 = lg.getX2().getBaseVal().getValue();
- float y2 = lg.getY2().getBaseVal().getValue();
- addLine(x1,y1,x2,y2, di);
- } else if (area instanceof SVGTextElementImpl) {
-// currentStream.add("q\n");
-// currentStream.add(1 + " " + 0 + " " + 0 + " " + 1 + " " + 0 + " " + 0 + " cm\n");
- currentStream.add("BT\n");
- renderText(svgarea, (SVGTextElementImpl)area, 0, 0/*, di*/);
- currentStream.add("ET\n");
-// currentStream.add("Q\n");
- } else if (area instanceof SVGCircleElement) {
- SVGCircleElement cg = (SVGCircleElement)area;
- float cx = cg.getCx().getBaseVal().getValue();
- float cy = cg.getCy().getBaseVal().getValue();
- float r = cg.getR().getBaseVal().getValue();
- addCircle(cx,cy,r, di);
- } else if (area instanceof SVGEllipseElement) {
- SVGEllipseElement cg = (SVGEllipseElement)area;
- float cx = cg.getCx().getBaseVal().getValue();
- float cy = cg.getCy().getBaseVal().getValue();
- float rx = cg.getRx().getBaseVal().getValue();
- float ry = cg.getRy().getBaseVal().getValue();
- addEllipse(cx,cy,rx,ry, di);
- } else if (area instanceof SVGPathElementImpl) {
- addPath(((SVGPathElementImpl)area).pathElements, posx, posy, di);
- } else if (area instanceof SVGPolylineElementImpl) {
- addPolyline(((SVGPolylineElementImpl)area).points, posx, posy, di, false);
- } else if (area instanceof SVGPolygonElementImpl) {
- addPolyline(((SVGPolygonElementImpl)area).points, posx, posy, di, true);
- } else if (area instanceof SVGGElementImpl) {
- renderGArea(svgarea, (SVGGElementImpl)area, x, y);
- } else if(area instanceof SVGUseElementImpl) {
- SVGUseElementImpl ug = (SVGUseElementImpl)area;
- String ref = ug.link;
- ref = ref.substring(1, ref.length());
- GraphicImpl graph = null;
- graph = area.locateDef(ref);
- if(graph != null) {
- // probably not the best way to do this, should be able
- // to render without the style being set.
- GraphicImpl parent = graph.getGraphicParent();
- graph.setParent(area);
- // need to clip (if necessary) to the use area
- // the style of the linked element is as if is was
- // a direct descendant of the use element.
- renderElement(svgarea, graph, posx, posy);
- graph.setParent(parent);
- }
- } else if (area instanceof SVGImageElementImpl) {
- SVGImageElementImpl ig = (SVGImageElementImpl)area;
- renderImage(ig.link, ig.x, ig.y, ig.width, ig.height);
- } else if (area instanceof SVGArea) {
- // the x and y pos will be wrong!
- Enumeration e = ((SVGArea)area).getChildren().elements();
- currentStream.add("q\n");
- while (e.hasMoreElements()) {
- Object o = e.nextElement();
- if(o instanceof GraphicImpl) {
- renderElement((SVGArea)area, (GraphicImpl)o, x, y);
- }
- }
- currentStream.add("Q\n");
- } else if (area instanceof SVGAElement) {
- SVGAElement ael = (SVGAElement)area;
- org.w3c.dom.NodeList nl = ael.getChildNodes();
- for(int count = 0; count < nl.getLength(); count++) {
- org.w3c.dom.Node n = nl.item(count);
- if(n instanceof GraphicImpl) {
- if(n instanceof GraphicElement) {
- SVGRect rect = ((GraphicElement)n).getBBox();
- if(rect != null) {
-/* currentAnnotList = this.pdfDoc.makeAnnotList();
- currentPage.setAnnotList(currentAnnotList);
- String dest = linkSet.getDest();
- int linkType = linkSet.getLinkType();
- currentAnnotList.addLink(
- this.pdfDoc.makeLink(lrect.getRectangle(), dest, linkType));
- currentAnnotList = null;
-*/ }
- }
- renderElement(svgarea, (GraphicImpl)n, posx, posy);
- }
- }
- } else if (area instanceof SVGSwitchElement) {
- handleSwitchElement(svgarea, posx, posy, (SVGSwitchElement)area);
- }
- // should be done with some cleanup code, so only
- // required values are reset.
- currentStream.add("Q\n");
- }
-
-// need to escape certain chars
- public void renderText(SVGArea svgarea, SVGTextElementImpl tg, float x, float y)
- {
- FontState fontState = svgarea.getFontState();
- if(fontState == null) {
- return; // for now
- }
- PDFNumber pdfNumber = new PDFNumber();
-
- Hashtable styles;
- styles = tg.oldgetStyle();
- applyStyle(tg, styles);
- // apply transform
- // text has a Tm and need to handle each element
- SVGTransformList trans = tg.getTransform().getBaseVal();
- SVGMatrix matrix = trans.consolidate().getMatrix();
- String transstr = (pdfNumber.doubleOut(matrix.getA())
- + " " + pdfNumber.doubleOut(matrix.getB())
- + " " + pdfNumber.doubleOut(matrix.getC())
- + " " + pdfNumber.doubleOut(-matrix.getD()) + " ");
-
- String fontFamily;
- fontFamily = (String)styles.get("font-family");
- if(fontFamily == null)
- fontFamily = fontState.getFontFamily();
- String fontStyle;
- fontStyle = (String)styles.get("font-style");
- if(fontStyle == null)
- fontStyle = fontState.getFontStyle();
- String fontWeight;
- fontWeight = (String)styles.get("font-weight");
- if(fontWeight == null)
- fontWeight = fontState.getFontWeight();
- SVGLength len;
- len = (SVGLength)styles.get("font-size");
- float fontSize;
- fontSize = fontState.getFontSize() / 1000f;
- if(len != null)
- fontSize = len.getValue();
- FontState fs = fontState;
- try {
- fs = new FontState(fontState.getFontInfo(), fontFamily, fontStyle,
- fontWeight, (int)(fontSize * 1000));
- } catch(Exception fope) {
-// fope.printStackTrace();
- }
-
- currentStream.add("/" + fs.getFontName() + " " + fontSize + " Tf\n");
-
- float tx = tg.x;
- float ty = tg.y;
- float currentX = x + tx;
- Vector list = tg.textList;
- for(Enumeration e = list.elements(); e.hasMoreElements(); ) {
- Object o = e.nextElement();
- if(o instanceof String) {
- String str = (String)o;
- currentStream.add(transstr
- + (currentX + matrix.getE()) + " "
- + (y+ty + matrix.getF()) + " Tm "
- + "(" + str + ") Tj\n");
- for(int count = 0; count < str.length(); count++) {
- currentX += fs.width(str.charAt(count)) / 1000f;
- }
- currentX += fs.width(' ') / 1000f;
- } else if(o instanceof SVGTextPathElementImpl) {
- SVGTextPathElementImpl tpg = (SVGTextPathElementImpl)o;
- String ref = tpg.str;
- GraphicImpl graph = null;
- graph = tpg.locateDef(ref);
- if(graph != null && graph instanceof SVGPathElementImpl) {
- // probably not the best way to do this, should be able
- // to render without the style being set.
- GraphicImpl parent = graph.getGraphicParent();
- graph.setParent(tpg);
- // set text path??
- // how should this work
- graph.setParent(parent);
- }
- } else if(o instanceof SVGTRefElementImpl) {
- SVGTRefElementImpl trg = (SVGTRefElementImpl)o;
- String ref = trg.ref;
- ref = ref.substring(1, ref.length());
- GraphicImpl graph = null;
- graph = trg.locateDef(ref);
- if(graph != null && graph instanceof SVGTextElementImpl) {
- GraphicImpl parent = graph.getGraphicParent();
- graph.setParent(trg);
- SVGTextElementImpl te = (SVGTextElementImpl)graph;
- renderText(svgarea, te, (int)(x + tx), (int)(y + ty));
- graph.setParent(parent);
- }
- } else if(o instanceof SVGTSpanElementImpl) {
- // TODO handle dy properly
- SVGTSpanElementImpl tsg = (SVGTSpanElementImpl)o;
- styles = tsg.oldgetStyle();
- applyStyle(tsg, styles);
- boolean changed = false;
-
- String newprop;
- newprop = (String)styles.get("font-family");
- if(newprop != null && !newprop.equals(fontFamily)) {
- fontFamily = newprop;
- changed = true;
- }
- newprop = (String)styles.get("font-style");
- if(newprop != null && !newprop.equals(fontStyle)) {
- fontStyle = newprop;
- changed = true;
- }
- newprop = (String)styles.get("font-weight");
- if(newprop != null && !newprop.equals(fontWeight)) {
- fontWeight = newprop;
- changed = true;
- }
- len = (SVGLengthImpl)styles.get("font-size");
- if(len != null) {
- float newSize = len.getValue();
- if(fontSize != newSize) {
- fontSize = newSize;
- changed = true;
- }
- }
- if(changed) {
- try {
- fs = new FontState(fontState.getFontInfo(), fontFamily, fontStyle,
- fontWeight, (int)(fontSize * 1000));
- } catch(Exception fope) {
- }
-
- currentStream.add("/" + fs.getFontName() + " " + fontSize + " Tf\n");
- }
-
- if(tsg.ylist != null) {
- ty = ((Float)tsg.ylist.elementAt(0)).floatValue();
+ currentStream.add(fillColour.getColorSpaceOut(false));
+ } else if(sp instanceof String) {
+ if(sp.equals("none")) {
+ di.stroke = false;
+ } else {
+ handleGradient((String)sp, false, area);
}
- if(tsg.xlist != null) {
- Enumeration enum = tsg.xlist.elements();
- int count = 0;
- while(enum.hasMoreElements() && count < tsg.str.length()) {
- float pos = ((Float)enum.nextElement()).floatValue();
- currentStream.add(transstr
- + (x + pos + matrix.getE()) + " "
- + (y + ty + tsg.dy + matrix.getF()) + " Tm "
- + "(" + tsg.str.charAt(count) + ") Tj\n");
- currentX = x + pos + fs.width(tsg.str.charAt(count)) / 1000f;
- count++;
- }
- if(enum.hasMoreElements()) {
- // do nothing
- } else if(count < tsg.str.length()) {
- currentStream.add(transstr
- + (currentX + matrix.getE()) + " "
- + (y + ty + tsg.dy + matrix.getF()) + " Tm "
- + "(" + tsg.str.substring(count, tsg.str.length()) + ") Tj\n");
- }
- } else if(tsg.dxlist != null) {
- Enumeration enum = tsg.dxlist.elements();
- int count = 0;
- while(enum.hasMoreElements() && count < tsg.str.length()) {
- float pos = ((Float)enum.nextElement()).floatValue();
- currentStream.add(transstr
- + (currentX + pos + matrix.getE()) + " "
- + (y + ty + tsg.dy + matrix.getF()) + " Tm "
- + "(" + tsg.str.charAt(count) + ") Tj\n");
- currentX += pos + fs.width(tsg.str.charAt(count)) / 1000f;
- count++;
+ }*/
+ } else {
+ }
+ sp = style.getPropertyCSSValue("stroke-linecap");
+ if(sp != null) {
+ if(sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+ if(((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_STRING) {
+ String str = sp.getCssText();
+ // butt, round ,square
+ if(str.equals("butt")) {
+ currentStream.add(0 + " J\n");
+ } else if(str.equals("round")) {
+ currentStream.add(1 + " J\n");
+ } else if(str.equals("square")) {
+ currentStream.add(2 + " J\n");
}
- if(enum.hasMoreElements()) {
- // do nothing
- } else if(count < tsg.str.length()) {
- currentStream.add(transstr
- + (currentX + matrix.getE()) + " "
- + (y + ty + tsg.dy + matrix.getF()) + " Tm "
- + "(" + tsg.str.substring(count, tsg.str.length()) + ") Tj\n");
+ }
+ }
+ } else {
+ }
+ sp = style.getPropertyCSSValue("stroke-linejoin");
+ if(sp != null) {
+ if(sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+ if(((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_STRING) {
+ String str = sp.getCssText();
+ if(str.equals("miter")) {
+ currentStream.add(0 + " j\n");
+ } else if(str.equals("round")) {
+ currentStream.add(1 + " j\n");
+ } else if(str.equals("bevel")) {
+ currentStream.add(2 + " j\n");
}
+ }
+ }
+ } else {
+ }
+ sp = style.getPropertyCSSValue("stroke-miterlimit");
+ if(sp != null) {
+ if(sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+ float width;
+ width = ((CSSPrimitiveValue)sp).getFloatValue(CSSPrimitiveValue.CSS_PT);
+ PDFNumber pdfNumber = new PDFNumber();
+ currentStream.add(pdfNumber.doubleOut(width) + " M\n");
+ }
+ } else {
+ }
+ sp = style.getPropertyCSSValue("stroke-width");
+ if(sp != null) {
+ if(sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+ float width;
+ width = ((CSSPrimitiveValue)sp).getFloatValue(CSSPrimitiveValue.CSS_PT);
+ PDFNumber pdfNumber = new PDFNumber();
+ currentStream.add(pdfNumber.doubleOut(width) + " w\n");
+ }
+ }
+ sp = style.getPropertyCSSValue("stroke-dasharray");
+ if(sp != null) {
+ if(sp.getValueType() == CSSValue.CSS_VALUE_LIST) {
+ currentStream.add("[ ");
+ CSSValueList list = (CSSValueList)sp;
+ for(int count = 0; count < list.getLength(); count++) {
+ CSSValue val = list.item(count);
+ if(val.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+ currentStream.add(((CSSPrimitiveValue)val).getFloatValue(CSSPrimitiveValue.CSS_NUMBER) + " ");
+ }
+ }
+ currentStream.add("] ");
+ sp = style.getPropertyCSSValue("stroke-offset");
+ if(sp != null && sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+ currentStream.add(((CSSPrimitiveValue)sp).getFloatValue(CSSPrimitiveValue.CSS_NUMBER) + " d\n");
} else {
-/* currentStream.add(transstr
- + (((tsg.x == 0) ? (currentX) : (x))/1000f + tsg.x) + " "
- + (y / 1000f - ((tsg.y == 0) ? (ty + tsg.dy) : tsg.y)) + " Tm "
- + "(" + tsg.str + ") Tj\n");
- currentX = (tsg.x == 0) ? (currentX + tsg.dx) : (x + tsg.x);
- for(int count = 0; count < tsg.str.length(); count++) {
- currentX += fs.width(tsg.str.charAt(count));
- }*/
+ currentStream.add("0 d\n");
}
- currentX += fs.width(' ') / 1000f;
- } else {
- System.err.println("Error: unknown text element " + o);
+ }
+/* Vector list;
+ list = (Vector)sp;
+ currentStream.add("[ ");
+ for(Enumeration e = list.elements(); e.hasMoreElements(); ) {
+ Integer val = (Integer)e.nextElement();
+ currentStream.add(val.intValue() + " ");
}
+ sp = style.getPropertyCSSValue("stroke-offset");
+ if(sp != null) {
+ float width;
+ width = ((SVGLengthImpl)sp).getValue();
+ PDFNumber pdfNumber = new PDFNumber();
+ currentStream.add("] " + pdfNumber.doubleOut(width) + " d\n");
+ } else {
+ currentStream.add("] 0 d\n");
+ }*/
+
+ }
+ sp = style.getPropertyCSSValue("mask");
+ if(sp != null) {
+ String maskurl;
+// maskurl = (String)sp;
+// System.out.println("mask: " + maskurl);
+// maskurl = maskurl.substring(1, maskurl.length());
+ // get def of mask and set mask
+// SVGElement graph = null;
+// graph = area.locateDef(maskurl);
+// if(graph != null) {
+// System.out.println("mask: " + graph);
+// SVGElement parent = graph.getGraphicParent();
+// graph.setParent(area);
+// renderElement(svgarea, graph, posx, posy);
+// graph.setParent(parent);
+// }
}
+ return di;
}
- public void renderGArea(SVGArea svgarea, SVGGElementImpl area, int posx, int posy)
+ // need to transform about the origin of the current object
+ protected void applyTransform(SVGAnimatedTransformList trans, SVGRect bbox)
{
- Enumeration e = area.getChildren().elements();
- while (e.hasMoreElements()) {
- Object o = e.nextElement();
- if(o instanceof GraphicImpl) {
- renderElement(svgarea, (GraphicImpl)o, posx, posy);
- }
+ // need to rotate and scale about the bbox top left
+ PDFNumber pdfNumber = new PDFNumber();
+ if(bbox != null) {
+// currentStream.add("1 0 0 1 " + pdfNumber.doubleOut(bbox.getX()) + " " + pdfNumber.doubleOut(bbox.getY()) + " cm\n");
+ }
+ SVGTransformList list = trans.getBaseVal();
+ for(int count = 0; count < list.getNumberOfItems(); count++) {
+ SVGMatrix matrix = ((SVGTransform)list.getItem(count)).getMatrix();
+ currentStream.add(pdfNumber.doubleOut(matrix.getA()) + " " + pdfNumber.doubleOut(matrix.getB()) + " " + pdfNumber.doubleOut(matrix.getC())
+ + " " + pdfNumber.doubleOut(matrix.getD()) + " " + pdfNumber.doubleOut(matrix.getE()) + " " + pdfNumber.doubleOut(matrix.getF()) + " cm\n");
+ }
+ if(bbox != null) {
+// currentStream.add("1 0 0 1 " + pdfNumber.doubleOut(-bbox.getX()) + " " + pdfNumber.doubleOut(-bbox.getY()) + " cm\n");
}
}
- void handleSwitchElement(SVGArea svgarea, int posx, int posy, SVGSwitchElement ael)
+ public void renderElement(FontState fontState, SVGElement area, int posx, int posy)
{
- SVGList relist = ael.getRequiredExtensions();
- SVGList rflist = ael.getRequiredFeatures();
- SVGList sllist = ael.getSystemLanguage();
- org.w3c.dom.NodeList nl = ael.getChildNodes();
- for(int count = 0; count < nl.getLength(); count++) {
- org.w3c.dom.Node n = nl.item(count);
- // only render the first child that has a valid
- // test data
- if(n instanceof GraphicElement) {
- GraphicElement graphic = (GraphicElement)n;
- SVGList grelist = graphic.getRequiredExtensions();
- // if null it evaluates to true
- if(grelist != null) {
- for(int i = 0; i < grelist.getNumberOfItems(); i++) {
- String str = (String)grelist.getItem(i);
- if(relist == null) {
- // use default extension set
- // currently no extensions are supported
-// if(!(str.equals("http:// ??"))) {
- continue;
-// }
- } else {
- }
- }
- }
- SVGList grflist = graphic.getRequiredFeatures();
- if(grflist != null) {
- for(int i = 0; i < grflist.getNumberOfItems(); i++) {
- String str = (String)grflist.getItem(i);
- if(rflist == null) {
- // use default feature set
- if(!(str.equals("org.w3c.svg.static")
- || str.equals("org.w3c.dom.svg.all"))) {
- continue;
- }
- } else {
- boolean found = false;
- for(int j = 0; j < rflist.getNumberOfItems(); j++) {
- if(rflist.getItem(j).equals(str)) {
- found = true;
- break;
- }
- }
- if(!found)
- continue;
- }
- }
- }
- SVGList gsllist = graphic.getSystemLanguage();
- if(gsllist != null) {
- for(int i = 0; i < gsllist.getNumberOfItems(); i++) {
- String str = (String)gsllist.getItem(i);
- if(sllist == null) {
- // use default feature set
- if(!(str.equals("en"))) {
- continue;
- }
- } else {
- boolean found = false;
- for(int j = 0; j < sllist.getNumberOfItems(); j++) {
- if(sllist.getItem(j).equals(str)) {
- found = true;
- break;
- }
- }
- if(!found)
- continue;
- }
- }
- }
- renderElement(svgarea, (GraphicImpl)n, posx, posy);
- // only render the first valid one
- break;
+ int x = posx;
+ int y = posy;
+ CSSStyleDeclaration style = null;
+ if(area instanceof SVGStylable)
+ style = ((SVGStylable)area).getStyle();
+ DrawingInstruction di = null;
+
+ currentStream.add("q\n");
+ if(area instanceof SVGTransformable) {
+ SVGTransformable tf = (SVGTransformable)area;
+ SVGAnimatedTransformList trans = tf.getTransform();
+ SVGRect bbox = tf.getBBox();
+ if(trans != null) {
+ applyTransform(trans, bbox);
}
}
- }
-
- /**
- * render inline area to PDF
- *
- * @param area inline area to render
- */
- public void renderInlineArea(InlineArea area) {
- char ch;
- StringBuffer pdf = new StringBuffer();
-
- String name = area.getFontState().getFontName();
- int size = area.getFontState().getFontSize();
-
- PDFColor theAreaColor = new PDFColor(
- (double)area.getRed(),
- (double)area.getGreen(),
- (double)area.getBlue() );
-
- if ((!name.equals(this.currentFontName))
- || (size != this.currentFontSize)) {
- this.currentFontName = name;
- this.currentFontSize = size;
- pdf = pdf.append("/" + name + " " + (size/1000) + " Tf\n");
- }
-
- //if (theAreaColor.isEquivalent(this.currentFill)) {
- this.currentFill = theAreaColor;
-
- pdf = pdf.append(this.currentFill.getColorSpaceOut(true));
- //}
-
- int rx = this.currentXPosition;
- int bl = this.currentYPosition;
-
- pdf = pdf.append("1 0 0 1 "
- +(rx/1000f) + " " + (bl/1000f)
- + " Tm (");
-
- String s;
- if ( area.getPageNumberID()!=null ) { // this text is a page number, so resolve it
- s = idReferences.getPageNumber(area.getPageNumberID());
- if(s==null)
- {
- s="";
- }
- }
- else {
- s = area.getText();
- }
-
- int l = s.length();
- for (int i=0; i < l; i++) {
- ch = s.charAt(i);
- if (ch > 127) {
- pdf = pdf.append("\\");
- pdf = pdf.append(Integer.toOctalString((int)ch));
- } else {
- switch (ch) {
- case '(' : pdf = pdf.append("\\("); break;
- case ')' : pdf = pdf.append("\\)"); break;
- case '\\' : pdf = pdf.append("\\\\"); break;
- default : pdf = pdf.append(ch); break;
+ if(style != null) {
+ di = applyStyle(area, style);
}
+
+ if (area instanceof SVGRectElement) {
+ SVGRectElement rg = (SVGRectElement)area;
+ float rectx = rg.getX().getBaseVal().getValue();
+ float recty = rg.getY().getBaseVal().getValue();
+ float rx = rg.getRx().getBaseVal().getValue();
+ float ry = rg.getRy().getBaseVal().getValue();
+ float rw = rg.getWidth().getBaseVal().getValue();
+ float rh = rg.getHeight().getBaseVal().getValue();
+ addRect(rectx, recty, rw, rh, rx, ry, di);
+ } else if (area instanceof SVGLineElement) {
+ SVGLineElement lg = (SVGLineElement)area;
+ float x1 = lg.getX1().getBaseVal().getValue();
+ float y1 = lg.getY1().getBaseVal().getValue();
+ float x2 = lg.getX2().getBaseVal().getValue();
+ float y2 = lg.getY2().getBaseVal().getValue();
+ addLine(x1,y1,x2,y2, di);
+ } else if (area instanceof SVGTextElementImpl) {
+// currentStream.add("q\n");
+// currentStream.add(1 + " " + 0 + " " + 0 + " " + 1 + " " + 0 + " " + 0 + " cm\n");
+ currentStream.add("BT\n");
+ renderText(fontState, (SVGTextElementImpl)area, 0, 0/*, di*/);
+ currentStream.add("ET\n");
+// currentStream.add("Q\n");
+ } else if (area instanceof SVGCircleElement) {
+ SVGCircleElement cg = (SVGCircleElement)area;
+ float cx = cg.getCx().getBaseVal().getValue();
+ float cy = cg.getCy().getBaseVal().getValue();
+ float r = cg.getR().getBaseVal().getValue();
+ addCircle(cx,cy,r, di);
+ } else if (area instanceof SVGEllipseElement) {
+ SVGEllipseElement cg = (SVGEllipseElement)area;
+ float cx = cg.getCx().getBaseVal().getValue();
+ float cy = cg.getCy().getBaseVal().getValue();
+ float rx = cg.getRx().getBaseVal().getValue();
+ float ry = cg.getRy().getBaseVal().getValue();
+ addEllipse(cx,cy,rx,ry, di);
+ } else if (area instanceof SVGPathElementImpl) {
+ addPath(((SVGPathElementImpl)area).pathElements, posx, posy, di);
+ } else if (area instanceof SVGPolylineElementImpl) {
+ addPolyline(((SVGPolylineElementImpl)area).points, posx, posy, di, false);
+ } else if (area instanceof SVGPolygonElementImpl) {
+ addPolyline(((SVGPolygonElementImpl)area).points, posx, posy, di, true);
+ } else if (area instanceof SVGGElementImpl) {
+ renderGArea(fontState, (SVGGElementImpl)area, x, y);
+ } else if(area instanceof SVGUseElementImpl) {
+ SVGUseElementImpl ug = (SVGUseElementImpl)area;
+ String ref = ug.link;
+ ref = ref.substring(1, ref.length());
+ SVGElement graph = null;
+// graph = area.locateDef(ref);
+ if(graph != null) {
+ // probably not the best way to do this, should be able
+ // to render without the style being set.
+// SVGElement parent = graph.getGraphicParent();
+// graph.setParent(area);
+ // need to clip (if necessary) to the use area
+ // the style of the linked element is as if is was
+ // a direct descendant of the use element.
+ renderElement(fontState, graph, posx, posy);
+// graph.setParent(parent);
+ }
+ } else if (area instanceof SVGImageElementImpl) {
+ SVGImageElementImpl ig = (SVGImageElementImpl)area;
+ renderImage(fontState, ig.link, ig.x, ig.y, ig.width, ig.height);
+ } else if (area instanceof SVGSVGElement) {
+ // the x and y pos will be wrong!
+ currentStream.add("q\n");
+ renderSVG(fontState, (SVGSVGElement)area, x, y);
+ currentStream.add("Q\n");
+ } else if (area instanceof SVGAElement) {
+ SVGAElement ael = (SVGAElement)area;
+ org.w3c.dom.NodeList nl = ael.getChildNodes();
+ for(int count = 0; count < nl.getLength(); count++) {
+ org.w3c.dom.Node n = nl.item(count);
+ if(n instanceof SVGElement) {
+ if(n instanceof GraphicElement) {
+ SVGRect rect = ((GraphicElement)n).getBBox();
+ if(rect != null) {
+/* currentAnnotList = this.pdfDoc.makeAnnotList();
+ currentPage.setAnnotList(currentAnnotList);
+ String dest = linkSet.getDest();
+ int linkType = linkSet.getLinkType();
+ currentAnnotList.addLink(
+ this.pdfDoc.makeLink(lrect.getRectangle(), dest, linkType));
+ currentAnnotList = null;
+*/ }
+ }
+ renderElement(fontState, (SVGElement)n, posx, posy);
+ }
+ }
+ } else if (area instanceof SVGSwitchElement) {
+ handleSwitchElement(fontState, posx, posy, (SVGSwitchElement)area);
}
+ // should be done with some cleanup code, so only
+ // required values are reset.
+ currentStream.add("Q\n");
}
- pdf = pdf.append(") Tj\n");
-
- currentStream.add(pdf.toString());
-
- this.currentXPosition += area.getContentWidth();
- }
-
- /**
- * render inline space to PDF
- *
- * @param space space to render
- */
- public void renderInlineSpace(InlineSpace space) {
- this.currentXPosition += space.getSize();
- }
-
- /**
- * render line area to PDF
- *
- * @param area area to render
- */
- public void renderLineArea(LineArea area) {
- int rx = this.currentAreaContainerXPosition
- + area.getStartIndent();
- int ry = this.currentYPosition;
- int w = area.getContentWidth();
- int h = area.getHeight();
-
- this.currentYPosition -= area.getPlacementOffset();
- this.currentXPosition = rx;
-
- int bl = this.currentYPosition;
-
- Enumeration e = area.getChildren().elements();
- while (e.hasMoreElements()) {
- Box b = (Box) e.nextElement();
- b.render(this);
- }
-
- this.currentYPosition = ry-h;
- }
-
- /**
- * render page into PDF
- *
- * @param page page to render
- */
- public void renderPage(Page page) {
- AreaContainer body, before, after;
-
- currentStream = this.pdfDoc.makeStream();
- body = page.getBody();
- before = page.getBefore();
- after = page.getAfter();
- this.currentFontName = "";
- this.currentFontSize = 0;
+ public void renderText(FontState fontState, SVGTextElementImpl tg, float x, float y)
+ {
+ PDFNumber pdfNumber = new PDFNumber();
- currentStream.add("BT\n");
- renderAreaContainer(body);
+ CSSStyleDeclaration styles;
+ styles = tg.getStyle();
+ applyStyle(tg, styles);
+ // apply transform
+ // text has a Tm and need to handle each element
+ SVGTransformList trans = tg.getTransform().getBaseVal();
+ SVGMatrix matrix = trans.consolidate().getMatrix();
+ String transstr = (pdfNumber.doubleOut(matrix.getA())
+ + " " + pdfNumber.doubleOut(matrix.getB())
+ + " " + pdfNumber.doubleOut(matrix.getC())
+ + " " + pdfNumber.doubleOut(-matrix.getD()) + " ");
- if (before != null) {
- renderAreaContainer(before);
- }
+ String fontFamily = null;
+ CSSValue sp = styles.getPropertyCSSValue("font-family");
+ if(sp != null && sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+ if(((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_STRING) {
+ fontFamily = sp.getCssText();
+ }
+ }
+ if(fontFamily == null)
+ fontFamily = fontState.getFontFamily();
+ String fontStyle = null;
+ sp = styles.getPropertyCSSValue("font-style");
+ if(sp != null && sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+ if(((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_STRING) {
+ fontStyle = sp.getCssText();
+ }
+ }
+ if(fontStyle == null)
+ fontStyle = fontState.getFontStyle();
+ String fontWeight = null;
+ sp = styles.getPropertyCSSValue("font-weight");
+ if(sp != null && sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+ if(((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_STRING) {
+ fontWeight = sp.getCssText();
+ }
+ }
+ if(fontWeight == null)
+ fontWeight = fontState.getFontWeight();
+ float fontSize;
+ sp = styles.getPropertyCSSValue("font-size");
+ if(sp != null && sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+// if(((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_NUMBER) {
+ fontSize = ((CSSPrimitiveValue)sp).getFloatValue(CSSPrimitiveValue.CSS_PT);
+// }
+ } else {
+ fontSize = fontState.getFontSize() / 1000f;
+ }
+ FontState fs = fontState;
+ try {
+ fs = new FontState(fontState.getFontInfo(), fontFamily, fontStyle,
+ fontWeight, (int)(fontSize * 1000));
+ } catch(Exception fope) {
+// fope.printStackTrace();
+ }
- if (after != null) {
- renderAreaContainer(after);
- }
-
- currentStream.add("ET\n");
+ currentStream.add("/" + fs.getFontName() + " " + fontSize + " Tf\n");
- currentPage = this.pdfDoc.makePage(this.pdfResources, currentStream,
- page.getWidth()/1000,
- page.getHeight()/1000, page);
+ float tx = tg.x;
+ float ty = tg.y;
+ float currentX = x + tx;
+ float currentY = y + ty;
+ Vector list = tg.textList;
+ for(Enumeration e = list.elements(); e.hasMoreElements(); ) {
+ Object o = e.nextElement();
+ styles = tg.getStyle();
+ applyStyle(tg, styles);
+ if(o instanceof String) {
+ String str = (String)o;
+ currentStream.add(transstr
+ + (currentX + matrix.getE()) + " "
+ + (y+ty + matrix.getF()) + " Tm "
+ + "(");
+ boolean spacing = "preserve".equals(tg.getXMLspace());
+ currentX = addSVGStr(fs, currentX, str, spacing);
+ currentStream.add(") Tj\n");
+// for(int count = 0; count < str.length(); count++) {
+// }
+// currentX += fs.width(' ') / 1000f;
+ } else if(o instanceof SVGTextPathElementImpl) {
+ SVGTextPathElementImpl tpg = (SVGTextPathElementImpl)o;
+ String ref = tpg.str;
+ SVGElement graph = null;
+// graph = tpg.locateDef(ref);
+ if(graph != null && graph instanceof SVGPathElementImpl) {
+ // probably not the best way to do this, should be able
+ // to render without the style being set.
+// GraphicImpl parent = graph.getGraphicParent();
+// graph.setParent(tpg);
+ // set text path??
+ // how should this work
+// graph.setParent(parent);
+ }
+ } else if(o instanceof SVGTRefElementImpl) {
+ SVGTRefElementImpl trg = (SVGTRefElementImpl)o;
+ String ref = trg.ref;
+ ref = ref.substring(1, ref.length());
+ SVGElement graph = null;
+// graph = trg.locateDef(ref);
+ if(graph != null && graph instanceof SVGTextElementImpl) {
+// GraphicImpl parent = graph.getGraphicParent();
+// graph.setParent(trg);
+ SVGTextElementImpl te = (SVGTextElementImpl)graph;
+ renderText(fs, te, (int)(x + tx), (int)(y + ty));
+// graph.setParent(parent);
+ }
+ } else if(o instanceof SVGTSpanElementImpl) {
+ SVGTSpanElementImpl tsg = (SVGTSpanElementImpl)o;
+ styles = tsg.getStyle();
+ applyStyle(tsg, styles);
+ boolean changed = false;
- if (page.hasLinks()) {
- currentAnnotList = this.pdfDoc.makeAnnotList();
- currentPage.setAnnotList(currentAnnotList);
+ String newprop = null;
+ sp = styles.getPropertyCSSValue("font-family");
+ if(sp != null && sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+ if(((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_STRING) {
+ newprop = sp.getCssText();
+ }
+ }
+ if(newprop != null && !newprop.equals(fontFamily)) {
+ fontFamily = newprop;
+ changed = true;
+ }
+ sp = styles.getPropertyCSSValue("font-style");
+ if(sp != null && sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+ if(((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_STRING) {
+ newprop = sp.getCssText();
+ }
+ }
+ if(newprop != null && !newprop.equals(fontStyle)) {
+ fontStyle = newprop;
+ changed = true;
+ }
+ sp = styles.getPropertyCSSValue("font-weight");
+ if(sp != null && sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+ if(((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_STRING) {
+ newprop = sp.getCssText();
+ }
+ }
+ if(newprop != null && !newprop.equals(fontWeight)) {
+ fontWeight = newprop;
+ changed = true;
+ }
+ float newSize = fontSize;
+ sp = styles.getPropertyCSSValue("font-size");
+ if(sp != null && sp.getValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
+// if(((CSSPrimitiveValue)sp).getPrimitiveType() == CSSPrimitiveValue.CSS_NUMBER) {
+ newSize = ((CSSPrimitiveValue)sp).getFloatValue(CSSPrimitiveValue.CSS_PT);
+// }
+ }
+ if(fontSize != newSize) {
+ fontSize = newSize;
+ changed = true;
+ }
+ FontState oldfs = null;
+ if(changed) {
+ oldfs = fs;
+ try {
+ fs = new FontState(fontState.getFontInfo(), fontFamily, fontStyle,
+ fontWeight, (int)(fontSize * 1000));
+ } catch(Exception fope) {
+ }
- Enumeration e = page.getLinkSets().elements();
- while (e.hasMoreElements()) {
- LinkSet linkSet = (LinkSet) e.nextElement();
+ currentStream.add("/" + fs.getFontName() + " " + fontSize + " Tf\n");
+ }
- linkSet.align();
- String dest = linkSet.getDest();
- int linkType = linkSet.getLinkType();
- Enumeration f = linkSet.getRects().elements();
- while (f.hasMoreElements()) {
- LinkedRectangle lrect = (LinkedRectangle) f.nextElement();
- currentAnnotList.addLink(
- this.pdfDoc.makeLink(lrect.getRectangle(), dest, linkType));
- }
+ float baseX;
+ float baseY;
+
+ StringBuffer pdf = new StringBuffer();
+ boolean spacing = "preserve".equals(tsg.getXMLspace());
+ boolean inbetween = false;
+ boolean addedspace = false;
+ int charPos = 0;
+ float xpos = currentX;
+ float ypos = currentY;
+ for (int i=0; i < tsg.str.length(); i++) {
+ char ch = tsg.str.charAt(i);
+ xpos = currentX;
+ ypos = currentY;
+ if(tsg.ylist.size() > charPos) {
+ ypos = y + ty + ((Float)tsg.ylist.elementAt(charPos)).floatValue();
+ }
+ if(tsg.dylist.size() > charPos) {
+ ypos = ypos + ((Float)tsg.dylist.elementAt(charPos)).floatValue();
+ }
+ if(tsg.xlist.size() > charPos) {
+ xpos = x + tx + ((Float)tsg.xlist.elementAt(charPos)).floatValue();
+ }
+ if(tsg.dxlist.size() > charPos) {
+ xpos = xpos + ((Float)tsg.dxlist.elementAt(charPos)).floatValue();
+ }
+ if (ch > 127) {
+ pdf = pdf.append(transstr
+ + (xpos + matrix.getE()) + " "
+ + (ypos + matrix.getF()) + " Tm "
+ + "(" + "\\" + Integer.toOctalString((int)ch) + ") Tj\n");
+ currentX = xpos + fs.width(ch) / 1000f;
+ currentY = ypos;
+ charPos++;
+ inbetween = true;
+ addedspace = false;
+ } else {
+ switch (ch) {
+ case '(' :
+ pdf = pdf.append(transstr
+ + (xpos + matrix.getE()) + " "
+ + (ypos + matrix.getF()) + " Tm "
+ + "(" + "\\(" + ") Tj\n");
+ currentX = xpos + fs.width(ch) / 1000f;
+ currentY = ypos;
+ charPos++;
+ inbetween = true;
+ addedspace = false;
+ break;
+ case ')' :
+ pdf = pdf.append(transstr
+ + (xpos + matrix.getE()) + " "
+ + (ypos + matrix.getF()) + " Tm "
+ + "(" + "\\)" + ") Tj\n");
+ currentX = xpos + fs.width(ch) / 1000f;
+ currentY = ypos;
+ charPos++;
+ inbetween = true;
+ addedspace = false;
+ break;
+ case '\\' :
+ pdf = pdf.append(transstr
+ + (xpos + matrix.getE()) + " "
+ + (ypos + matrix.getF()) + " Tm "
+ + "(" + "\\\\" + ") Tj\n");
+ currentX = xpos + fs.width(ch) / 1000f;
+ currentY = ypos;
+ charPos++;
+ inbetween = true;
+ addedspace = false;
+ break;
+ case ' ':
+ case ' ':
+ if(spacing) {
+ currentX = xpos + fs.width(' ') / 1000f;
+ currentY = ypos;
+ charPos++;
+ } else {
+ if(inbetween && !addedspace) {
+ addedspace = true;
+ currentX = xpos + fs.width(' ') / 1000f;
+ currentY = ypos;
+ charPos++;
+ }
+ }
+ break;
+ case '\n':
+ case '\r':
+ if(spacing) {
+ currentX = xpos + fs.width(' ') / 1000f;
+ currentY = ypos;
+ charPos++;
+ }
+ break;
+ default:
+ addedspace = false;
+ pdf = pdf.append(transstr
+ + (xpos + matrix.getE()) + " "
+ + (ypos + matrix.getF()) + " Tm "
+ + "(" + ch + ") Tj\n");
+ currentX = xpos + fs.width(ch) / 1000f;
+ currentY = ypos;
+ charPos++;
+ inbetween = true;
+ break;
+ }
+ }
+ currentStream.add(pdf.toString());
+ }
+// currentX += fs.width(' ') / 1000f;
+ if(changed) {
+ fs = oldfs;
+ currentStream.add("/" + fs.getFontName() + " " + fs.getFontSize() / 1000f + " Tf\n");
+ }
+ } else {
+ System.err.println("Error: unknown text element " + o);
+ }
}
- } else {
- // just to be on the safe side
- currentAnnotList = null;
- }
}
- /**
- * render rule area into PDF
- *
- * @param area area to render
- */
- public void renderRuleArea(RuleArea area) {
- int rx = this.currentAreaContainerXPosition
- + area.getStartIndent();
- int ry = this.currentYPosition;
- int w = area.getContentWidth();
- int h = area.getHeight();
- int th = area.getRuleThickness();
-
- addLine(rx, ry, rx+w, ry, th, new PDFColor(area.getRed(), area.getGreen(),area.getBlue()));
+ protected float addSVGStr(FontState fs, float currentX, String str, boolean spacing)
+ {
+ boolean inbetween = false;
+ boolean addedspace = false;
+ StringBuffer pdf = new StringBuffer();
+ for (int i=0; i < str.length(); i++) {
+ char ch = str.charAt(i);
+ if (ch > 127) {
+ pdf = pdf.append("\\");
+ pdf = pdf.append(Integer.toOctalString((int)ch));
+ currentX += fs.width(ch) / 1000f;
+ inbetween = true;
+ addedspace = false;
+ } else {
+ switch (ch) {
+ case '(' :
+ pdf = pdf.append("\\(");
+ currentX += fs.width(ch) / 1000f;
+ inbetween = true;
+ addedspace = false;
+ break;
+ case ')' :
+ pdf = pdf.append("\\)");
+ currentX += fs.width(ch) / 1000f;
+ inbetween = true;
+ addedspace = false;
+ break;
+ case '\\' :
+ pdf = pdf.append("\\\\");
+ currentX += fs.width(ch) / 1000f;
+ inbetween = true;
+ addedspace = false;
+ break;
+ case ' ':
+ case ' ':
+ if(spacing) {
+ pdf = pdf.append(' ');
+ currentX += fs.width(' ') / 1000f;
+ } else {
+ if(inbetween && !addedspace) {
+ addedspace = true;
+ pdf = pdf.append(' ');
+ currentX += fs.width(' ') / 1000f;
+ }
+ }
+ break;
+ case '\n':
+ case '\r':
+ if(spacing) {
+ pdf = pdf.append(' ');
+ currentX += fs.width(' ') / 1000f;
+ }
+ break;
+ default:
+ addedspace = false;
+ pdf = pdf.append(ch);
+ currentX += fs.width(ch) / 1000f;
+ inbetween = true;
+ break;
+ }
+ }
+ }
+ currentStream.add(pdf.toString());
+ return currentX;
}
- /**
- * set up the font info
- *
- * @param fontInfo font info to set up
- */
- public void setupFontInfo(FontInfo fontInfo) {
- FontSetup.setup(fontInfo);
- FontSetup.addToResources(this.pdfDoc, fontInfo);
- }
}