import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.fop.datatypes.PercentBaseContext;
-import org.apache.fop.datatypes.Length;
+import org.apache.fop.datatypes.Length;
+import org.apache.fop.datatypes.PercentBaseContext;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.flow.table.Table;
import org.apache.fop.fo.flow.table.TableColumn;
private Table table;
private List columns = new java.util.ArrayList();
private List colWidths = new java.util.ArrayList();
-
+
private int maxColIndexReferenced = 0;
-
+
/**
* Main Constructor.
* @param table the table to construct this column setup for
prepareColumns();
initializeColumnWidths();
}
-
+
private void prepareColumns() {
List rawCols = table.getColumns();
if (rawCols != null) {
return (TableColumn) columns.get(index - 1);
}
}
-
+
/** {@inheritDoc} */
public String toString() {
return columns.toString();
return columns.size();
}
}
-
+
/** @return an Iterator over all columns */
public Iterator iterator() {
return this.columns.iterator();
}
-
+
/*
private void createColumnsFromFirstRow() {
- //TODO Create oldColumns from first row here
+ //TODO Create oldColumns from first row here
//--> rule 2 in "fixed table layout", see CSS2, 17.5.2
//Alternative: extend oldColumns on-the-fly, but in this case we need the
//new property evaluation context so proportional-column-width() works
/**
* Initializes the column's widths
- *
+ *
*/
private void initializeColumnWidths() {
-
+
TableColumn col;
Length colWidth;
-
+
for (int i = columns.size(); --i >= 0;) {
if (columns.get(i) != null) {
col = (TableColumn) columns.get(i);
}
colWidths.add(0, null);
}
-
+
/**
* Works out the base unit for resolving proportional-column-width()
* [p-c-w(x) = x * base_unit_ipd]
- *
+ *
* @param tlm the TableLayoutManager
* @return the computed base unit (in millipoint)
*/
protected double computeTableUnit(TableLayoutManager tlm) {
-
+ return computeTableUnit(tlm, tlm.getContentAreaIPD());
+ }
+
+ /**
+ * Works out the base unit for resolving proportional-column-width()
+ * [p-c-w(x) = x * base_unit_ipd]
+ *
+ * @param percentBaseContext the percent base context for relative values
+ * @param contentAreaIPD the IPD of the available content area
+ * @return the computed base unit (in millipoints)
+ */
+ public float computeTableUnit(PercentBaseContext percentBaseContext, int contentAreaIPD) {
+
int sumCols = 0;
float factors = 0;
- double unit = 0;
-
- /* calculate the total width (specified absolute/percentages),
+ float unit = 0;
+
+ /* calculate the total width (specified absolute/percentages),
* and work out the total number of factors to use to distribute
* the remaining space (if any)
*/
for (Iterator i = colWidths.iterator(); i.hasNext();) {
Length colWidth = (Length) i.next();
if (colWidth != null) {
- sumCols += colWidth.getValue(tlm);
+ sumCols += colWidth.getValue(percentBaseContext);
if (colWidth instanceof TableColLength) {
- factors +=
- ((TableColLength) colWidth).getTableUnits();
+ factors += ((TableColLength) colWidth).getTableUnits();
}
}
}
-
- /* distribute the remaining space over the accumulated
- * factors (if any)
+
+ /* distribute the remaining space over the accumulated
+ * factors (if any)
*/
if (factors > 0) {
- if (sumCols < tlm.getContentAreaIPD()) {
- unit = (tlm.getContentAreaIPD() - sumCols) / factors;
+ if (sumCols < contentAreaIPD) {
+ unit = (contentAreaIPD - sumCols) / factors;
} else {
log.warn("No space remaining to distribute over columns.");
}
}
-
+
return unit;
}
-
+
/**
* @param col column index (1 is first column)
* @param context the context for percentage based calculations
}
return sum;
}
-
+
}
* 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.
package org.apache.fop.render.rtf;
-import java.util.Map;
import java.util.HashMap;
+import java.util.Map;
-//FOP
import org.apache.fop.apps.FOPException;
import org.apache.fop.fo.properties.FixedLength;
// RTF font size units are in half-points
return (int)(result * 2.0);
}
+
+ public float convertMptToTwips(int width) {
+ return width * POINT_TO_TWIPS / 1000;
+ }
}
* 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.
import org.apache.commons.logging.Log;
import org.apache.commons.logging.impl.SimpleLog;
+
import org.apache.fop.datatypes.Length;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.expr.NumericOp;
*/
private PageAttributesConverter() {
}
-
+
/** convert xsl:fo attributes to RTF text attributes */
static RtfAttributes convertPageAttributes(SimplePageMaster pagemaster) {
FOPRtfAttributes attrib = new FOPRtfAttributes();
-
+
try {
RegionBA before = (RegionBA) pagemaster.getRegion(Constants.FO_REGION_BEFORE);
RegionBody body = (RegionBody) pagemaster.getRegion(Constants.FO_REGION_BODY);
RegionBA after = (RegionBA) pagemaster.getRegion(Constants.FO_REGION_AFTER);
-
+
attrib.setTwips(RtfPage.PAGE_WIDTH, pagemaster.getPageWidth());
attrib.setTwips(RtfPage.PAGE_HEIGHT, pagemaster.getPageHeight());
-
+ //Sets the document level property
+ attrib.set(RtfPage.ITAP, "0");
+
Object widthRaw = attrib.getValue(RtfPage.PAGE_WIDTH);
Object heightRaw = attrib.getValue(RtfPage.PAGE_HEIGHT);
if ((widthRaw instanceof Integer) && (heightRaw instanceof Integer)
bodyLeft = (Length) NumericOp.addition(pageLeft, bodyMargin.marginLeft);
bodyRight = (Length) NumericOp.addition(pageRight, bodyMargin.marginRight);
}
-
+
attrib.setTwips(RtfPage.MARGIN_TOP, bodyTop);
attrib.setTwips(RtfPage.MARGIN_BOTTOM, bodyBottom);
attrib.setTwips(RtfPage.MARGIN_LEFT, bodyLeft);
if (after != null) {
afterBottom = (Length) NumericOp.addition(pageBottom, after.getExtent());
}
- attrib.setTwips(RtfPage.FOOTERY, beforeTop);
+ attrib.setTwips(RtfPage.FOOTERY, afterBottom);
} catch (Exception e) {
- log.error("Exception in convertPageAttributes: "
+ log.error("Exception in convertPageAttributes: "
+ e.getMessage() + "- page attributes ignored");
attrib = new FOPRtfAttributes();
}
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.datatypes.LengthBase;
-import org.apache.fop.datatypes.SimplePercentBaseContext;
import org.apache.fop.fo.Constants;
import org.apache.fop.fo.FOEventHandler;
import org.apache.fop.fo.FONode;
import org.apache.fop.fo.flow.ListItemBody;
import org.apache.fop.fo.flow.ListItemLabel;
import org.apache.fop.fo.flow.PageNumber;
+import org.apache.fop.fo.flow.PageNumberCitation;
import org.apache.fop.fo.flow.table.Table;
import org.apache.fop.fo.flow.table.TableBody;
import org.apache.fop.fo.flow.table.TableCell;
import org.apache.fop.fo.pagination.SimplePageMaster;
import org.apache.fop.fo.pagination.StaticContent;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
-import org.apache.fop.fo.properties.FixedLength;
+import org.apache.fop.fo.properties.EnumLength;
import org.apache.fop.fonts.FontSetup;
+import org.apache.fop.layoutmgr.table.ColumnSetup;
import org.apache.fop.render.DefaultFontResolver;
import org.apache.fop.render.rtf.rtflib.rtfdoc.IRtfAfterContainer;
import org.apache.fop.render.rtf.rtflib.rtfdoc.IRtfBeforeContainer;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfHyperLink;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfList;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfListItem;
+import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfPage;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfSection;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTable;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTableCell;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfTextrun;
import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfListItem.RtfListItemLabel;
import org.apache.fop.render.rtf.rtflib.tools.BuilderContext;
+import org.apache.fop.render.rtf.rtflib.tools.PercentContext;
import org.apache.fop.render.rtf.rtflib.tools.TableContext;
/**
private SimplePageMaster pagemaster;
+ private int nestedTableDepth = 1;
+
+ private PercentContext percentManager = new PercentContext();
+
/**
* Creates a new RTF structure handler.
* @param userAgent the FOUserAgent for this process
FontSetup.setup(fontInfo, null, new DefaultFontResolver(userAgent));
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void startDocument() throws SAXException {
// TODO sections should be created
try {
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void endDocument() throws SAXException {
try {
rtfFile.flush();
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void startPageSequence(PageSequence pageSeq) {
try {
//This is needed for region handling
this.pagemaster
= pageSeq.getRoot().getLayoutMasterSet().getSimplePageMaster(reference);
if (this.pagemaster == null) {
- log.warn("Only simple-page-masters are supported on page-sequences: "
+ log.warn("Only simple-page-masters are supported on page-sequences: "
+ reference);
log.warn("Using default simple-page-master from page-sequence-master...");
- PageSequenceMaster master
+ PageSequenceMaster master
= pageSeq.getRoot().getLayoutMasterSet().getPageSequenceMaster(reference);
this.pagemaster = master.getNextSimplePageMaster(
false, false, false, false, false);
builderContext.pushContainer(sect);
+ //Calculate usable page width for this flow
+ int useAblePageWidth = pagemaster.getPageWidth().getValue()
+ - pagemaster.getCommonMarginBlock().marginLeft.getValue()
+ - pagemaster.getCommonMarginBlock().marginRight.getValue()
+ - sect.getRtfAttributes().getValueAsInteger(RtfPage.MARGIN_LEFT).intValue()
+ - sect.getRtfAttributes().getValueAsInteger(RtfPage.MARGIN_RIGHT).intValue();
+ percentManager.setDimension(pageSeq, useAblePageWidth);
+
bHeaderSpecified = false;
bFooterSpecified = false;
} catch (IOException ioe) {
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void endPageSequence(PageSequence pageSeq) {
if (bDefer) {
//If endBlock was called while SAX parsing, and the passed FO is Block
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void startFlow(Flow fl) {
if (bDefer) {
return;
contAfter.newAfter(attr);
}
handled = true;
- } else if (regionBefore != null
+ } else if (regionBefore != null
&& fl.getFlowName().equals(regionBefore.getRegionName())) {
bHeaderSpecified = true;
bPrevHeaderSpecified = true;
RtfBefore before = c.newBefore(beforeAttributes);
builderContext.pushContainer(before);
handled = true;
- } else if (regionAfter != null
+ } else if (regionAfter != null
&& fl.getFlowName().equals(regionAfter.getRegionName())) {
bFooterSpecified = true;
bPrevFooterSpecified = true;
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void endFlow(Flow fl) {
if (bDefer) {
return;
Region regionAfter = pagemaster.getRegion(Constants.FO_REGION_AFTER);
if (fl.getFlowName().equals(regionBody.getRegionName())) {
//just do nothing
- } else if (regionBefore != null
+ } else if (regionBefore != null
&& fl.getFlowName().equals(regionBefore.getRegionName())) {
builderContext.popContainer();
- } else if (regionAfter != null
+ } else if (regionAfter != null
&& fl.getFlowName().equals(regionAfter.getRegionName())) {
builderContext.popContainer();
}
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void startBlock(Block bl) {
if (bDefer) {
return;
}
}
-
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void endBlock(Block bl) {
if (bDefer) {
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void startBlockContainer(BlockContainer blc) {
if (bDefer) {
return;
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void endBlockContainer(BlockContainer bl) {
if (bDefer) {
return;
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void startTable(Table tbl) {
if (bDefer) {
return;
final IRtfTableContainer tc
= (IRtfTableContainer)builderContext.getContainer(
IRtfTableContainer.class, true, null);
-
+
RtfAttributes atts
= TableAttributesConverter.convertTableAttributes(tbl);
-
+
RtfTable table = tc.newTable(atts, tableContext);
-
+ table.setNestedTableDepth(nestedTableDepth);
+ nestedTableDepth++;
+
CommonBorderPaddingBackground border = tbl.getCommonBorderPaddingBackground();
RtfAttributes borderAttributes = new RtfAttributes();
-
+
BorderAttributesConverter.makeBorder(border, CommonBorderPaddingBackground.BEFORE,
borderAttributes, ITableAttributes.CELL_BORDER_TOP);
BorderAttributesConverter.makeBorder(border, CommonBorderPaddingBackground.AFTER,
borderAttributes, ITableAttributes.CELL_BORDER_LEFT);
BorderAttributesConverter.makeBorder(border, CommonBorderPaddingBackground.END,
borderAttributes, ITableAttributes.CELL_BORDER_RIGHT);
-
+
table.setBorderAttributes(borderAttributes);
-
+
builderContext.pushContainer(table);
} catch (Exception e) {
log.error("startTable:" + e.getMessage());
builderContext.pushTableContext(tableContext);
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void endTable(Table tbl) {
if (bDefer) {
return;
}
+ nestedTableDepth--;
builderContext.popTableContext();
builderContext.popContainer();
}
- /**
- *
- * @param tc TableColumn that is starting;
- */
-
+ /** {@inheritDoc} */
public void startColumn(TableColumn tc) {
if (bDefer) {
return;
}
try {
- /**
- * Pass a SimplePercentBaseContext to getValue in order to
- * avoid a NullPointerException, which occurs when you use
- * proportional-column-width function in column-width attribute.
- * Of course the results won't be correct, but at least the
- * rest of the document will be rendered. Usage of the
- * TableLayoutManager is not welcome due to design reasons and
- * it also does not provide the correct values.
- * TODO: Make proportional-column-width working for rtf output
- */
- SimplePercentBaseContext context
- = new SimplePercentBaseContext(null,
- LengthBase.TABLE_UNITS,
- 100000);
-
- Integer iWidth
- = new Integer(tc.getColumnWidth().getValue(context) / 1000);
-
- String strWidth = iWidth.toString() + FixedLength.POINT;
- Float width = new Float(
- FoUnitsConverter.getInstance().convertToTwips(strWidth));
+ int iWidth = tc.getColumnWidth().getValue(percentManager);
+ percentManager.setDimension(tc, iWidth);
+
+ //convert to twips
+ Float width = new Float(FoUnitsConverter.getInstance().convertMptToTwips(iWidth));
builderContext.getTableContext().setNextColumnWidth(width);
builderContext.getTableContext().setNextColumnRowSpanning(
- new Integer(0), null);
+ new Integer(0), null);
builderContext.getTableContext().setNextFirstSpanningCol(false);
} catch (Exception e) {
log.error("startColumn: " + e.getMessage());
}
- /**
- *
- * @param tc TableColumn that is ending;
- */
-
+ /** {@inheritDoc} */
public void endColumn(TableColumn tc) {
if (bDefer) {
return;
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void startHeader(TableBody th) {
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void endHeader(TableBody th) {
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void startFooter(TableBody tf) {
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void endFooter(TableBody tf) {
}
- /**
- *
- * @param inl Inline that is starting.
- */
+ /** {@inheritDoc} */
public void startInline(Inline inl) {
if (bDefer) {
return;
}
}
- /**
- *
- * @param inl Inline that is ending.
- */
+ /** {@inheritDoc} */
public void endInline(Inline inl) {
if (bDefer) {
return;
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void startBody(TableBody tb) {
if (bDefer) {
return;
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void endBody(TableBody tb) {
if (bDefer) {
return;
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void startRow(TableRow tr) {
if (bDefer) {
return;
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void endRow(TableRow tr) {
if (bDefer) {
return;
}
-
+
try {
TableContext tctx = builderContext.getTableContext();
final RtfTableRow row = (RtfTableRow)builderContext.getContainer(RtfTableRow.class,
RtfTableCell vCell = row.newTableCellMergedVertically(
(int)tctx.getColumnWidth(),
tctx.getColumnRowSpanningAttrs());
-
+
if (!tctx.getFirstSpanningCol()) {
vCell.setHMerge(RtfTableCell.MERGE_WITH_PREVIOUS);
}
-
+
tctx.selectNextColumn();
}
} catch (Exception e) {
builderContext.getTableContext().decreaseRowSpannings();
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void startCell(TableCell tc) {
if (bDefer) {
return;
RtfTableCell vCell = row.newTableCellMergedVertically(
(int)tctx.getColumnWidth(),
tctx.getColumnRowSpanningAttrs());
-
+
if (!tctx.getFirstSpanningCol()) {
vCell.setHMerge(RtfTableCell.MERGE_WITH_PREVIOUS);
}
-
+
tctx.selectNextColumn();
}
// create an RtfTableCell in the current RtfTableRow
RtfAttributes atts = TableAttributesConverter.convertCellAttributes(tc);
RtfTableCell cell = row.newTableCell((int)width, atts);
-
+
//process number-rows-spanned attribute
if (numberRowsSpanned > 1) {
// Start vertical merge
cell.setVMerge(RtfTableCell.MERGE_START);
// set the number of rows spanned
- tctx.setCurrentColumnRowSpanning(new Integer(numberRowsSpanned),
+ tctx.setCurrentColumnRowSpanning(new Integer(numberRowsSpanned),
cell.getRtfAttributes());
} else {
tctx.setCurrentColumnRowSpanning(
//process number-columns-spanned attribute
if (numberColumnsSpanned > 0) {
// Get the number of columns spanned
- RtfTable table = row.getTable();
tctx.setCurrentFirstSpanningCol(true);
-
+
// We widthdraw one cell because the first cell is already created
// (it's the current cell) !
for (int i = 0; i < numberColumnsSpanned - 1; ++i) {
tctx.selectNextColumn();
-
+
+ //aggregate width for further elements
+ width += tctx.getColumnWidth();
tctx.setCurrentFirstSpanningCol(false);
RtfTableCell hCell = row.newTableCellMergedHorizontally(
0, null);
-
+
if (numberRowsSpanned > 1) {
// Start vertical merge
hCell.setVMerge(RtfTableCell.MERGE_START);
// set the number of rows spanned
tctx.setCurrentColumnRowSpanning(
- new Integer(numberRowsSpanned),
+ new Integer(numberRowsSpanned),
cell.getRtfAttributes());
} else {
tctx.setCurrentColumnRowSpanning(
- new Integer(numberRowsSpanned), null);
+ new Integer(numberRowsSpanned), cell.getRtfAttributes());
}
}
}
-
+ //save width of the cell, convert from twips to mpt
+ percentManager.setDimension(tc, (int)width * 50);
+
builderContext.pushContainer(cell);
} catch (Exception e) {
log.error("startCell: " + e.getMessage());
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void endCell(TableCell tc) {
if (bDefer) {
return;
}
// Lists
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void startList(ListBlock lb) {
if (bDefer) {
return;
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void endList(ListBlock lb) {
if (bDefer) {
return;
builderContext.popContainer();
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void startListItem(ListItem li) {
if (bDefer) {
return;
}
-
+
// create an RtfListItem in the current RtfList
try {
RtfList list = (RtfList)builderContext.getContainer(
RtfList.class, true, this);
-
+
/**
* If the current list already contains a list item, then close the
* list and open a new one, so every single list item gets its own
this.endList((ListBlock) li.getParent());
this.startList((ListBlock) li.getParent());
this.startListBody();
-
+
list = (RtfList)builderContext.getContainer(
RtfList.class, true, this);
- }
-
+ }
+
builderContext.pushContainer(list.newListItem());
} catch (IOException ioe) {
log.error("startList: " + ioe.getMessage());
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void endListItem(ListItem li) {
if (bDefer) {
return;
builderContext.popContainer();
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void startListLabel() {
if (bDefer) {
return;
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void endListLabel() {
if (bDefer) {
return;
builderContext.popContainer();
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void startListBody() {
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void endListBody() {
}
// Static Regions
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void startStatic() {
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void endStatic() {
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void startMarkup() {
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void endMarkup() {
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void startLink(BasicLink basicLink) {
if (bDefer) {
return;
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void endLink() {
if (bDefer) {
return;
builderContext.popContainer();
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void image(ExternalGraphic eg) {
if (bDefer) {
return;
log.error("Image could not be found: " + uri);
return;
}
-
+
putGraphic(eg, info);
} catch (Exception e) {
log.error("Error while handling an external-graphic: " + e.getMessage(), e);
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void foreignObject(InstreamForeignObject ifo) {
if (bDefer) {
return;
}
-
+
try {
- XMLObj child = (XMLObj) ifo.getChildXMLObj();
+ XMLObj child = ifo.getChildXMLObj();
Document doc = child.getDOMDocument();
String ns = child.getNamespaceURI();
-
+
ImageInfo info = new ImageInfo(null, null);
// Set the resolution to that of the FOUserAgent
FOUserAgent ua = ifo.getUserAgent();
ImageSize size = new ImageSize();
size.setResolution(ua.getSourceResolution());
-
+
// Set the image size to the size of the svg.
Point2D csize = new Point2D.Float(-1, -1);
Point2D intrinsicDimensions = child.getDimension(csize);
info.setSize(size);
ImageXMLDOM image = new ImageXMLDOM(info, doc, ns);
-
+
FOUserAgent userAgent = ifo.getUserAgent();
ImageManager manager = userAgent.getFactory().getImageManager();
Map hints = ImageUtil.getDefaultHints(ua.getImageSessionContext());
Image converted = manager.convertImage(image, FLAVORS, hints);
putGraphic(ifo, converted);
-
+
} catch (Exception e) {
log.error("Error while handling an instream-foreign-object: " + e.getMessage(), e);
}
private static final ImageFlavor[] FLAVORS = new ImageFlavor[] {
ImageFlavor.RAW_EMF, ImageFlavor.RAW_PNG, ImageFlavor.RAW_JPEG
};
-
+
/**
* Puts a graphic/image into the generated RTF file.
* @param abstractGraphic the graphic (external-graphic or instream-foreign-object)
* @param info the image info object
* @throws IOException In case of an I/O error
*/
- private void putGraphic(AbstractGraphics abstractGraphic, ImageInfo info)
+ private void putGraphic(AbstractGraphics abstractGraphic, ImageInfo info)
throws IOException {
try {
FOUserAgent userAgent = abstractGraphic.getUserAgent();
log.error("Error while loading/processing image: " + info.getOriginalURI(), ie);
}
}
-
+
/**
* Puts a graphic/image into the generated RTF file.
* @param abstractGraphic the graphic (external-graphic or instream-foreign-object)
* @param image the image
* @throws IOException In case of an I/O error
*/
- private void putGraphic(AbstractGraphics abstractGraphic, Image image)
+ private void putGraphic(AbstractGraphics abstractGraphic, Image image)
throws IOException {
byte[] rawData = null;
-
+
ImageInfo info = image.getInfo();
if (image instanceof ImageRawStream) {
IRtfTextrunContainer.class, true, this);
final RtfExternalGraphic rtfGraphic = c.getTextrun().newImage();
-
+
//set URL
if (info.getOriginalURI() != null) {
rtfGraphic.setURL(info.getOriginalURI());
}
}
}
-
- /**
- * {@inheritDoc}
- */
+
+ /** {@inheritDoc} */
public void pageRef() {
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void startFootnote(Footnote footnote) {
if (bDefer) {
return;
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void endFootnote(Footnote footnote) {
if (bDefer) {
return;
builderContext.popContainer();
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void startFootnoteBody(FootnoteBody body) {
if (bDefer) {
return;
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void endFootnoteBody(FootnoteBody body) {
if (bDefer) {
return;
}
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
public void leader(Leader l) {
}
}
}
- /**
- *
- * @param pagenum PageNumber that is starting.
- */
+ /** {@inheritDoc} */
public void startPageNumber(PageNumber pagenum) {
if (bDefer) {
return;
}
}
- /**
- *
- * @param pagenum PageNumber that is ending.
- */
+ /** {@inheritDoc} */
public void endPageNumber(PageNumber pagenum) {
if (bDefer) {
return;
}
}
+ /** {@inheritDoc} */
+ public void startPageNumberCitation(PageNumberCitation l) {
+ if (bDefer) {
+ return;
+ }
+ try {
+
+ IRtfTextrunContainer container
+ = (IRtfTextrunContainer)builderContext.getContainer(
+ IRtfTextrunContainer.class, true, this);
+ RtfTextrun textrun = container.getTextrun();
+
+ textrun.addPageNumberCitation(l.getRefId());
+
+ } catch (Exception e) {
+ log.error("startPageNumberCitation: " + e.getMessage());
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+
+ private void prepareTable(Table tab) {
+ // Allows to receive the available width of the table
+ percentManager.setDimension(tab);
+
+ // Table gets expanded by half of the border on each side inside Word
+ // When using wide borders the table gets cut off
+ int tabDiff = tab.getCommonBorderPaddingBackground().getBorderStartWidth(false) / 2
+ + tab.getCommonBorderPaddingBackground().getBorderEndWidth(false);
+
+ // check for "auto" value
+ if (!(tab.getInlineProgressionDimension().getMaximum(null).getLength()
+ instanceof EnumLength)) {
+ // value specified
+ percentManager.setDimension(tab,
+ tab.getInlineProgressionDimension().getMaximum(null)
+ .getLength().getValue(percentManager)
+ - tabDiff);
+ } else {
+ // set table width again without border width
+ percentManager.setDimension(tab, percentManager.getBaseLength(
+ LengthBase.CONTAINING_BLOCK_WIDTH, tab) - tabDiff);
+ }
+
+ ColumnSetup columnSetup = new ColumnSetup(tab);
+ //int sumOfColumns = columnSetup.getSumOfColumnWidths(percentManager);
+ float tableWidth = percentManager.getBaseLength(LengthBase.CONTAINING_BLOCK_WIDTH, tab);
+ float tableUnit = columnSetup.computeTableUnit(percentManager, Math.round(tableWidth));
+ percentManager.setTableUnit(tab, Math.round(tableUnit));
+
+ }
+
/**
* Calls the appropriate event handler for the passed FObj.
*
} else {
endCell( (TableCell) foNode);
}
+ } else if (foNode instanceof PageNumberCitation) {
+ if (bStart) {
+ startPageNumberCitation((PageNumberCitation) foNode);
+ } else {
+ endPageNumberCitation((PageNumberCitation) foNode);
+ }
} else {
log.warn("Ignored deferred event for " + foNode);
}
//recurse all table-columns
if (table.getColumns() != null) {
- for (Iterator it = table.getColumns().iterator(); it.hasNext();) {
- recurseFONode( (FONode) it.next() );
- }
+ //Calculation for column-widths which are not set
+ prepareTable(table);
+
+ for (Iterator it = table.getColumns().iterator(); it.hasNext();) {
+ recurseFONode( (FONode) it.next() );
+ }
} else {
//TODO Implement implicit column setup handling!
log.warn("No table-columns found on table. RTF output requires that all"
* 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.
import java.util.HashMap;
import java.util.Iterator;
+
import org.xml.sax.Attributes;
import org.xml.sax.helpers.AttributesImpl;
return values.get(name);
}
+ /**
+ * Returns a value as an Integer. The value is simply cast to an Integer.
+ * @param name String containing attribute name
+ * @return the value of an attribute, null if not found
+ */
+ public Integer getValueAsInteger(String name) {
+ return (Integer)values.get(name);
+ }
+
/**
* @param name String containing attribute name
* @return true if given attribute is set
xslAttributes = new org.xml.sax.helpers.AttributesImpl(pAttribs);
}
}
-
+
/**
* Add integer value <code>addValue</code> to attribute with name <code>name</code>.
- * If there is no such setted attribute, then value of this attribure is equal to
+ * If there is no such setted attribute, then value of this attribure is equal to
* <code>addValue</code>.
* @param addValue the increment of value
* @param name the name of attribute
*/
public void addIntegerValue(int addValue, String name) {
Integer value = (Integer) getValue(name);
- int v = (value != null) ? value.intValue() : 0;
+ int v = (value != null) ? value.intValue() : 0;
set(name, v + addValue);
}
}
public static final String HEADERY = "headery";
/** constant for footer position */
public static final String FOOTERY = "footery";
-
+ /** constant for itap level */
+ public static final String ITAP = "itap";
+
/** String array of RtfPage attributes */
public static final String[] PAGE_ATTR = new String[]{
PAGE_WIDTH, PAGE_HEIGHT, LANDSCAPE, MARGIN_TOP, MARGIN_BOTTOM,
- MARGIN_LEFT, MARGIN_RIGHT, HEADERY, FOOTERY
+ MARGIN_LEFT, MARGIN_RIGHT, HEADERY, FOOTERY, ITAP
};
/** RtfPage creates new page attributes with the parent container, the writer
* 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.
* the FOP project.
*/
-import java.io.Writer;
import java.io.IOException;
+import java.io.Writer;
/**
* @author Christopher Scott, scottc@westinghouse.com
private String id = null;
/** Create an RTF page number citation as a child of given container with default attributes */
- RtfPageNumberCitation (IRtfPageNumberCitationContainer parent, Writer w, String id)
+ RtfPageNumberCitation (RtfContainer parent, Writer w, String id)
throws IOException {
- super((RtfContainer)parent, w);
+ super(parent, w);
this.id = id;
}
// Build page reference field
String pageRef = RTF_FIELD_PAGEREF_MODEL;
final int insertionIndex = pageRef.indexOf("}");
- pageRef = pageRef.substring(0, insertionIndex)
- + "\"" + id
+ pageRef = pageRef.substring(0, insertionIndex)
+ + "\"" + id
+ "\"" + " "
+ pageRef.substring(insertionIndex, pageRef.length());
id = null;
writeStarControlWord(pageRef);
writeGroupMark(false);
writeGroupMark(true);
- writeControlWord(RTF_FIELD_RESULT);
+ writeControlWord(RTF_FIELD_RESULT + '#'); //To see where the page-number would be
writeGroupMark(false);
writeGroupMark(false);
}
* 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.
* the FOP project.
*/
-import java.io.Writer;
import java.io.IOException;
+import java.io.Writer;
/** Container for RtfRow elements
* @author Bertrand Delacretaz bdelacretaz@codeconsult.ch
* number-columns-spanned attribute */
private ITableColumnsInfo tableContext;
+ /** Shows the table depth necessary for nested tables */
+ private int nestedTableDepth = 0;
+
/** Create an RTF element as a child of given container */
RtfTable(IRtfTableContainer parent, Writer w, ITableColumnsInfo tc)
throws IOException {
writeControlWordNS("pard");
}
- writeGroupMark(true);
+ writeGroupMark(true);
}
-
+
/**
* Overridden to write RTF suffix code, what comes after our children
* @throws IOException for I/O problems
*/
protected void writeRtfSuffix() throws IOException {
writeGroupMark(false);
-
+
if (isNestedTable()) {
getRow().writeRowAndCellsDefintions();
}
}
/**
- *
+ *
* @return RtfAttributes of Header
*/
public RtfAttributes getHeaderAttribs() {
return super.getRtfAttributes();
}
-
+
/** @return true if the the table is a nested table */
public boolean isNestedTable() {
if (isNestedTable == null) {
return false;
}
-
+
/**
- *
+ *
* @return Parent row table (for nested tables only)
*/
public RtfTableRow getRow() {
e = e.parent;
}
- return null;
+ return null;
+ }
+
+ /**
+ * Sets the nested table depth.
+ * @param nestedTableDepth the nested table depth
+ */
+ public void setNestedTableDepth(int nestedTableDepth) {
+ this.nestedTableDepth = nestedTableDepth;
+ }
+
+ /**
+ * Returns the nested table depth.
+ * @return the nested table depth
+ */
+ public int getNestedTableDepth() {
+ return this.nestedTableDepth;
}
/**
public void setBorderAttributes(RtfAttributes attributes) {
borderAttributes = attributes;
}
-
+
/**
* Returns the RtfAttributes for the borders of the table.
* @return Border attributes of the table.
* 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.
* @throws IOException for I/O problems
*/
protected void writeRtfContent() throws IOException {
-
if (getTable().isNestedTable()) {
//nested table
writeControlWord("intbl");
- writeControlWord("itap2");
+ //itap is the depth (level) of the current nested table
+ writeControlWord("itap" + getTable().getNestedTableDepth());
} else {
//normal (not nested) table
writeRowAndCellsDefintions();
// now children can write themselves, we have the correct RTF prefix code
super.writeRtfContent();
}
-
+
/**
- *
+ *
* @throws IOException In case of a IO-problem
*/
public void writeRowAndCellsDefintions() throws IOException {
// render the row and cells definitions
writeControlWord("trowd");
-
+
if (!getTable().isNestedTable()) {
writeControlWord("itap0");
}
// write X positions of our cells
int xPos = 0;
-
+
final Object leftIndent = attrib.getValue(ITableAttributes.ATTR_ROW_LEFT_INDENT);
if (leftIndent != null) {
xPos = ((Integer)leftIndent).intValue();
}
-
+
RtfAttributes tableBorderAttributes = getTable().getBorderAttributes();
-
+
int index = 0;
for (Iterator it = getChildren().iterator(); it.hasNext();) {
final RtfElement e = (RtfElement)it.next();
if (e instanceof RtfTableCell) {
-
+
RtfTableCell rtfcell = (RtfTableCell)e;
-
+
// Adjust the cell's display attributes so the table's/row's borders
// are drawn properly.
-
+
if (tableBorderAttributes != null) {
// get border attributes from table
if (index == 0) {
}
}
}
-
+
// get border attributes from row
if (index == 0) {
if (!rtfcell.getRtfAttributes().isSet(ITableAttributes.CELL_BORDER_LEFT)) {
}
index++; // Added by Boris POUDEROUS on 2002/07/02
}
-
+
newLine();
}
public boolean isHighestCell(int cellId) {
return (highestCell == cellId) ? true : false;
}
-
+
/**
- *
+ *
* @return Parent table of the row.
*/
public RtfTable getTable() {
e = e.parent;
}
- return null;
+ return null;
}
}
* 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.
// Java
import java.io.IOException;
import java.io.Writer;
-import java.util.List;
import java.util.Iterator;
+import java.util.List;
import java.util.ListIterator;
-// FOP
-import org.apache.fop.render.rtf.rtflib.rtfdoc.RtfExternalGraphic;
-
-/**
- * Class which contains a linear text run. It has methods to add attributes,
+/**
+ * Class which contains a linear text run. It has methods to add attributes,
* text, paragraph breaks....
* @author Peter Herweg, pherweg@web.de
*/
public class RtfTextrun extends RtfContainer {
private boolean bSuppressLastPar = false;
private RtfListItem rtfListItem;
-
+
/** Manager for handling space-* property. */
private RtfSpaceManager rtfSpaceManager = new RtfSpaceManager();
-
+
/** Class which represents the opening of a RTF group mark.*/
private class RtfOpenGroupMark extends RtfElement {
-
+
RtfOpenGroupMark(RtfContainer parent, Writer w, RtfAttributes attr)
throws IOException {
super(parent, w, attr);
}
-
+
/**
* @return true if this element would generate no "useful" RTF content
*/
public boolean isEmpty() {
return false;
}
-
+
/**
* write RTF code of all our children
* @throws IOException for I/O problems
writeAttributes(getRtfAttributes(), null);
}
}
-
+
/** Class which represents the closing of a RTF group mark.*/
private class RtfCloseGroupMark extends RtfElement {
-
+
RtfCloseGroupMark(RtfContainer parent, Writer w)
throws IOException {
super(parent, w);
}
-
+
/**
* @return true if this element would generate no "useful" RTF content
*/
public boolean isEmpty() {
return false;
}
-
+
/**
* write RTF code of all our children
* @throws IOException for I/O problems
/** Class which represents a paragraph break.*/
private class RtfParagraphBreak extends RtfElement {
-
+
RtfParagraphBreak(RtfContainer parent, Writer w)
throws IOException {
super(parent, w);
}
-
+
/**
* @return true if this element would generate no "useful" RTF content
*/
public boolean isEmpty() {
return false;
}
-
+
/**
* write RTF code of all our children
* @throws IOException for I/O problems
writeControlWord("par");
}
}
-
+
/** Create an RTF container as a child of given container */
RtfTextrun(RtfContainer parent, Writer w, RtfAttributes attrs) throws IOException {
super(parent, w, attrs);
}
-
-
+
+
/**
* Adds instance of <code>OpenGroupMark</code> as a child with attributes.
- *
+ *
* @param attrs attributes to add
* @throws IOException for I/O problems
*/
/**
* Adds instance of <code>CloseGroupMark</code> as a child.
- *
+ *
* @throws IOException for I/O problems
*/
private void addCloseGroupMark() throws IOException {
RtfCloseGroupMark r = new RtfCloseGroupMark(this, writer);
}
-
+
/**
- * Pushes block attributes, notifies all opened blocks about pushing block
+ * Pushes block attributes, notifies all opened blocks about pushing block
* attributes, adds <code>OpenGroupMark</code> as a child.
- *
+ *
* @param attrs the block attributes to push
* @throws IOException for I/O problems
*/
RtfSpaceSplitter splitter = rtfSpaceManager.pushRtfSpaceSplitter(attrs);
addOpenGroupMark(splitter.getCommonAttributes());
}
-
+
/**
- * Pops block attributes, notifies all opened blocks about pushing block
+ * Pops block attributes, notifies all opened blocks about pushing block
* attributes, adds <code>CloseGroupMark</code> as a child.
- *
+ *
* @throws IOException for I/O problems
*/
public void popBlockAttributes() throws IOException {
/**
* Pushes inline attributes.
- *
+ *
* @param attrs the inline attributes to push
* @throws IOException for I/O problems
*/
addOpenGroupMark(attrs);
}
+ /**
+ * Inserts a page number citation.
+ * @param refId the identifier being referenced
+ * @throws IOException for I/O problems
+ */
+ public void addPageNumberCitation(String refId) throws IOException {
+ RtfPageNumberCitation r = new RtfPageNumberCitation(this, writer, refId);
+ }
+
/**
* Pop inline attributes.
- *
+ *
* @throws IOException for I/O problems
*/
public void popInlineAttributes() throws IOException {
rtfSpaceManager.popInlineAttributes();
addCloseGroupMark();
}
-
+
/**
* Add string to children list.
- *
+ *
* @param s string to add
* @throws IOException for I/O problems
*/
RtfString r = new RtfString(this, writer, s);
rtfSpaceManager.popRtfSpaceSplitter();
}
-
+
/**
* Inserts a footnote.
- *
+ *
* @return inserted footnote
* @throws IOException for I/O problems
*/
public RtfFootnote addFootnote() throws IOException {
return new RtfFootnote(this, writer);
}
-
+
/**
* Inserts paragraph break before all close group marks.
- *
+ *
* @throws IOException for I/O problems
*/
public void addParagraphBreak() throws IOException {
}
}
}
-
+
/**
* Inserts a page number.
* @param attr Attributes for the page number to insert.
public void addPageNumber(RtfAttributes attr) throws IOException {
RtfPageNumber r = new RtfPageNumber(this, writer, attr);
}
-
+
/**
* Inserts a hyperlink.
* @param attr Attributes for the hyperlink to insert.
public RtfHyperLink addHyperlink(RtfAttributes attr) throws IOException {
return new RtfHyperLink(this, writer, attr);
}
-
+
/**
* Inserts a bookmark.
* @param id Id for the inserted bookmark
throws IOException {
List list = container.getChildren();
-
+
if (list.size() == 0) {
//add a new RtfTextrun
RtfTextrun textrun = new RtfTextrun(container, writer, attrs);
return textrun;
}
-
+
Object obj = list.get(list.size() - 1);
if (obj instanceof RtfTextrun) {
//add a new RtfTextrun as the last child
RtfTextrun textrun = new RtfTextrun(container, writer, attrs);
list.add(textrun);
-
+
return textrun;
}
-
+
/**
* specify, if the last paragraph control word (\par) should be suppressed.
* @param bSuppress true, if the last \par should be suppressed
- */
+ */
public void setSuppressLastPar(boolean bSuppress) {
bSuppressLastPar = bSuppress;
}
-
+
/**
* write RTF code of all our children
* @throws IOException for I/O problems
* 2. To write the children
* Maybe this can be done more efficient.
*/
-
+
boolean bHasTableCellParent =
this.getParentOfClass(RtfTableCell.class) != null;
RtfAttributes attrBlockLevel = new RtfAttributes();
break;
}
}
-
+
//get last RtfParagraphBreak, which is not followed by any visible child
RtfParagraphBreak lastParagraphBreak = null;
if (bLast) {
}
}
}
-
+
//may contain for example \intbl
writeAttributes(attrib, null);
-
+
if (rtfListItem != null) {
rtfListItem.getRtfListStyle().writeParagraphPrefix(this);
}
if (bHasTableCellParent) {
attrBlockLevel.set(e.getRtfAttributes());
}
-
-
+
+
/**
* -Write RtfParagraphBreak only, if the previous visible child
* was't also a RtfParagraphBreak.
*/
boolean bHide = false;
bHide = bRtfParagraphBreak;
- bHide = bHide
- && (bPrevPar
- || bFirst
- || (bSuppressLastPar && bLast && lastParagraphBreak != null
+ bHide = bHide
+ && (bPrevPar
+ || bFirst
+ || (bSuppressLastPar && bLast && lastParagraphBreak != null
&& e == lastParagraphBreak));
-
+
if (!bHide) {
newLine();
- e.writeRtf();
-
+ e.writeRtf();
+
if (rtfListItem != null && e instanceof RtfParagraphBreak) {
rtfListItem.getRtfListStyle().writeParagraphPrefix(this);
}
}
-
+
if (e instanceof RtfParagraphBreak) {
bPrevPar = true;
} else if (e instanceof RtfCloseGroupMark) {
bFirst = bFirst && e.isEmpty();
}
} //for (Iterator it = ...)
-
+
//
if (bHasTableCellParent) {
writeAttributes(attrBlockLevel, null);
}
-
+
}
-
+
/**
* Set the parent list-item of the textrun.
- *
+ *
* @param listItem parent list-item of the textrun
*/
public void setRtfListItem(RtfListItem listItem) {
rtfListItem = listItem;
}
-
+
/**
- * Gets the parent list-item of the textrun.
- *
+ * Gets the parent list-item of the textrun.
+ *
* @return parent list-item of the textrun
*/
public RtfListItem getRtfListItem() {
--- /dev/null
+/*
+ * 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.rtflib.tools;
+
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.apache.fop.datatypes.LengthBase;
+import org.apache.fop.datatypes.PercentBaseContext;
+import org.apache.fop.fo.FONode;
+import org.apache.fop.fo.FObj;
+import org.apache.fop.fo.flow.table.Table;
+import org.apache.fop.fo.pagination.PageSequence;
+
+/**
+ * PercentBaseContext implementation to track base widths for percentage calculations.
+ */
+public class PercentContext implements PercentBaseContext {
+ private static Log log = LogFactory.getLog(PercentContext.class);
+
+ private static final String BLOCKCONTAINER = "fo:block-container";
+ private static final String INLINECONTAINER = "fo:inline-container";
+ private static final String TABLE = "fo:table";
+ private static final String TABLECOLUMN = "fo:table-column";
+ private static final String PAGESEQUENCE = "fo:page-sequence";
+ private static final String EXTERNALGRAPHIC = "fo:external-graphic";
+
+ /** String array of Elements having a width property */
+ public static final String[] WIDTH_OBJECTS = new String[] {
+ BLOCKCONTAINER, INLINECONTAINER,
+ TABLE, TABLECOLUMN, PAGESEQUENCE, EXTERNALGRAPHIC};
+
+ /** Map containing the FObj and its width */
+ private Map lengthMap = new java.util.HashMap();
+
+ /** Map containing the Tables and their table units */
+ private Map tableUnitMap = new java.util.HashMap();
+
+ /** Variable to check if a base width is set */
+ private boolean baseWidthSet = false;
+
+ /**
+ * Returns the available width for a specific FObj
+ *
+ * @param lengthBase
+ * lengthBase not used
+ * @param fobj
+ * the FObj
+ * @return Available Width
+ */
+ public int getBaseLength(int lengthBase, FObj fobj) {
+ if (fobj == null) {
+ return 0;
+ }
+ switch (lengthBase) {
+ case LengthBase.CONTAINING_BLOCK_WIDTH:
+ case LengthBase.PARENT_AREA_WIDTH:
+ case LengthBase.CONTAINING_REFAREA_WIDTH:
+ Object width = lengthMap.get(fobj);
+ if (width != null) {
+ return Integer.parseInt(width.toString());
+ } else {
+ return -1;
+ }
+ case LengthBase.TABLE_UNITS:
+ Object unit = tableUnitMap.get(fobj);
+ /*
+ if (unit == null && !(fobj instanceof Table)) {
+ FONode node = fobj;
+ do {
+ node = node.getParent();
+ } while (!(node instanceof FObj) || node != null);
+ return getBaseLength(lengthBase, (FObj)node);
+ }
+ */
+ return (unit != null) ? ((Integer)unit).intValue() : 0;
+ default:
+ log.error(new Exception("Unsupported base type for LengthBase:" + lengthBase));
+ return 0;
+ }
+ }
+
+ /**
+ * Elements having a width property can call this function if their width is
+ * calculated in RTFHandler
+ *
+ * @param fobj the FObj
+ * @param width width of the FObj (in millipoints)
+ */
+ public void setDimension(FObj fobj, int width) {
+ // TODO ACCEPT only objects above for setting a width
+ if (fobj instanceof PageSequence) {
+ baseWidthSet = true;
+ }
+ // width in mpt
+ lengthMap.put(fobj, new Integer(width));
+ }
+
+ /**
+ * Records the calculated table unit for a given table.
+ * @param table the table for which the table unit is set
+ * @param tableUnit the table unit value (in millipoints)
+ */
+ public void setTableUnit(Table table, int tableUnit) {
+ tableUnitMap.put(table, new Integer(tableUnit));
+ }
+
+ /**
+ * Searches for the parent object of fobj.
+ */
+ private Integer findParent(FONode fobj) {
+ if (fobj.getRoot() != fobj) {
+ if (lengthMap.containsKey(fobj)) {
+ return new Integer(lengthMap.get(fobj).toString());
+ } else {
+ return findParent(fobj.getParent());
+ }
+ } else {
+ log.error("Base Value for element " + fobj.getName() + " not found");
+ return new Integer(-1);
+ }
+ }
+
+ /**
+ * Elements willing to use this context have to register themselves by
+ * calling this function.
+ *
+ * @param fobj the FObj
+ */
+ public void setDimension(FObj fobj) {
+ if (baseWidthSet) {
+ Integer width = findParent(fobj.getParent());
+ if (width.intValue() != -1) {
+ lengthMap.put(fobj, width);
+ }
+ }
+ }
+}
-->
<!--/release-->
<release version="0.95" date="TBD">
+ <action context="Renderers" dev="JM" type="add" fixes-bug="43824" due-to="Maximilian Aster">
+ Added support for page-number-citation for RTF output.
+ </action>
+ <action context="Renderers" dev="JM" type="fix" fixes-bug="43606" due-to="Maximilian Aster">
+ Fixed handling of proportional-column-width() and percentages for table column in RTF
+ output.
+ </action>
<action context="Images" dev="JM" type="fix">
Fixed two bugs concerning resolution handling with SVG images and their
conversion to bitmaps for RTF output.