package org.apache.fop.render.afp;
-import java.awt.Color;
import java.awt.geom.AffineTransform;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
import org.apache.fop.fo.Constants;
import org.apache.fop.render.afp.modca.DataStream;
import org.apache.fop.util.ColorUtil;
/**
* Handles the drawing of borders/lines in AFP
*/
-public class AFPBorderPainter {
- /** Static logging instance */
- protected static Log log = LogFactory.getLog("org.apache.fop.render.afp");
-
- private final DataStream dataStream;
- private final AFPState state;
+public class AFPBorderPainter extends AbstractAFPPainter {
/**
* Main constructor
* @param dataStream the afp datastream
*/
public AFPBorderPainter(AFPState state, DataStream dataStream) {
- this.state = state;
- this.dataStream = dataStream;
+ super(state, dataStream);
}
/** {@inheritDoc} */
- public void fillRect(float x, float y, float width, float height) {
- int pageWidth = dataStream.getCurrentPage().getWidth();
- int pageHeight = dataStream.getCurrentPage().getHeight();
-
- AFPUnitConverter unitConv = state.getUnitConverter();
- width = unitConv.pt2units(width);
- height = unitConv.pt2units(height);
- x = unitConv.pt2units(x);
- y = unitConv.pt2units(y);
-
- AffineTransform at = state.getData().getTransform();
-
- AFPLineDataInfo lineDataInfo = new AFPLineDataInfo();
- lineDataInfo.color = state.getColor();
- lineDataInfo.rotation = state.getRotation();
- lineDataInfo.thickness = Math.round(height);
-
- switch (lineDataInfo.rotation) {
- case 0:
- lineDataInfo.x1 = Math.round((float)at.getTranslateX() + x);
- lineDataInfo.y1 = lineDataInfo.y2 = Math.round((float)at.getTranslateY() + y);
- lineDataInfo.x2 = Math.round((float)at.getTranslateX() + x + width);
- break;
- case 90:
- lineDataInfo.x1 = Math.round((float)at.getTranslateY() + x);
- lineDataInfo.y1 = lineDataInfo.y2
- = pageWidth - Math.round((float)at.getTranslateX()) + Math.round(y);
- lineDataInfo.x2 = Math.round(width + (float)at.getTranslateY() + x);
- break;
- case 180:
- lineDataInfo.x1 = pageWidth - Math.round((float)at.getTranslateX() - x);
- lineDataInfo.y1 = lineDataInfo.y2 = pageHeight - Math.round((float)at.getTranslateY() - y);
- lineDataInfo.x2 = pageWidth - Math.round((float)at.getTranslateX() - x - width);
- break;
- case 270:
- lineDataInfo.x1 = pageHeight - Math.round((float)at.getTranslateY() - x);
- lineDataInfo.y1 = lineDataInfo.y2 = Math.round((float)at.getTranslateX() + y);
- lineDataInfo.x2 = lineDataInfo.x1 + Math.round(width - x);
- break;
- }
- dataStream.createLine(lineDataInfo);
- }
-
- /** {@inheritDoc} */
- public void drawBorderLine(float x1, float y1, float x2, float y2,
- boolean isHorizontal, boolean startOrBefore, int style, Color color) {
- float w = x2 - x1;
- float h = y2 - y1;
+ public void paint(PaintInfo paintInfo) {
+ BorderPaintInfo borderPaintInfo = (BorderPaintInfo)paintInfo;
+ float w = borderPaintInfo.getX2() - borderPaintInfo.getX1();
+ float h = borderPaintInfo.getY2() - borderPaintInfo.getY1();
if ((w < 0) || (h < 0)) {
log.error("Negative extent received. Border won't be painted.");
return;
AFPUnitConverter unitConv = state.getUnitConverter();
AffineTransform at = state.getData().getTransform();
- x1 = unitConv.pt2units(x1);
- y1 = unitConv.pt2units(y1);
- x2 = unitConv.pt2units(x2);
- y2 = unitConv.pt2units(y2);
+ float x1 = unitConv.pt2units(borderPaintInfo.getX1());
+ float y1 = unitConv.pt2units(borderPaintInfo.getY1());
+ float x2 = unitConv.pt2units(borderPaintInfo.getX2());
+ float y2 = unitConv.pt2units(borderPaintInfo.getY2());
switch (state.getRotation()) {
case 0:
}
AFPLineDataInfo lineDataInfo = new AFPLineDataInfo();
- lineDataInfo.setThickness(Math.round(y2 - y1));
- lineDataInfo.setColor(color);
+ lineDataInfo.setColor(borderPaintInfo.getColor());
lineDataInfo.setRotation(state.getRotation());
-
lineDataInfo.x1 = Math.round(x1);
lineDataInfo.y1 = Math.round(y1);
+ if (borderPaintInfo.isHorizontal()) {
+ lineDataInfo.setThickness(Math.round(y2 - y1));
+ } else {
+ lineDataInfo.setThickness(Math.round(x2 - x1));
+ }
// handle border-*-style
- switch (style) {
+ switch (borderPaintInfo.getStyle()) {
case Constants.EN_DOUBLE:
- lineDataInfo.x2 = Math.round(x2);
- lineDataInfo.y2 = lineDataInfo.y1;
- dataStream.createLine(lineDataInfo);
- float w3 = lineDataInfo.thickness / 3;
- lineDataInfo.y1 += Math.round(w3 * 2);
- dataStream.createLine(lineDataInfo);
+ if (borderPaintInfo.isHorizontal()) {
+ lineDataInfo.x2 = Math.round(x2);
+ lineDataInfo.y2 = lineDataInfo.y1;
+ dataStream.createLine(lineDataInfo);
+ lineDataInfo.y1 += Math.round((lineDataInfo.thickness / 3) * 2);
+ dataStream.createLine(lineDataInfo);
+ } else {
+ lineDataInfo.x2 = lineDataInfo.x1;
+ lineDataInfo.y2 = Math.round(y2);
+ dataStream.createLine(lineDataInfo);
+ lineDataInfo.x1 += Math.round((lineDataInfo.thickness / 3) * 2);
+ dataStream.createLine(lineDataInfo);
+ }
break;
case Constants.EN_DASHED:
- case Constants.EN_DOTTED:
- int factor = style == Constants.EN_DASHED ? 3 : 2;
- int thick = lineDataInfo.thickness * factor;
- lineDataInfo.x2 = lineDataInfo.x1 + thick;
- lineDataInfo.y2 = lineDataInfo.y1;
- int ex2 = Math.round(x2);
- while (lineDataInfo.x1 + thick < ex2) {
- dataStream.createLine(lineDataInfo);
- lineDataInfo.x1 += 2 * thick;
+ int thick = lineDataInfo.thickness * 3;
+ if (borderPaintInfo.isHorizontal()) {
lineDataInfo.x2 = lineDataInfo.x1 + thick;
+ lineDataInfo.y2 = lineDataInfo.y1;
+ int ex2 = Math.round(x2);
+ while (lineDataInfo.x1 + thick < ex2) {
+ dataStream.createLine(lineDataInfo);
+ lineDataInfo.x1 += 2 * thick;
+ lineDataInfo.x2 = lineDataInfo.x1 + thick;
+ }
+ } else {
+ lineDataInfo.x2 = lineDataInfo.x1;
+ lineDataInfo.y2 = lineDataInfo.y1 + thick;
+ int ey2 = Math.round(y2);
+ while (lineDataInfo.y1 + thick < ey2) {
+ dataStream.createLine(lineDataInfo);
+ lineDataInfo.y1 += 2 * thick;
+ lineDataInfo.y2 = lineDataInfo.y1 + thick;
+ }
+ }
+ break;
+ case Constants.EN_DOTTED:
+ if (borderPaintInfo.isHorizontal()) {
+ lineDataInfo.x2 = lineDataInfo.x1 + lineDataInfo.thickness;
+ lineDataInfo.y2 = lineDataInfo.y1;
+ int ex2 = Math.round(x2);
+ while (lineDataInfo.x1 + lineDataInfo.thickness < ex2) {
+ dataStream.createLine(lineDataInfo);
+ lineDataInfo.x1 += 3 * lineDataInfo.thickness;
+ lineDataInfo.x2 = lineDataInfo.x1 + lineDataInfo.thickness;
+ }
+ } else {
+ lineDataInfo.x2 = lineDataInfo.x1;
+ lineDataInfo.y2 = lineDataInfo.y1 + lineDataInfo.thickness;
+ int ey2 = Math.round(y2);
+ while (lineDataInfo.y1 + lineDataInfo.thickness < ey2) {
+ dataStream.createLine(lineDataInfo);
+ lineDataInfo.y1 += 3 * lineDataInfo.thickness;
+ lineDataInfo.y2 = lineDataInfo.y1 + lineDataInfo.thickness;
+ }
}
break;
case Constants.EN_GROOVE:
case Constants.EN_RIDGE:
+ //TODO
lineDataInfo.x2 = Math.round(x2);
- float colFactor = (style == Constants.EN_GROOVE ? 0.4f : -0.4f);
+ float colFactor = (borderPaintInfo.getStyle() == Constants.EN_GROOVE ? 0.4f : -0.4f);
float h3 = (y2 - y1) / 3;
- lineDataInfo.color = ColorUtil.lightenColor(color, -colFactor);
+ lineDataInfo.color = ColorUtil.lightenColor(borderPaintInfo.getColor(), -colFactor);
lineDataInfo.thickness = Math.round(h3);
lineDataInfo.y1 = lineDataInfo.y2 = Math.round(y1);
dataStream.createLine(lineDataInfo);
- lineDataInfo.color = color;
+ lineDataInfo.color = borderPaintInfo.getColor();
lineDataInfo.y1 = lineDataInfo.y2 = Math.round(y1 + h3);
dataStream.createLine(lineDataInfo);
- lineDataInfo.color = ColorUtil.lightenColor(color, colFactor);
+ lineDataInfo.color = ColorUtil.lightenColor(borderPaintInfo.getColor(), colFactor);
lineDataInfo.y1 = lineDataInfo.y2 = Math.round(y1 + h3 + h3);
dataStream.createLine(lineDataInfo);
break;
case Constants.EN_OUTSET:
case Constants.EN_SOLID:
default:
- lineDataInfo.x2 = Math.round(x2);
- lineDataInfo.y2 = lineDataInfo.y1;
+ if (borderPaintInfo.isHorizontal()) {
+ lineDataInfo.x2 = Math.round(x2);
+ lineDataInfo.y2 = lineDataInfo.y1;
+ } else {
+ lineDataInfo.x2 = lineDataInfo.x1;
+ lineDataInfo.y2 = Math.round(y2);
+ }
dataStream.createLine(lineDataInfo);
}
}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp;
+
+import java.awt.geom.AffineTransform;
+
+import org.apache.fop.render.afp.modca.DataStream;
+
+public class AFPRectanglePainter extends AbstractAFPPainter {
+
+ /**
+ * Main constructor
+ *
+ * @param state the afp state
+ * @param dataStream the afp datastream
+ */
+ public AFPRectanglePainter(AFPState state, DataStream dataStream) {
+ super(state, dataStream);
+ }
+
+ /** {@inheritDoc} */
+ public void paint(PaintInfo paintInfo) {
+ RectanglePaintInfo rectanglePaintInfo = (RectanglePaintInfo)paintInfo;
+ int pageWidth = dataStream.getCurrentPage().getWidth();
+ int pageHeight = dataStream.getCurrentPage().getHeight();
+
+ AFPUnitConverter unitConv = state.getUnitConverter();
+ float width = unitConv.pt2units(rectanglePaintInfo.getWidth());
+ float height = unitConv.pt2units(rectanglePaintInfo.getHeight());
+ float x = unitConv.pt2units(rectanglePaintInfo.getX());
+ float y = unitConv.pt2units(rectanglePaintInfo.getY());
+
+ AffineTransform at = state.getData().getTransform();
+
+ AFPLineDataInfo lineDataInfo = new AFPLineDataInfo();
+ lineDataInfo.color = state.getColor();
+ lineDataInfo.rotation = state.getRotation();
+ lineDataInfo.thickness = Math.round(height);
+
+ switch (lineDataInfo.rotation) {
+ case 0:
+ lineDataInfo.x1 = Math.round((float)at.getTranslateX() + x);
+ lineDataInfo.y1 = lineDataInfo.y2 = Math.round((float)at.getTranslateY() + y);
+ lineDataInfo.x2 = Math.round((float)at.getTranslateX() + x + width);
+ break;
+ case 90:
+ lineDataInfo.x1 = Math.round((float)at.getTranslateY() + x);
+ lineDataInfo.y1 = lineDataInfo.y2
+ = pageWidth - Math.round((float)at.getTranslateX()) + Math.round(y);
+ lineDataInfo.x2 = Math.round(width + (float)at.getTranslateY() + x);
+ break;
+ case 180:
+ lineDataInfo.x1 = pageWidth - Math.round((float)at.getTranslateX() - x);
+ lineDataInfo.y1 = lineDataInfo.y2 = pageHeight - Math.round((float)at.getTranslateY() - y);
+ lineDataInfo.x2 = pageWidth - Math.round((float)at.getTranslateX() - x - width);
+ break;
+ case 270:
+ lineDataInfo.x1 = pageHeight - Math.round((float)at.getTranslateY() - x);
+ lineDataInfo.y1 = lineDataInfo.y2 = Math.round((float)at.getTranslateX() + y);
+ lineDataInfo.x2 = lineDataInfo.x1 + Math.round(width - x);
+ break;
+ }
+ dataStream.createLine(lineDataInfo);
+ }
+}
/** data object information factory */
private final AFPDataObjectInfoProvider dataObjectInfoProvider;
+ private AFPRectanglePainter rectanglePainter;
+
/**
* Constructor for AFPRenderer.
this.dataStream = resourceManager.getDataStream();
this.borderPainter = new AFPBorderPainter(state, dataStream);
+ this.rectanglePainter = new AFPRectanglePainter(state, dataStream);
// dataStream.setPortraitRotation(state.getPortraitRotation());
// dataStream.setLandscapeRotation(state.getLandscapeRotation());
Rectangle2D bounds = pageViewport.getViewArea();
- state.concatenate(getBaseTransform());
+ AffineTransform baseTransform = getBaseTransform();
+ state.concatenate(baseTransform);
if (pages.containsKey(pageViewport)) {
dataStream.restorePage(
}
/** {@inheritDoc} */
- public void fillRect(float x, float y, float width, float height) {
- borderPainter.fillRect(x, y, width, height);
+ public void drawBorderLine(float x1, float y1, float x2, float y2,
+ boolean horz, boolean startOrBefore, int style, Color col) {
+ BorderPaintInfo borderPaintInfo = new BorderPaintInfo(x1, y1, x2, y2, horz, style, col);
+ borderPainter.paint(borderPaintInfo);
}
/** {@inheritDoc} */
- public void drawBorderLine(float x1, float y1, float x2, float y2,
- boolean horz, boolean startOrBefore, int style, Color col) {
- borderPainter.drawBorderLine(x1, y1, x2, y2, horz, startOrBefore, style, col);
+ public void fillRect(float x, float y, float width, float height) {
+ RectanglePaintInfo rectanglePaintInfo = new RectanglePaintInfo(x, y, width, height);
+ rectanglePainter.paint(rectanglePaintInfo);
}
/** {@inheritDoc} */
/** {@inheritDoc} */
protected void establishTransformationMatrix(AffineTransform at) {
saveGraphicsState();
- //state.resetTransform(); // reset to base transform (scale)
concatenateTransformationMatrix(at);
}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.fop.render.afp.modca.DataStream;
+
+public abstract class AbstractAFPPainter {
+
+ /** Static logging instance */
+ protected static Log log = LogFactory.getLog("org.apache.fop.render.afp");
+
+ protected final DataStream dataStream;
+ protected final AFPState state;
+
+ /**
+ * Main constructor
+ *
+ * @param state the afp state
+ * @param dataStream the afp datastream
+ */
+ public AbstractAFPPainter(AFPState state, DataStream dataStream) {
+ this.state = state;
+ this.dataStream = dataStream;
+ }
+
+ /**
+ * Paints the painting item
+ *
+ * @param paintInfo the painting information
+ */
+ public abstract void paint(PaintInfo paintInfo);
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp;
+
+import java.awt.Color;
+
+/**
+ * Border painting information
+ */
+public class BorderPaintInfo implements PaintInfo {
+ private final float x1;
+ private final float y1;
+ private final float x2;
+ private final float y2;
+ private final boolean isHorizontal;
+// private final boolean startOrBefore;
+ private final int style;
+ private final Color color;
+
+ /**
+ * Main constructor
+ *
+ * @param x1 the x1 coordinate
+ * @param y1 the y1 coordinate
+ * @param x2 the x2 coordinate
+ * @param y2 the y2 coordinate
+ * @param isHorizontal true when the border line is horizontal
+ * @param startOrBefore true when is before
+ * @param style the border style
+ * @param color the border color
+ */
+ public BorderPaintInfo(float x1, float y1, float x2, float y2,
+ boolean isHorizontal, /*boolean startOrBefore,*/ int style, Color color) {
+ this.x1 = x1;
+ this.y1 = y1;
+ this.x2 = x2;
+ this.y2 = y2;
+ this.isHorizontal = isHorizontal;
+// this.startOrBefore = startOrBefore;
+ this.style = style;
+ this.color = color;
+ }
+
+ /**
+ * Returns the x1 coordinate
+ *
+ * @return the x1 coordinate
+ */
+ public float getX1() {
+ return x1;
+ }
+
+ /**
+ * Returns the y1 coordinate
+ *
+ * @return the y1 coordinate
+ */
+ public float getY1() {
+ return y1;
+ }
+
+ /**
+ * Returns the x2 coordinate
+ *
+ * @return the x2 coordinate
+ */
+ public float getX2() {
+ return x2;
+ }
+
+ /**
+ * Returns the y2 coordinate
+ *
+ * @return the y2 coordinate
+ */
+ public float getY2() {
+ return y2;
+ }
+
+ /**
+ * Returns true when this is a horizontal line
+ *
+ * @return true when this is a horizontal line
+ */
+ public boolean isHorizontal() {
+ return isHorizontal;
+ }
+
+// /**
+// * Returns true when this is start
+// *
+// * @return true when this is start
+// */
+// public boolean isStartOrBefore() {
+// return startOrBefore;
+// }
+//
+ /**
+ * Returns the style
+ *
+ * @return the style
+ */
+ public int getStyle() {
+ return style;
+ }
+
+ /**
+ * Returns the color
+ *
+ * @return the color
+ */
+ public Color getColor() {
+ return color;
+ }
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp;
+
+/**
+ * Generic painting information interface
+ */
+public interface PaintInfo {
+
+}
--- /dev/null
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+
+package org.apache.fop.render.afp;
+
+/**
+ * Filled rectangle painting information
+ */
+public class RectanglePaintInfo implements PaintInfo {
+
+ private final float x;
+ private final float y;
+ private final float width;
+ private final float height;
+
+ /**
+ * Main constructor
+ *
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param width the width
+ * @param height the height
+ */
+ public RectanglePaintInfo(float x, float y, float width, float height) {
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+ }
+
+ /**
+ * Returns the x coordinate
+ *
+ * @return the x coordinate
+ */
+ protected float getX() {
+ return x;
+ }
+
+ /**
+ * Returns the y coordinate
+ *
+ * @return the y coordinate
+ */
+ protected float getY() {
+ return y;
+ }
+
+ /**
+ * Returns the width
+ *
+ * @return the width
+ */
+ protected float getWidth() {
+ return width;
+ }
+
+ /**
+ * Returns the height
+ *
+ * @return the height
+ */
+ protected float getHeight() {
+ return height;
+ }
+
+}