Source Code Cross Referenced for WordDocument.java in  » Collaboration » poi-3.0.2-beta2 » org » apache » poi » hdf » extractor » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Collaboration » poi 3.0.2 beta2 » org.apache.poi.hdf.extractor 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* ====================================================================
0002:         Licensed to the Apache Software Foundation (ASF) under one or more
0003:         contributor license agreements.  See the NOTICE file distributed with
0004:         this work for additional information regarding copyright ownership.
0005:         The ASF licenses this file to You under the Apache License, Version 2.0
0006:         (the "License"); you may not use this file except in compliance with
0007:         the License.  You may obtain a copy of the License at
0008:
0009:         http://www.apache.org/licenses/LICENSE-2.0
0010:
0011:         Unless required by applicable law or agreed to in writing, software
0012:         distributed under the License is distributed on an "AS IS" BASIS,
0013:         WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         See the License for the specific language governing permissions and
0015:         limitations under the License.
0016:         ==================================================================== */
0017:
0018:        package org.apache.poi.hdf.extractor;
0019:
0020:        import org.apache.poi.hdf.extractor.util.*;
0021:        import org.apache.poi.hdf.extractor.data.*;
0022:        import java.util.*;
0023:        import java.io.*;
0024:
0025:        import org.apache.poi.poifs.filesystem.POIFSFileSystem;
0026:        import org.apache.poi.poifs.filesystem.DocumentEntry;
0027:
0028:        import org.apache.poi.util.LittleEndian;
0029:
0030:        /**
0031:         * This class contains the main functionality for the Word file "reader". Much
0032:         * of the code in this class is based on the Word 97 document file format. Only
0033:         * works for non-complex files
0034:         *
0035:         * @author Ryan Ackley
0036:         */
0037:
0038:        public class WordDocument {
0039:            /** byte buffer containing the main Document stream*/
0040:            byte[] _header;
0041:            /** contains all style information for this document see Word 97 Doc spec*/
0042:            StyleSheet _styleSheet;
0043:            /** contains All list information for this document*/
0044:            ListTables _listTables;
0045:            /** contains global Document properties for this document*/
0046:            DOP _docProps = new DOP();
0047:
0048:            int _currentList = -1;
0049:            int _tableSize;
0050:            int _sectionCounter = 1;
0051:            /** fonts available for this document*/
0052:            FontTable _fonts;
0053:
0054:            /** document's text blocks*/
0055:            BTreeSet _text = new BTreeSet();
0056:            /** document's character runs */
0057:            BTreeSet _characterTable = new BTreeSet();
0058:            /** document's paragraphs*/
0059:            BTreeSet _paragraphTable = new BTreeSet();
0060:            /** doucment's sections*/
0061:            BTreeSet _sectionTable = new BTreeSet();
0062:
0063:            /** used for XSL-FO conversion*/
0064:            StringBuffer _headerBuffer = new StringBuffer();
0065:            /** used for XSL-FO conversion*/
0066:            StringBuffer _bodyBuffer = new StringBuffer();
0067:            /** used for XSL-FO table conversion*/
0068:            StringBuffer _cellBuffer;
0069:            /** used for XSL-FO table conversion*/
0070:            ArrayList _cells;
0071:            /** used for XSL-FO table conversion*/
0072:            ArrayList _table;
0073:
0074:            /** document's header and footer information*/
0075:            byte[] _plcfHdd;
0076:
0077:            /** starting position of text in main document stream*/
0078:            int _fcMin;
0079:            /** length of main document text stream*/
0080:            int _ccpText;
0081:            /** length of footnotes text*/
0082:            int _ccpFtn;
0083:
0084:            /** The name of the file to write to */
0085:            private static String _outName;
0086:
0087:            /** OLE stuff*/
0088:            private InputStream istream;
0089:            /** OLE stuff*/
0090:            private POIFSFileSystem filesystem;
0091:
0092:            //used internally
0093:            private static int HEADER_EVEN_INDEX = 0;
0094:            private static int HEADER_ODD_INDEX = 1;
0095:            private static int FOOTER_EVEN_INDEX = 2;
0096:            private static int FOOTER_ODD_INDEX = 3;
0097:            private static int HEADER_FIRST_INDEX = 4;
0098:            private static int FOOTER_FIRST_INDEX = 5;
0099:
0100:            /**
0101:             *  right now this function takes one parameter: a Word file, and outputs an
0102:             *  XSL-FO document at c:\test.xml (this is hardcoded)
0103:             */
0104:            public static void main(String args[]) {
0105:                /*try
0106:                {
0107:                  WordDocument file = new WordDocument(args[0], "r");
0108:                  Writer out = new BufferedWriter(new FileWriter(args[1]));
0109:                  file.writeAllText(out);
0110:                  out.flush();
0111:                  out.close();
0112:                }
0113:                catch(Throwable t)
0114:                {
0115:                  t.printStackTrace();
0116:                }*/
0117:                try {
0118:                    _outName = args[1];
0119:                    WordDocument file = new WordDocument(args[0]);
0120:                    file.closeDoc();
0121:                } catch (Exception e) {
0122:                    e.printStackTrace();
0123:                }
0124:                System.exit(0);
0125:            }
0126:
0127:            /**
0128:             * Spits out the document text
0129:             *
0130:             * @param out The Writer to write the text to.
0131:             * @throws IOException if there is a problem while reading from the file or
0132:             *         writing out the text.
0133:             */
0134:            public void writeAllText(Writer out) throws IOException {
0135:                int textStart = Utils.convertBytesToInt(_header, 0x18);
0136:                int textEnd = Utils.convertBytesToInt(_header, 0x1c);
0137:                ArrayList textPieces = findProperties(textStart, textEnd,
0138:                        _text.root);
0139:                int size = textPieces.size();
0140:
0141:                for (int x = 0; x < size; x++) {
0142:                    TextPiece nextPiece = (TextPiece) textPieces.get(x);
0143:                    int start = nextPiece.getStart();
0144:                    int end = nextPiece.getEnd();
0145:                    boolean unicode = nextPiece.usesUnicode();
0146:                    int add = 1;
0147:
0148:                    if (unicode) {
0149:                        add = 2;
0150:                        char ch;
0151:                        for (int y = start; y < end; y += add) {
0152:                            ch = (char) Utils.convertBytesToShort(_header, y);
0153:                            out.write(ch);
0154:                        }
0155:                    } else {
0156:                        String sText = new String(_header, start, end - start);
0157:                        out.write(sText);
0158:                    }
0159:                }
0160:            }
0161:
0162:            /**
0163:             * Constructs a Word document from fileName. Parses the document and places
0164:             * all the important stuff into data structures.
0165:             *
0166:             * @param fileName The name of the file to read.
0167:             * @throws IOException if there is a problem while parsing the document.
0168:             */
0169:            public WordDocument(String fileName) throws IOException {
0170:                this (new FileInputStream(fileName));
0171:            }
0172:
0173:            public WordDocument(InputStream inputStream) throws IOException {
0174:                //do Ole stuff
0175:                istream = inputStream;
0176:                filesystem = new POIFSFileSystem(istream);
0177:
0178:                //get important stuff from the Header block and parse all the
0179:                //data structures
0180:                readFIB();
0181:
0182:                //get the SEPS for the main document text
0183:                ArrayList sections = findProperties(_fcMin, _fcMin + _ccpText,
0184:                        _sectionTable.root);
0185:
0186:                //iterate through sections, paragraphs, and character runs doing what
0187:                //you will with the data.
0188:                int size = sections.size();
0189:                for (int x = 0; x < size; x++) {
0190:                    SepxNode node = (SepxNode) sections.get(x);
0191:                    int start = node.getStart();
0192:                    int end = node.getEnd();
0193:                    SEP sep = (SEP) StyleSheet.uncompressProperty(node
0194:                            .getSepx(), new SEP(), _styleSheet);
0195:                    writeSection(Math.max(_fcMin, start), Math.min(_fcMin
0196:                            + _ccpText, end), sep, _text, _paragraphTable,
0197:                            _characterTable, _styleSheet);
0198:                }
0199:                //finish
0200:                istream.close();
0201:
0202:            }
0203:
0204:            /**
0205:             * Extracts the main document stream from the POI file then hands off to other
0206:             * functions that parse other areas.
0207:             *
0208:             * @throws IOException
0209:             */
0210:            private void readFIB() throws IOException {
0211:                //get the main document stream
0212:                DocumentEntry headerProps = (DocumentEntry) filesystem
0213:                        .getRoot().getEntry("WordDocument");
0214:
0215:                //I call it the header but its also the main document stream
0216:                _header = new byte[headerProps.getSize()];
0217:                filesystem.createDocumentInputStream("WordDocument").read(
0218:                        _header);
0219:
0220:                //Get the information we need from the header
0221:                int info = LittleEndian.getShort(_header, 0xa);
0222:
0223:                _fcMin = LittleEndian.getInt(_header, 0x18);
0224:                _ccpText = LittleEndian.getInt(_header, 0x4c);
0225:                _ccpFtn = LittleEndian.getInt(_header, 0x50);
0226:
0227:                int charPLC = LittleEndian.getInt(_header, 0xfa);
0228:                int charPlcSize = LittleEndian.getInt(_header, 0xfe);
0229:                int parPLC = LittleEndian.getInt(_header, 0x102);
0230:                int parPlcSize = LittleEndian.getInt(_header, 0x106);
0231:                boolean useTable1 = (info & 0x200) != 0;
0232:
0233:                //process the text and formatting properties
0234:                processComplexFile(useTable1, charPLC, charPlcSize, parPLC,
0235:                        parPlcSize);
0236:            }
0237:
0238:            /**
0239:             * Extracts the correct Table stream from the POI filesystem then hands off to
0240:             * other functions to process text and formatting info. the name is based on
0241:             * the fact that in Word 8(97) all text (not character or paragraph formatting)
0242:             * is stored in complex format.
0243:             *
0244:             * @param useTable1 boolean that specifies if we should use table1 or table0
0245:             * @param charTable offset in table stream of character property bin table
0246:             * @param charPlcSize size of character property bin table
0247:             * @param parTable offset in table stream of paragraph property bin table.
0248:             * @param parPlcSize size of paragraph property bin table.
0249:             * @return boolean indocating success of
0250:             * @throws IOException
0251:             */
0252:            private void processComplexFile(boolean useTable1, int charTable,
0253:                    int charPlcSize, int parTable, int parPlcSize)
0254:                    throws IOException {
0255:
0256:                //get the location of the piece table
0257:                int complexOffset = LittleEndian.getInt(_header, 0x1a2);
0258:
0259:                String tablename = null;
0260:                DocumentEntry tableEntry = null;
0261:                if (useTable1) {
0262:                    tablename = "1Table";
0263:                } else {
0264:                    tablename = "0Table";
0265:                }
0266:                tableEntry = (DocumentEntry) filesystem.getRoot().getEntry(
0267:                        tablename);
0268:
0269:                //load the table stream into a buffer
0270:                int size = tableEntry.getSize();
0271:                byte[] tableStream = new byte[size];
0272:                filesystem.createDocumentInputStream(tablename).read(
0273:                        tableStream);
0274:
0275:                //init the DOP for this document
0276:                initDocProperties(tableStream);
0277:                //load the header/footer raw data for this document
0278:                initPclfHdd(tableStream);
0279:                //parse out the text locations
0280:                findText(tableStream, complexOffset);
0281:                //parse out text formatting
0282:                findFormatting(tableStream, charTable, charPlcSize, parTable,
0283:                        parPlcSize);
0284:
0285:            }
0286:
0287:            /**
0288:             * Goes through the piece table and parses out the info regarding the text
0289:             * blocks. For Word 97 and greater all text is stored in the "complex" way
0290:             * because of unicode.
0291:             *
0292:             * @param tableStream buffer containing the main table stream.
0293:             * @param beginning of the complex data.
0294:             * @throws IOException
0295:             */
0296:            private void findText(byte[] tableStream, int complexOffset)
0297:                    throws IOException {
0298:                //actual text
0299:                int pos = complexOffset;
0300:                //skips through the prms before we reach the piece table. These contain data
0301:                //for actual fast saved files
0302:                while (tableStream[pos] == 1) {
0303:                    pos++;
0304:                    int skip = LittleEndian.getShort(tableStream, pos);
0305:                    pos += 2 + skip;
0306:                }
0307:                if (tableStream[pos] != 2) {
0308:                    throw new IOException("corrupted Word file");
0309:                } else {
0310:                    //parse out the text pieces
0311:                    int pieceTableSize = LittleEndian
0312:                            .getInt(tableStream, ++pos);
0313:                    pos += 4;
0314:                    int pieces = (pieceTableSize - 4) / 12;
0315:                    for (int x = 0; x < pieces; x++) {
0316:                        int filePos = LittleEndian.getInt(tableStream, pos
0317:                                + ((pieces + 1) * 4) + (x * 8) + 2);
0318:                        boolean unicode = false;
0319:                        if ((filePos & 0x40000000) == 0) {
0320:                            unicode = true;
0321:                        } else {
0322:                            unicode = false;
0323:                            filePos &= ~(0x40000000);//gives me FC in doc stream
0324:                            filePos /= 2;
0325:                        }
0326:                        int totLength = LittleEndian.getInt(tableStream, pos
0327:                                + (x + 1) * 4)
0328:                                - LittleEndian.getInt(tableStream, pos
0329:                                        + (x * 4));
0330:
0331:                        TextPiece piece = new TextPiece(filePos, totLength,
0332:                                unicode);
0333:                        _text.add(piece);
0334:
0335:                    }
0336:
0337:                }
0338:            }
0339:
0340:            /**
0341:             * Does all of the formatting parsing
0342:             *
0343:             * @param tableStream Main table stream buffer.
0344:             * @param charOffset beginning of the character bin table.
0345:             * @param chrPlcSize size of the char bin table.
0346:             * @param parOffset offset of the paragraph bin table.
0347:             * @param size of the paragraph bin table.
0348:             */
0349:            private void findFormatting(byte[] tableStream, int charOffset,
0350:                    int charPlcSize, int parOffset, int parPlcSize)
0351:                    throws IOException {
0352:                openDoc();
0353:                createStyleSheet(tableStream);
0354:                createListTables(tableStream);
0355:                createFontTable(tableStream);
0356:
0357:                //find character runs
0358:                //Get all the chpx info and store it
0359:
0360:                int arraySize = (charPlcSize - 4) / 8;
0361:
0362:                //first we must go through the bin table and find the fkps
0363:                for (int x = 0; x < arraySize; x++) {
0364:
0365:                    //get page number(has nothing to do with document page)
0366:                    //containing the chpx for the paragraph
0367:                    int PN = LittleEndian.getInt(tableStream, charOffset
0368:                            + (4 * (arraySize + 1) + (4 * x)));
0369:
0370:                    byte[] fkp = new byte[512];
0371:                    System.arraycopy(_header, (PN * 512), fkp, 0, 512);
0372:                    //take each fkp and get the chpxs
0373:                    int crun = Utils.convertUnsignedByteToInt(fkp[511]);
0374:                    for (int y = 0; y < crun; y++) {
0375:                        //get the beginning fc of each paragraph text run
0376:                        int fcStart = LittleEndian.getInt(fkp, y * 4);
0377:                        int fcEnd = LittleEndian.getInt(fkp, (y + 1) * 4);
0378:                        //get the offset in fkp of the papx for this paragraph
0379:                        int chpxOffset = 2 * Utils
0380:                                .convertUnsignedByteToInt(fkp[((crun + 1) * 4)
0381:                                        + y]);
0382:
0383:                        //optimization if offset == 0 use "Normal" style
0384:                        if (chpxOffset == 0)
0385:
0386:                        {
0387:                            _characterTable.add(new ChpxNode(fcStart, fcEnd,
0388:                                    new byte[0]));
0389:                            continue;
0390:                        }
0391:
0392:                        int size = Utils
0393:                                .convertUnsignedByteToInt(fkp[chpxOffset]);
0394:
0395:                        byte[] chpx = new byte[size];
0396:                        System.arraycopy(fkp, ++chpxOffset, chpx, 0, size);
0397:                        //_papTable.put(new Integer(fcStart), papx);
0398:                        _characterTable.add(new ChpxNode(fcStart, fcEnd, chpx));
0399:                    }
0400:
0401:                }
0402:
0403:                //find paragraphs
0404:                arraySize = (parPlcSize - 4) / 8;
0405:                //first we must go through the bin table and find the fkps
0406:                for (int x = 0; x < arraySize; x++) {
0407:                    int PN = LittleEndian.getInt(tableStream, parOffset
0408:                            + (4 * (arraySize + 1) + (4 * x)));
0409:
0410:                    byte[] fkp = new byte[512];
0411:                    System.arraycopy(_header, (PN * 512), fkp, 0, 512);
0412:                    //take each fkp and get the paps
0413:                    int crun = Utils.convertUnsignedByteToInt(fkp[511]);
0414:                    for (int y = 0; y < crun; y++) {
0415:                        //get the beginning fc of each paragraph text run
0416:                        int fcStart = LittleEndian.getInt(fkp, y * 4);
0417:                        int fcEnd = LittleEndian.getInt(fkp, (y + 1) * 4);
0418:                        //get the offset in fkp of the papx for this paragraph
0419:                        int papxOffset = 2 * Utils
0420:                                .convertUnsignedByteToInt(fkp[((crun + 1) * 4)
0421:                                        + (y * 13)]);
0422:                        int size = 2 * Utils
0423:                                .convertUnsignedByteToInt(fkp[papxOffset]);
0424:                        if (size == 0) {
0425:                            size = 2 * Utils
0426:                                    .convertUnsignedByteToInt(fkp[++papxOffset]);
0427:                        } else {
0428:                            size--;
0429:                        }
0430:
0431:                        byte[] papx = new byte[size];
0432:                        System.arraycopy(fkp, ++papxOffset, papx, 0, size);
0433:                        _paragraphTable.add(new PapxNode(fcStart, fcEnd, papx));
0434:
0435:                    }
0436:
0437:                }
0438:
0439:                //find sections
0440:                int fcMin = Utils.convertBytesToInt(_header, 0x18);
0441:                int plcfsedFC = Utils.convertBytesToInt(_header, 0xca);
0442:                int plcfsedSize = Utils.convertBytesToInt(_header, 0xce);
0443:                byte[] plcfsed = new byte[plcfsedSize];
0444:                System.arraycopy(tableStream, plcfsedFC, plcfsed, 0,
0445:                        plcfsedSize);
0446:
0447:                arraySize = (plcfsedSize - 4) / 16;
0448:
0449:                //openDoc();
0450:
0451:                for (int x = 0; x < arraySize; x++) {
0452:                    int sectionStart = Utils.convertBytesToInt(plcfsed, x * 4)
0453:                            + fcMin;
0454:                    int sectionEnd = Utils.convertBytesToInt(plcfsed,
0455:                            (x + 1) * 4)
0456:                            + fcMin;
0457:                    int sepxStart = Utils.convertBytesToInt(plcfsed, 4
0458:                            * (arraySize + 1) + (x * 12) + 2);
0459:                    int sepxSize = Utils
0460:                            .convertBytesToShort(_header, sepxStart);
0461:                    byte[] sepx = new byte[sepxSize];
0462:                    System.arraycopy(_header, sepxStart + 2, sepx, 0, sepxSize);
0463:                    SepxNode node = new SepxNode(x + 1, sectionStart,
0464:                            sectionEnd, sepx);
0465:                    _sectionTable.add(node);
0466:                }
0467:
0468:            }
0469:
0470:            public void openDoc() {
0471:                _headerBuffer
0472:                        .append("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\r\n");
0473:                _headerBuffer
0474:                        .append("<fo:root xmlns:fo=\"http://www.w3.org/1999/XSL/Format\">\r\n");
0475:                _headerBuffer.append("<fo:layout-master-set>\r\n");
0476:
0477:            }
0478:
0479:            private HeaderFooter findSectionHdrFtr(int type, int index) {
0480:                if (_plcfHdd.length < 50) {
0481:                    return new HeaderFooter(0, 0, 0);
0482:                }
0483:                int start = _fcMin + _ccpText + _ccpFtn;
0484:                int end = start;
0485:                int arrayIndex = 0;
0486:
0487:                switch (type) {
0488:                case HeaderFooter.HEADER_EVEN:
0489:                    arrayIndex = (HEADER_EVEN_INDEX + (index * 6));
0490:                    break;
0491:                case HeaderFooter.FOOTER_EVEN:
0492:                    arrayIndex = (FOOTER_EVEN_INDEX + (index * 6));
0493:                    break;
0494:                case HeaderFooter.HEADER_ODD:
0495:                    arrayIndex = (HEADER_ODD_INDEX + (index * 6));
0496:                    break;
0497:                case HeaderFooter.FOOTER_ODD:
0498:                    arrayIndex = (FOOTER_ODD_INDEX + (index * 6));
0499:                    break;
0500:                case HeaderFooter.HEADER_FIRST:
0501:                    arrayIndex = (HEADER_FIRST_INDEX + (index * 6));
0502:                    break;
0503:                case HeaderFooter.FOOTER_FIRST:
0504:                    arrayIndex = (FOOTER_FIRST_INDEX + (index * 6));
0505:                    break;
0506:                }
0507:                start += Utils.convertBytesToInt(_plcfHdd, (arrayIndex * 4));
0508:                end += Utils.convertBytesToInt(_plcfHdd, (arrayIndex + 1) * 4);
0509:
0510:                HeaderFooter retValue = new HeaderFooter(type, start, end);
0511:
0512:                if ((end - start) == 0 && index > 1) {
0513:                    retValue = findSectionHdrFtr(type, index - 1);
0514:                }
0515:                return retValue;
0516:            }
0517:
0518:            /**
0519:             * inits this document DOP structure.
0520:             *
0521:             * @param tableStream The documents table stream.
0522:             */
0523:            private void initDocProperties(byte[] tableStream) {
0524:                int pos = LittleEndian.getInt(_header, 0x192);
0525:                int size = LittleEndian.getInt(_header, 0x196);
0526:                byte[] dop = new byte[size];
0527:
0528:                System.arraycopy(tableStream, pos, dop, 0, size);
0529:
0530:                _docProps._fFacingPages = (dop[0] & 0x1) > 0;
0531:                _docProps._fpc = (dop[0] & 0x60) >> 5;
0532:
0533:                short num = LittleEndian.getShort(dop, 2);
0534:                _docProps._rncFtn = (num & 0x3);
0535:                _docProps._nFtn = (short) (num & 0xfffc) >> 2;
0536:                num = LittleEndian.getShort(dop, 52);
0537:                _docProps._rncEdn = num & 0x3;
0538:                _docProps._nEdn = (short) (num & 0xfffc) >> 2;
0539:                num = LittleEndian.getShort(dop, 54);
0540:                _docProps._epc = num & 0x3;
0541:            }
0542:
0543:            public void writeSection(int start, int end, SEP sep,
0544:                    BTreeSet text, BTreeSet paragraphTable,
0545:                    BTreeSet characterTable, StyleSheet stylesheet) {
0546:
0547:                HeaderFooter titleHeader = findSectionHdrFtr(
0548:                        HeaderFooter.HEADER_FIRST, _sectionCounter);
0549:                HeaderFooter titleFooter = findSectionHdrFtr(
0550:                        HeaderFooter.FOOTER_FIRST, _sectionCounter);
0551:                HeaderFooter oddHeader = findSectionHdrFtr(
0552:                        HeaderFooter.HEADER_ODD, _sectionCounter);
0553:                HeaderFooter evenHeader = findSectionHdrFtr(
0554:                        HeaderFooter.HEADER_EVEN, _sectionCounter);
0555:                HeaderFooter oddFooter = findSectionHdrFtr(
0556:                        HeaderFooter.FOOTER_ODD, _sectionCounter);
0557:                HeaderFooter evenFooter = findSectionHdrFtr(
0558:                        HeaderFooter.FOOTER_EVEN, _sectionCounter);
0559:
0560:                String titlePage = null;
0561:                String evenPage = null;
0562:                String oddPage = null;
0563:                String regPage = null;
0564:
0565:                String sequenceName = null;
0566:
0567:                /*if(sep._fTitlePage)
0568:                {
0569:                  titlePage = createPageMaster(sep, "first", _sectionCounter, createRegion("before", "title-header"), createRegion("after", "title-footer"));
0570:
0571:                  if(!titleHeader.isEmpty())
0572:                  {
0573:                    addStaticContent("title-header" + _sectionCounter, titleHeader);
0574:                  }
0575:                  if(!titleFooter.isEmpty())
0576:                  {
0577:                    addStaticContent("title-footer" + _sectionCounter, titleFooter);
0578:                  }
0579:                }*/
0580:
0581:                if (_docProps._fFacingPages) {
0582:                    if (sep._fTitlePage) {
0583:                        String before = createRegion(true, titleHeader, sep,
0584:                                "title-header" + _sectionCounter);
0585:                        String after = createRegion(false, titleFooter, sep,
0586:                                "title-footer" + _sectionCounter);
0587:                        titlePage = createPageMaster(sep, "first",
0588:                                _sectionCounter, before, after);
0589:                    }
0590:                    String before = createRegion(true, evenHeader, sep,
0591:                            "even-header" + _sectionCounter);
0592:                    String after = createRegion(false, evenFooter, sep,
0593:                            "even-footer" + _sectionCounter);
0594:                    evenPage = createPageMaster(sep, "even", _sectionCounter,
0595:                            before, after);
0596:                    before = createRegion(true, oddHeader, sep, "odd-header"
0597:                            + _sectionCounter);
0598:                    after = createRegion(false, oddFooter, sep, "odd-footer"
0599:                            + _sectionCounter);
0600:                    oddPage = createPageMaster(sep, "odd", _sectionCounter,
0601:                            before, after);
0602:                    sequenceName = createEvenOddPageSequence(titlePage,
0603:                            evenPage, oddPage, _sectionCounter);
0604:
0605:                    openPage(sequenceName, "reference");
0606:
0607:                    if (sep._fTitlePage) {
0608:
0609:                        if (!titleHeader.isEmpty()) {
0610:                            addStaticContent("title-header" + _sectionCounter,
0611:                                    titleHeader);
0612:                        }
0613:                        if (!titleFooter.isEmpty()) {
0614:                            addStaticContent("title-footer" + _sectionCounter,
0615:                                    titleFooter);
0616:                        }
0617:                    }
0618:
0619:                    //handle the headers and footers for odd and even pages
0620:                    if (!oddHeader.isEmpty()) {
0621:                        addStaticContent("odd-header" + _sectionCounter,
0622:                                oddHeader);
0623:                    }
0624:                    if (!oddFooter.isEmpty()) {
0625:                        addStaticContent("odd-footer" + _sectionCounter,
0626:                                oddFooter);
0627:                    }
0628:                    if (!evenHeader.isEmpty()) {
0629:                        addStaticContent("even-header" + _sectionCounter,
0630:                                evenHeader);
0631:                    }
0632:                    if (!evenFooter.isEmpty()) {
0633:                        addStaticContent("even-footer" + _sectionCounter,
0634:                                evenFooter);
0635:                    }
0636:                    openFlow();
0637:                    addBlockContent(start, end, text, paragraphTable,
0638:                            characterTable);
0639:                    closeFlow();
0640:                    closePage();
0641:                } else {
0642:                    /*if(sep._fTitlePage)
0643:                    {
0644:                      String before = createRegion(true, titleHeader, sep);
0645:                      String after = createRegion(false, titleFooter, sep);
0646:                      titlePage = createPageMaster(sep, "first", _sectionCounter, before, after);
0647:                    }*/
0648:                    String before = createRegion(true, oddHeader, sep, null);
0649:                    String after = createRegion(false, oddFooter, sep, null);
0650:                    regPage = createPageMaster(sep, "page", _sectionCounter,
0651:                            before, after);
0652:
0653:                    if (sep._fTitlePage) {
0654:                        before = createRegion(true, titleHeader, sep,
0655:                                "title-header" + _sectionCounter);
0656:                        after = createRegion(false, titleFooter, sep,
0657:                                "title-footer" + _sectionCounter);
0658:                        titlePage = createPageMaster(sep, "first",
0659:                                _sectionCounter, before, after);
0660:                        sequenceName = createPageSequence(titlePage, regPage,
0661:                                _sectionCounter);
0662:                        openPage(sequenceName, "reference");
0663:
0664:                        if (!titleHeader.isEmpty()) {
0665:                            addStaticContent("title-header" + _sectionCounter,
0666:                                    titleHeader);
0667:                        }
0668:                        if (!titleFooter.isEmpty()) {
0669:                            addStaticContent("title-footer" + _sectionCounter,
0670:                                    titleFooter);
0671:                        }
0672:                    } else {
0673:                        openPage(regPage, "name");
0674:                    }
0675:                    if (!oddHeader.isEmpty()) {
0676:                        addStaticContent("xsl-region-before", oddHeader);
0677:                    }
0678:                    if (!oddFooter.isEmpty()) {
0679:                        addStaticContent("xsl-region-after", oddFooter);
0680:                    }
0681:                    openFlow();
0682:                    addBlockContent(start, end, text, paragraphTable,
0683:                            characterTable);
0684:                    closeFlow();
0685:                    closePage();
0686:                }
0687:                _sectionCounter++;
0688:            }
0689:
0690:            private int calculateHeaderHeight(int start, int end, int pageWidth) {
0691:                ArrayList paragraphs = findProperties(start, end,
0692:                        _paragraphTable.root);
0693:                int size = paragraphs.size();
0694:                ArrayList lineHeights = new ArrayList();
0695:                //StyleContext context = StyleContext.getDefaultStyleContext();
0696:
0697:                for (int x = 0; x < size; x++) {
0698:                    PapxNode node = (PapxNode) paragraphs.get(x);
0699:                    int parStart = Math.max(node.getStart(), start);
0700:                    int parEnd = Math.min(node.getEnd(), end);
0701:
0702:                    int lineWidth = 0;
0703:                    int maxHeight = 0;
0704:
0705:                    ArrayList textRuns = findProperties(parStart, parEnd,
0706:                            _characterTable.root);
0707:                    int charSize = textRuns.size();
0708:
0709:                    //StringBuffer lineBuffer = new StringBuffer();
0710:                    for (int y = 0; y < charSize; y++) {
0711:                        ChpxNode charNode = (ChpxNode) textRuns.get(y);
0712:                        int istd = Utils.convertBytesToShort(node.getPapx(), 0);
0713:                        StyleDescription sd = _styleSheet
0714:                                .getStyleDescription(istd);
0715:                        CHP chp = (CHP) StyleSheet.uncompressProperty(charNode
0716:                                .getChpx(), sd.getCHP(), _styleSheet);
0717:
0718:                        //get Font info
0719:                        //FontMetrics metrics = getFontMetrics(chp, context);
0720:
0721:                        int height = 10;//metrics.getHeight();
0722:                        maxHeight = Math.max(maxHeight, height);
0723:
0724:                        int charStart = Math.max(parStart, charNode.getStart());
0725:                        int charEnd = Math.min(parEnd, charNode.getEnd());
0726:
0727:                        ArrayList text = findProperties(charStart, charEnd,
0728:                                _text.root);
0729:
0730:                        int textSize = text.size();
0731:                        StringBuffer buf = new StringBuffer();
0732:                        for (int z = 0; z < textSize; z++) {
0733:
0734:                            TextPiece piece = (TextPiece) text.get(z);
0735:                            int textStart = Math.max(piece.getStart(),
0736:                                    charStart);
0737:                            int textEnd = Math.min(piece.getEnd(), charEnd);
0738:
0739:                            if (piece.usesUnicode()) {
0740:                                addUnicodeText(textStart, textEnd, buf);
0741:                            } else {
0742:                                addText(textStart, textEnd, buf);
0743:                            }
0744:                        }
0745:
0746:                        String tempString = buf.toString();
0747:                        lineWidth += 10 * tempString.length();//metrics.stringWidth(tempString);
0748:                        if (lineWidth > pageWidth) {
0749:                            lineHeights.add(new Integer(maxHeight));
0750:                            maxHeight = 0;
0751:                            lineWidth = 0;
0752:                        }
0753:                    }
0754:                    lineHeights.add(new Integer(maxHeight));
0755:                }
0756:                int sum = 0;
0757:                size = lineHeights.size();
0758:                for (int x = 0; x < size; x++) {
0759:                    Integer height = (Integer) lineHeights.get(x);
0760:                    sum += height.intValue();
0761:                }
0762:
0763:                return sum;
0764:            }
0765:
0766:            /*  private FontMetrics getFontMetrics(CHP chp, StyleContext context)
0767:             {
0768:             String fontName = _fonts.getFont(chp._ftcAscii);
0769:             int style = 0;
0770:             if(chp._bold)
0771:             {
0772:             style |= Font.BOLD;
0773:             }
0774:             if(chp._italic)
0775:             {
0776:             style |= Font.ITALIC;
0777:             }
0778:
0779:             Font font = new Font(fontName, style, chp._hps/2);
0780:
0781:
0782:             return context.getFontMetrics(font);
0783:             }*/
0784:            private String createRegion(boolean before, HeaderFooter header,
0785:                    SEP sep, String name) {
0786:                if (header.isEmpty()) {
0787:                    return "";
0788:                }
0789:                String region = "region-name=\"" + name + "\"";
0790:                if (name == null) {
0791:                    region = "";
0792:                }
0793:                int height = calculateHeaderHeight(header.getStart(), header
0794:                        .getEnd(), sep._xaPage / 20);
0795:                int marginTop = 0;
0796:                int marginBottom = 0;
0797:                int extent = 0;
0798:                String where = null;
0799:                String align = null;
0800:
0801:                if (before) {
0802:                    where = "before";
0803:                    align = "before";
0804:                    marginTop = sep._dyaHdrTop / 20;
0805:                    extent = height + marginTop;
0806:                    sep._dyaTop = Math.max(extent * 20, sep._dyaTop);
0807:                } else {
0808:                    where = "after";
0809:                    align = "after";
0810:                    marginBottom = sep._dyaHdrBottom / 20;
0811:                    extent = height + marginBottom;
0812:                    sep._dyaBottom = Math.max(extent * 20, sep._dyaBottom);
0813:                }
0814:
0815:                int marginLeft = sep._dxaLeft / 20;
0816:                int marginRight = sep._dxaRight / 20;
0817:
0818:                return "<fo:region-" + where + " display-align=\"" + align
0819:                        + "\" extent=\"" + extent + "pt\" " + region + "/>";
0820:                // org.apache.fop.fo.expr.PropertyException: 
0821:                // Border and padding for region "xsl-region-before" must be '0' 
0822:                // (See 6.4.13 in XSL 1.0).
0823:                //             extent + "pt\" padding-left=\"" + marginLeft + "pt\" padding-right=\"" +
0824:                //             marginRight + "pt\" padding-top=\"" + marginTop + "pt\" padding-bottom=\"" +
0825:                //             marginBottom + "pt\" " + region + "/>";
0826:
0827:            }
0828:
0829:            private String createRegion(String where, String name) {
0830:                return "<fo:region-" + where
0831:                        + " overflow=\"scroll\" region-name=\"" + name + "\"/>";
0832:            }
0833:
0834:            private String createEvenOddPageSequence(String titlePage,
0835:                    String evenPage, String oddPage, int counter) {
0836:                String name = "my-sequence" + counter;
0837:                _headerBuffer.append("<fo:page-sequence-master master-name=\""
0838:                        + name + "\"> ");
0839:                _headerBuffer
0840:                        .append("<fo:repeatable-page-master-alternatives>");
0841:                if (titlePage != null) {
0842:                    _headerBuffer
0843:                            .append("<fo:conditional-page-master-reference "
0844:                                    + "page-position=\"first\" master-reference=\""
0845:                                    + titlePage + "\"/>");
0846:                }
0847:                _headerBuffer
0848:                        .append("<fo:conditional-page-master-reference odd-or-even=\"odd\" ");
0849:                _headerBuffer.append("master-reference=\"" + oddPage + "\"/> ");
0850:                _headerBuffer
0851:                        .append("<fo:conditional-page-master-reference odd-or-even=\"even\" ");
0852:                _headerBuffer
0853:                        .append("master-reference=\"" + evenPage + "\"/> ");
0854:                _headerBuffer
0855:                        .append("</fo:repeatable-page-master-alternatives>");
0856:                _headerBuffer.append("</fo:page-sequence-master>");
0857:                return name;
0858:            }
0859:
0860:            private String createPageSequence(String titlePage, String regPage,
0861:                    int counter) {
0862:                String name = null;
0863:                if (titlePage != null) {
0864:                    name = "my-sequence" + counter;
0865:                    _headerBuffer
0866:                            .append("<fo:page-sequence-master master-name=\""
0867:                                    + name + "\"> ");
0868:                    _headerBuffer
0869:                            .append("<fo:single-page-master-reference master-reference=\""
0870:                                    + titlePage + "\"/>");
0871:                    _headerBuffer
0872:                            .append("<fo:repeatable-page-master-reference master-reference=\""
0873:                                    + regPage + "\"/>");
0874:                    _headerBuffer.append("</fo:page-sequence-master>");
0875:                }
0876:                return name;
0877:            }
0878:
0879:            private void addBlockContent(int start, int end, BTreeSet text,
0880:                    BTreeSet paragraphTable, BTreeSet characterTable) {
0881:
0882:                BTreeSet.BTreeNode root = paragraphTable.root;
0883:                ArrayList pars = findProperties(start, end, root);
0884:                //root = characterTable.root;
0885:                int size = pars.size();
0886:
0887:                for (int c = 0; c < size; c++) {
0888:                    PapxNode currentNode = (PapxNode) pars.get(c);
0889:                    createParagraph(start, end, currentNode, characterTable,
0890:                            text);
0891:                }
0892:                //closePage();
0893:            }
0894:
0895:            private String getTextAlignment(byte jc) {
0896:                switch (jc) {
0897:                case 0:
0898:                    return "start";
0899:                case 1:
0900:                    return "center";
0901:                case 2:
0902:                    return "end";
0903:                case 3:
0904:                    return "justify";
0905:                default:
0906:                    return "left";
0907:                }
0908:            }
0909:
0910:            private void createParagraph(int start, int end,
0911:                    PapxNode currentNode, BTreeSet characterTable, BTreeSet text) {
0912:                StringBuffer blockBuffer = _bodyBuffer;
0913:                byte[] papx = currentNode.getPapx();
0914:                int istd = Utils.convertBytesToShort(papx, 0);
0915:                StyleDescription std = _styleSheet.getStyleDescription(istd);
0916:                PAP pap = (PAP) StyleSheet.uncompressProperty(papx, std
0917:                        .getPAP(), _styleSheet);
0918:
0919:                //handle table cells
0920:                if (pap._fInTable > 0) {
0921:                    if (pap._fTtp == 0) {
0922:                        if (_cellBuffer == null) {
0923:                            _cellBuffer = new StringBuffer();
0924:                        }
0925:                        blockBuffer = _cellBuffer;
0926:                    } else {
0927:                        if (_table == null) {
0928:                            _table = new ArrayList();
0929:                        }
0930:                        TAP tap = (TAP) StyleSheet.uncompressProperty(papx,
0931:                                new TAP(), _styleSheet);
0932:                        TableRow nextRow = new TableRow(_cells, tap);
0933:                        _table.add(nextRow);
0934:                        _cells = null;
0935:                        return;
0936:                    }
0937:                } else {
0938:                    //just prints out any table that is stored in _table
0939:                    printTable();
0940:                }
0941:
0942:                if (pap._ilfo > 0) {
0943:                    LVL lvl = _listTables.getLevel(pap._ilfo, pap._ilvl);
0944:                    addListParagraphContent(lvl, blockBuffer, pap, currentNode,
0945:                            start, end, std);
0946:                } else {
0947:                    addParagraphContent(blockBuffer, pap, currentNode, start,
0948:                            end, std);
0949:                }
0950:
0951:            }
0952:
0953:            private void addListParagraphContent(LVL lvl,
0954:                    StringBuffer blockBuffer, PAP pap, PapxNode currentNode,
0955:                    int start, int end, StyleDescription std) {
0956:                pap = (PAP) StyleSheet.uncompressProperty(lvl._papx, pap,
0957:                        _styleSheet, false);
0958:
0959:                addParagraphProperties(pap, blockBuffer);
0960:
0961:                ArrayList charRuns = findProperties(Math.max(currentNode
0962:                        .getStart(), start), Math
0963:                        .min(currentNode.getEnd(), end), _characterTable.root);
0964:                int len = charRuns.size();
0965:
0966:                CHP numChp = (CHP) StyleSheet.uncompressProperty(
0967:                        ((ChpxNode) charRuns.get(len - 1)).getChpx(), std
0968:                                .getCHP(), _styleSheet);
0969:
0970:                numChp = (CHP) StyleSheet.uncompressProperty(lvl._chpx, numChp,
0971:                        _styleSheet);
0972:
0973:                //StyleContext context = StyleContext.getDefaultStyleContext();
0974:                //FontMetrics metrics = getFontMetrics(numChp, context);
0975:                int indent = -1 * pap._dxaLeft1;
0976:                String bulletText = getBulletText(lvl, pap);
0977:
0978:                indent = indent - (bulletText.length() * 10) * 20;//(metrics.stringWidth(bulletText) * 20);
0979:
0980:                if (indent > 0) {
0981:                    numChp._paddingEnd = (short) indent;
0982:                }
0983:
0984:                addCharacterProperties(numChp, blockBuffer);
0985:                int listNum = 0;
0986:
0987:                //if(number != null)
0988:                //{
0989:                blockBuffer.append(bulletText);
0990:                //listNum = 1;
0991:                //}
0992:
0993:                //for(;listNum < lvl._xst.length; listNum++)
0994:                //{
0995:                //  addText(lvl._xst[listNum], blockBuffer);
0996:                //}
0997:
0998:                switch (lvl._ixchFollow) {
0999:                case 0:
1000:                    addText('\u0009', blockBuffer);
1001:                    break;
1002:                case 1:
1003:                    addText(' ', blockBuffer);
1004:                    break;
1005:                }
1006:
1007:                closeLine(blockBuffer);
1008:                for (int x = 0; x < len; x++) {
1009:                    ChpxNode charNode = (ChpxNode) charRuns.get(x);
1010:                    byte[] chpx = charNode.getChpx();
1011:                    CHP chp = (CHP) StyleSheet.uncompressProperty(chpx, std
1012:                            .getCHP(), _styleSheet);
1013:
1014:                    addCharacterProperties(chp, blockBuffer);
1015:
1016:                    int charStart = Math.max(charNode.getStart(), currentNode
1017:                            .getStart());
1018:                    int charEnd = Math.min(charNode.getEnd(), currentNode
1019:                            .getEnd());
1020:                    ArrayList textRuns = findProperties(charStart, charEnd,
1021:                            _text.root);
1022:                    int textRunLen = textRuns.size();
1023:                    for (int y = 0; y < textRunLen; y++) {
1024:                        TextPiece piece = (TextPiece) textRuns.get(y);
1025:                        charStart = Math.max(charStart, piece.getStart());
1026:                        charEnd = Math.min(charEnd, piece.getEnd());
1027:
1028:                        if (piece.usesUnicode()) {
1029:                            addUnicodeText(charStart, charEnd, blockBuffer);
1030:                        } else {
1031:                            addText(charStart, charEnd, blockBuffer);
1032:                        }
1033:                        closeLine(blockBuffer);
1034:                    }
1035:                }
1036:                closeBlock(blockBuffer);
1037:            }
1038:
1039:            private void addParagraphContent(StringBuffer blockBuffer, PAP pap,
1040:                    PapxNode currentNode, int start, int end,
1041:                    StyleDescription std) {
1042:                addParagraphProperties(pap, blockBuffer);
1043:
1044:                ArrayList charRuns = findProperties(Math.max(currentNode
1045:                        .getStart(), start), Math
1046:                        .min(currentNode.getEnd(), end), _characterTable.root);
1047:                int len = charRuns.size();
1048:
1049:                for (int x = 0; x < len; x++) {
1050:                    ChpxNode charNode = (ChpxNode) charRuns.get(x);
1051:                    byte[] chpx = charNode.getChpx();
1052:                    CHP chp = (CHP) StyleSheet.uncompressProperty(chpx, std
1053:                            .getCHP(), _styleSheet);
1054:
1055:                    addCharacterProperties(chp, blockBuffer);
1056:
1057:                    int charStart = Math.max(charNode.getStart(), currentNode
1058:                            .getStart());
1059:                    int charEnd = Math.min(charNode.getEnd(), currentNode
1060:                            .getEnd());
1061:                    ArrayList textRuns = findProperties(charStart, charEnd,
1062:                            _text.root);
1063:                    int textRunLen = textRuns.size();
1064:                    for (int y = 0; y < textRunLen; y++) {
1065:                        TextPiece piece = (TextPiece) textRuns.get(y);
1066:                        charStart = Math.max(charStart, piece.getStart());
1067:                        charEnd = Math.min(charEnd, piece.getEnd());
1068:
1069:                        if (piece.usesUnicode()) {
1070:                            addUnicodeText(charStart, charEnd, blockBuffer);
1071:                        } else {
1072:                            addText(charStart, charEnd, blockBuffer);
1073:                        }
1074:                        closeLine(blockBuffer);
1075:                    }
1076:                }
1077:                closeBlock(blockBuffer);
1078:            }
1079:
1080:            private void addText(int start, int end, StringBuffer buf) {
1081:                for (int x = start; x < end; x++) {
1082:                    char ch = '?';
1083:
1084:                    ch = (char) _header[x];
1085:
1086:                    addText(ch, buf);
1087:                }
1088:            }
1089:
1090:            private void addText(char ch, StringBuffer buf) {
1091:                int num = 0xffff & ch;
1092:                if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')
1093:                        || (ch >= '0' && ch <= '9') || ch == '_' || ch == ' '
1094:                        || ch == '-' || ch == '.' || ch == '$') {
1095:                    buf.append(ch);
1096:                } else if (num == 0x07 && _cellBuffer != null) {
1097:
1098:                    if (_cells == null) {
1099:                        _cells = new ArrayList();
1100:                    }
1101:                    closeLine(_cellBuffer);
1102:                    closeBlock(_cellBuffer);
1103:                    _cells.add(_cellBuffer.toString());
1104:                    _cellBuffer = null;
1105:
1106:                }
1107:
1108:                else {
1109:                    /** @todo handle special characters */
1110:                    if (num < 0x20)
1111:                        num = 0x20;
1112:                    buf.append("&#");
1113:                    buf.append(num);
1114:                    buf.append(';');
1115:                }
1116:            }
1117:
1118:            private void addUnicodeText(int start, int end, StringBuffer buf) {
1119:                for (int x = start; x < end; x += 2) {
1120:                    char ch = Utils.getUnicodeCharacter(_header, x);
1121:                    //if(ch < 0x0020)
1122:                    //{
1123:                    //  _bodyBuffer.append('?');
1124:                    //}
1125:                    //else
1126:                    //{
1127:                    addText(ch, buf);
1128:                    //}
1129:                }
1130:            }
1131:
1132:            private void addParagraphProperties(PAP pap, StringBuffer buf) {
1133:                buf.append("<fo:block ");
1134:                buf.append("text-align=\"" + getTextAlignment(pap._jc)
1135:                        + "\"\r\n");
1136:                buf.append("linefeed-treatment=\"preserve\" ");
1137:                buf.append("white-space-collapse=\"false\" ");
1138:
1139:                if (pap._fKeep > 0) {
1140:                    buf.append("keep-together.within-page=\"always\"\r\n");
1141:                }
1142:                if (pap._fKeepFollow > 0) {
1143:                    buf.append("keep-with-next.within-page=\"always\"\r\n");
1144:                }
1145:                if (pap._fPageBreakBefore > 0) {
1146:                    buf.append("break-before=\"page\"\r\n");
1147:                }
1148:                if (pap._fNoAutoHyph == 0) {
1149:                    buf.append("hyphenate=\"true\"\r\n");
1150:                } else {
1151:                    buf.append("hyphenate=\"false\"\r\n");
1152:                }
1153:                if (pap._dxaLeft > 0) {
1154:                    buf.append("start-indent=\"" + ((float) pap._dxaLeft)
1155:                            / 1440.0f + "in\"\r\n");
1156:                }
1157:                if (pap._dxaRight > 0) {
1158:                    buf.append("end-indent=\"" + ((float) pap._dxaRight)
1159:                            / 1440.0f + "in\"\r\n");
1160:                }
1161:                if (pap._dxaLeft1 != 0) {
1162:                    buf.append("text-indent=\"" + ((float) pap._dxaLeft1)
1163:                            / 1440.0f + "in\"\r\n");
1164:                }
1165:                if (pap._lspd[1] == 0) {
1166:                    //buf.append("line-height=\"" + ((float)pap._lspd[0])/1440.0f + "in\"\r\n");
1167:                }
1168:                addBorder(buf, pap._brcTop, "top");
1169:                addBorder(buf, pap._brcBottom, "bottom");
1170:                addBorder(buf, pap._brcLeft, "left");
1171:                addBorder(buf, pap._brcRight, "right");
1172:
1173:                buf.append(">");
1174:
1175:            }
1176:
1177:            private void addCharacterProperties(CHP chp, StringBuffer buf) {
1178:                buf.append("<fo:inline ");
1179:                buf.append("font-family=\"" + _fonts.getFont(chp._ftcAscii)
1180:                        + "\" ");
1181:                buf.append("font-size=\"" + (chp._hps / 2) + "pt\" ");
1182:                buf.append("color=\"" + getColor(chp._ico) + "\" ");
1183:                //not supported by fop
1184:                //buf.append("letter-spacing=\"" + ((double)chp._dxaSpace)/1440.0f + "in\" ");
1185:
1186:                addBorder(buf, chp._brc, "top");
1187:                addBorder(buf, chp._brc, "bottom");
1188:                addBorder(buf, chp._brc, "left");
1189:                addBorder(buf, chp._brc, "right");
1190:
1191:                if (chp._italic) {
1192:                    buf.append("font-style=\"italic\" ");
1193:                }
1194:                if (chp._bold) {
1195:                    buf.append("font-weight=\"bold\" ");
1196:                }
1197:                if (chp._fSmallCaps) {
1198:                    buf.append("font-variant=\"small-caps\" ");
1199:                }
1200:                if (chp._fCaps) {
1201:                    buf.append("text-transform=\"uppercase\" ");
1202:                }
1203:                if (chp._fStrike || chp._fDStrike) {
1204:                    buf.append("text-decoration=\"line-through\" ");
1205:                }
1206:                if (chp._fShadow) {
1207:                    int size = chp._hps / 24;
1208:                    buf.append("text-shadow=\"" + size + "pt\"");
1209:                }
1210:                if (chp._fLowerCase) {
1211:                    buf.append("text-transform=\"lowercase\" ");
1212:                }
1213:                if (chp._kul > 0) {
1214:                    buf.append("text-decoration=\"underline\" ");
1215:                }
1216:                if (chp._highlighted) {
1217:                    buf.append("background-color=\""
1218:                            + getColor(chp._icoHighlight) + "\" ");
1219:                }
1220:                if (chp._paddingStart != 0) {
1221:                    buf.append("padding-start=\"" + (float) chp._paddingStart
1222:                            / 1440.0f + "in\" ");
1223:                }
1224:                if (chp._paddingEnd != 0) {
1225:                    buf.append("padding-end=\"" + (float) chp._paddingEnd
1226:                            / 1440.0f + "in\" ");
1227:                }
1228:                buf.append(">");
1229:            }
1230:
1231:            private void addStaticContent(String flowName, HeaderFooter content) {
1232:                _bodyBuffer.append("<fo:static-content flow-name=\"" + flowName
1233:                        + "\">");
1234:                //_bodyBuffer.append("<fo:float float=\"before\">");
1235:                addBlockContent(content.getStart(), content.getEnd(), _text,
1236:                        _paragraphTable, _characterTable);
1237:                //_bodyBuffer.append("</fo:float>");
1238:                _bodyBuffer.append("</fo:static-content>");
1239:
1240:            }
1241:
1242:            private String getBulletText(LVL lvl, PAP pap) {
1243:                StringBuffer bulletBuffer = new StringBuffer();
1244:                for (int x = 0; x < lvl._xst.length; x++) {
1245:                    if (lvl._xst[x] < 9) {
1246:                        LVL numLevel = _listTables.getLevel(pap._ilfo,
1247:                                lvl._xst[x]);
1248:                        int num = numLevel._iStartAt;
1249:                        if (lvl == numLevel) {
1250:                            numLevel._iStartAt++;
1251:                        } else if (num > 1) {
1252:                            num--;
1253:                        }
1254:                        bulletBuffer.append(NumberFormatter.getNumber(num,
1255:                                lvl._nfc));
1256:
1257:                    } else {
1258:                        bulletBuffer.append(lvl._xst[x]);
1259:                    }
1260:
1261:                }
1262:                return bulletBuffer.toString();
1263:            }
1264:
1265:            /**
1266:             * finds all chpx's that are between start and end
1267:             */
1268:            private ArrayList findProperties(int start, int end,
1269:                    BTreeSet.BTreeNode root) {
1270:                ArrayList results = new ArrayList();
1271:                BTreeSet.Entry[] entries = root.entries;
1272:
1273:                for (int x = 0; x < entries.length; x++) {
1274:                    if (entries[x] != null) {
1275:                        BTreeSet.BTreeNode child = entries[x].child;
1276:                        PropertyNode xNode = (PropertyNode) entries[x].element;
1277:                        if (xNode != null) {
1278:                            int xStart = xNode.getStart();
1279:                            int xEnd = xNode.getEnd();
1280:                            if (xStart < end) {
1281:                                if (xStart >= start) {
1282:                                    if (child != null) {
1283:                                        ArrayList beforeItems = findProperties(
1284:                                                start, end, child);
1285:                                        results.addAll(beforeItems);
1286:                                    }
1287:                                    results.add(xNode);
1288:                                } else if (start < xEnd) {
1289:                                    results.add(xNode);
1290:                                    //break;
1291:                                }
1292:                            } else {
1293:                                if (child != null) {
1294:                                    ArrayList beforeItems = findProperties(
1295:                                            start, end, child);
1296:                                    results.addAll(beforeItems);
1297:                                }
1298:                                break;
1299:                            }
1300:                        } else if (child != null) {
1301:                            ArrayList afterItems = findProperties(start, end,
1302:                                    child);
1303:                            results.addAll(afterItems);
1304:                        }
1305:                    } else {
1306:                        break;
1307:                    }
1308:                }
1309:                return results;
1310:            }
1311:
1312:            private void openPage(String page, String type) {
1313:                _bodyBuffer.append("<fo:page-sequence master-reference=\""
1314:                        + page + "\">\r\n");
1315:            }
1316:
1317:            private void openFlow() {
1318:                _bodyBuffer
1319:                        .append("<fo:flow flow-name=\"xsl-region-body\">\r\n");
1320:            }
1321:
1322:            private void closeFlow() {
1323:                _bodyBuffer.append("</fo:flow>\r\n");
1324:            }
1325:
1326:            private void closePage() {
1327:                _bodyBuffer.append("</fo:page-sequence>\r\n");
1328:            }
1329:
1330:            private void closeLine(StringBuffer buf) {
1331:                buf.append("</fo:inline>");
1332:            }
1333:
1334:            private void closeBlock(StringBuffer buf) {
1335:                buf.append("</fo:block>\r\n");
1336:            }
1337:
1338:            private ArrayList findPAPProperties(int start, int end,
1339:                    BTreeSet.BTreeNode root) {
1340:                ArrayList results = new ArrayList();
1341:                BTreeSet.Entry[] entries = root.entries;
1342:
1343:                for (int x = 0; x < entries.length; x++) {
1344:                    if (entries[x] != null) {
1345:                        BTreeSet.BTreeNode child = entries[x].child;
1346:                        PapxNode papxNode = (PapxNode) entries[x].element;
1347:                        if (papxNode != null) {
1348:                            int papxStart = papxNode.getStart();
1349:                            if (papxStart < end) {
1350:                                if (papxStart >= start) {
1351:                                    if (child != null) {
1352:                                        ArrayList beforeItems = findPAPProperties(
1353:                                                start, end, child);
1354:                                        results.addAll(beforeItems);
1355:                                    }
1356:                                    results.add(papxNode);
1357:                                }
1358:                            } else {
1359:                                if (child != null) {
1360:                                    ArrayList beforeItems = findPAPProperties(
1361:                                            start, end, child);
1362:                                    results.addAll(beforeItems);
1363:                                }
1364:                                break;
1365:                            }
1366:                        } else if (child != null) {
1367:                            ArrayList afterItems = findPAPProperties(start,
1368:                                    end, child);
1369:                            results.addAll(afterItems);
1370:                        }
1371:                    } else {
1372:                        break;
1373:                    }
1374:                }
1375:                return results;
1376:            }
1377:
1378:            private String createPageMaster(SEP sep, String type, int section,
1379:                    String regionBefore, String regionAfter) {
1380:                float height = ((float) sep._yaPage) / 1440.0f;
1381:                float width = ((float) sep._xaPage) / 1440.0f;
1382:                float leftMargin = ((float) sep._dxaLeft) / 1440.0f;
1383:                float rightMargin = ((float) sep._dxaRight) / 1440.0f;
1384:                float topMargin = ((float) sep._dyaTop) / 1440.0f;
1385:                float bottomMargin = ((float) sep._dyaBottom) / 1440.0f;
1386:
1387:                //add these to the header
1388:                String this Page = type + "-page" + section;
1389:
1390:                _headerBuffer.append("<fo:simple-page-master master-name=\""
1391:                        + this Page + "\"\r\n");
1392:                _headerBuffer.append("page-height=\"" + height + "in\"\r\n");
1393:                _headerBuffer.append("page-width=\"" + width + "in\"\r\n");
1394:                _headerBuffer.append(">\r\n");
1395:
1396:                _headerBuffer.append("<fo:region-body ");
1397:                //top right bottom left
1398:
1399:                _headerBuffer.append("margin=\"" + topMargin + "in "
1400:                        + rightMargin + "in " + bottomMargin + "in "
1401:                        + leftMargin + "in\"\r\n");
1402:
1403:                //String style = null;
1404:                //String color = null;
1405:                addBorder(_headerBuffer, sep._brcTop, "top");
1406:                addBorder(_headerBuffer, sep._brcBottom, "bottom");
1407:                addBorder(_headerBuffer, sep._brcLeft, "left");
1408:                addBorder(_headerBuffer, sep._brcRight, "right");
1409:
1410:                if (sep._ccolM1 > 0) {
1411:                    _headerBuffer.append("column-count=\"" + (sep._ccolM1 + 1)
1412:                            + "\" ");
1413:                    if (sep._fEvenlySpaced) {
1414:                        _headerBuffer.append("column-gap=\""
1415:                                + ((float) (sep._dxaColumns)) / 1440.0f
1416:                                + "in\"");
1417:                    } else {
1418:                        _headerBuffer.append("column-gap=\"0.25in\"");
1419:                    }
1420:                }
1421:                _headerBuffer.append("/>\r\n");
1422:
1423:                if (regionBefore != null) {
1424:                    _headerBuffer.append(regionBefore);
1425:                }
1426:                if (regionAfter != null) {
1427:                    _headerBuffer.append(regionAfter);
1428:                }
1429:
1430:                _headerBuffer.append("</fo:simple-page-master>\r\n");
1431:                return this Page;
1432:            }
1433:
1434:            private void addBorder(StringBuffer buf, short[] brc, String where) {
1435:                if ((brc[0] & 0xff00) != 0 && brc[0] != -1) {
1436:                    int type = (brc[0] & 0xff00) >> 8;
1437:                    float width = ((float) (brc[0] & 0x00ff)) / 8.0f;
1438:                    String style = getBorderStyle(brc[0]);
1439:                    String color = getColor(brc[1] & 0x00ff);
1440:                    String thickness = getBorderThickness(brc[0]);
1441:                    buf.append("border-" + where + "-style=\"" + style
1442:                            + "\"\r\n");
1443:                    buf.append("border-" + where + "-color=\"" + color
1444:                            + "\"\r\n");
1445:                    buf.append("border-" + where + "-width=\"" + width
1446:                            + "pt\"\r\n");
1447:                }
1448:            }
1449:
1450:            public void closeDoc() {
1451:                _headerBuffer.append("</fo:layout-master-set>");
1452:                _bodyBuffer.append("</fo:root>");
1453:                //_headerBuffer.append();
1454:
1455:                //test code
1456:                try {
1457:                    OutputStreamWriter test = new OutputStreamWriter(
1458:                            new FileOutputStream(_outName), "8859_1");
1459:                    test.write(_headerBuffer.toString());
1460:                    test.write(_bodyBuffer.toString());
1461:                    test.flush();
1462:                    test.close();
1463:                } catch (Throwable t) {
1464:                    t.printStackTrace();
1465:                }
1466:            }
1467:
1468:            private String getBorderThickness(int style) {
1469:                switch (style) {
1470:                case 1:
1471:                    return "medium";
1472:                case 2:
1473:                    return "thick";
1474:                case 3:
1475:                    return "medium";
1476:                case 5:
1477:                    return "thin";
1478:                default:
1479:                    return "medium";
1480:                }
1481:            }
1482:
1483:            private String getColor(int ico) {
1484:                switch (ico) {
1485:                case 1:
1486:                    return "black";
1487:                case 2:
1488:                    return "blue";
1489:                case 3:
1490:                    return "cyan";
1491:                case 4:
1492:                    return "green";
1493:                case 5:
1494:                    return "magenta";
1495:                case 6:
1496:                    return "red";
1497:                case 7:
1498:                    return "yellow";
1499:                case 8:
1500:                    return "white";
1501:                case 9:
1502:                    return "darkblue";
1503:                case 10:
1504:                    return "darkcyan";
1505:                case 11:
1506:                    return "darkgreen";
1507:                case 12:
1508:                    return "darkmagenta";
1509:                case 13:
1510:                    return "darkred";
1511:                case 14:
1512:                    return "darkyellow";
1513:                case 15:
1514:                    return "darkgray";
1515:                case 16:
1516:                    return "lightgray";
1517:                default:
1518:                    return "black";
1519:                }
1520:            }
1521:
1522:            private String getBorderStyle(int type) {
1523:
1524:                switch (type) {
1525:                case 1:
1526:                case 2:
1527:                    return "solid";
1528:                case 3:
1529:                    return "double";
1530:                case 5:
1531:                    return "solid";
1532:                case 6:
1533:                    return "dotted";
1534:                case 7:
1535:                case 8:
1536:                    return "dashed";
1537:                case 9:
1538:                    return "dotted";
1539:                case 10:
1540:                case 11:
1541:                case 12:
1542:                case 13:
1543:                case 14:
1544:                case 15:
1545:                case 16:
1546:                case 17:
1547:                case 18:
1548:                case 19:
1549:                    return "double";
1550:                case 20:
1551:                    return "solid";
1552:                case 21:
1553:                    return "double";
1554:                case 22:
1555:                    return "dashed";
1556:                case 23:
1557:                    return "dashed";
1558:                case 24:
1559:                    return "ridge";
1560:                case 25:
1561:                    return "grooved";
1562:                default:
1563:                    return "solid";
1564:                }
1565:            }
1566:
1567:            /**
1568:             * creates the List data
1569:             *
1570:             * @param tableStream Main table stream buffer.
1571:             */
1572:            private void createListTables(byte[] tableStream) {
1573:
1574:                int lfoOffset = LittleEndian.getInt(_header, 0x2ea);
1575:                int lfoSize = LittleEndian.getInt(_header, 0x2ee);
1576:                byte[] plflfo = new byte[lfoSize];
1577:
1578:                System.arraycopy(tableStream, lfoOffset, plflfo, 0, lfoSize);
1579:
1580:                int lstOffset = LittleEndian.getInt(_header, 0x2e2);
1581:                int lstSize = LittleEndian.getInt(_header, 0x2e2);
1582:                if (lstOffset > 0 && lstSize > 0) {
1583:                    lstSize = lfoOffset - lstOffset;
1584:                    byte[] plcflst = new byte[lstSize];
1585:                    System.arraycopy(tableStream, lstOffset, plcflst, 0,
1586:                            lstSize);
1587:                    _listTables = new ListTables(plcflst, plflfo);
1588:                }
1589:
1590:            }
1591:
1592:            /**
1593:             * Creates the documents StyleSheet
1594:             *
1595:             * @param tableStream Main table stream buffer.
1596:             *
1597:             */
1598:            private void createStyleSheet(byte[] tableStream) {
1599:                int stshIndex = LittleEndian.getInt(_header, 0xa2);
1600:                int stshSize = LittleEndian.getInt(_header, 0xa6);
1601:                byte[] stsh = new byte[stshSize];
1602:                System.arraycopy(tableStream, stshIndex, stsh, 0, stshSize);
1603:
1604:                _styleSheet = new StyleSheet(stsh);
1605:
1606:            }
1607:
1608:            /**
1609:             * creates the Font table
1610:             *
1611:             * @param tableStream Main table stream buffer.
1612:             */
1613:            private void createFontTable(byte[] tableStream) {
1614:                int fontTableIndex = LittleEndian.getInt(_header, 0x112);
1615:                int fontTableSize = LittleEndian.getInt(_header, 0x116);
1616:                byte[] fontTable = new byte[fontTableSize];
1617:                System.arraycopy(tableStream, fontTableIndex, fontTable, 0,
1618:                        fontTableSize);
1619:                _fonts = new FontTable(fontTable);
1620:            }
1621:
1622:            private void overrideCellBorder(int row, int col, int height,
1623:                    int width, TC tc, TAP tap) {
1624:
1625:                if (row == 0) {
1626:                    if (tc._brcTop[0] == 0 || tc._brcTop[0] == -1) {
1627:                        tc._brcTop = tap._brcTop;
1628:                    }
1629:                    if (tc._brcBottom[0] == 0 || tc._brcBottom[0] == -1) {
1630:                        tc._brcBottom = tap._brcHorizontal;
1631:                    }
1632:                } else if (row == (height - 1)) {
1633:                    if (tc._brcTop[0] == 0 || tc._brcTop[0] == -1) {
1634:                        tc._brcTop = tap._brcHorizontal;
1635:                    }
1636:                    if (tc._brcBottom[0] == 0 || tc._brcBottom[0] == -1) {
1637:                        tc._brcBottom = tap._brcBottom;
1638:                    }
1639:                } else {
1640:                    if (tc._brcTop[0] == 0 || tc._brcTop[0] == -1) {
1641:                        tc._brcTop = tap._brcHorizontal;
1642:                    }
1643:                    if (tc._brcBottom[0] == 0 || tc._brcBottom[0] == -1) {
1644:                        tc._brcBottom = tap._brcHorizontal;
1645:                    }
1646:                }
1647:                if (col == 0) {
1648:                    if (tc._brcLeft[0] == 0 || tc._brcLeft[0] == -1) {
1649:                        tc._brcLeft = tap._brcLeft;
1650:                    }
1651:                    if (tc._brcRight[0] == 0 || tc._brcRight[0] == -1) {
1652:                        tc._brcRight = tap._brcVertical;
1653:                    }
1654:                } else if (col == (width - 1)) {
1655:                    if (tc._brcLeft[0] == 0 || tc._brcLeft[0] == -1) {
1656:                        tc._brcLeft = tap._brcVertical;
1657:                    }
1658:                    if (tc._brcRight[0] == 0 || tc._brcRight[0] == -1) {
1659:                        tc._brcRight = tap._brcRight;
1660:                    }
1661:                } else {
1662:                    if (tc._brcLeft[0] == 0 || tc._brcLeft[0] == -1) {
1663:                        tc._brcLeft = tap._brcVertical;
1664:                    }
1665:                    if (tc._brcRight[0] == 0 || tc._brcRight[0] == -1) {
1666:                        tc._brcRight = tap._brcVertical;
1667:                    }
1668:                }
1669:            }
1670:
1671:            private void printTable() {
1672:                if (_table != null) {
1673:                    int size = _table.size();
1674:
1675:                    //local buffers for the table
1676:                    StringBuffer tableHeaderBuffer = new StringBuffer();
1677:                    StringBuffer tableBodyBuffer = new StringBuffer();
1678:
1679:                    for (int x = 0; x < size; x++) {
1680:                        StringBuffer rowBuffer = tableBodyBuffer;
1681:                        TableRow row = (TableRow) _table.get(x);
1682:                        TAP tap = row.getTAP();
1683:                        ArrayList cells = row.getCells();
1684:
1685:                        if (tap._fTableHeader) {
1686:                            rowBuffer = tableHeaderBuffer;
1687:                        }
1688:                        rowBuffer.append("<fo:table-row ");
1689:                        if (tap._dyaRowHeight > 0) {
1690:                            rowBuffer.append("height=\""
1691:                                    + ((float) tap._dyaRowHeight) / 1440.0f
1692:                                    + "in\" ");
1693:                        }
1694:                        if (tap._fCantSplit) {
1695:                            rowBuffer.append("keep-together=\"always\" ");
1696:                        }
1697:                        rowBuffer.append(">");
1698:                        //add cells
1699:                        for (int y = 0; y < tap._itcMac; y++) {
1700:                            TC tc = tap._rgtc[y];
1701:                            overrideCellBorder(x, y, size, tap._itcMac, tc, tap);
1702:                            rowBuffer.append("<fo:table-cell ");
1703:                            rowBuffer
1704:                                    .append("width=\""
1705:                                            + ((float) (tap._rgdxaCenter[y + 1] - tap._rgdxaCenter[y]))
1706:                                            / 1440.0f + "in\" ");
1707:                            rowBuffer.append("padding-start=\""
1708:                                    + ((float) tap._dxaGapHalf) / 1440.0f
1709:                                    + "in\" ");
1710:                            rowBuffer.append("padding-end=\""
1711:                                    + ((float) tap._dxaGapHalf) / 1440.0f
1712:                                    + "in\" ");
1713:                            addBorder(rowBuffer, tc._brcTop, "top");
1714:                            addBorder(rowBuffer, tc._brcLeft, "left");
1715:                            addBorder(rowBuffer, tc._brcBottom, "bottom");
1716:                            addBorder(rowBuffer, tc._brcRight, "right");
1717:                            rowBuffer.append(">");
1718:                            rowBuffer.append((String) cells.get(y));
1719:                            rowBuffer.append("</fo:table-cell>");
1720:                        }
1721:                        rowBuffer.append("</fo:table-row>");
1722:                    }
1723:                    StringBuffer tableBuffer = new StringBuffer();
1724:                    tableBuffer.append("<fo:table>");
1725:                    if (tableHeaderBuffer.length() > 0) {
1726:                        tableBuffer.append("<fo:table-header>");
1727:                        tableBuffer.append(tableHeaderBuffer.toString());
1728:                        tableBuffer.append("</fo:table-header>");
1729:                    }
1730:                    tableBuffer.append("<fo:table-body>");
1731:                    tableBuffer.append(tableBodyBuffer.toString());
1732:                    tableBuffer.append("</fo:table-body>");
1733:                    tableBuffer.append("</fo:table>");
1734:                    _bodyBuffer.append(tableBuffer.toString());
1735:                    _table = null;
1736:                }
1737:            }
1738:
1739:            private void initPclfHdd(byte[] tableStream) {
1740:                int size = Utils.convertBytesToInt(_header, 0xf6);
1741:                int pos = Utils.convertBytesToInt(_header, 0xf2);
1742:
1743:                _plcfHdd = new byte[size];
1744:
1745:                System.arraycopy(tableStream, pos, _plcfHdd, 0, size);
1746:            }
1747:
1748:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.