From 44ce4a9a4545cfb2537dc632c64924611b6b4f5a Mon Sep 17 00:00:00 2001 From: Karen Lease Date: Wed, 11 Apr 2001 21:42:45 +0000 Subject: [PATCH] Make borders closer to CR spec git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@194203 13f79535-47bb-0310-9956-ffa450edef68 --- src/org/apache/fop/fo/flow/TableBody.java | 18 +- src/org/apache/fop/fo/flow/TableCell.java | 372 +++++++++++++--------- src/org/apache/fop/fo/flow/TableRow.java | 15 +- 3 files changed, 251 insertions(+), 154 deletions(-) diff --git a/src/org/apache/fop/fo/flow/TableBody.java b/src/org/apache/fop/fo/flow/TableBody.java index 83a7f5f0b..edb774fbe 100644 --- a/src/org/apache/fop/fo/flow/TableBody.java +++ b/src/org/apache/fop/fo/flow/TableBody.java @@ -144,11 +144,19 @@ public class TableBody extends FObj { } int spaceLeft = area.spaceLeft(); - this.areaContainer = new AreaContainer(propMgr.getFontState(area.getFontInfo()), - -area.getBorderLeftWidth(), - -area.getBorderTopWidth() + area.getHeight(), - area.getAllocationWidth(), area.spaceLeft(), - Position.RELATIVE); + + /* Note: the parent FO must be a Table. The parent Area is the Block + * type area created by the Table, which is also a reference area. + * The content "width" (IPD) of the TableBody is the same as that + * of the containing table area, and its relative position is 0,0. + * Strictly speaking (CR), this FO should generate no areas! + */ + this.areaContainer = + new AreaContainer(propMgr.getFontState(area.getFontInfo()), + 0,area.getHeight(), + area.getContentWidth(), // IPD + area.spaceLeft(), + Position.RELATIVE); areaContainer.foCreator=this; // G Seshadri areaContainer.setPage(area.getPage()); areaContainer.setBackgroundColor(backgroundColor); diff --git a/src/org/apache/fop/fo/flow/TableCell.java b/src/org/apache/fop/fo/flow/TableCell.java index 097ebd56a..e04f71c23 100644 --- a/src/org/apache/fop/fo/flow/TableCell.java +++ b/src/org/apache/fop/fo/flow/TableCell.java @@ -1,53 +1,9 @@ /*-- $Id$ -- - - ============================================================================ - The Apache Software License, Version 1.1 - ============================================================================ - - Copyright (C) 1999 The Apache Software Foundation. All rights reserved. - - Redistribution and use in source and binary forms, with or without modifica- - tion, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - 3. The end-user documentation included with the redistribution, if any, must - include the following acknowledgment: "This product includes software - developed by the Apache Software Foundation (http://www.apache.org/)." - Alternately, this acknowledgment may appear in the software itself, if - and wherever such third-party acknowledgments normally appear. - - 4. The names "FOP" and "Apache Software Foundation" must not be used to - endorse or promote products derived from this software without prior - written permission. For written permission, please contact - apache@apache.org. - - 5. Products derived from this software may not be called "Apache", nor may - "Apache" appear in their name, without prior written permission of the - Apache Software Foundation. - - THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - This software consists of voluntary contributions made by many individuals - on behalf of the Apache Software Foundation and was originally created by - James Tauber . For more information on the Apache - Software Foundation, please see . - + * 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.fo.flow; // FOP @@ -60,47 +16,66 @@ import org.apache.fop.datatypes.*; public class TableCell extends FObj { public static class Maker extends FObj.Maker { - public FObj make(FObj parent, PropertyList propertyList) - throws FOPException { - return new TableCell(parent, propertyList); - } + public FObj make(FObj parent, PropertyList propertyList) + throws FOPException { + return new TableCell(parent, propertyList); + } } public static FObj.Maker maker() { - return new TableCell.Maker(); + return new TableCell.Maker(); } - int spaceBefore; - int spaceAfter; + // int spaceBefore; + // int spaceAfter; ColorType backgroundColor; - int position; String id; int numColumnsSpanned; int numRowsSpanned; + /** Offset of content rectangle in inline-progression-direction, + * relative to table. + */ protected int startOffset; + + /** Dimension of content rectangle in inline-progression-direction */ protected int width; + /** Offset of content rectangle, in block-progression-direction, + * relative to the row. + */ + protected int beforeOffset; + protected int height = 0; - protected int top; - protected int verticalAlign = VerticalAlign.BASELINE; + protected int top; // Ypos of cell ??? + protected int verticalAlign ; + protected boolean bRelativeAlign = false; boolean setup = false; + boolean bSepBorders = true; + + /** Border separation value in the block-progression dimension. + * Used in calculating cells height. + */ + int m_borderSeparation = 0; - AreaContainer areaContainer; + AreaContainer cellArea; public TableCell(FObj parent, PropertyList propertyList) { - super(parent, propertyList); - this.name = "fo:table-cell"; + super(parent, propertyList); + this.name = "fo:table-cell"; } + // Set position relative to table (set by body?) public void setStartOffset(int offset) { - startOffset = offset; + startOffset = offset; } + // Initially same as the column width containg this cell or the + // sum of the spanned columns if numColumnsSpanned > 1 public void setWidth(int width) { - this.width = width; + this.width = width; } public int getNumColumnsSpanned() @@ -116,47 +91,57 @@ public class TableCell extends FObj { public void doSetup(Area area) throws FOPException { this.numColumnsSpanned = - this.properties.get("number-columns-spanned").getNumber().intValue(); + this.properties.get("number-columns-spanned").getNumber().intValue(); this.numRowsSpanned = - this.properties.get("number-rows-spanned").getNumber().intValue(); + this.properties.get("number-rows-spanned").getNumber().intValue(); + /** this.spaceBefore = this.properties.get("space-before.optimum").getLength().mvalue(); this.spaceAfter = this.properties.get("space-after.optimum").getLength().mvalue(); + **/ this.backgroundColor = - this.properties.get("background-color").getColorType(); - this.id = - this.properties.get("id").getString(); + this.properties.get("background-color").getColorType(); + this.id = this.properties.get("id").getString(); + bSepBorders = (this.properties.get("border-collapse").getEnum() == + BorderCollapse.SEPARATE); + // Vertical cell alignment + verticalAlign = this.properties.get("display-align").getEnum(); + if (verticalAlign == DisplayAlign.AUTO) { + // Depends on all cells starting in row + bRelativeAlign = true; + verticalAlign = this.properties.get("relative-align").getEnum(); + } + else bRelativeAlign = false; // Align on a per-cell basis + } + public Status layout(Area area) throws FOPException { - int originalAbsoluteHeight = area.getAbsoluteHeight(); + int originalAbsoluteHeight = area.getAbsoluteHeight(); if (this.marker == BREAK_AFTER) { - return new Status(Status.OK); - } - - if (this.marker == START) { - if(!setup) - doSetup(area); + return new Status(Status.OK); + } - if (area instanceof BlockArea) { - area.end(); - } + if (this.marker == START) { + if (!setup) { + doSetup(area); + } - //if (this.isInListBody) { - //startIndent += bodyIndent + distanceBetweenStarts; - //} + // Calculate cell borders + calcBorders(propMgr.getBorderAndPadding()); area.getIDReferences().createID(id); - this.marker = 0; - - } + this.marker = 0; + } - if ((spaceBefore != 0) && (this.marker ==0)) { - area.increaseHeight(spaceBefore); - } + /* + if ((spaceBefore != 0) && (this.marker ==0)) { + area.increaseHeight(spaceBefore); + } + */ if ( marker==0 ) { // configure id @@ -164,67 +149,168 @@ public class TableCell extends FObj { } int spaceLeft = area.spaceLeft(); - this.areaContainer = - new AreaContainer(propMgr.getFontState(area.getFontInfo()), - startOffset - area.getBorderLeftWidth(), - - area.getBorderTopWidth() + ((this.marker ==0) ? spaceBefore : 0), - width, area.spaceLeft(), Position.RELATIVE); - areaContainer.foCreator=this; // G Seshadri - areaContainer.setPage(area.getPage()); - areaContainer.setBorderAndPadding(propMgr.getBorderAndPadding()); - areaContainer.start(); - - areaContainer.setAbsoluteHeight(area.getAbsoluteHeight()); - areaContainer.setIDReferences(area.getIDReferences()); - areaContainer.setTableCellXOffset(startOffset); - int numChildren = this.children.size(); - for (int i = this.marker; i < numChildren; i++) { - FObj fo = (FObj) children.elementAt(i); - fo.setIsInTableCell(); - fo.forceWidth(width); - verticalAlign = fo.properties.get("vertical-align").getEnum(); - Status status; - if ((status = fo.layout(areaContainer)).isIncomplete()) { - this.marker = i; - if ((i == 0) && (status.getCode() == Status.AREA_FULL_NONE)) { - return new Status(Status.AREA_FULL_NONE); - } else { - // hani Elabed 11/21/2000 - area.addChild(areaContainer); - area.setAbsoluteHeight(areaContainer.getAbsoluteHeight()); - - return new Status(Status.AREA_FULL_SOME); - } - } - area.setMaxHeight(area.getMaxHeight() - spaceLeft + this.areaContainer.getMaxHeight()); - } - areaContainer.end(); - area.addChild(areaContainer); - - height = areaContainer.getHeight(); - top = areaContainer.getCurrentYPosition(); - // reset absoluteHeight to beginning of row - area.setHeight(areaContainer.getHeight() + spaceBefore + spaceAfter); - area.setAbsoluteHeight(originalAbsoluteHeight); - - return new Status(Status.OK); + + // The Area position defines the content rectangle! Borders + // and padding are outside of this rectangle. + this.cellArea = + new AreaContainer(propMgr.getFontState(area.getFontInfo()), + startOffset, beforeOffset, + width, area.spaceLeft()- m_borderSeparation/2, + Position.RELATIVE); + + cellArea.foCreator=this; // G Seshadri + cellArea.setPage(area.getPage()); + cellArea.setBorderAndPadding(propMgr.getBorderAndPadding()); + cellArea.start(); + + cellArea.setAbsoluteHeight(area.getAbsoluteHeight()); //??? + cellArea.setIDReferences(area.getIDReferences()); + //******** CHECK THIS: we've changed startOffset (KL) + cellArea.setTableCellXOffset(startOffset); + + int numChildren = this.children.size(); + for (int i = this.marker; i < numChildren; i++) { + FObj fo = (FObj) children.elementAt(i); + fo.setIsInTableCell(); + fo.forceWidth(width); // ??? + + Status status; + if ((status = fo.layout(cellArea)).isIncomplete()) { + this.marker = i; + if ((i == 0) && (status.getCode() == Status.AREA_FULL_NONE)) { + return new Status(Status.AREA_FULL_NONE); + } else { + // hani Elabed 11/21/2000 + area.addChild(cellArea); + area.setAbsoluteHeight(cellArea.getAbsoluteHeight()); + return new Status(Status.AREA_FULL_SOME); + } + } + area.setMaxHeight(area.getMaxHeight() - spaceLeft + + this.cellArea.getMaxHeight()); + } + cellArea.end(); + area.addChild(cellArea); + + // This is the allocation height of the cell (including borders + // and padding + // ALSO need to include offsets if using "separate borders" + height = cellArea.getHeight(); + top = cellArea.getCurrentYPosition(); // CHECK THIS!!! + + // reset absoluteHeight to beginning of row + // area.setHeight(cellArea.getHeight() + spaceBefore + spaceAfter); + // I don't think we should do this here (KL) !!! + area.setHeight(cellArea.getHeight()); + area.setAbsoluteHeight(originalAbsoluteHeight); + + return new Status(Status.OK); } + // TableRow calls this. Anyone else? public int getHeight() { - return areaContainer.getHeight() + spaceBefore + spaceAfter; + // return cellArea.getHeight() + spaceBefore + spaceAfter; + return cellArea.getHeight() + m_borderSeparation ; } + /** Called by TableRow to set final size of cell content rectangles and + * to vertically align the actual content within the cell rectangle. + * Passed value is height of this row in the grid : allocation height + * of the cells (including any border separation values). + */ public void setRowHeight(int h) { - areaContainer.setMaxHeight(h); - switch(verticalAlign) { - case VerticalAlign.MIDDLE: - areaContainer.setHeight(height); - areaContainer.setYPosition(spaceBefore + top + h / 2 - height / 2); - break; - case VerticalAlign.BASELINE: - default: - areaContainer.setHeight(h - (spaceBefore + spaceAfter)); - break; - } + // This seems wierd. It's very old. + // The height passed here is the total row height. + // But we need to align the content of the cell. + // cellArea.setMaxHeight(h); + // Increase content height by difference of row content height + // and current cell allocation height (includes borders & padding) + cellArea.increaseHeight(h - cellArea.getHeight()); + if (bRelativeAlign) { + // Must get info for all cells starting in row! + // verticalAlign can be BEFORE or BASELINE + } + else { + int delta = h - getHeight(); + if (delta > 0) { + switch(verticalAlign) { + case DisplayAlign.CENTER: + // Increase cell padding before and after and change + // "Y" position of content rectangle + // cellArea.getBorderAndPadding().setPaddingBefore(delta/2); + //cellArea.getBorderAndPadding().setPaddingAfter(delta-delta/2); + cellArea.shiftYPosition(delta/2); + break; + case DisplayAlign.AFTER: + // Increase cell padding before and change + // "Y" position of content rectangle + //cellArea.getBorderAndPadding().setPaddingBefore(delta); + cellArea.shiftYPosition(delta); + break; + case DisplayAlign.BEFORE: + default: // OK + break; + } + } + } + } + + // Calculate cell border and padding + private void calcBorders(BorderAndPadding bp) { + if (this.bSepBorders) { + /* Easy case. + * Cell border is the property specified directly on cell. + * Offset content rect by half the border-separation value, + * in addition to the border and padding values. Note: + * border-separate should only be specified on the table object, + * but it inherits. + */ + int iSep = properties.get("border-separation.inline-progression-direction").getLength().mvalue()/2; + int contentOffset = iSep + bp.getBorderLeftWidth(false) + + bp.getPaddingLeft(false); + /* + int contentOffset = iSep + bp.getBorderStartWidth(false) + + bp.getPaddingStart(false); + */ + this.startOffset += contentOffset; + this.width -= (contentOffset + iSep + + bp.getBorderRightWidth(false) + bp.getPaddingRight(false)); + // bp.getBorderEndWidth(false) + bp.getPaddingEnd(false); + // Offset of content rectangle in the block-progression direction + m_borderSeparation = + properties.get("border-separation.block-progression-direction").getLength().mvalue(); + this.beforeOffset = m_borderSeparation/2 + + bp.getBorderTopWidth(false) + bp.getPaddingTop(false); + // bp.getBorderBeforeWidth(false) + bp.getPaddingBefore(false); + } + else { + //System.err.println("Collapse borders"); + /* Hard case. + * Cell border is combination of other cell borders, or table + * border for edge cells. Also seems to border values specified + * on row and column FO in the table (if I read CR correclty.) + */ + /* + border-start + If cell in column 1, then combine with table border-start props + else combine with border-end props for preceding cell in this + row. Look out for spanning rows. + border-end + If cell in last column, then combine with table border-end props + else combine with border-start props for following cell in this + row. Look out for spanning rows. + border-before + If cell in row 1 (of whole table, not just body), + then combine with table border-before props, + else combine with border-after props for preceding cell in this + column. Look out for spanning columns. + border-after + If cell in last row (of whole table, not just body), + then combine with table border-after props, + else combine with border-before props for following cell in this + column. Look out for spanning columns. + */ + + } } } diff --git a/src/org/apache/fop/fo/flow/TableRow.java b/src/org/apache/fop/fo/flow/TableRow.java index 83387d450..3f7d7b25f 100644 --- a/src/org/apache/fop/fo/flow/TableRow.java +++ b/src/org/apache/fop/fo/flow/TableRow.java @@ -314,26 +314,29 @@ public class TableRow extends FObj { } } + /** if ((spaceBefore != 0) && (this.marker == 0)) { spacer = new DisplaySpace(spaceBefore); area.increaseHeight(spaceBefore); } - + ***/ if (marker == 0 && configID) { // configure id area.getIDReferences().configureID(id, area); } int spaceLeft = area.spaceLeft(); - this.areaContainer = new AreaContainer(propMgr.getFontState(area.getFontInfo()), - -area.getBorderLeftWidth(), - -area.getBorderTopWidth(), area.getAllocationWidth(), - area.spaceLeft(), Position.RELATIVE); + this.areaContainer = + new AreaContainer(propMgr.getFontState(area.getFontInfo()), + 0,0, + area.getContentWidth(), + area.spaceLeft(), + Position.RELATIVE); areaContainer.foCreator=this; // G Seshadri areaContainer.setPage(area.getPage()); areaContainer.setBackgroundColor(backgroundColor); - areaContainer.setBorderAndPadding(propMgr.getBorderAndPadding()); + // areaContainer.setBorderAndPadding(propMgr.getBorderAndPadding()); areaContainer.start(); areaContainer.setAbsoluteHeight(area.getAbsoluteHeight()); -- 2.39.5