/* * 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.TableCell; import org.apache.fop.fo.flow.table.TableHeader; import org.apache.fop.fo.flow.table.TablePart; 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; /** * <p>Table attributes converter.</p> * * <p>This work was authored by Roberto Marra (roberto@link-u.com), * Boris Poudérous (boris.pouderous@eads-telecom.com), * Normand Massé, and * Peter Herweg (pherweg@web.de).</p> * * 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 fobj the table for which the attributes are converted * @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 part the table part for which the attributes are converted * @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 * @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; } }