Minor bug fixes and some cleanup git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_RoundedCorners@1133370 13f79535-47bb-0310-9956-ffa450edef68tags/fop-2_0
@@ -79,6 +79,7 @@ | |||
<xs:complexType> | |||
<xs:attributeGroup ref="mf:rectAtts"/> | |||
<xs:attributeGroup ref="mf:fillAtts"/> | |||
<xs:attributeGroup ref="mf:borderAtts"/> | |||
</xs:complexType> | |||
</xs:element> | |||
<xs:element name="line"> | |||
@@ -95,11 +96,8 @@ | |||
<xs:element name="border-rect"> | |||
<xs:complexType> | |||
<xs:attributeGroup ref="mf:rectAtts"/> | |||
<xs:attribute name="start" type="mf:borderDef"/> | |||
<xs:attribute name="end" type="mf:borderDef"/> | |||
<xs:attribute name="before" type="mf:borderDef"/> | |||
<xs:attribute name="after" type="mf:borderDef"/> | |||
<xs:attribute name="inner-background-color" type="mf:colorType"/> | |||
<xs:attributeGroup ref="mf:borderAtts"/> | |||
</xs:complexType> | |||
</xs:element> | |||
<xs:element name="image"> | |||
@@ -126,6 +124,12 @@ | |||
<xs:attributeGroup name="rectAtts"> | |||
<xs:attributeGroup ref="mf:posAtts"/> | |||
<xs:attributeGroup ref="mf:sizeAtts"/> | |||
</xs:attributeGroup> | |||
<xs:attributeGroup name="borderAtts"> | |||
<xs:attribute name="start" type="mf:borderDef"/> | |||
<xs:attribute name="end" type="mf:borderDef"/> | |||
<xs:attribute name="before" type="mf:borderDef"/> | |||
<xs:attribute name="after" type="mf:borderDef"/> | |||
</xs:attributeGroup> | |||
<xs:attributeGroup name="fillAtts"> | |||
<xs:attribute name="fill" type="xs:string" default="none"/> |
@@ -132,7 +132,7 @@ public class AFPResourceManager { | |||
AFPResourceInfo resourceInfo = dataObjectInfo.getResourceInfo(); | |||
updateResourceInfoUri(resourceInfo); | |||
if (includeCachedObject(resourceInfo, null)) { | |||
if (includeCachedObject(resourceInfo, dataObjectInfo.getObjectAreaInfo())) { | |||
return; | |||
} | |||
@@ -159,8 +159,9 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { | |||
(Trait.Background) backgroundArea.getTrait(Trait.BACKGROUND), | |||
bpsBefore, bpsAfter, bpsStart, bpsEnd); | |||
Color bg = null; | |||
if (backgroundTrait != null) { | |||
// TODO what is the default bg color? Should we serialize it? | |||
Color bg = Color.white; | |||
if (backgroundTrait != null && backgroundTrait.getColor() != null) { | |||
bg = backgroundTrait.getColor(); | |||
} | |||
@@ -223,9 +224,9 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { | |||
updateColor(back.getColor(), true); | |||
fillRect(sx, sy, paddRectWidth, paddRectHeight); | |||
} | |||
if (back.getImageInfo() != null) { | |||
ImageSize imageSize = back.getImageInfo().getSize(); | |||
int horzCount = (int)((paddRectWidth | |||
* 1000 / imageSize.getWidthMpt()) + 1.0f); | |||
int vertCount = (int)((paddRectHeight | |||
@@ -267,6 +268,7 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { | |||
} | |||
/** | |||
* TODO represent border related parameters in a class | |||
* Clip the background to the inner border. | |||
* This draws the border traits given the position and the traits. | |||
* | |||
@@ -300,6 +302,7 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { | |||
* @param bpsAfter the border-after traits | |||
* @param bpsStart the border-start traits | |||
* @param bpsEnd the border-end traits | |||
* @param innerBackgroundColor the background color of the block | |||
*/ | |||
protected void drawBorders( // CSOK: ParameterNumber | |||
float startx, float starty, float width, float height, | |||
@@ -321,6 +324,7 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { | |||
* @param bpsAfter the border specification on the after side | |||
* @param bpsStart the border specification on the start side | |||
* @param bpsEnd the border specification on the end side | |||
* @param innerBackgroundColor the background color of the block | |||
*/ | |||
protected void drawBorders( // CSOK: MethodLength | |||
Rectangle2D.Float borderRect, |
@@ -309,6 +309,7 @@ public class AFPPainter extends AbstractIFPainter { | |||
private final boolean[] roundCorner; | |||
private final Color innerBackgroundColor; | |||
/* TODO represent border related parameters in a class */ | |||
private BorderImagePainter(double esf, Rectangle borderRect, | |||
BorderProps bpsStart, BorderProps bpsEnd, | |||
BorderProps bpsBefore, BorderProps bpsAfter, | |||
@@ -807,7 +808,7 @@ public class AFPPainter extends AbstractIFPainter { | |||
return clip; | |||
} | |||
/* TODO collect parameters in a useful structure */ | |||
private void paintCorner(final Graphics2D g2d, final int beforeWidth, | |||
final int startWidth, final int beforeRadius, | |||
final int startRadius, final Color innerBackgroundColor, | |||
@@ -841,7 +842,7 @@ public class AFPPainter extends AbstractIFPainter { | |||
afterCut.lineTo(startRadius, 0); | |||
beforeCut.lineTo(0, beforeRadius); | |||
} else { | |||
afterCut.lineTo(startRadius, (float)(borderWidthRatio * startRadius)); | |||
afterCut.lineTo(startRadius, (borderWidthRatio * startRadius)); | |||
beforeCut.lineTo(1f / borderWidthRatio * beforeRadius, beforeRadius); | |||
afterCut.lineTo(startRadius, 0); | |||
@@ -1341,4 +1342,9 @@ public class AFPPainter extends AbstractIFPainter { | |||
bpsStart, bpsEnd); | |||
} | |||
/** {@inheritDoc} */ | |||
public void fillBackground(Rectangle rect, Paint fill, BorderProps bpsBefore, | |||
BorderProps bpsAfter, BorderProps bpsStart, BorderProps bpsEnd) throws IFException { | |||
// not supported in AFP | |||
} | |||
} |
@@ -32,9 +32,14 @@ import org.apache.fop.traits.RuleStyle; | |||
*/ | |||
public abstract class BorderPainter { | |||
/** TODO remove before integration*/ | |||
public static final String ROUNDED_CORNERS = "fop.round-corners"; | |||
/** TODO Use a class to model border instead of an array | |||
* convention index of before, end, after and start borders */ | |||
protected static final int BEFORE = 0, END = 1, AFTER = 2, START = 3; | |||
/** TODO Use a class to model border corners instead of an array | |||
convention index of before_start, before_end, after_end and after_start border corners*/ | |||
protected static final int BEFORE_START = 0, BEFORE_END = 1, AFTER_END = 2, AFTER_START = 3; | |||
@@ -45,6 +50,7 @@ public abstract class BorderPainter { | |||
* @param bpsAfter the border specification on the after side | |||
* @param bpsStart the border specification on the start side | |||
* @param bpsEnd the border specification on the end side | |||
* @param innerBackgroundColor the inner background color | |||
* @throws IFException if an error occurs while drawing the borders | |||
*/ | |||
public void drawBorders(Rectangle borderRect, // CSOK: MethodLength | |||
@@ -71,6 +77,15 @@ public abstract class BorderPainter { | |||
return bps == null ? bps : bps.width == 0 ? (BorderProps)null : bps; | |||
} | |||
/** | |||
* TODO merge with drawRoundedBorders()? | |||
* @param borderRect the border rectangle | |||
* @param bpsBefore the border specification on the before side | |||
* @param bpsAfter the border specification on the after side | |||
* @param bpsStart the border specification on the start side | |||
* @param bpsEnd the border specification on the end side | |||
* @throws IOException | |||
*/ | |||
protected void drawRectangularBorders(Rectangle borderRect, | |||
BorderProps bpsBefore, BorderProps bpsAfter, | |||
BorderProps bpsStart, BorderProps bpsEnd) throws IOException { | |||
@@ -243,6 +258,14 @@ public abstract class BorderPainter { | |||
} | |||
} | |||
/** TODO merge with drawRectangularBorders? | |||
* @param borderRect the border rectangle | |||
* @param bpsBefore the border specification on the before side | |||
* @param bpsAfter the border specification on the after side | |||
* @param bpsStart the border specification on the start side | |||
* @param bpsEnd the border specification on the end side | |||
* @throws IOException on io exception | |||
* */ | |||
protected void drawRoundedBorders(Rectangle borderRect, | |||
BorderProps bpsBefore, BorderProps bpsAfter, | |||
BorderProps bpsStart, BorderProps bpsEnd) throws IOException { | |||
@@ -400,6 +423,7 @@ public abstract class BorderPainter { | |||
} | |||
} | |||
/** TODO collect parameters into useful data structures*/ | |||
private void drawBorderSegment(final int sx2, final int ex1, final int ex2, | |||
final int outery, final int innery, | |||
final int clipWidthStart, final int clipWidthEnd, | |||
@@ -444,7 +468,7 @@ public abstract class BorderPainter { | |||
} | |||
} | |||
if (ellipseBERadiusX != 0) { | |||
if (ellipseBERadiusX != 0 && ellipseBERadiusY != 0) { | |||
final double[] outerJoinMetrics = getCornerBorderJoinMetrics( | |||
ellipseBERadiusX, ellipseBERadiusY, (double)innery / (ex1 - ex2)); | |||
@@ -553,11 +577,11 @@ public abstract class BorderPainter { | |||
/** | |||
* Clip the background to the inner border | |||
* @param rect | |||
* @param bpsBefore | |||
* @param bpsAfter | |||
* @param bpsStart | |||
* @param bpsEnd | |||
* @param rect clipping rectangle | |||
* @param bpsBefore before border | |||
* @param bpsAfter after border | |||
* @param bpsStart start border | |||
* @param bpsEnd end border | |||
* @throws IOException if an I/O error occurs | |||
*/ | |||
public void clipBackground(Rectangle rect, | |||
@@ -629,7 +653,7 @@ public abstract class BorderPainter { | |||
lineTo(startx + ellipseSE, starty + height); | |||
if (ellipseSE > 0 && ellipseSE > 0) { | |||
if (ellipseSE > 0 && ellipseAS > 0) { | |||
arcTo( Math.PI / 2, Math.PI, startx + ellipseSE, | |||
starty + height - ellipseAS, ellipseSE, ellipseAS); | |||
} | |||
@@ -645,8 +669,9 @@ public abstract class BorderPainter { | |||
} | |||
/* | |||
* If the ellipse radii exceed the border edge length, the ellipses are rescaled. | |||
/** | |||
* TODO javadocs | |||
* If an ellipse radii exceed the border edge length then all ellipses must be rescaled. | |||
*/ | |||
protected double cornerScaleFactor(int width, int height, | |||
BorderProps bpsBefore, BorderProps bpsAfter, | |||
@@ -655,29 +680,35 @@ public abstract class BorderPainter { | |||
double esf = 1d; | |||
if (bpsBefore != null) { | |||
if (bpsStart != null && bpsEnd != null | |||
&& bpsStart.getRadiusStart() + bpsEnd.getRadiusStart() > 0) { | |||
double ellipseExtent = (bpsStart == null ? 0 : bpsStart.getRadiusStart()) | |||
+ (bpsEnd == null ? 0 : bpsEnd.getRadiusStart()); | |||
double f = (double)width / (bpsStart.getRadiusStart() + bpsEnd.getRadiusStart()); | |||
if (ellipseExtent > 0) { | |||
double f = width / ellipseExtent; | |||
if (f < esf) { | |||
esf = f; | |||
} | |||
} | |||
} | |||
if (bpsStart != null) { | |||
if (bpsAfter != null && bpsBefore != null | |||
&& bpsAfter.getRadiusStart() + bpsBefore.getRadiusStart() > 0) { | |||
double f = (double)height / (bpsAfter.getRadiusStart() | |||
+ bpsBefore.getRadiusStart()); | |||
double ellipseExtent = (bpsAfter == null ? 0 : bpsAfter.getRadiusStart()) | |||
+ (bpsBefore == null ? 0 : bpsBefore.getRadiusStart()); | |||
if (ellipseExtent > 0) { | |||
double f = height / ellipseExtent; | |||
if ( f < esf) { | |||
esf = f; | |||
} | |||
} | |||
} | |||
if (bpsAfter != null) { | |||
if (bpsStart != null && bpsEnd != null | |||
&& bpsStart.getRadiusEnd() + bpsEnd.getRadiusEnd() > 0) { | |||
double f = (double)width / (bpsStart.getRadiusEnd() + bpsEnd.getRadiusEnd()); | |||
double ellipseExtent = (bpsStart == null ? 0 : bpsStart.getRadiusEnd()) | |||
+ (bpsEnd == null ? 0 : bpsEnd.getRadiusEnd()); | |||
if (ellipseExtent > 0) { | |||
double f = width / ellipseExtent; | |||
if (f < esf) { | |||
esf = f; | |||
} | |||
@@ -685,9 +716,11 @@ public abstract class BorderPainter { | |||
} | |||
if (bpsEnd != null) { | |||
if (bpsAfter != null && bpsBefore != null | |||
&& bpsAfter.getRadiusEnd() + bpsBefore.getRadiusEnd() > 0) { | |||
double f = (double)height / (bpsAfter.getRadiusEnd() + bpsBefore.getRadiusEnd()); | |||
double ellipseExtent = (bpsAfter == null ? 0 : bpsAfter.getRadiusEnd()) | |||
+ (bpsBefore == null ? 0 : bpsBefore.getRadiusEnd()); | |||
if (ellipseExtent > 0) { | |||
double f = height / ellipseExtent; | |||
if (f < esf) { | |||
esf = f; | |||
} | |||
@@ -881,6 +914,10 @@ public abstract class BorderPainter { | |||
*/ | |||
protected abstract void restoreGraphicsState() throws IOException; | |||
/** | |||
* TODO remove the System.props when rounded corners code is stable | |||
* @return true iff in rounded corners mode | |||
*/ | |||
public static boolean isRoundedCornersSupported() { | |||
return "true".equalsIgnoreCase(System.getProperty(ROUNDED_CORNERS, "true")); | |||
} |
@@ -182,14 +182,16 @@ public interface IFPainter { | |||
/** | |||
* | |||
* @param bpsBefore | |||
* @param bpsAfter | |||
* @param bpsStart | |||
* @param bpsEnd | |||
* @return true if the background needs to be painted | |||
*/ | |||
boolean isBackgroundRequired( BorderProps bpsBefore, BorderProps bpsAfter, | |||
* TODO Painter-specific rounded borders logic required background drawing to be | |||
* made optional. A future refactoring of the rounded borders code should aim to make | |||
* the need for this abstraction obsolete | |||
* @param bpsBefore the before border | |||
* @param bpsAfter the after border | |||
* @param bpsStart the start border | |||
* @param bpsEnd the end border | |||
* @return true if and only if background drawing is required | |||
*/ | |||
boolean isBackgroundRequired(BorderProps bpsBefore, BorderProps bpsAfter, | |||
BorderProps bpsStart, BorderProps bpsEnd); | |||
/** |
@@ -583,6 +583,19 @@ public class IFParser implements IFConstants { | |||
int y = Integer.parseInt(attributes.getValue("y")); | |||
int width = Integer.parseInt(attributes.getValue("width")); | |||
int height = Integer.parseInt(attributes.getValue("height")); | |||
BorderProps[] borders = new BorderProps[4]; | |||
for (int i = 0; i < 4; i++) { | |||
String b = attributes.getValue(SIDES[i]); | |||
if (b != null) { | |||
borders[i] = BorderProps.valueOf(userAgent, b); | |||
} | |||
} | |||
if (!(borders[0] == null && borders[1] == null | |||
&& borders[2] == null && borders[3] == null)) { | |||
painter.clipBackground(new Rectangle(x, y, width, height), | |||
borders[0], borders[1], borders[2], borders[3]); | |||
} | |||
painter.clipRect(new Rectangle(x, y, width, height)); | |||
} | |||
@@ -601,7 +614,26 @@ public class IFParser implements IFConstants { | |||
} catch (PropertyException pe) { | |||
throw new IFException("Error parsing the fill attribute", pe); | |||
} | |||
painter.fillRect(new Rectangle(x, y, width, height), fillColor); | |||
Rectangle rectangularArea = new Rectangle(x, y, width, height); | |||
//TODO should rect be overloaded to include rounded corners | |||
// or should we introduce a new IF element? | |||
BorderProps[] borders = new BorderProps[4]; | |||
for (int i = 0; i < 4; i++) { | |||
String b = attributes.getValue(SIDES[i]); | |||
if (b != null) { | |||
borders[i] = BorderProps.valueOf(userAgent, b); | |||
} | |||
} | |||
if (!(borders[0] == null && borders[1] == null | |||
&& borders[2] == null && borders[3] == null)) { | |||
painter.clipBackground(rectangularArea, | |||
borders[0], borders[1], borders[2], borders[3]); | |||
} | |||
painter.fillRect(rectangularArea , fillColor); | |||
} | |||
} |
@@ -474,8 +474,31 @@ public class IFSerializer extends AbstractXMLWritingIFDocumentHandler | |||
/** {@inheritDoc} */ | |||
public void clipBackground(Rectangle rect, BorderProps bpsBefore, BorderProps bpsAfter, | |||
BorderProps bpsStart, BorderProps bpsEnd) throws IFException { | |||
// TODO Auto-generated method stub | |||
try { | |||
AttributesImpl atts = new AttributesImpl(); | |||
addAttribute(atts, "x", Integer.toString(rect.x)); | |||
addAttribute(atts, "y", Integer.toString(rect.y)); | |||
addAttribute(atts, "width", Integer.toString(rect.width)); | |||
addAttribute(atts, "height", Integer.toString(rect.height)); | |||
if (hasRoundedCorners(bpsBefore, bpsAfter, bpsStart, bpsEnd)) { | |||
if (bpsBefore != null) { | |||
addAttribute(atts, "before", bpsBefore.toString()); | |||
} | |||
if (bpsAfter != null) { | |||
addAttribute(atts, "after", bpsAfter.toString()); | |||
} | |||
if (bpsStart != null) { | |||
addAttribute(atts, "start", bpsStart.toString()); | |||
} | |||
if (bpsEnd != null) { | |||
addAttribute(atts, "end", bpsEnd.toString()); | |||
} | |||
} | |||
handler.element(EL_CLIP_RECT, atts); | |||
} catch (SAXException e) { | |||
throw new IFException("SAX error in clipRect()", e); | |||
} | |||
} | |||
@@ -497,6 +520,35 @@ public class IFSerializer extends AbstractXMLWritingIFDocumentHandler | |||
} | |||
} | |||
//TODO create a class representing all borders should exist | |||
//with query methods like this | |||
private boolean hasRoundedCorners(BorderProps bpsBefore, BorderProps bpsAfter, | |||
BorderProps bpsStart, BorderProps bpsEnd) { | |||
boolean rtn = false; | |||
if (bpsBefore != null && bpsBefore.getRadiusStart() > 0 | |||
&& bpsStart != null && bpsStart.getRadiusStart() > 0) { | |||
rtn = true; | |||
} | |||
if (bpsBefore != null && bpsBefore.getRadiusEnd() > 0 | |||
&& bpsEnd != null && bpsEnd.getRadiusStart() > 0) { | |||
rtn = true; | |||
} | |||
if (bpsEnd != null && bpsEnd.getRadiusEnd() > 0 | |||
&& bpsAfter != null && bpsAfter.getRadiusEnd() > 0) { | |||
rtn = true; | |||
} | |||
if (bpsAfter != null && bpsAfter.getRadiusStart() > 0 | |||
&& bpsStart != null && bpsStart.getRadiusEnd() > 0) { | |||
rtn = true; | |||
} | |||
return rtn; | |||
} | |||
/** {@inheritDoc} */ | |||
public void drawBorderRect(Rectangle rect, BorderProps before, BorderProps after, | |||
BorderProps start, BorderProps end, Color innerBackgroundColor) throws IFException { |
@@ -412,6 +412,13 @@ public class SVGPainter extends AbstractIFPainter implements SVGConstants { | |||
} | |||
} | |||
/** {@inheritDoc} */ | |||
public void fillBackground(Rectangle rect, Paint fill, BorderProps bpsBefore, | |||
BorderProps bpsAfter, BorderProps bpsStart, BorderProps bpsEnd) throws IFException { | |||
// Not supported in SVG | |||
} | |||
} |