Browse Source

FOP-2372: New extension to resize background images

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1593863 13f79535-47bb-0310-9956-ffa450edef68
tags/fop-2_0
Luis Bernardo 10 years ago
parent
commit
c4e5885007

+ 26
- 0
src/java/org/apache/fop/area/Trait.java View File

@@ -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;
}

}
}


+ 5
- 1
src/java/org/apache/fop/fo/Constants.java View File

@@ -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


+ 10
- 0
src/java/org/apache/fop/fo/FOPropertyMapping.java View File

@@ -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);

+ 3
- 0
src/java/org/apache/fop/fo/extensions/ExtensionElementMapping.java View File

@@ -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");
}

/**

+ 19
- 12
src/java/org/apache/fop/fo/properties/CommonBorderPaddingBackground.java View File

@@ -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],

+ 6
- 0
src/java/org/apache/fop/layoutmgr/TraitSetter.java View File

@@ -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);

+ 17
- 10
src/java/org/apache/fop/render/AbstractPathOrientedRenderer.java View File

@@ -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);
}
}

+ 42
- 0
test/java/org/apache/fop/area/TraitTestCase.java View File

@@ -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)));
}

}

+ 162
- 0
test/java/org/apache/fop/render/AbstractPathOrientedRendererTestCase.java View File

@@ -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() {
}

}
}

Loading…
Cancel
Save