📄 worddocument.java
字号:
//get the offset in fkp of the papx for this paragraph int papxOffset = 2 * Utils.convertUnsignedByteToInt(fkp[((crun + 1) * 4) + (y * 13)]); int size = 2 * Utils.convertUnsignedByteToInt(fkp[papxOffset]); if(size == 0) { size = 2 * Utils.convertUnsignedByteToInt(fkp[++papxOffset]); } else { size--; } byte[] papx = new byte[size]; System.arraycopy(fkp, ++papxOffset, papx, 0, size); _paragraphTable.add(new PapxNode(fcStart, fcEnd, papx)); } } //find sections int fcMin = Utils.convertBytesToInt(_header, 0x18); int plcfsedFC = Utils.convertBytesToInt(_header, 0xca); int plcfsedSize = Utils.convertBytesToInt(_header, 0xce); byte[] plcfsed = new byte[plcfsedSize]; System.arraycopy(tableStream, plcfsedFC, plcfsed, 0, plcfsedSize); arraySize = (plcfsedSize - 4)/16; //openDoc(); for(int x = 0; x < arraySize; x++) { int sectionStart = Utils.convertBytesToInt(plcfsed, x * 4) + fcMin; int sectionEnd = Utils.convertBytesToInt(plcfsed, (x+1) * 4) + fcMin; int sepxStart = Utils.convertBytesToInt(plcfsed, 4 * (arraySize + 1) + (x * 12) + 2); int sepxSize = Utils.convertBytesToShort(_header, sepxStart); byte[] sepx = new byte[sepxSize]; System.arraycopy(_header, sepxStart + 2, sepx, 0, sepxSize); SepxNode node = new SepxNode(x + 1, sectionStart, sectionEnd, sepx); _sectionTable.add(node); } } public void openDoc() { _headerBuffer.append("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\r\n"); _headerBuffer.append("<fo:root xmlns:fo=\"http://www.w3.org/1999/XSL/Format\">\r\n"); _headerBuffer.append("<fo:layout-master-set>\r\n"); } private HeaderFooter findSectionHdrFtr(int type, int index) { if(_plcfHdd.length < 50) { return new HeaderFooter(0,0,0); } int start = _fcMin + _ccpText + _ccpFtn; int end = start; int arrayIndex = 0; switch(type) { case HeaderFooter.HEADER_EVEN: arrayIndex = (HEADER_EVEN_INDEX + (index * 6)); break; case HeaderFooter.FOOTER_EVEN: arrayIndex = (FOOTER_EVEN_INDEX + (index * 6)); break; case HeaderFooter.HEADER_ODD: arrayIndex = (HEADER_ODD_INDEX + (index * 6)); break; case HeaderFooter.FOOTER_ODD: arrayIndex = (FOOTER_ODD_INDEX + (index * 6)); break; case HeaderFooter.HEADER_FIRST: arrayIndex = (HEADER_FIRST_INDEX + (index * 6)); break; case HeaderFooter.FOOTER_FIRST: arrayIndex = (FOOTER_FIRST_INDEX + (index * 6)); break; } start += Utils.convertBytesToInt(_plcfHdd, (arrayIndex * 4)); end += Utils.convertBytesToInt(_plcfHdd, (arrayIndex + 1) * 4); HeaderFooter retValue = new HeaderFooter(type, start, end); if((end - start) == 0 && index > 1) { retValue = findSectionHdrFtr(type, index - 1); } return retValue; } /** * inits this document DOP structure. * * @param tableStream The documents table stream. */ private void initDocProperties(byte[] tableStream) { int pos = LittleEndian.getInt(_header, 0x192); int size = LittleEndian.getInt(_header, 0x196); byte[] dop = new byte[size]; System.arraycopy(tableStream, pos, dop, 0, size); _docProps._fFacingPages = (dop[0] & 0x1) > 0; _docProps._fpc = (dop[0] & 0x60) >> 5; short num = LittleEndian.getShort(dop, 2); _docProps._rncFtn = (num & 0x3); _docProps._nFtn = (short)(num & 0xfffc) >> 2; num = LittleEndian.getShort(dop, 52); _docProps._rncEdn = num & 0x3; _docProps._nEdn = (short)(num & 0xfffc) >> 2; num = LittleEndian.getShort(dop, 54); _docProps._epc = num & 0x3; } public void writeSection(int start, int end, SEP sep, BTreeSet text, BTreeSet paragraphTable, BTreeSet characterTable, StyleSheet stylesheet) { HeaderFooter titleHeader = findSectionHdrFtr(HeaderFooter.HEADER_FIRST, _sectionCounter); HeaderFooter titleFooter = findSectionHdrFtr(HeaderFooter.FOOTER_FIRST, _sectionCounter); HeaderFooter oddHeader = findSectionHdrFtr(HeaderFooter.HEADER_ODD, _sectionCounter); HeaderFooter evenHeader = findSectionHdrFtr(HeaderFooter.HEADER_EVEN, _sectionCounter); HeaderFooter oddFooter = findSectionHdrFtr(HeaderFooter.FOOTER_ODD, _sectionCounter); HeaderFooter evenFooter = findSectionHdrFtr(HeaderFooter.FOOTER_EVEN, _sectionCounter); String titlePage = null; String evenPage = null; String oddPage = null; String regPage = null; String sequenceName = null; /*if(sep._fTitlePage) { titlePage = createPageMaster(sep, "first", _sectionCounter, createRegion("before", "title-header"), createRegion("after", "title-footer")); if(!titleHeader.isEmpty()) { addStaticContent("title-header" + _sectionCounter, titleHeader); } if(!titleFooter.isEmpty()) { addStaticContent("title-footer" + _sectionCounter, titleFooter); } }*/ if(_docProps._fFacingPages) { if(sep._fTitlePage) { String before = createRegion(true, titleHeader, sep, "title-header" + _sectionCounter); String after = createRegion(false, titleFooter, sep, "title-footer" + _sectionCounter); titlePage = createPageMaster(sep, "first", _sectionCounter, before, after); } String before = createRegion(true, evenHeader, sep, "even-header" + _sectionCounter); String after = createRegion(false, evenFooter, sep, "even-footer" + _sectionCounter); evenPage = createPageMaster(sep, "even", _sectionCounter, before, after); before = createRegion(true, oddHeader, sep, "odd-header" + _sectionCounter); after = createRegion(false, oddFooter, sep, "odd-footer" + _sectionCounter); oddPage = createPageMaster(sep, "odd", _sectionCounter, before, after); sequenceName = createEvenOddPageSequence(titlePage, evenPage, oddPage, _sectionCounter); openPage(sequenceName, "reference"); if(sep._fTitlePage) { if(!titleHeader.isEmpty()) { addStaticContent("title-header" + _sectionCounter, titleHeader); } if(!titleFooter.isEmpty()) { addStaticContent("title-footer" + _sectionCounter, titleFooter); } } //handle the headers and footers for odd and even pages if(!oddHeader.isEmpty()) { addStaticContent("odd-header" + _sectionCounter, oddHeader); } if(!oddFooter.isEmpty()) { addStaticContent("odd-footer" + _sectionCounter, oddFooter); } if(!evenHeader.isEmpty()) { addStaticContent("even-header" + _sectionCounter, evenHeader); } if(!evenFooter.isEmpty()) { addStaticContent("even-footer" + _sectionCounter, evenFooter); } openFlow(); addBlockContent(start, end, text, paragraphTable, characterTable); closeFlow(); closePage(); } else { /*if(sep._fTitlePage) { String before = createRegion(true, titleHeader, sep); String after = createRegion(false, titleFooter, sep); titlePage = createPageMaster(sep, "first", _sectionCounter, before, after); }*/ String before = createRegion(true, oddHeader, sep, null); String after = createRegion(false, oddFooter, sep, null); regPage = createPageMaster(sep, "page", _sectionCounter, before, after); if(sep._fTitlePage) { before = createRegion(true, titleHeader, sep, "title-header" + _sectionCounter); after = createRegion(false, titleFooter, sep, "title-footer" + _sectionCounter); titlePage = createPageMaster(sep, "first", _sectionCounter, before, after); sequenceName = createPageSequence(titlePage, regPage, _sectionCounter); openPage(sequenceName, "reference"); if(!titleHeader.isEmpty()) { addStaticContent("title-header" + _sectionCounter, titleHeader); } if(!titleFooter.isEmpty()) { addStaticContent("title-footer" + _sectionCounter, titleFooter); } } else { openPage(regPage, "name"); } if(!oddHeader.isEmpty()) { addStaticContent("xsl-region-before", oddHeader); } if(!oddFooter.isEmpty()) { addStaticContent("xsl-region-after", oddFooter); } openFlow(); addBlockContent(start, end, text, paragraphTable, characterTable); closeFlow(); closePage(); } _sectionCounter++; } private int calculateHeaderHeight(int start, int end, int pageWidth) { ArrayList paragraphs = findProperties(start, end, _paragraphTable.root); int size = paragraphs.size(); ArrayList lineHeights = new ArrayList(); //StyleContext context = StyleContext.getDefaultStyleContext(); for(int x = 0; x < size; x++) { PapxNode node = (PapxNode)paragraphs.get(x); int parStart = Math.max(node.getStart(), start); int parEnd = Math.min(node.getEnd(), end); int lineWidth = 0; int maxHeight = 0; ArrayList textRuns = findProperties(parStart, parEnd, _characterTable.root); int charSize = textRuns.size(); //StringBuffer lineBuffer = new StringBuffer(); for(int y = 0; y < charSize; y++) { ChpxNode charNode = (ChpxNode)textRuns.get(y); int istd = Utils.convertBytesToShort(node.getPapx(), 0); StyleDescription sd = _styleSheet.getStyleDescription(istd); CHP chp = (CHP)StyleSheet.uncompressProperty(charNode.getChpx(), sd.getCHP(), _styleSheet); //get Font info //FontMetrics metrics = getFontMetrics(chp, context); int height = 10;//metrics.getHeight(); maxHeight = Math.max(maxHeight, height); int charStart = Math.max(parStart, charNode.getStart()); int charEnd = Math.min(parEnd, charNode.getEnd()); ArrayList text = findProperties(charStart, charEnd, _text.root); int textSize = text.size(); StringBuffer buf = new StringBuffer(); for(int z = 0; z < textSize; z++) { TextPiece piece = (TextPiece)text.get(z); int textStart = Math.max(piece.getStart(), charStart); int textEnd = Math.min(piece.getEnd(), charEnd); if(piece.usesUnicode()) { addUnicodeText(textStart, textEnd, buf); } else { addText(textStart, textEnd, buf); } } String tempString = buf.toString(); lineWidth += 10 * tempString.length();//metrics.stringWidth(tempString); if(lineWidth > pageWidth) { lineHeights.add(new Integer(maxHeight)); maxHeight = 0; lineWidth = 0; } } lineHeights.add(new Integer(maxHeight)); } int sum = 0; size = lineHeights.size(); for(int x = 0; x < size; x++) { Integer height = (Integer)lineHeights.get(x); sum += height.intValue(); } return sum; }/* private FontMetrics getFontMetrics(CHP chp, StyleContext context) { String fontName = _fonts.getFont(chp._ftcAscii); int style = 0; if(chp._bold) { style |= Font.BOLD; } if(chp._italic) { style |= Font.ITALIC; } Font font = new Font(fontName, style, chp._hps/2); return context.getFontMetrics(font); }*/ private String createRegion(boolean before, HeaderFooter header, SEP sep, String name) { if(header.isEmpty()) { return ""; } String region = "region-name=\"" + name + "\""; if(name == null) { region = ""; } int height = calculateHeaderHeight(header.getStart(), header.getEnd(), sep._xaPage/20); int marginTop = 0; int marginBottom = 0; int extent = 0; String where = null; String align = null; if(before) { where = "before"; align = "before"; marginTop = sep._dyaHdrTop/20; extent = height + marginTop; sep._dyaTop = Math.max(extent*20, sep._dyaTop); } else { where = "after"; align = "after"; marginBottom = sep._dyaHdrBottom/20; extent = height + marginBottom; sep._dyaBottom = Math.max(extent*20, sep._dyaBottom); } int marginLeft = sep._dxaLeft/20; int marginRight = sep._dxaRight/20; return "<fo:region-" + where + " display-align=\"" + align + "\" extent=\"" + extent + "pt\" padding-left=\"" + marginLeft + "pt\" padding-right=\"" + marginRight + "pt\" padding-top=\"" + marginTop + "pt\" padding-bottom=\"" + marginBottom + "pt\" " + region + "/>"; } private String createRegion(String where, String name) { return "<fo:region-" + where + " overflow=\"scroll\" region-name=\"" + name + "\"/>"; } private String createEvenOddPageSequence(String titlePage, String evenPage, String oddPage, int counter) { String name = "my-sequence" + counter; _headerBuffer.append("<fo:page-sequence-master master-name=\"" + name + "\"> "); _headerBuffer.append("<fo:repeatable-page-master-alternatives>"); if(titlePage != null) { _headerBuffer.append("<fo:conditional-page-master-reference " + "page-position=\"first\" master-reference=\"" + titlePage + "\"/>"); } _headerBuffer.append("<fo:conditional-page-master-reference odd-or-even=\"odd\" "); _headerBuffer.append("master-reference=\""+ oddPage + "\"/> "); _headerBuffer.append("<fo:conditional-page-master-reference odd-or-even=\"even\" "); _headerBuffer.append("master-reference=\"" + evenPage + "\"/> "); _headerBuffer.append("</fo:repeatable-page-master-alternatives>"); _headerBuffer.append("</fo:page-sequence-master>"); return name; } private String createPageSequence(String titlePage, String regPage, int counter) { String name = null; if(titlePage != null) { name = "my-sequence" + counter; _headerBuffer.append("<fo:page-sequence-master master-name=\"" + name + "\"> "); _headerBuffer.append("<fo:single-page-master-reference master-reference=\"" + titlePage + "\"/>"); _headerBuffer.append("<fo:repeatable-page-master-reference master-reference=\"" + regPage + "\"/>"); _headerBuffer.append("</fo:page-sequence-master>"); } return name; } private void addBlockContent(int start, int end, BTreeSet text, BTreeSet paragraphTable, BTreeSet characterTable) { BTreeSet.BTreeNode root = paragraphTable.root; ArrayList pars = findProperties(start, end, root); //root = characterTable.root; int size = pars.size(); for(int c = 0; c < size; c++) { PapxNode currentNode = (PapxNode)pars.get(c); createParagraph(start, end, currentNode, characterTable, text); } //closePage(); } private String getTextAlignment(byte jc) { switch(jc) { case 0: return "start"; case 1: return "center"; case 2: return "end"; case 3: return "justify"; default: return "left"; } } private void createParagraph(int start, int end, PapxNode currentNode,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -