public void setBaselineOffset(int baselineOffset) {
this.baselineOffset = baselineOffset;
}
- return getOffset();
+
+ @Override
+ int getVirtualOffset() {
++ return getBlockProgressionOffset();
+ }
+
+ @Override
+ int getVirtualBPD() {
+ /* Word and space areas don't have a properly set bpd; return this area's bpd instead. */
+ return getBPD();
+ }
}
--- /dev/null
- setOffset(getOffset() + minChildOffset);
+ /*
+ * 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.area.inline;
+
+ import org.apache.fop.area.Area;
+
+ /**
+ * An inline area produced by an fo:basic-link element. This class implements a different
+ * behavior to what is prescribed by the XSL-FO 1.1 Recommendation. With the standard
+ * behavior, there is no easy way to make a link cover e.g. a whole image.
+ *
+ * <p>See following bug report at W3C's:
+ * http://www.w3.org/Bugs/Public/show_bug.cgi?id=11672</p>
+ */
+ public class BasicLinkArea extends InlineParent {
+
+ private static final long serialVersionUID = 5183753430412208151L;
+
+ @Override
+ public void setParentArea(Area parentArea) {
+ super.setParentArea(parentArea);
+ /*
+ * Perform necessary modifications to make this area encompass all of its children
+ * elements, so as to have a useful active area. We assume that this method is
+ * called after all of the children areas have been added to this area.
+ */
+ /* Make this area start at its beforest child. */
- inline.setOffset(inline.getOffset() - minChildOffset);
++ setBlockProgressionOffset(getBlockProgressionOffset() + minChildOffset);
+ /* Update children offsets accordingly. */
+ for (InlineArea inline : inlines) {
++ inline.setBlockProgressionOffset(inline.getBlockProgressionOffset() - minChildOffset);
+ }
+ setBPD(getVirtualBPD());
+ }
+
+ }
InlineArea child = (InlineArea) childrenIterator.next();
if (child instanceof InlineParent) {
setChildOffset(((InlineParent) child).getChildAreas().listIterator(), v);
- } else if (child instanceof org.apache.fop.area.inline.Viewport) {
+ } else if (child instanceof InlineViewport) {
// nothing
} else {
- child.setOffset(v);
+ child.setBlockProgressionOffset(v);
}
}
}
storedIPDVariation += ipdVariation;
}
}
- return getOffset();
+
+ /**
+ * Returns the offset that this area would have if its offset and size were taking
+ * children areas into account. The bpd of an inline area is taken from its nominal
+ * font and doesn't depend on the bpds of its children elements. However, in the case
+ * of a basic-link element we want the active area to cover all of the children
+ * elements.
+ *
+ * @return the offset that this area would have if the before-edge of its
+ * content-rectangle were coinciding with the <q>beforest</q> before-edge of its
+ * children allocation-rectangles.
+ * @see #getVirtualBPD()
+ * @see BasicLinkArea
+ */
+ int getVirtualOffset() {
++ return getBlockProgressionOffset();
+ }
+
+ /**
+ * Returns the block-progression-dimension that this area would have if it were taking
+ * its children elements into account. See {@linkplain #getVirtualOffset()}.
+ *
+ * @return the bpd
+ */
+ int getVirtualBPD() {
+ return getBPD();
+ }
}
-
if (inlines.size() == 0) {
autoSize = (getIPD() == 0);
}
- if (childArea instanceof InlineArea) {
- InlineArea inlineChildArea = (InlineArea) childArea;
- inlines.add(inlineChildArea);
- // set the parent area for the child area
- inlineChildArea.setParentArea(this);
- if (autoSize) {
- increaseIPD(inlineChildArea.getAllocIPD());
- }
+ InlineArea childArea = (InlineArea) c;
+ inlines.add(childArea);
+ // set the parent area for the child area
+ childArea.setParentArea(this);
+ if (autoSize) {
+ increaseIPD(childArea.getAllocIPD());
+ updateLevel ( childArea.getBidiLevel() );
}
- return getOffset() + minChildOffset;
+ int childOffset = childArea.getVirtualOffset();
+ minChildOffset = Math.min(minChildOffset, childOffset);
+ maxAfterEdge = Math.max(maxAfterEdge, childOffset + childArea.getVirtualBPD());
+ }
+
+ @Override
+ int getVirtualOffset() {
++ return getBlockProgressionOffset() + minChildOffset;
+ }
+
+ @Override
+ int getVirtualBPD() {
+ return maxAfterEdge - minChildOffset;
}
/**
--- /dev/null
- out.writeObject(props);
+ /*
+ * 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.area.inline;
+
+ import java.awt.Rectangle;
+ import java.awt.geom.Rectangle2D;
+ import java.io.IOException;
+ import java.util.HashMap;
+
+ import org.apache.fop.area.Area;
+ import org.apache.fop.area.Viewport;
+
+ /**
+ * Inline viewport area.
+ * This is an inline-level viewport area for inline container,
+ * external graphic and instream foreign object. This viewport
+ * holds the area and positions it.
+ */
+ public class InlineViewport extends InlineArea implements Viewport {
+
+ private static final long serialVersionUID = 813338534627918689L;
+
+ // contents could be container, foreign object or image
+ private Area content;
+ // clipping for the viewport
+ private boolean clip = false;
+ // position of the child area relative to this area
+ private Rectangle2D contentPosition;
+
+ /**
+ * Create a new viewport area with the content area.
+ *
+ * @param child the child content area of this viewport
+ */
+ public InlineViewport(Area child) {
+ this.content = child;
+ }
+
+ /**
+ * Set the clip of this viewport.
+ *
+ * @param c true if this viewport should clip
+ */
+ public void setClip(boolean c) {
+ this.clip = c;
+ }
+
+ /** {@inheritDoc} */
+ public boolean hasClip() {
+ return this.clip;
+ }
+
+ /** {@inheritDoc} */
+ public Rectangle getClipRectangle() {
+ if (clip) {
+ return new Rectangle(getIPD(), getBPD());
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Set the position and size of the content of this viewport.
+ *
+ * @param cp the position and size to place the content
+ */
+ public void setContentPosition(Rectangle2D cp) {
+ this.contentPosition = cp;
+ }
+
+ /**
+ * Get the position and size of the content of this viewport.
+ *
+ * @return the position and size to place the content
+ */
+ public Rectangle2D getContentPosition() {
+ return this.contentPosition;
+ }
+
+ /**
+ * Sets the content area.
+ * @param content the content area
+ */
+ public void setContent(Area content) {
+ this.content = content;
+ }
+
+ /**
+ * Get the content area for this viewport.
+ *
+ * @return the content area
+ */
+ public Area getContent() {
+ return this.content;
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out)
+ throws IOException {
+ out.writeBoolean(contentPosition != null);
+ if (contentPosition != null) {
+ out.writeFloat((float) contentPosition.getX());
+ out.writeFloat((float) contentPosition.getY());
+ out.writeFloat((float) contentPosition.getWidth());
+ out.writeFloat((float) contentPosition.getHeight());
+ }
+ out.writeBoolean(clip);
- this.props = (HashMap) in.readObject();
++ out.writeObject(traits);
+ out.writeObject(content);
+ }
+
+ private void readObject(java.io.ObjectInputStream in)
+ throws IOException, ClassNotFoundException {
+ if (in.readBoolean()) {
+ contentPosition = new Rectangle2D.Float(in.readFloat(),
+ in.readFloat(),
+ in.readFloat(),
+ in.readFloat());
+ }
+ this.clip = in.readBoolean();
++ this.traits = (HashMap) in.readObject();
+ this.content = (Area) in.readObject();
+ }
+
+ }
}
/** {@inheritDoc} */
+ @Override
public String toString() {
- StringBuffer sb = new StringBuffer();
+ StringBuilder sb = new StringBuilder("BFEntry: ");
- sb.append("Unicode ").append(getUnicodeStart()).append("..").append(getUnicodeEnd());
- sb.append(" --> ").append(getGlyphStartIndex()).append("..");
- sb.append(getGlyphStartIndex() + getUnicodeEnd() - getUnicodeStart());
+ sb.append ( "{ UC[" );
+ sb.append ( unicodeStart );
+ sb.append ( ',' );
+ sb.append ( unicodeEnd );
+ sb.append ( "]: GC[" );
+ sb.append ( glyphStartIndex );
+ sb.append ( ',' );
+ sb.append ( glyphStartIndex + ( unicodeEnd - unicodeStart ) );
+ sb.append ( "] }" );
return sb.toString();
}
/**
* Create and initialize an <code>InlineArea</code>
*
- * @param hasInlineParent true if the parent is an inline
+ * @param isInline true if the parent is an inline
* @return the area
*/
- protected InlineArea createArea(boolean hasInlineParent) {
+ protected InlineArea createArea(boolean isInline) {
InlineArea area;
- if (hasInlineParent) {
- area = new InlineParent();
+ if (isInline) {
+ area = createInlineParent();
- area.setOffset(0);
+ area.setBlockProgressionOffset(0);
} else {
area = new InlineBlockParent();
}
}
lineArea.setBPD(lbp.lineHeight);
lineArea.setIPD(lbp.lineWidth);
- lineArea.addTrait(Trait.SPACE_BEFORE, new Integer(lbp.spaceBefore));
- lineArea.addTrait(Trait.SPACE_AFTER, new Integer(lbp.spaceAfter));
+ lineArea.setBidiLevel(bidiLevel);
+ lineArea.addTrait(Trait.SPACE_BEFORE, lbp.spaceBefore);
+ lineArea.addTrait(Trait.SPACE_AFTER, lbp.spaceAfter);
alignmentContext.resizeLine(lbp.lineHeight, lbp.baseline);
if (seq instanceof Paragraph) {
* This renders an inline viewport by clipping if necessary.
* @param viewport the viewport to handle
*/
- public void renderViewport(Viewport viewport) {
+ public void renderInlineViewport(InlineViewport viewport) {
float x = currentIPPosition / 1000f;
- float y = (currentBPPosition + viewport.getOffset()) / 1000f;
+ float y = (currentBPPosition + viewport.getBlockProgressionOffset()) / 1000f;
float width = viewport.getIPD() / 1000f;
float height = viewport.getBPD() / 1000f;
// TODO: Calculate the border rect correctly.
* Render the given Viewport.
* @param viewport the viewport to render
*/
- protected void renderViewport(Viewport viewport) {
+ protected void renderInlineViewport(InlineViewport viewport) {
Area content = viewport.getContent();
int saveBP = currentBPPosition;
- currentBPPosition += viewport.getOffset();
+ currentBPPosition += viewport.getBlockProgressionOffset();
Rectangle2D contpos = viewport.getContentPosition();
if (content instanceof Image) {
renderImage((Image) content, contpos);
/** {@inheritDoc} */
public void drawText(int x, int y, int letterSpacing, int wordSpacing,
- int[] dx, String text) throws IFException {
+ int[][] dp, String text) throws IFException {
try {
+ addID();
AttributesImpl atts = new AttributesImpl();
addAttribute(atts, "x", Integer.toString(x));
addAttribute(atts, "y", Integer.toString(y));
atts.clear();
addAreaAttributes(viewport);
addTraitAttributes(viewport);
- addAttribute("offset", viewport.getOffset());
+ addAttribute("offset", viewport.getBlockProgressionOffset());
addAttribute("pos", viewport.getContentPosition());
- if (viewport.getClip()) {
+ if (viewport.hasClip()) {
addAttribute("clip", "true");
}
startElement("viewport", atts);