blob: 764c2c93e92994fb742513b621d4ff0838e0a09b [file] [log] [blame]
/*
* 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.render.rtf;
import java.awt.Color;
import org.apache.fop.apps.FOPException;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.flow.table.Table;
import org.apache.fop.fo.flow.table.TablePart;
import org.apache.fop.fo.flow.table.TableCell;
import org.apache.fop.fo.flow.table.TableHeader;
import org.apache.fop.fo.flow.table.TableRow;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.render.rtf.rtflib.rtfdoc.ITableAttributes;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfAttributes;
/**
* Contributor(s):
* @author Roberto Marra <roberto@link-u.com>
* @author Boris Poudérous <boris.pouderous@eads-telecom.com>
* @author Normand Massé
* @author Peter Herweg <pherweg@web.de>
*
* This class was originally developed for the JFOR project and
* is now integrated into FOP.
-----------------------------------------------------------------------------*/
/**
* Provides methods to convert the attributes to RtfAttributes.
*/
public final class TableAttributesConverter {
//////////////////////////////////////////////////
// @@ Construction
//////////////////////////////////////////////////
/**
* Constructor is private, because it's just a utility class.
*/
private TableAttributesConverter() {
}
//////////////////////////////////////////////////
// @@ Static converter methods
//////////////////////////////////////////////////
/**
* Converts table-only attributes to rtf attributes.
*
* @param attrs Given attributes
* @param defaultAttributes Default rtf attributes
*
* @return All valid rtf attributes together
*
* @throws ConverterException On convertion error
*/
static RtfAttributes convertTableAttributes(Table fobj)
throws FOPException {
FOPRtfAttributes attrib = new FOPRtfAttributes();
attrib.setTwips(ITableAttributes.ATTR_ROW_LEFT_INDENT,
fobj.getCommonMarginBlock().marginLeft);
return attrib;
}
/**
* Converts table-only attributes to rtf attributes.
*
* @param attrs Given attributes
* @param defaultAttributes Default rtf attributes
*
* @return All valid rtf attributes together
*
* @throws ConverterException On convertion error
*/
static RtfAttributes convertTablePartAttributes(TablePart part)
throws FOPException {
FOPRtfAttributes attrib = new FOPRtfAttributes();
return attrib;
}
/**
* Converts cell attributes to rtf attributes.
* @param fobj FObj whose properties are to be converted
*
* @return All valid rtf attributes together
*
* @throws ConverterException On conversion error
*/
static RtfAttributes convertCellAttributes(TableCell fobj)
throws FOPException {
//Property p;
//RtfColorTable colorTable = RtfColorTable.getInstance();
FOPRtfAttributes attrib = new FOPRtfAttributes();
//boolean isBorderPresent = false;
CommonBorderPaddingBackground border = fobj.getCommonBorderPaddingBackground();
// Cell background color
Color color = border.backgroundColor;
if (color == null) {
//If there is no background-color specified for the cell,
//then try to read it from table-row or table-header.
CommonBorderPaddingBackground brd = null;
if (fobj.getParent() instanceof TableRow) {
TableRow parentRow = (TableRow)fobj.getParent();
brd = parentRow.getCommonBorderPaddingBackground();
color = brd.backgroundColor;
} else if (fobj.getParent() instanceof TableHeader) {
TableHeader parentHeader = (TableHeader)fobj.getParent();
brd = parentHeader.getCommonBorderPaddingBackground();
color = brd.backgroundColor;
}
if (color == null
&& fobj.getParent() != null
&& fobj.getParent().getParent() != null
&& fobj.getParent().getParent().getParent() instanceof Table) {
Table table = (Table)fobj.getParent().getParent().getParent();
brd = table.getCommonBorderPaddingBackground();
color = brd.backgroundColor;
}
}
if ((color != null)
&& (color.getAlpha() != 0
|| color.getRed() != 0
|| color.getGreen() != 0
|| color.getBlue() != 0)) {
attrib.set(ITableAttributes.CELL_COLOR_BACKGROUND, color);
}
BorderAttributesConverter.makeBorder(border, CommonBorderPaddingBackground.BEFORE,
attrib, ITableAttributes.CELL_BORDER_TOP);
BorderAttributesConverter.makeBorder(border, CommonBorderPaddingBackground.AFTER,
attrib, ITableAttributes.CELL_BORDER_BOTTOM);
BorderAttributesConverter.makeBorder(border, CommonBorderPaddingBackground.START,
attrib, ITableAttributes.CELL_BORDER_LEFT);
BorderAttributesConverter.makeBorder(border, CommonBorderPaddingBackground.END,
attrib, ITableAttributes.CELL_BORDER_RIGHT);
int padding;
boolean reproduceMSWordBug = true;
//TODO Make this configurable
if (reproduceMSWordBug) {
//MS Word has a bug where padding left and top are exchanged
padding = border.getPaddingStart(false, null); // TODO do we need a real context here?
if (padding != 0) {
attrib.setTwips(ITableAttributes.ATTR_CELL_PADDING_TOP, padding);
attrib.set(ITableAttributes.ATTR_CELL_U_PADDING_TOP, 3 /*=twips*/);
}
padding = border.getPaddingBefore(false, null); // TODO do we need a real context here?
if (padding != 0) {
attrib.setTwips(ITableAttributes.ATTR_CELL_PADDING_LEFT, padding);
attrib.set(ITableAttributes.ATTR_CELL_U_PADDING_LEFT, 3 /*=twips*/);
}
} else {
padding = border.getPaddingStart(false, null); // TODO do we need a real context here?
if (padding != 0) {
attrib.setTwips(ITableAttributes.ATTR_CELL_PADDING_LEFT, padding);
attrib.set(ITableAttributes.ATTR_CELL_U_PADDING_LEFT, 3 /*=twips*/);
}
padding = border.getPaddingBefore(false, null); // TODO do we need a real context here?
if (padding != 0) {
attrib.setTwips(ITableAttributes.ATTR_CELL_PADDING_TOP, padding);
attrib.set(ITableAttributes.ATTR_CELL_U_PADDING_TOP, 3 /*=twips*/);
}
}
padding = border.getPaddingEnd(false, null); // TODO do we need a real context here?
if (padding != 0) {
attrib.setTwips(ITableAttributes.ATTR_CELL_PADDING_RIGHT, padding);
attrib.set(ITableAttributes.ATTR_CELL_U_PADDING_RIGHT, 3 /*=twips*/);
}
padding = border.getPaddingAfter(false, null); // TODO do we need a real context here?
if (padding != 0) {
attrib.setTwips(ITableAttributes.ATTR_CELL_PADDING_BOTTOM, padding);
attrib.set(ITableAttributes.ATTR_CELL_U_PADDING_BOTTOM, 3 /*=twips*/);
}
int n = fobj.getNumberColumnsSpanned();
// Column spanning :
if (n > 1) {
attrib.set(ITableAttributes.COLUMN_SPAN, n);
}
switch (fobj.getDisplayAlign()) {
case Constants.EN_BEFORE:
attrib.set(ITableAttributes.ATTR_CELL_VERT_ALIGN_TOP);
break;
case Constants.EN_CENTER:
attrib.set(ITableAttributes.ATTR_CELL_VERT_ALIGN_CENTER);
break;
case Constants.EN_AFTER:
attrib.set(ITableAttributes.ATTR_CELL_VERT_ALIGN_BOTTOM);
break;
default: //nop
}
return attrib;
}
/**
* Converts table and row attributes to rtf attributes.
*
* @param fobj FObj to be converted
* @param defaultAttributes Default rtf attributes
*
* @return All valid rtf attributes together
* @throws ConverterException On converion error
*/
static RtfAttributes convertRowAttributes(TableRow fobj,
RtfAttributes rtfatts)
throws FOPException {
//Property p;
//RtfColorTable colorTable = RtfColorTable.getInstance();
RtfAttributes attrib = null;
if (rtfatts == null) {
attrib = new RtfAttributes();
} else {
attrib = rtfatts;
}
//String attrValue;
//boolean isBorderPresent = false;
//need to set a default width
//check for keep-together row attribute
if (fobj.getKeepTogether().getWithinPage().getEnum() == Constants.EN_ALWAYS) {
attrib.set(ITableAttributes.ROW_KEEP_TOGETHER);
}
//Check for keep-with-next row attribute.
if (fobj.getKeepWithNext().getWithinPage().getEnum() == Constants.EN_ALWAYS) {
attrib.set(ITableAttributes.ROW_KEEP_WITH_NEXT);
}
//Check for keep-with-previous row attribute.
if (fobj.getKeepWithPrevious().getWithinPage().getEnum() == Constants.EN_ALWAYS) {
attrib.set(ITableAttributes.ROW_KEEP_WITH_PREVIOUS);
}
//Check for height row attribute.
if (fobj.getHeight().getEnum() != Constants.EN_AUTO) {
attrib.set(ITableAttributes.ROW_HEIGHT, fobj.getHeight().getValue() / (1000 / 20));
}
/* to write a border to a side of a cell one must write the directional
* side (ie. left, right) and the inside value if one needs to be taken
* out ie if the cell lies on the edge of a table or not, the offending
* value will be taken out by RtfTableRow. This is because you can't
* say BORDER_TOP and BORDER_HORIZONTAL if the cell lies at the top of
* the table. Similarly using BORDER_BOTTOM and BORDER_HORIZONTAL will
* not work if the cell lies at th bottom of the table. The same rules
* apply for left right and vertical.
* Also, the border type must be written after every control word. Thus
* it is implemented that the border type is the value of the border
* place.
*/
CommonBorderPaddingBackground border = fobj.getCommonBorderPaddingBackground();
BorderAttributesConverter.makeBorder(border, CommonBorderPaddingBackground.BEFORE,
attrib, ITableAttributes.CELL_BORDER_TOP);
BorderAttributesConverter.makeBorder(border, CommonBorderPaddingBackground.AFTER,
attrib, ITableAttributes.CELL_BORDER_BOTTOM);
BorderAttributesConverter.makeBorder(border, CommonBorderPaddingBackground.START,
attrib, ITableAttributes.CELL_BORDER_LEFT);
BorderAttributesConverter.makeBorder(border, CommonBorderPaddingBackground.END,
attrib, ITableAttributes.CELL_BORDER_RIGHT);
/*
ep = (EnumProperty)fobj.getProperty(Constants.PR_BORDER_TOP_STYLE);
if (ep != null && ep.getEnum() != Constants.EN_NONE) {
attrib.set(ITableAttributes.ROW_BORDER_TOP, "\\"
+ convertAttributetoRtf(ep.getEnum()));
attrib.set(ITableAttributes.ROW_BORDER_HORIZONTAL, "\\"
+ convertAttributetoRtf(ep.getEnum()));
isBorderPresent = true;
}
ep = (EnumProperty)fobj.getProperty(Constants.PR_BORDER_BOTTOM_STYLE);
if (ep != null && ep.getEnum() != Constants.EN_NONE) {
attrib.set(ITableAttributes.ROW_BORDER_BOTTOM, "\\"
+ convertAttributetoRtf(ep.getEnum()));
attrib.set(ITableAttributes.ROW_BORDER_HORIZONTAL, "\\"
+ convertAttributetoRtf(ep.getEnum()));
isBorderPresent = true;
}
ep = (EnumProperty)fobj.getProperty(Constants.PR_BORDER_LEFT_STYLE);
if (ep != null && ep.getEnum() != Constants.EN_NONE) {
attrib.set(ITableAttributes.ROW_BORDER_LEFT, "\\"
+ convertAttributetoRtf(ep.getEnum()));
attrib.set(ITableAttributes.ROW_BORDER_VERTICAL, "\\"
+ convertAttributetoRtf(ep.getEnum()));
isBorderPresent = true;
}
ep = (EnumProperty)fobj.getProperty(Constants.PR_BORDER_RIGHT_STYLE);
if (ep != null && ep.getEnum() != Constants.EN_NONE) {
attrib.set(ITableAttributes.ROW_BORDER_RIGHT, "\\"
+ convertAttributetoRtf(ep.getEnum()));
attrib.set(ITableAttributes.ROW_BORDER_VERTICAL, "\\"
+ convertAttributetoRtf(ep.getEnum()));
isBorderPresent = true;
}
//Currently there is only one border width supported in each cell.
p = fobj.getProperty(Constants.PR_BORDER_LEFT_WIDTH);
if(p == null) {
p = fobj.getProperty(Constants.PR_BORDER_RIGHT_WIDTH);
}
if(p == null) {
p = fobj.getProperty(Constants.PR_BORDER_TOP_WIDTH);
}
if(p == null) {
p = fobj.getProperty(Constants.PR_BORDER_BOTTOM_WIDTH);
}
if (p != null) {
LengthProperty lengthprop = (LengthProperty)p;
Float f = new Float(lengthprop.getLength().getValue() / 1000f);
String sValue = f.toString() + FixedLength.POINT;
attrib.set(BorderAttributesConverter.BORDER_WIDTH,
(int)FoUnitsConverter.getInstance().convertToTwips(sValue));
} else if (isBorderPresent) {
//if not defined, set default border width
//note 20 twips = 1 point
attrib.set(BorderAttributesConverter.BORDER_WIDTH,
(int)FoUnitsConverter.getInstance().convertToTwips("1pt"));
}
*/
return attrib;
}
}