gmazza 2004/08/14 11:36:22
Modified: src/java/org/apache/fop/fo FObjMixed.java
src/java/org/apache/fop/fo/flow Inline.java
InstreamForeignObject.java
src/java/org/apache/fop/layoutmgr AddLMVisitor.java
Added: src/java/org/apache/fop/layoutmgr
InstreamForeignObjectLM.java
Log:
1.) fo:Instream-Foreign-Object initialization logic moved from AddLMVisitor
to flow.InstreamForiegnObject.java, and the layout logic itself moved to
a new layoutmgr.InstreamForeignObjectLM.java. (Broke with usual nomenclature of
adding
~LayoutManager to end, given that newer 1.1 and post-1.1 FO names are
getting even larger.)
2.) validateChildNode() added for fo:inline.
Revision Changes Path
1.33 +1 -0 xml-fop/src/java/org/apache/fop/fo/FObjMixed.java
Index: FObjMixed.java
===================================================================
RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/fo/FObjMixed.java,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -r1.32 -r1.33
--- FObjMixed.java 11 Aug 2004 04:15:25 -0000 1.32
+++ FObjMixed.java 14 Aug 2004 18:36:21 -0000 1.33
@@ -26,6 +26,7 @@
/**
* Base class for representation of mixed content formatting objects
* and their processing
+ * @todo define what a "mixed content formatting object" is
*/
public class FObjMixed extends FObj {
/** TextInfo for this object */
1.25 +53 -33 xml-fop/src/java/org/apache/fop/fo/flow/Inline.java
Index: Inline.java
===================================================================
RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/fo/flow/Inline.java,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -r1.24 -r1.25
--- Inline.java 11 Aug 2004 04:15:25 -0000 1.24
+++ Inline.java 14 Aug 2004 18:36:21 -0000 1.25
@@ -20,34 +20,23 @@
// XML
import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
import org.xml.sax.SAXParseException;
// FOP
-import org.apache.fop.apps.FOPException;
import org.apache.fop.fo.CharIterator;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.FObjMixed;
import org.apache.fop.fo.InlineCharIterator;
-import org.apache.fop.layoutmgr.AddLMVisitor;
-import org.apache.fop.fo.properties.CommonAccessibility;
-import org.apache.fop.fo.properties.CommonAural;
-import org.apache.fop.fo.properties.CommonBackground;
-import org.apache.fop.fo.properties.CommonBorderAndPadding;
-import org.apache.fop.fo.properties.CommonMarginInline;
-import org.apache.fop.fo.properties.CommonRelativePosition;
/**
- * Class modelling the fo:inline object. See Sec. 6.6.7 of the XSL-FO Standard.
+ * Class modelling the fo:inline formatting object.
*/
public class Inline extends FObjMixed {
- // Textdecoration
- /** is this text underlined? */
- protected boolean underlined = false;
- /** is this text overlined? */
- protected boolean overlined = false;
- /** is this text lined through? */
- protected boolean lineThrough = false;
+ // used for FO validation
+ private boolean blockOrInlineItemFound = false;
+ private boolean canHaveBlockLevelChildren = true;
/**
* @param parent FONode that is the parent of this object
@@ -62,28 +51,56 @@
protected void addProperties(Attributes attlist) throws SAXParseException {
super.addProperties(attlist);
- if (parent.getName().equals("fo:flow")) {
- throw new SAXParseException("inline formatting objects cannot"
- + " be directly under flow", locator);
- }
-
- int textDecoration = this.propertyList.get(PR_TEXT_DECORATION).getEnum();
-
- if (textDecoration == TextDecoration.UNDERLINE) {
- this.underlined = true;
- }
+ /* Check to see if this node can have block-level children.
+ * See validateChildNode() below.
+ */
+ int lvlLeader = findAncestor("fo:leader");
+ int lvlFootnote = findAncestor("fo:footnote");
+ int lvlInCntr = findAncestor("fo:inline-container");
+
+ if (lvlLeader > 0) {
+ if (lvlInCntr < 0 ||
+ (lvlInCntr > 0 && lvlInCntr > lvlLeader)) {
+ canHaveBlockLevelChildren = false;
+ }
+ } else if (lvlFootnote > 0) {
+ if (lvlInCntr < 0 || lvlInCntr > lvlFootnote) {
+ canHaveBlockLevelChildren = false;
+ }
+ }
- if (textDecoration == TextDecoration.OVERLINE) {
- this.overlined = true;
- }
+ getFOInputHandler().startInline(this);
+ }
- if (textDecoration == TextDecoration.LINE_THROUGH) {
- this.lineThrough = true;
+ /**
+ * @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String)
+ * XSL Content Model: marker* (#PCDATA|%inline;|%block;)*
+ * Additionally: " An fo:inline that is a descendant of an fo:leader
+ * or fo:footnote may not have block-level children, unless it has a
+ * nearer ancestor that is an fo:inline-container." (paraphrased)
+ */
+ protected void validateChildNode(Locator loc, String nsURI, String localName)
+ throws SAXParseException {
+ if (nsURI == FO_URI && localName.equals("marker")) {
+ if (blockOrInlineItemFound) {
+ nodesOutOfOrderError(loc, "fo:marker",
+ "(#PCDATA|%inline;|%block;)");
+ }
+ } else if (!isBlockOrInlineItem(nsURI, localName)) {
+ invalidChildError(loc, nsURI, localName);
+ } else if (!canHaveBlockLevelChildren && isBlockItem(nsURI, localName)) {
+ String ruleViolated =
+ " An fo:inline that is a descendant of an fo:leader" +
+ " or fo:footnote may not have block-level children," +
+ " unless it has a nearer ancestor that is an" +
+ " fo:inline-container.";
+ invalidChildError(loc, nsURI, localName, ruleViolated);
+ } else {
+ blockOrInlineItemFound = true;
}
-
- getFOInputHandler().startInline(this);
}
+
/**
* @see org.apache.fop.fo.FONode#end
*/
@@ -98,6 +115,9 @@
return new InlineCharIterator(this, propMgr.getBorderAndPadding());
}
+ /**
+ * @see org.apache.fop.fo.FObj#getName()
+ */
public String getName() {
return "fo:inline";
}
1.20 +12 -8
xml-fop/src/java/org/apache/fop/fo/flow/InstreamForeignObject.java
Index: InstreamForeignObject.java
===================================================================
RCS file:
/home/cvs/xml-fop/src/java/org/apache/fop/fo/flow/InstreamForeignObject.java,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- InstreamForeignObject.java 8 Aug 2004 18:39:23 -0000 1.19
+++ InstreamForeignObject.java 14 Aug 2004 18:36:21 -0000 1.20
@@ -18,6 +18,9 @@
package org.apache.fop.fo.flow;
+// Java
+import java.util.List;
+
// XML
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
@@ -25,8 +28,7 @@
// FOP
import org.apache.fop.fo.FONode;
-import org.apache.fop.fo.LMVisited;
-import org.apache.fop.layoutmgr.AddLMVisitor;
+import org.apache.fop.layoutmgr.InstreamForeignObjectLM;
import org.apache.fop.fo.FObj;
/**
@@ -34,7 +36,7 @@
* This is an atomic inline object that contains
* xml data.
*/
-public class InstreamForeignObject extends FObj implements LMVisited {
+public class InstreamForeignObject extends FObj {
boolean hasNonXSLNamespaceElement = false;
@@ -121,14 +123,16 @@
}
/**
- * This is a hook for the AddLMVisitor class to be able to access
- * this object.
- * @param aLMV the AddLMVisitor object that can access this object.
+ * @see org.apache.fop.fo.FObj#addLayoutManager(List)
*/
- public void acceptVisitor(AddLMVisitor aLMV) {
- aLMV.serveInstreamForeignObject(this);
+ public void addLayoutManager(List list) {
+ InstreamForeignObjectLM lm = new InstreamForeignObjectLM(this);
+ list.add(lm);
}
+ /**
+ * @see org.apache.fop.fo.FObj#getName()
+ */
public String getName() {
return "fo:instream-foreign-object";
}
1.56 +1 -170 xml-fop/src/java/org/apache/fop/layoutmgr/AddLMVisitor.java
Index: AddLMVisitor.java
===================================================================
RCS file: /home/cvs/xml-fop/src/java/org/apache/fop/layoutmgr/AddLMVisitor.java,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -r1.55 -r1.56
--- AddLMVisitor.java 13 Aug 2004 12:29:51 -0000 1.55
+++ AddLMVisitor.java 14 Aug 2004 18:36:21 -0000 1.56
@@ -16,29 +16,20 @@
/* $Id$ */
-
package org.apache.fop.layoutmgr;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
import java.util.List;
import java.util.ListIterator;
import org.apache.fop.area.Trait;
import org.apache.fop.area.inline.FilledArea;
-import org.apache.fop.area.inline.ForeignObject;
import org.apache.fop.area.inline.InlineArea;
import org.apache.fop.area.inline.Space;
-import org.apache.fop.area.inline.Viewport;
import org.apache.fop.area.inline.TextArea;
import org.apache.fop.datatypes.Length;
import org.apache.fop.fo.Constants;
-import org.apache.fop.fo.FONode;
import org.apache.fop.fo.FObj;
-import org.apache.fop.fo.XMLObj;
-import org.apache.fop.fo.flow.Block;
import org.apache.fop.fo.flow.Inline;
-import org.apache.fop.fo.flow.InstreamForeignObject;
import org.apache.fop.fo.flow.Leader;
import org.apache.fop.fo.flow.Wrapper;
import org.apache.fop.traits.MinOptMax;
@@ -208,165 +199,5 @@
leaderArea = fa;
}
return leaderArea;
- }
-
- public void serveInstreamForeignObject(InstreamForeignObject node) {
- Viewport areaCurrent = getInstreamForeignObjectInlineArea(node);
- if (areaCurrent != null) {
- LeafNodeLayoutManager lm = new LeafNodeLayoutManager(node);
- lm.setCurrentArea(areaCurrent);
-
lm.setAlignment(node.getProperty(Constants.PR_VERTICAL_ALIGN).getEnum());
- lm.setLead(areaCurrent.getHeight());
- currentLMList.add(lm);
- }
- }
- /**
- * Get the inline area created by this element.
- *
- * @return the viewport inline area
- */
- public Viewport getInstreamForeignObjectInlineArea(InstreamForeignObject node)
{
- if (node.getChildNodes() == null) {
- return null;
- }
-
- if (node.childNodes.size() != 1) {
- // error
- return null;
- }
- FONode fo = (FONode) node.childNodes.get(0);
- if (!(fo instanceof XMLObj)) {
- // error
- return null;
- }
- XMLObj child = (XMLObj)fo;
-
- // viewport size is determined by block-progression-dimension
- // and inline-progression-dimension
-
- // if replaced then use height then ignore block-progression-dimension
- //int h = this.propertyList.get("height").getLength().mvalue();
-
- // use specified line-height then ignore dimension in height direction
- boolean hasLH =
false;//propertyList.get("line-height").getSpecifiedValue() != null;
-
- Length len;
-
- int bpd = -1;
- int ipd = -1;
- boolean bpdauto = false;
- if (hasLH) {
- bpd =
node.getProperty(Constants.PR_LINE_HEIGHT).getLength().getValue();
- } else {
- // this property does not apply when the line-height applies
- // isn't the block-progression-dimension always in the same
- // direction as the line height?
- len = node.getProperty(Constants.PR_BLOCK_PROGRESSION_DIMENSION |
Constants.CP_OPTIMUM).getLength();
- if (!len.isAuto()) {
- bpd = len.getValue();
- } else {
- len = node.getProperty(Constants.PR_HEIGHT).getLength();
- if (!len.isAuto()) {
- bpd = len.getValue();
- }
- }
- }
-
- len = node.getProperty(Constants.PR_INLINE_PROGRESSION_DIMENSION |
Constants.CP_OPTIMUM).getLength();
- if (!len.isAuto()) {
- ipd = len.getValue();
- } else {
- len = node.getProperty(Constants.PR_WIDTH).getLength();
- if (!len.isAuto()) {
- ipd = len.getValue();
- }
- }
-
- // if auto then use the intrinsic size of the content scaled
- // to the content-height and content-width
- int cwidth = -1;
- int cheight = -1;
- len = node.getProperty(Constants.PR_CONTENT_WIDTH).getLength();
- if (!len.isAuto()) {
- /*if(len.scaleToFit()) {
- if(ipd != -1) {
- cwidth = ipd;
- }
- } else {*/
- cwidth = len.getValue();
- }
- len = node.getProperty(Constants.PR_CONTENT_HEIGHT).getLength();
- if (!len.isAuto()) {
- /*if(len.scaleToFit()) {
- if(bpd != -1) {
- cwidth = bpd;
- }
- } else {*/
- cheight = len.getValue();
- }
-
- Point2D csize = new Point2D.Float(cwidth == -1 ? -1 : cwidth / 1000f,
- cheight == -1 ? -1 : cheight / 1000f);
- Point2D size = child.getDimension(csize);
- if (size == null) {
- // error
- return null;
- }
- if (cwidth == -1) {
- cwidth = (int)size.getX() * 1000;
- }
- if (cheight == -1) {
- cheight = (int)size.getY() * 1000;
- }
- int scaling = node.getProperty(Constants.PR_SCALING).getEnum();
- if (scaling == Constants.Scaling.UNIFORM) {
- // adjust the larger
- double rat1 = cwidth / (size.getX() * 1000f);
- double rat2 = cheight / (size.getY() * 1000f);
- if (rat1 < rat2) {
- // reduce cheight
- cheight = (int)(rat1 * size.getY() * 1000);
- } else {
- cwidth = (int)(rat2 * size.getX() * 1000);
- }
- }
-
- if (ipd == -1) {
- ipd = cwidth;
- }
- if (bpd == -1) {
- bpd = cheight;
- }
-
- boolean clip = false;
- if (cwidth > ipd || cheight > bpd) {
- int overflow = node.getProperty(Constants.PR_OVERFLOW).getEnum();
- if (overflow == Constants.Overflow.HIDDEN) {
- clip = true;
- } else if (overflow == Constants.Overflow.ERROR_IF_OVERFLOW) {
- node.getLogger().error("Instream foreign object overflows the
viewport: clipping");
- clip = true;
- }
- }
-
- int xoffset = node.computeXOffset(ipd, cwidth);
- int yoffset = node.computeYOffset(bpd, cheight);
-
- Rectangle2D placement = new Rectangle2D.Float(xoffset, yoffset, cwidth,
cheight);
-
- org.w3c.dom.Document doc = child.getDOMDocument();
- String ns = child.getDocumentNamespace();
-
- node.childNodes = null;
- ForeignObject foreign = new ForeignObject(doc, ns);
-
- Viewport areaCurrent = new Viewport(foreign);
- areaCurrent.setWidth(ipd);
- areaCurrent.setHeight(bpd);
- areaCurrent.setContentPosition(placement);
- areaCurrent.setClip(clip);
- areaCurrent.setOffset(0);
-
- return areaCurrent;
}
}
1.1
xml-fop/src/java/org/apache/fop/layoutmgr/InstreamForeignObjectLM.java
Index: InstreamForeignObjectLM.java
===================================================================
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed 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: InstreamForeignObjectLM.java,v 1.1 2004/08/14 18:36:21 gmazza Exp $ */
package org.apache.fop.layoutmgr;
// Java
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
// FOP
import org.apache.fop.datatypes.Length;
import org.apache.fop.fo.XMLObj;
import org.apache.fop.fo.flow.InstreamForeignObject;
import org.apache.fop.area.inline.ForeignObject;
import org.apache.fop.area.inline.InlineArea;
import org.apache.fop.area.inline.Viewport;
/**
* LayoutManager for the fo:basic-link formatting object
*/
public class InstreamForeignObjectLM extends LeafNodeLayoutManager {
InstreamForeignObject ifoNode;
/**
* Constructor
* @param node the formatting object that creates this area
*/
public InstreamForeignObjectLM(InstreamForeignObject node) {
super(node);
ifoNode = node;
Viewport areaCurrent = getInlineArea();
setCurrentArea(areaCurrent);
setAlignment(node.getProperty(PR_VERTICAL_ALIGN).getEnum());
setLead(areaCurrent.getHeight());
}
/**
* Get the inline area created by this element.
*
* @return the viewport inline area
*/
private Viewport getInlineArea() {
XMLObj child = (XMLObj) ifoNode.childNodes.get(0);
// viewport size is determined by block-progression-dimension
// and inline-progression-dimension
// if replaced then use height then ignore block-progression-dimension
//int h = this.propertyList.get("height").getLength().mvalue();
// use specified line-height then ignore dimension in height direction
boolean hasLH = false;//propertyList.get("line-height").getSpecifiedValue()
!= null;
Length len;
int bpd = -1;
int ipd = -1;
boolean bpdauto = false;
if (hasLH) {
bpd = ifoNode.getProperty(PR_LINE_HEIGHT).getLength().getValue();
} else {
// this property does not apply when the line-height applies
// isn't the block-progression-dimension always in the same
// direction as the line height?
len = ifoNode.getProperty(PR_BLOCK_PROGRESSION_DIMENSION |
CP_OPTIMUM).getLength();
if (!len.isAuto()) {
bpd = len.getValue();
} else {
len = ifoNode.getProperty(PR_HEIGHT).getLength();
if (!len.isAuto()) {
bpd = len.getValue();
}
}
}
len = ifoNode.getProperty(PR_INLINE_PROGRESSION_DIMENSION |
CP_OPTIMUM).getLength();
if (!len.isAuto()) {
ipd = len.getValue();
} else {
len = ifoNode.getProperty(PR_WIDTH).getLength();
if (!len.isAuto()) {
ipd = len.getValue();
}
}
// if auto then use the intrinsic size of the content scaled
// to the content-height and content-width
int cwidth = -1;
int cheight = -1;
len = ifoNode.getProperty(PR_CONTENT_WIDTH).getLength();
if (!len.isAuto()) {
/*if(len.scaleToFit()) {
if(ipd != -1) {
cwidth = ipd;
}
} else {*/
cwidth = len.getValue();
}
len = ifoNode.getProperty(PR_CONTENT_HEIGHT).getLength();
if (!len.isAuto()) {
/*if(len.scaleToFit()) {
if(bpd != -1) {
cwidth = bpd;
}
} else {*/
cheight = len.getValue();
}
Point2D csize = new Point2D.Float(cwidth == -1 ? -1 : cwidth / 1000f,
cheight == -1 ? -1 : cheight / 1000f);
Point2D size = child.getDimension(csize);
if (size == null) {
// error
return null;
}
if (cwidth == -1) {
cwidth = (int)size.getX() * 1000;
}
if (cheight == -1) {
cheight = (int)size.getY() * 1000;
}
int scaling = ifoNode.getProperty(PR_SCALING).getEnum();
if (scaling == Scaling.UNIFORM) {
// adjust the larger
double rat1 = cwidth / (size.getX() * 1000f);
double rat2 = cheight / (size.getY() * 1000f);
if (rat1 < rat2) {
// reduce cheight
cheight = (int)(rat1 * size.getY() * 1000);
} else {
cwidth = (int)(rat2 * size.getX() * 1000);
}
}
if (ipd == -1) {
ipd = cwidth;
}
if (bpd == -1) {
bpd = cheight;
}
boolean clip = false;
if (cwidth > ipd || cheight > bpd) {
int overflow = ifoNode.getProperty(PR_OVERFLOW).getEnum();
if (overflow == Overflow.HIDDEN) {
clip = true;
} else if (overflow == Overflow.ERROR_IF_OVERFLOW) {
ifoNode.getLogger().error("Instream foreign object overflows the
viewport: clipping");
clip = true;
}
}
int xoffset = ifoNode.computeXOffset(ipd, cwidth);
int yoffset = ifoNode.computeYOffset(bpd, cheight);
Rectangle2D placement = new Rectangle2D.Float(xoffset, yoffset, cwidth,
cheight);
org.w3c.dom.Document doc = child.getDOMDocument();
String ns = child.getDocumentNamespace();
ifoNode.childNodes = null;
ForeignObject foreign = new ForeignObject(doc, ns);
Viewport areaCurrent = new Viewport(foreign);
areaCurrent.setWidth(ipd);
areaCurrent.setHeight(bpd);
areaCurrent.setContentPosition(placement);
areaCurrent.setClip(clip);
areaCurrent.setOffset(0);
return areaCurrent;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]