001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /* $Id: ExternalGraphicLayoutManager.java 426576 2006-07-28 15:44:37Z jeremias $ */
019:
020: package org.apache.fop.layoutmgr.inline;
021:
022: import java.awt.geom.Rectangle2D;
023: import org.apache.fop.area.Area;
024: import org.apache.fop.area.inline.Image;
025: import org.apache.fop.fo.flow.ExternalGraphic;
026:
027: /**
028: * LayoutManager for the fo:external-graphic formatting object
029: */
030: public class ExternalGraphicLayoutManager extends
031: AbstractGraphicsLayoutManager {
032:
033: private ExternalGraphic fobj;
034:
035: /**
036: * Constructor
037: *
038: * @param node the fo:external-graphic formatting object that creates the area
039: */
040: public ExternalGraphicLayoutManager(ExternalGraphic node) {
041: super (node);
042: fobj = node;
043: }
044:
045: /**
046: * Setup this image.
047: * This gets the sizes for the image and the dimensions and clipping.
048: * @todo see if can simplify property handling logic
049: */
050: /*
051: private void setup() {
052: // assume lr-tb for now and just use the .optimum value of the range
053: Length ipd = fobj.getInlineProgressionDimension().getOptimum(this).getLength();
054: if (ipd.getEnum() != EN_AUTO) {
055: viewWidth = ipd.getValue(this);
056: } else {
057: ipd = fobj.getWidth();
058: if (ipd.getEnum() != EN_AUTO) {
059: viewWidth = ipd.getValue(this);
060: }
061: }
062: Length bpd = fobj.getBlockProgressionDimension().getOptimum(this).getLength();
063: if (bpd.getEnum() != EN_AUTO) {
064: viewHeight = bpd.getValue(this);
065: } else {
066: bpd = fobj.getHeight();
067: if (bpd.getEnum() != EN_AUTO) {
068: viewHeight = bpd.getValue(this);
069: }
070: }
071:
072: int cwidth = -1;
073: int cheight = -1;
074: Length ch = fobj.getContentHeight();
075: if (ch.getEnum() != EN_AUTO) {
076: if (ch.getEnum() == EN_SCALE_TO_FIT) {
077: if (viewHeight != -1) {
078: cheight = viewHeight;
079: }
080: } else {
081: cheight = ch.getValue(this);
082: }
083: }
084: Length cw = fobj.getContentWidth();
085: if (cw.getEnum() != EN_AUTO) {
086: if (cw.getEnum() == EN_SCALE_TO_FIT) {
087: if (viewWidth != -1) {
088: cwidth = viewWidth;
089: }
090: } else {
091: cwidth = cw.getValue(this);
092: }
093: }
094:
095: int scaling = fobj.getScaling();
096: if ((scaling == EN_UNIFORM) || (cwidth == -1) || cheight == -1) {
097: if (cwidth == -1 && cheight == -1) {
098: cwidth = fobj.getIntrinsicWidth();
099: cheight = fobj.getIntrinsicHeight();
100: } else if (cwidth == -1) {
101: cwidth = (int)(fobj.getIntrinsicWidth() * (double)cheight
102: / fobj.getIntrinsicHeight());
103: } else if (cheight == -1) {
104: cheight = (int)(fobj.getIntrinsicHeight() * (double)cwidth
105: / fobj.getIntrinsicWidth());
106: } else {
107: // adjust the larger
108: double rat1 = (double)cwidth / fobj.getIntrinsicWidth();
109: double rat2 = (double)cheight / fobj.getIntrinsicHeight();
110: if (rat1 < rat2) {
111: // reduce cheight
112: cheight = (int)(rat1 * fobj.getIntrinsicHeight());
113: } else if (rat1 > rat2) {
114: cwidth = (int)(rat2 * fobj.getIntrinsicWidth());
115: }
116: }
117: }
118:
119: if (viewWidth == -1) {
120: viewWidth = cwidth;
121: }
122: if (viewHeight == -1) {
123: viewHeight = cheight;
124: }
125:
126: if (cwidth > viewWidth || cheight > viewHeight) {
127: int overflow = fobj.getOverflow();
128: if (overflow == EN_HIDDEN) {
129: clip = true;
130: } else if (overflow == EN_ERROR_IF_OVERFLOW) {
131: fobj.getLogger().error("Image: " + fobj.getURL()
132: + " overflows the viewport, clipping to viewport");
133: clip = true;
134: }
135: }
136:
137: int xoffset = 0;
138: int yoffset = 0;
139: switch(fobj.getDisplayAlign()) {
140: case EN_BEFORE:
141: break;
142: case EN_AFTER:
143: yoffset = viewHeight - cheight;
144: break;
145: case EN_CENTER:
146: yoffset = (viewHeight - cheight) / 2;
147: break;
148: case EN_AUTO:
149: default:
150: break;
151: }
152:
153: switch(fobj.getTextAlign()) {
154: case EN_CENTER:
155: xoffset = (viewWidth - cwidth) / 2;
156: break;
157: case EN_END:
158: xoffset = viewWidth - cwidth;
159: break;
160: case EN_START:
161: break;
162: case EN_JUSTIFY:
163: default:
164: break;
165: }
166:
167:
168: CommonBorderPaddingBackground borderProps = fobj.getCommonBorderPaddingBackground();
169:
170: //Determine extra BPD from borders etc.
171: int beforeBPD = borderProps.getPadding(CommonBorderPaddingBackground.BEFORE, false, this);
172: beforeBPD += borderProps.getBorderWidth(CommonBorderPaddingBackground.BEFORE,
173: false);
174: int afterBPD = borderProps.getPadding(CommonBorderPaddingBackground.AFTER, false, this);
175: afterBPD += borderProps.getBorderWidth(CommonBorderPaddingBackground.AFTER, false);
176:
177: yoffset += beforeBPD;
178: viewBPD = viewHeight;
179: viewHeight += beforeBPD;
180: viewHeight += afterBPD;
181:
182: //Determine extra IPD from borders etc.
183: int startIPD = borderProps.getPadding(CommonBorderPaddingBackground.START,
184: false, this);
185: startIPD += borderProps.getBorderWidth(CommonBorderPaddingBackground.START,
186: false);
187: int endIPD = borderProps.getPadding(CommonBorderPaddingBackground.END, false, this);
188: endIPD += borderProps.getBorderWidth(CommonBorderPaddingBackground.END, false);
189:
190: xoffset += startIPD;
191: viewIPD = viewWidth;
192: viewWidth += startIPD;
193: viewWidth += endIPD;
194:
195: placement = new Rectangle2D.Float(xoffset, yoffset, cwidth, cheight);
196: }
197: */
198:
199: /**
200: * Get the inline area created by this element.
201: *
202: * @return the inline area
203: */
204: protected Area getChildArea() {
205: return new Image(fobj.getSrc());
206: }
207:
208: }
|