public static DocumentFragment createBlockForR( SvgConversionContext context, NodeIterator rPrNodeIt, NodeIterator childResults) { DocumentFragment docfrag = null; Document d = null; Element span = null; try { // Create a DOM builder and parse the fragment d = XmlUtils.getNewDocumentBuilder().newDocument(); span = d.createElement("span"); d.appendChild(span); CTTextCharacterProperties textCharProps = (CTTextCharacterProperties) nodeToObjectModel(rPrNodeIt.nextNode(), CTTextCharacterProperties.class); RPr rPr = TextStyles.getWmlRPr(textCharProps); // Does our rPr contain anything else? StringBuilder inlineStyle = new StringBuilder(); HtmlCssHelper.createCss(context.getPmlPackage(), rPr, inlineStyle); if (!inlineStyle.toString().equals("")) { span.setAttribute("style", inlineStyle.toString()); } Node n = childResults.nextNode(); XmlUtils.treeCopy(n, span); } catch (Exception e) { log.error(e.getMessage(), e); // If something went wrong with the formatting, // still try to display the text! Node n = childResults.nextNode(); XmlUtils.treeCopy(n, span); } // Machinery docfrag = d.createDocumentFragment(); docfrag.appendChild(d.getDocumentElement()); return docfrag; }
/** Connection (line) */ public static Document CxnSpToSVG(CxnSp cxnSp) { // Geometrical transforms CTTransform2D xfrm = cxnSp.getSpPr().getXfrm(); Box b = new Box( xfrm.getOff().getX(), xfrm.getOff().getY(), xfrm.getExt().getCx(), xfrm.getExt().getCy()); if (xfrm.getRot() != 0) { b.rotate(xfrm.getRot()); } if (xfrm.isFlipH()) { b.flipH(); } if (xfrm.isFlipV()) { b.flipV(); } // Convert from EMU to pixels b.toPixels(); // Wrap in a div positioning it on the page Document document = XmlUtils.getNewDocumentBuilder().newDocument(); Element xhtmlDiv = document.createElement("div"); // Firefox needs the following; Chrome doesn't xhtmlDiv.setAttribute( "style", "position: absolute; width:100%; height:100%; left:0px; top:0px;"); Node n = document.appendChild(xhtmlDiv); // Convert the object itself to SVG Svg svg = oFactory.createSvg(); Line line = oFactory.createLine(); svg.getSVGDescriptionClassOrSVGAnimationClassOrSVGStructureClass().add(line); line.setX1(b.getOffset().getXAsString()); line.setY1(b.getOffset().getYAsString()); Point otherEnd = b.getOtherCorner(); line.setX2(otherEnd.getXAsString()); line.setY2(otherEnd.getYAsString()); line.setStyle("stroke:rgb(99,99,99)"); // You can't see the line in Midori, unless you specify the color. // width eg stroke-width:2 is optional Document d2 = XmlUtils.marshaltoW3CDomDocument(svg, jcSVG); XmlUtils.treeCopy(d2, n); return document; }
public Node toNode(Model tableModel, TransformState transformState, Document doc) throws TransformerException { TableModel table = (TableModel) tableModel; getLog().debug("Table asXML:\n" + table.debugStr()); DocumentFragment docfrag = doc.createDocumentFragment(); Element tableRoot = createNode(doc, null, NODE_TABLE); List<Property> rowProperties = new ArrayList<Property>(); int rowPropertiesTableSize = -1; List<Property> cellProperties = new ArrayList<Property>(); int cellPropertiesTableSize = -1; int cellPropertiesRowSize = -1; boolean inHeader = (table.getHeaderMaxRow() > -1); TableModelRow rowModel = null; Element rowContainer = null; Element row = null; Element cellNode = null; createRowProperties(rowProperties, table.getEffectiveTableStyle().getTrPr(), true); rowPropertiesTableSize = rowProperties.size(); createCellProperties(cellProperties, table.getEffectiveTableStyle().getTrPr()); createCellProperties(cellProperties, table.getEffectiveTableStyle().getTcPr()); // will apply these as a default on each td, and then override createCellProperties(cellProperties, table.getEffectiveTableStyle().getTblPr()); cellPropertiesTableSize = cellProperties.size(); docfrag.appendChild(tableRoot); applyTableStyles(table, transformState, tableRoot); // setup column widths createColumns(table, transformState, doc, tableRoot); rowContainer = createNode(doc, tableRoot, (inHeader ? NODE_TABLE_HEADER : NODE_TABLE_BODY)); tableRoot.appendChild(rowContainer); applyTableRowContainerCustomAttributes(table, transformState, rowContainer, inHeader); for (int rowIndex = 0; rowIndex < table.getCells().size(); rowIndex++) { rowModel = table.getCells().get(rowIndex); if ((inHeader) && (rowIndex > table.getHeaderMaxRow())) { rowContainer = createNode(doc, tableRoot, NODE_TABLE_BODY); tableRoot.appendChild(rowContainer); inHeader = false; applyTableRowContainerCustomAttributes(table, transformState, rowContainer, inHeader); } row = createNode(doc, rowContainer, (inHeader ? NODE_TABLE_HEADER_ROW : NODE_TABLE_BODY_ROW)); TrPr trPr = rowModel.getRowProperties(); CTTblPrEx tblPrEx = rowModel.getRowPropertiesExceptions(); createRowProperties(rowProperties, trPr, false); processAttributes(rowProperties, row); applyTableRowCustomAttributes(table, transformState, row, rowIndex, inHeader); createCellProperties(cellProperties, trPr); createCellProperties(cellProperties, tblPrEx); cellPropertiesRowSize = cellProperties.size(); for (Cell cell : rowModel.getRowContents()) { // process cell if (cell.isDummy()) { if (!cell.isVMerged()) { // Dummy-Cells resulting from vertical merged cells shouldn't be included cellNode = createNode(doc, row, (inHeader ? NODE_TABLE_HEADER_CELL : NODE_TABLE_BODY_CELL)); row.appendChild(cellNode); applyTableCellCustomAttributes(table, transformState, cell, cellNode, inHeader, true); } } else { cellNode = createNode(doc, row, (inHeader ? NODE_TABLE_HEADER_CELL : NODE_TABLE_BODY_CELL)); row.appendChild(cellNode); // Apply cell style createCellProperties(cellProperties, cell.getTcPr()); processAttributes(cellProperties, cellNode); applyTableCellCustomAttributes(table, transformState, cell, cellNode, inHeader, false); // remove properties defined on cell level resetProperties(cellProperties, cellPropertiesRowSize); // insert content into cell // skipping w:tc node itself, insert only its children if (cell.getContent() == null) { getLog().warn("model cell had no contents!"); } else { getLog().debug("copying cell contents.."); XmlUtils.treeCopy(cell.getContent().getChildNodes(), cellNode); } } } // remove properties defined on row level resetProperties(cellProperties, cellPropertiesTableSize); resetProperties(rowProperties, rowPropertiesTableSize); } return docfrag; }
@Override public List<Object> apply(Object o) { if (o instanceof P) { currentP = createNode(document, NODE_BLOCK); currentSpan = null; if (tc.peek() != null) { tc.peek().appendChild(currentP); } else { parentNode.appendChild(currentP); } pPr = ((P) o).getPPr(); currentP = handlePPr(conversionContext, pPr, false, currentP); } else if (o instanceof org.docx4j.wml.R) { if (!conversionContext.isInComplexFieldDefinition()) { // Convert run to span Element spanEl = createNode(document, NODE_INLINE); currentSpan = spanEl; rPr = ((R) o).getRPr(); if (rPr != null) { handleRPr(conversionContext, pPr, rPr, currentSpan); } if (currentP == null) { // Hyperlink special case parentNode.appendChild(spanEl); } else { rtlAwareAppendChildToCurrentP(spanEl); } // To merge nested span (which we could do if there is a single child span), // TraversalUtil Callback would need an after walk children } } else if (o instanceof org.docx4j.wml.FldChar) { conversionContext.updateComplexFieldDefinition(((org.docx4j.wml.FldChar) o).getFldCharType()); } else if (o instanceof org.docx4j.wml.Text) { if (!conversionContext.isInComplexFieldDefinition()) { if (currentSpan == null) { // eg after <br/> log.error("null currentSpan! " + ((Text) o).getValue()); Element spanEl = createNode(document, NODE_INLINE); if (currentP == null) { // Hyperlink special case parentNode.appendChild(spanEl); } else { currentP.appendChild(spanEl); } currentSpan = spanEl; } log.debug(((Text) o).getValue()); DocumentFragment df = (DocumentFragment) conversionContext.getRunFontSelector().fontSelector(pPr, rPr, ((Text) o)); XmlUtils.treeCopy(df, currentSpan); // TODO would be more efficient without the treeCopy // but fontSelector would need to be refactored a bit } } else if (o instanceof org.docx4j.wml.R.Tab) { convertTabToNode(conversionContext, document); } else if (o instanceof org.docx4j.wml.CTSimpleField) { convertToNode( conversionContext, o, AbstractFldSimpleWriter.WRITER_ID, document, getCurrentParent()); } else if (o instanceof org.docx4j.wml.P.Hyperlink) { convertToNode( conversionContext, o, AbstractHyperlinkWriter.WRITER_ID, document, getCurrentParent()); } else if (o instanceof org.docx4j.wml.CTBookmark) { convertToNode( conversionContext, o, AbstractBookmarkStartWriter.WRITER_ID, document, getCurrentParent()); } else if (o instanceof org.docx4j.wml.Tbl) { convertToNode( conversionContext, o, AbstractTableWriter.WRITER_ID, document, (currentP != null ? currentP : parentNode)); currentP = null; currentSpan = null; } else if (o instanceof org.docx4j.wml.Tr) { // done in walkJAXBElements // tr = document.createElementNS(Namespaces.NS_WORD12, "tr"); // //parentNode is in this case the DocumentFragment, that get's passed // //to the TableModel/TableModelWriter // parentNode.appendChild(tr); } else if (o instanceof org.docx4j.wml.Tc) { // done in walkJAXBElements // tc = document.createElementNS(Namespaces.NS_WORD12, "tc"); // tr.appendChild(tc); // // now the html p content will go temporarily go in w:tc, // // which is what we need for our existing table model. // System.out.println("#wrapped in w:tc OK"); } else if (o instanceof org.docx4j.dml.wordprocessingDrawing.Inline || o instanceof org.docx4j.dml.wordprocessingDrawing.Anchor) { anchorOrInline = o; // keep this until we handle CTBlip } else if (o instanceof org.docx4j.dml.CTBlip) { /*<w:drawing> <wp:inline distT="0" distB="0" distL="0" distR="0"> <a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"> <a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture"> <pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture"> <pic:blipFill> <a:blip r:embed="rId10" cstate="print"/> */ DocumentFragment foreignFragment = createImage(IMAGE_E20, conversionContext, anchorOrInline); anchorOrInline = null; currentP.appendChild(document.importNode(foreignFragment, true)); } else if (o instanceof org.docx4j.wml.Pict) { /*<w:pict> <v:shape id="_x0000_i1025" type="#_x0000_t75" style="width:428.25pt;height:321pt"> <v:imagedata r:id="rId4" o:title=""/> </v:shape> */ org.docx4j.vml.CTTextbox textBox = getTextBox((org.docx4j.wml.Pict) o); if (textBox == null) { // Assume it contains an image! DocumentFragment foreignFragment = createImage(IMAGE_E10, conversionContext, o); currentP.appendChild(document.importNode(foreignFragment, true)); } else { convertToNode( conversionContext, o, AbstractPictWriter.WRITER_ID, document, getCurrentParent()); } } else if (o instanceof Br) { handleBr((Br) o); } else if (o instanceof org.docx4j.wml.R.Sym) { convertToNode( conversionContext, o, AbstractSymbolWriter.WRITER_ID, document, getCurrentParent()); } else if ((o instanceof org.docx4j.wml.ProofErr) || (o instanceof org.docx4j.wml.R.LastRenderedPageBreak) || (o instanceof org.docx4j.wml.CTMarkupRange)) { // Ignore theese types, they don't need to be outputed/handled // CTMarkupRange is the w:bookmarkEnd } else { getLog().warn("Need to handle " + o.getClass().getName()); log.debug(XmlUtils.marshaltoString(o)); } return null; }
public static DocumentFragment createBlockForP( SvgConversionContext context, String lvl, String cNvPrName, String phType, NodeIterator childResults, NodeIterator lvlNpPr) { StyleTree styleTree = null; try { styleTree = context.getPmlPackage().getStyleTree(); } catch (InvalidFormatException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } log.debug("lvl:" + lvl); int level; if (lvl.equals("NaN")) { level = 1; } else { level = Integer.parseInt(lvl); } String pStyleVal; System.out.println("cNvPrName: " + cNvPrName + "; " + "phType: " + phType); if (cNvPrName.toLowerCase().indexOf("subtitle") > -1 || phType.toLowerCase().indexOf("subtitle") > -1) { // Subtitle on first page in default layout is styled as a Body. pStyleVal = "Lvl" + level + "Master" + context.getResolvedLayout().getMasterNumber() + "Body"; } else if (cNvPrName.toLowerCase().indexOf("title") > -1 || phType.toLowerCase().indexOf("title") > -1) { pStyleVal = "Lvl" + level + "Master" + context.getResolvedLayout().getMasterNumber() + "Title"; } else { // eg cNvPrName: TextBox 2; phType: pStyleVal = "Lvl" + level + "Master" + context.getResolvedLayout().getMasterNumber() + "Other"; } System.out.println("--> " + pStyleVal); try { // Create a DOM builder and parse the fragment Document document = XmlUtils.getNewDocumentBuilder().newDocument(); // log.info("Document: " + document.getClass().getName() ); Node xhtmlP = document.createElement("p"); document.appendChild(xhtmlP); // Set @class log.debug(pStyleVal); Tree<AugmentedStyle> pTree = styleTree.getParagraphStylesTree(); org.docx4j.model.styles.Node<AugmentedStyle> asn = pTree.get(pStyleVal); ((Element) xhtmlP).setAttribute("class", StyleTree.getHtmlClassAttributeValue(pTree, asn)); StringBuilder inlineStyle = new StringBuilder(); // Do we have CTTextParagraphProperties // <a:lvl?pPr> // Convert it to a WordML pPr CTTextParagraphProperties lvlPPr = unmarshalFormatting(lvlNpPr); if (lvlPPr != null) { log.debug("We have lvlPPr"); log.debug( XmlUtils.marshaltoString( lvlPPr, true, true, Context.jcPML, "FIXME", "lvl1pPr", CTTextParagraphProperties.class)); PPr pPr = TextStyles.getWmlPPr(lvlPPr); if (pPr != null) { HtmlCssHelper.createCss(context.getPmlPackage(), pPr, inlineStyle, false, false); } // TODO RPR } // Without this, top-margin is too large in Webkit (Midor). // Not tested elsewhere... inlineStyle.append("margin-left:3px; margin-top:3px;"); if (!inlineStyle.toString().equals("")) { ((Element) xhtmlP).setAttribute("style", inlineStyle.toString()); } // Our fo:block wraps whatever result tree fragment // our style sheet produced when it applied-templates // to the child nodes // init Node n = childResults.nextNode(); do { // getNumberXmlNode creates a span node, which is empty // if there is no numbering. // Let's get rid of any such <span/>. // What we actually get is a document node if (n.getNodeType() == Node.DOCUMENT_NODE) { log.debug("handling DOCUMENT_NODE"); // Do just enough of the handling here NodeList nodes = n.getChildNodes(); if (nodes != null) { for (int i = 0; i < nodes.getLength(); i++) { if (((Node) nodes.item(i)).getLocalName().equals("span") && !((Node) nodes.item(i)).hasChildNodes()) { // ignore log.debug(".. ignoring <span/> "); } else { XmlUtils.treeCopy((Node) nodes.item(i), xhtmlP); } } } } else { // log.info("Node we are importing: " + n.getClass().getName() ); // foBlockElement.appendChild( // document.importNode(n, true) ); /* * Node we'd like to import is of type org.apache.xml.dtm.ref.DTMNodeProxy * which causes * org.w3c.dom.DOMException: NOT_SUPPORTED_ERR: The implementation does not support the requested type of object or operation. * * See http://osdir.com/ml/text.xml.xerces-j.devel/2004-04/msg00066.html * * So instead of importNode, use */ XmlUtils.treeCopy(n, xhtmlP); } // next n = childResults.nextNode(); } while (n != null); DocumentFragment docfrag = document.createDocumentFragment(); docfrag.appendChild(document.getDocumentElement()); return docfrag; } catch (Exception e) { log.error(e.getMessage(), e); } return null; }