handles alignment.fo git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194730 13f79535-47bb-0310-9956-ffa450edef68tags/fop-0_20_4-doc
@@ -12,6 +12,8 @@ import org.apache.fop.area.MinOptMax; | |||
import org.apache.fop.area.Trait; | |||
import org.apache.fop.render.Renderer; | |||
import org.apache.fop.layoutmgr.LayoutInfo; | |||
import java.util.List; | |||
import java.util.ArrayList; | |||
@@ -28,6 +30,7 @@ public class InlineArea extends Area { | |||
// position within the line area, either top or baseline | |||
int verticalPosition; | |||
// width, height, vertical alignment | |||
public LayoutInfo info = null; | |||
// store properties in array list, need better solution | |||
ArrayList props = null; |
@@ -21,7 +21,7 @@ import org.apache.fop.datatypes.ColorType; | |||
*/ | |||
public class FObjMixed extends FObj { | |||
TextInfo textInfo = null; | |||
FontInfo fontInfo=null; | |||
protected FontInfo fontInfo=null; | |||
public FObjMixed(FONode parent) { | |||
super(parent); |
@@ -28,6 +28,7 @@ import java.util.NoSuchElementException; | |||
public int wrapOption; | |||
public int whiteSpaceCollapse; | |||
public int verticalAlign; | |||
public int lineHeight; | |||
// Textdecoration | |||
public boolean underlined = false; |
@@ -16,6 +16,7 @@ import org.apache.fop.apps.FOPException; | |||
import org.apache.fop.layoutmgr.LayoutManager; | |||
import org.apache.fop.layoutmgr.BlockLayoutManager; | |||
import org.apache.fop.util.CharUtilities; | |||
import org.apache.fop.apps.StreamRenderer; | |||
import org.xml.sax.Attributes; | |||
@@ -370,12 +371,13 @@ public class Block extends FObjMixed { | |||
BlockLayoutManager blm = new BlockLayoutManager(this); | |||
TextInfo ti = new TextInfo(); | |||
/* try { | |||
try { | |||
ti.fs = propMgr.getFontState(fontInfo); | |||
} catch (FOPException fopex) { | |||
log.error("Error setting FontState for characters: " + | |||
fopex.getMessage()); | |||
}*/ | |||
} | |||
ti.lineHeight = this.lineHeight; | |||
ColorType c = getProperty("color").getColorType(); | |||
ti.color = c; |
@@ -24,6 +24,7 @@ import org.apache.fop.layout.RelativePositionProps; | |||
import org.apache.fop.apps.FOPException; | |||
import org.apache.fop.layoutmgr.LayoutManager; | |||
import org.apache.fop.layoutmgr.LeafNodeLayoutManager; | |||
import org.apache.fop.layoutmgr.LayoutInfo; | |||
import org.w3c.dom.Document; | |||
@@ -136,6 +137,9 @@ public class InstreamForeignObject extends FObj { | |||
areaCurrent.setWidth((int)size.getX() * 1000); | |||
areaCurrent.setHeight((int)size.getY() * 1000); | |||
areaCurrent.setOffset(0); | |||
areaCurrent.info = new LayoutInfo(); | |||
areaCurrent.info.alignment = properties.get("vertical-align").getEnum(); | |||
areaCurrent.info.lead = areaCurrent.getHeight(); | |||
return areaCurrent; | |||
} |
@@ -23,12 +23,18 @@ public class BlockLayoutManager extends BlockStackingLayoutManager { | |||
private Block curBlockArea; | |||
int lead = 12000; | |||
int lineHeight = 14000; | |||
int follow = 2000; | |||
public BlockLayoutManager(FObj fobj) { | |||
super(fobj); | |||
} | |||
public void setBlockTextInfo(TextInfo ti) { | |||
lead = ti.fs.getAscender(); | |||
follow = ti.fs.getDescender(); | |||
lineHeight = ti.lineHeight; | |||
} | |||
/** | |||
@@ -54,7 +60,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager { | |||
FObj childFO = (FObj) children.next(); | |||
if (childFO.generatesInlineAreas()) { | |||
children.previous(); | |||
lm = new LineLayoutManager(children); | |||
lm = new LineLayoutManager(children, lineHeight, lead, follow); | |||
} else { | |||
lm = childFO.getLayoutManager(); | |||
} |
@@ -0,0 +1,21 @@ | |||
/* | |||
* $Id$ | |||
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved. | |||
* For details on use and redistribution please refer to the | |||
* LICENSE file included with these sources. | |||
*/ | |||
package org.apache.fop.layoutmgr; | |||
import org.apache.fop.area.Area; | |||
import org.apache.fop.area.MinOptMax; | |||
public class LayoutInfo { | |||
public int alignment; | |||
public int lead; | |||
public boolean blOffset = false; | |||
public LayoutInfo() { | |||
} | |||
} |
@@ -13,6 +13,10 @@ import org.apache.fop.area.Area; | |||
import org.apache.fop.area.LineArea; | |||
import org.apache.fop.area.MinOptMax; | |||
import org.apache.fop.area.inline.InlineArea; | |||
import org.apache.fop.fo.properties.VerticalAlign; | |||
import org.apache.fop.area.inline.Word; | |||
import org.apache.fop.area.inline.Character; | |||
import java.util.ListIterator; | |||
import java.util.List; | |||
@@ -31,11 +35,18 @@ public class LineLayoutManager extends AbstractLayoutManager { | |||
private boolean bFirstLine; | |||
private LayoutManager curLM; | |||
private MinOptMax remainingIPD; | |||
private int lineHeight = 14000; | |||
// the following values must be set by the block | |||
// these are the dominant basline and lineheight values | |||
private int lineHeight; | |||
private int lead; | |||
private int follow; | |||
public LineLayoutManager(ListIterator fobjIter) { | |||
public LineLayoutManager(ListIterator fobjIter, int lh, int l, int f) { | |||
super(null); | |||
this.fobjIter = fobjIter; | |||
lineHeight = lh; | |||
lead = l; | |||
follow = f; | |||
} | |||
/** | |||
@@ -70,23 +81,115 @@ public class LineLayoutManager extends AbstractLayoutManager { | |||
public void flush() { | |||
if (lineArea != null) { | |||
// Adjust spacing as necessary | |||
// Calculate height, based on content (or does the Area do this?) | |||
int maxHeight = lineHeight; | |||
List inlineAreas = lineArea.getInlineAreas(); | |||
for(Iterator iter = inlineAreas.iterator(); iter.hasNext(); ) { | |||
InlineArea inline = (InlineArea)iter.next(); | |||
int h = inline.getHeight(); | |||
if(h > maxHeight) { | |||
maxHeight = h; | |||
} | |||
} | |||
lineArea.setHeight(maxHeight); | |||
verticalAlign(); | |||
parentLM.addChild(lineArea); | |||
lineArea = null; | |||
} | |||
} | |||
private void verticalAlign() { | |||
int maxHeight = lineHeight; | |||
List inlineAreas = lineArea.getInlineAreas(); | |||
// get smallest possible offset to before edge | |||
// this depends on the height of no and middle alignments | |||
int before = lead; | |||
int after = follow; | |||
for(Iterator iter = inlineAreas.iterator(); iter.hasNext(); ) { | |||
InlineArea inline = (InlineArea)iter.next(); | |||
LayoutInfo info = inline.info; | |||
int al; | |||
int ld = inline.getHeight(); | |||
if(info != null) { | |||
al = info.alignment; | |||
ld = info.lead; | |||
} else { | |||
al = VerticalAlign.BASELINE; | |||
} | |||
if(al == VerticalAlign.BASELINE) { | |||
if(ld > before) { | |||
before = ld; | |||
} | |||
if(inline.getHeight() > before) { | |||
before = inline.getHeight(); | |||
} | |||
} else if(al == VerticalAlign.MIDDLE) { | |||
if(inline.getHeight() / 2 + lead / 2 > before) { | |||
before = inline.getHeight() / 2 + lead / 2; | |||
} | |||
if(inline.getHeight() / 2 - lead / 2 > after) { | |||
after = inline.getHeight() / 2 - lead / 2; | |||
} | |||
} else if(al == VerticalAlign.TOP) { | |||
} else if(al == VerticalAlign.BOTTOM) { | |||
} | |||
} | |||
// then align all before, no and middle alignment | |||
for(Iterator iter = inlineAreas.iterator(); iter.hasNext(); ) { | |||
InlineArea inline = (InlineArea)iter.next(); | |||
LayoutInfo info = inline.info; | |||
int al; | |||
int ld = inline.getHeight(); | |||
boolean bloffset = false; | |||
if(info != null) { | |||
al = info.alignment; | |||
ld = info.lead; | |||
bloffset = info.blOffset; | |||
} else { | |||
al = VerticalAlign.BASELINE; | |||
} | |||
if(al == VerticalAlign.BASELINE) { | |||
// the offset position for text is the baseline | |||
if(bloffset) { | |||
inline.setOffset(before); | |||
} else { | |||
inline.setOffset(before - ld); | |||
} | |||
if(inline.getHeight() - ld > after) { | |||
after = inline.getHeight() - ld; | |||
} | |||
} else if(al == VerticalAlign.MIDDLE) { | |||
inline.setOffset(before - inline.getHeight() / 2 - lead / 2); | |||
} else if(al == VerticalAlign.TOP) { | |||
inline.setOffset(0); | |||
if(inline.getHeight() - before > after) { | |||
after = inline.getHeight() - before; | |||
} | |||
} else if(al == VerticalAlign.BOTTOM) { | |||
if(inline.getHeight() - before > after) { | |||
after = inline.getHeight() - before; | |||
} | |||
} | |||
} | |||
// after alignment depends on maximum height of before | |||
// and middle alignments | |||
for(Iterator iter = inlineAreas.iterator(); iter.hasNext(); ) { | |||
InlineArea inline = (InlineArea)iter.next(); | |||
LayoutInfo info = inline.info; | |||
int al; | |||
if(info != null) { | |||
al = info.alignment; | |||
} else { | |||
al = VerticalAlign.BASELINE; | |||
} | |||
if(al == VerticalAlign.BASELINE) { | |||
} else if(al == VerticalAlign.MIDDLE) { | |||
} else if(al == VerticalAlign.TOP) { | |||
} else if(al == VerticalAlign.BOTTOM) { | |||
inline.setOffset(before + after - inline.getHeight()); | |||
} | |||
} | |||
if(before + after > maxHeight) { | |||
lineArea.setHeight(before + after); | |||
} else { | |||
lineArea.setHeight(maxHeight); | |||
} | |||
} | |||
/** | |||
* Return current lineArea or generate a new one if necessary. | |||
*/ |
@@ -14,6 +14,7 @@ import org.apache.fop.area.Trait; | |||
import org.apache.fop.area.inline.Word; | |||
import org.apache.fop.area.inline.Space; | |||
import org.apache.fop.util.CharUtilities; | |||
import org.apache.fop.fo.properties.VerticalAlign; | |||
import org.apache.fop.fo.properties.*; | |||
@@ -226,6 +227,10 @@ public class TextLayoutManager extends LeafNodeLayoutManager { | |||
curWordArea.setWidth(width); | |||
curWordArea.setHeight(textInfo.fs.getAscender() - textInfo.fs.getDescender()); | |||
curWordArea.setOffset(textInfo.fs.getAscender()); | |||
curWordArea.info = new LayoutInfo(); | |||
curWordArea.info.lead = textInfo.fs.getAscender(); | |||
curWordArea.info.alignment = VerticalAlign.BASELINE; | |||
curWordArea.info.blOffset = true; | |||
curWordArea.setWord(str); | |||
Trait prop = new Trait(); |
@@ -254,6 +254,8 @@ public abstract class AbstractRenderer implements Renderer { | |||
public void renderViewport(Viewport viewport) { | |||
Area content = viewport.getContent(); | |||
int saveBP = currentBPPosition; | |||
currentBPPosition += viewport.getOffset(); | |||
if (content instanceof Image) { | |||
renderImage((Image) content); | |||
} else if (content instanceof Container) { | |||
@@ -262,6 +264,7 @@ public abstract class AbstractRenderer implements Renderer { | |||
renderForeignObject((ForeignObject) content); | |||
} | |||
currentBlockIPPosition += viewport.getWidth(); | |||
currentBPPosition = saveBP; | |||
} | |||
public void renderImage(Image image) { |