git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1593863 13f79535-47bb-0310-9956-ffa450edef68tags/fop-2_0
@@ -508,6 +508,10 @@ public final class Trait implements Serializable { | |||
/** Background vertical offset for images. */ | |||
private int vertical; | |||
private int imageTargetWidth; | |||
private int imageTargetHeight; | |||
/** | |||
* Returns the background color. | |||
* @return background color, null if n/a | |||
@@ -655,9 +659,31 @@ public final class Trait implements Serializable { | |||
sb.append(",horiz=").append(horiz); | |||
sb.append(",vertical=").append(vertical); | |||
} | |||
if (imageTargetWidth != 0) { | |||
sb.append(",target-width=").append(Integer.toString(imageTargetWidth)); | |||
} | |||
if (imageTargetHeight != 0) { | |||
sb.append(",target-height=").append(Integer.toString(imageTargetHeight)); | |||
} | |||
return sb.toString(); | |||
} | |||
public void setImageTargetWidth(int value) { | |||
imageTargetWidth = value; | |||
} | |||
public int getImageTargetWidth() { | |||
return imageTargetWidth; | |||
} | |||
public void setImageTargetHeight(int value) { | |||
imageTargetHeight = value; | |||
} | |||
public int getImageTargetHeight() { | |||
return imageTargetHeight; | |||
} | |||
} | |||
} | |||
@@ -822,8 +822,12 @@ public interface Constants { | |||
/** Property constant */ | |||
int PR_X_AUTO_TOGGLE = 292; | |||
/** Used for scaling of background images */ | |||
int PR_X_BACKGROUND_IMAGE_WIDTH = 293; | |||
int PR_X_BACKGROUND_IMAGE_HEIGHT = 294; | |||
/** Number of property constants defined */ | |||
int PROPERTY_COUNT = 292; | |||
int PROPERTY_COUNT = 294; | |||
// compound property constants | |||
@@ -2624,6 +2624,16 @@ public final class FOPropertyMapping implements Constants { | |||
m.setDefault("select-first-fitting"); | |||
addPropertyMaker("fox:auto-toggle", m); | |||
// fox:background-image-width|height, used for scaling of background images | |||
m = new LengthProperty.Maker(PR_X_BACKGROUND_IMAGE_WIDTH); | |||
m.setInherited(false); | |||
m.setDefault("0pt"); | |||
addPropertyMaker("fox:background-image-width", m); | |||
m = new LengthProperty.Maker(PR_X_BACKGROUND_IMAGE_HEIGHT); | |||
m.setInherited(false); | |||
m.setDefault("0pt"); | |||
addPropertyMaker("fox:background-image-height", m); | |||
// fox:border-*-radius-* | |||
m = new CondLengthProperty.Maker(PR_X_BORDER_BEFORE_RADIUS_START); | |||
m.useGeneric(genericCondCornerRadius); |
@@ -69,6 +69,9 @@ public class ExtensionElementMapping extends ElementMapping { | |||
PROPERTY_ATTRIBUTES.add("border-after-end-radius"); | |||
//Optional content groups (layers) | |||
PROPERTY_ATTRIBUTES.add("layer"); | |||
// used for scaling of background images | |||
PROPERTY_ATTRIBUTES.add("background-image-width"); | |||
PROPERTY_ATTRIBUTES.add("background-image-height"); | |||
} | |||
/** |
@@ -84,6 +84,8 @@ public class CommonBorderPaddingBackground { | |||
*/ | |||
public final Length backgroundPositionVertical; | |||
public final Length backgroungImageTargetWidth; | |||
public final Length backgroungImageTargetHeight; | |||
private ImageInfo backgroundImageInfo; | |||
@@ -353,6 +355,9 @@ public class CommonBorderPaddingBackground { | |||
Constants.PR_BACKGROUND_POSITION_VERTICAL).getLength(); | |||
} | |||
backgroungImageTargetWidth = pList.get(Constants.PR_X_BACKGROUND_IMAGE_WIDTH).getLength(); | |||
backgroungImageTargetHeight = pList.get(Constants.PR_X_BACKGROUND_IMAGE_HEIGHT).getLength(); | |||
initBorderInfo(pList, BEFORE, | |||
Constants.PR_BORDER_BEFORE_COLOR, | |||
Constants.PR_BORDER_BEFORE_STYLE, | |||
@@ -397,18 +402,18 @@ public class CommonBorderPaddingBackground { | |||
CommonBorderPaddingBackground cachedInstance = null; | |||
/* if padding-* and background-position-* resolve to absolute lengths | |||
* the whole instance can be cached */ | |||
if ((newInstance.padding[BEFORE] == null | |||
|| newInstance.padding[BEFORE].getLength().isAbsolute()) | |||
&& (newInstance.padding[AFTER] == null | |||
|| newInstance.padding[AFTER].getLength().isAbsolute()) | |||
&& (newInstance.padding[START] == null | |||
|| newInstance.padding[START].getLength().isAbsolute()) | |||
&& (newInstance.padding[END] == null | |||
|| newInstance.padding[END].getLength().isAbsolute()) | |||
&& (newInstance.backgroundPositionHorizontal == null | |||
|| newInstance.backgroundPositionHorizontal.isAbsolute()) | |||
&& (newInstance.backgroundPositionVertical == null | |||
|| newInstance.backgroundPositionVertical.isAbsolute())) { | |||
if ((newInstance.padding[BEFORE] == null || newInstance.padding[BEFORE].getLength().isAbsolute()) | |||
&& (newInstance.padding[AFTER] == null || newInstance.padding[AFTER].getLength().isAbsolute()) | |||
&& (newInstance.padding[START] == null || newInstance.padding[START].getLength().isAbsolute()) | |||
&& (newInstance.padding[END] == null || newInstance.padding[END].getLength().isAbsolute()) | |||
&& (newInstance.backgroundPositionHorizontal == null || newInstance.backgroundPositionHorizontal | |||
.isAbsolute()) | |||
&& (newInstance.backgroundPositionVertical == null || newInstance.backgroundPositionVertical | |||
.isAbsolute()) | |||
&& (newInstance.backgroungImageTargetHeight == null || newInstance.backgroungImageTargetHeight | |||
.isAbsolute()) | |||
&& (newInstance.backgroungImageTargetWidth == null || newInstance.backgroungImageTargetWidth | |||
.isAbsolute())) { | |||
cachedInstance = CACHE.fetch(newInstance); | |||
} | |||
synchronized (newInstance.backgroundImage.intern()) { | |||
@@ -837,6 +842,8 @@ public class CommonBorderPaddingBackground { | |||
backgroundImage, | |||
backgroundPositionHorizontal, | |||
backgroundPositionVertical, | |||
backgroungImageTargetWidth, | |||
backgroungImageTargetHeight, | |||
borderInfo[BEFORE], | |||
borderInfo[AFTER], | |||
borderInfo[START], |
@@ -443,6 +443,12 @@ public final class TraitSetter { | |||
} | |||
} | |||
} | |||
if (backProps.backgroungImageTargetWidth.getValue() != 0) { | |||
back.setImageTargetWidth(backProps.backgroungImageTargetWidth.getValue()); | |||
} | |||
if (backProps.backgroungImageTargetHeight.getValue() != 0) { | |||
back.setImageTargetHeight(backProps.backgroungImageTargetHeight.getValue()); | |||
} | |||
} | |||
area.addTrait(Trait.BACKGROUND, back); |
@@ -266,10 +266,21 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { | |||
if (back.getImageInfo() != null) { | |||
ImageSize imageSize = back.getImageInfo().getSize(); | |||
int horzCount = (int)((paddRectWidth | |||
* 1000 / imageSize.getWidthMpt()) + 1.0f); | |||
int vertCount = (int)((paddRectHeight | |||
* 1000 / imageSize.getHeightMpt()) + 1.0f); | |||
int targetWidth = imageSize.getWidthMpt(); | |||
int targetHeight = imageSize.getHeightMpt(); | |||
double multiplier = 1.0; | |||
if (back.getImageTargetWidth() != 0 && back.getImageTargetHeight() != 0) { | |||
multiplier = Math.min(1.0 * back.getImageTargetWidth() / targetWidth, | |||
1.0 * back.getImageTargetHeight() / targetHeight); | |||
} else if (back.getImageTargetHeight() != 0) { | |||
multiplier = 1.0 * back.getImageTargetHeight() / targetHeight; | |||
} else if (back.getImageTargetWidth() != 0) { | |||
multiplier = 1.0 * back.getImageTargetWidth() / targetWidth; | |||
} | |||
targetWidth = (int) (targetWidth * multiplier); | |||
targetHeight = (int) (targetHeight * multiplier); | |||
int horzCount = (int) ((paddRectWidth * 1000 / targetWidth) + 1.0f); | |||
int vertCount = (int) ((paddRectHeight * 1000 / targetHeight) + 1.0f); | |||
if (back.getRepeat() == EN_NOREPEAT) { | |||
horzCount = 1; | |||
vertCount = 1; | |||
@@ -292,12 +303,8 @@ public abstract class AbstractPathOrientedRenderer extends PrintRenderer { | |||
// place once | |||
Rectangle2D pos; | |||
// Image positions are relative to the currentIP/BP | |||
pos = new Rectangle2D.Float(sx - currentIPPosition | |||
+ (x * imageSize.getWidthMpt()), | |||
sy - currentBPPosition | |||
+ (y * imageSize.getHeightMpt()), | |||
imageSize.getWidthMpt(), | |||
imageSize.getHeightMpt()); | |||
pos = new Rectangle2D.Float(sx - currentIPPosition + (x * targetWidth), sy | |||
- currentBPPosition + (y * targetHeight), targetWidth, targetHeight); | |||
drawImage(back.getURL(), pos); | |||
} | |||
} |
@@ -0,0 +1,42 @@ | |||
/* | |||
* 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: ActiveLayouts.java 99 2008-11-24 11:06:55Z vincent $ */ | |||
package org.apache.fop.area; | |||
import org.junit.Test; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.junit.Assert.assertTrue; | |||
public class TraitTestCase { | |||
@Test | |||
public void testImageTargetWidthAndHeight() { | |||
int width = 2911; | |||
int height = 1911; | |||
Trait.Background background = new Trait.Background(); | |||
background.setImageTargetWidth(width); | |||
background.setImageTargetHeight(height); | |||
assertEquals(width, background.getImageTargetWidth()); | |||
assertEquals(height, background.getImageTargetHeight()); | |||
assertTrue(background.toString().contains(Integer.toString(width))); | |||
assertTrue(background.toString().contains(Integer.toString(height))); | |||
} | |||
} |
@@ -0,0 +1,162 @@ | |||
/* | |||
* 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; | |||
import java.awt.Color; | |||
import java.awt.Rectangle; | |||
import java.awt.geom.AffineTransform; | |||
import java.awt.geom.Rectangle2D; | |||
import java.util.List; | |||
import java.util.Map; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import static org.junit.Assert.assertEquals; | |||
import static org.mockito.Mockito.mock; | |||
import org.apache.xmlgraphics.image.loader.ImageInfo; | |||
import org.apache.xmlgraphics.image.loader.ImageSize; | |||
import org.apache.fop.apps.FOUserAgent; | |||
import org.apache.fop.area.CTM; | |||
import org.apache.fop.area.Trait; | |||
public class AbstractPathOrientedRendererTestCase { | |||
@Before | |||
public void setUp() throws Exception { | |||
} | |||
@Test | |||
public void testDrawBackgroundWithTargetImageSizes() { | |||
FOUserAgent userAgent = mock(FOUserAgent.class); | |||
MyAPOR myAPOR = new MyAPOR(userAgent); | |||
ImageSize imgSize = new ImageSize(300, 300, 300); | |||
imgSize.setSizeInMillipoints(72000, 72000); | |||
ImageInfo imgInfo = new ImageInfo(null, null); | |||
imgInfo.setSize(imgSize); | |||
Trait.Background background = new Trait.Background(); | |||
background.setImageTargetWidth(300000); | |||
background.setImageTargetHeight(300000); | |||
background.setImageInfo(imgInfo); | |||
myAPOR.drawBackground(0, 0, 600, 900, background, null, null, null, null); | |||
String expected = "[x=0.0,y=0.0,w=3.0,h=3.0][x=0.0,y=3.0,w=3.0,h=3.0][x=0.0,y=6.0,w=3.0,h=3.0]" | |||
+ "[x=0.0,y=9.0,w=3.0,h=3.0][x=3.0,y=0.0,w=3.0,h=3.0][x=3.0,y=3.0,w=3.0,h=3.0]" | |||
+ "[x=3.0,y=6.0,w=3.0,h=3.0][x=3.0,y=9.0,w=3.0,h=3.0][x=6.0,y=0.0,w=3.0,h=3.0]" | |||
+ "[x=6.0,y=3.0,w=3.0,h=3.0][x=6.0,y=6.0,w=3.0,h=3.0][x=6.0,y=9.0,w=3.0,h=3.0]"; | |||
assertEquals(expected, myAPOR.getActual().replaceAll("00000", "")); | |||
myAPOR.resetActual(); | |||
background.setImageTargetWidth(0); | |||
myAPOR.drawBackground(0, 0, 600, 900, background, null, null, null, null); | |||
assertEquals(expected, myAPOR.getActual().replaceAll("00000", "")); | |||
myAPOR.resetActual(); | |||
background.setImageTargetWidth(300000); | |||
background.setImageTargetHeight(0); | |||
myAPOR.drawBackground(0, 0, 600, 900, background, null, null, null, null); | |||
assertEquals(expected, myAPOR.getActual().replaceAll("00000", "")); | |||
} | |||
private class MyAPOR extends AbstractPathOrientedRenderer { | |||
private String actual = ""; | |||
public MyAPOR(FOUserAgent userAgent) { | |||
super(userAgent); | |||
} | |||
public String getActual() { | |||
return actual; | |||
} | |||
public void resetActual() { | |||
actual = ""; | |||
} | |||
public String getMimeType() { | |||
return null; | |||
} | |||
protected void concatenateTransformationMatrix(AffineTransform at) { | |||
} | |||
protected void restoreStateStackAfterBreakOut(List breakOutList) { | |||
} | |||
protected List breakOutOfStateStack() { | |||
return null; | |||
} | |||
protected void saveGraphicsState() { | |||
} | |||
protected void restoreGraphicsState() { | |||
} | |||
protected void beginTextObject() { | |||
} | |||
protected void endTextObject() { | |||
} | |||
protected void clip() { | |||
} | |||
protected void clipRect(float x, float y, float width, float height) { | |||
} | |||
protected void moveTo(float x, float y) { | |||
} | |||
protected void lineTo(float x, float y) { | |||
} | |||
protected void closePath() { | |||
} | |||
protected void fillRect(float x, float y, float width, float height) { | |||
} | |||
protected void updateColor(Color col, boolean fill) { | |||
} | |||
protected void drawImage(String url, Rectangle2D pos, Map foreignAttributes) { | |||
String s = pos.toString(); | |||
actual += s.substring(s.indexOf('[')); | |||
} | |||
protected void drawBorderLine(float x1, float y1, float x2, float y2, boolean horz, | |||
boolean startOrBefore, int style, Color col) { | |||
} | |||
protected void startVParea(CTM ctm, Rectangle clippingRect) { | |||
} | |||
protected void endVParea() { | |||
} | |||
protected void startLayer(String layer) { | |||
} | |||
protected void endLayer() { | |||
} | |||
} | |||
} |