From 9b319b7bb279862fb965b17119977d1b523d958d Mon Sep 17 00:00:00 2001 From: h Date: Sat, 8 Sep 2018 20:00:59 +0800 Subject: [PATCH 1/9] add HWPF project --- .../HWPF/Converter/AbstractWordConverter.cs | 995 +++++ .../HWPF/Converter/AbstractWordUtils.cs | 454 +++ .../HWPF/Converter/DefaultFontReplacer.cs | 97 + scratchpad/HWPF/Converter/FoDocumentFacade.cs | 328 ++ scratchpad/HWPF/Converter/FontReplacer.cs | 34 + .../HWPF/Converter/HtmlDocumentFacade.cs | 313 ++ scratchpad/HWPF/Converter/NumberFormatter.cs | 134 + scratchpad/HWPF/Converter/PicturesManager.cs | 29 + .../HWPF/Converter/TextDocumentFacade.cs | 191 + .../HWPF/Converter/WordToFoConverter.cs | 568 +++ scratchpad/HWPF/Converter/WordToFoUtils.cs | 329 ++ .../HWPF/Converter/WordToHtmlConverter.cs | 575 +++ scratchpad/HWPF/Converter/WordToHtmlUtils.cs | 224 ++ .../HWPF/Converter/WordToTextConverter.cs | 376 ++ scratchpad/HWPF/Extractor/Word6Extractor.cs | 127 + scratchpad/HWPF/Extractor/WordExtractor.cs | 321 ++ scratchpad/HWPF/HWPF.csproj | 299 ++ scratchpad/HWPF/HWPF.net2.csproj | 299 ++ scratchpad/HWPF/HWPFDocument.cs | 814 ++++ scratchpad/HWPF/HWPFDocumentCore.cs | 225 ++ scratchpad/HWPF/HWPFOldDocument.cs | 147 + scratchpad/HWPF/Model/BaseObject.cs | 177 + .../HWPF/Model/BookmarkFirstDescriptor.cs | 84 + scratchpad/HWPF/Model/BookmarksTables.cs | 171 + scratchpad/HWPF/Model/BytePropertyNode.cs | 78 + scratchpad/HWPF/Model/CHPBinTable.cs | 485 +++ scratchpad/HWPF/Model/CHPFormattedDiskPage.cs | 197 + scratchpad/HWPF/Model/CHPX.cs | 90 + scratchpad/HWPF/Model/CPSplitCalculator.cs | 161 + scratchpad/HWPF/Model/CachedPropertyNode.cs | 58 + scratchpad/HWPF/Model/CharIndexTranslator.cs | 87 + scratchpad/HWPF/Model/ComplexFileTable.cs | 101 + scratchpad/HWPF/Model/DocumentProperties.cs | 36 + scratchpad/HWPF/Model/EscherRecordHolder.cs | 215 ++ scratchpad/HWPF/Model/FIB/FIB.cs | 50 + scratchpad/HWPF/Model/FIB/FIBBase.cs | 176 + scratchpad/HWPF/Model/FIB/FIBCswNew.cs | 50 + scratchpad/HWPF/Model/FIB/FibRgFcLcb.cs | 59 + scratchpad/HWPF/Model/FIB/FibRgFcLcb2000.cs | 84 + scratchpad/HWPF/Model/FIB/FibRgFcLcb2002.cs | 136 + scratchpad/HWPF/Model/FIB/FibRgFcLcb2003.cs | 136 + scratchpad/HWPF/Model/FIB/FibRgFcLcb2007.cs | 98 + scratchpad/HWPF/Model/FIB/FibRgFcLcb97.cs | 397 ++ scratchpad/HWPF/Model/FIB/FibRgLw97.cs | 50 + scratchpad/HWPF/Model/FIB/FibRgW97.cs | 41 + scratchpad/HWPF/Model/FIBFieldHandler.cs | 226 ++ scratchpad/HWPF/Model/FIBLongHandler.cs | 100 + scratchpad/HWPF/Model/FIBShortHandler.cs | 81 + scratchpad/HWPF/Model/FSPA.cs | 187 + scratchpad/HWPF/Model/FSPADocumentPart.cs | 37 + scratchpad/HWPF/Model/FSPATable.cs | 112 + scratchpad/HWPF/Model/Ffn.cs | 229 ++ scratchpad/HWPF/Model/FieldDescriptor.cs | 105 + scratchpad/HWPF/Model/FieldsDocumentPart.cs | 59 + scratchpad/HWPF/Model/FieldsTables.cs | 120 + scratchpad/HWPF/Model/FileInformationBlock.cs | 979 +++++ scratchpad/HWPF/Model/FontTable.cs | 160 + .../HWPF/Model/FootnoteReferenceDescriptor.cs | 80 + scratchpad/HWPF/Model/FormattedDiskPage.cs | 94 + scratchpad/HWPF/Model/GenericPropertyNode.cs | 42 + scratchpad/HWPF/Model/HWPFStream.cs | 105 + scratchpad/HWPF/Model/IO/HWPFFileSystem.cs | 43 + scratchpad/HWPF/Model/IO/HWPFOutputStream.cs | 67 + scratchpad/HWPF/Model/ListData.cs | 159 + scratchpad/HWPF/Model/ListFormatOverride.cs | 122 + .../HWPF/Model/ListFormatOverrideLevel.cs | 122 + scratchpad/HWPF/Model/ListLevel.cs | 266 ++ scratchpad/HWPF/Model/ListTables.cs | 233 ++ scratchpad/HWPF/Model/NoteType.cs | 67 + scratchpad/HWPF/Model/NotesTables.cs | 125 + scratchpad/HWPF/Model/OldCHPBinTable.cs | 69 + scratchpad/HWPF/Model/OldPAPBinTable.cs | 64 + scratchpad/HWPF/Model/OldSectionTable.cs | 83 + scratchpad/HWPF/Model/PAPBinTable.cs | 435 +++ scratchpad/HWPF/Model/PAPFormattedDiskPage.cs | 332 ++ scratchpad/HWPF/Model/PAPX.cs | 163 + scratchpad/HWPF/Model/ParagraphHeight.cs | 81 + scratchpad/HWPF/Model/PictureDescriptor.cs | 215 ++ scratchpad/HWPF/Model/PicturesTable.cs | 246 ++ scratchpad/HWPF/Model/PieceDescriptor.cs | 126 + scratchpad/HWPF/Model/PlexOfCps.cs | 158 + scratchpad/HWPF/Model/PlexOfField.cs | 52 + scratchpad/HWPF/Model/Prm0.cs | 61 + scratchpad/HWPF/Model/PropertyModifier.cs | 148 + scratchpad/HWPF/Model/PropertyNode.cs | 239 ++ .../HWPF/Model/RevisionMarkAuthorTable.cs | 156 + scratchpad/HWPF/Model/SEPX.cs | 81 + scratchpad/HWPF/Model/SavedByEntry.cs | 89 + scratchpad/HWPF/Model/SavedByTable.cs | 114 + scratchpad/HWPF/Model/SectionDescriptor.cs | 99 + scratchpad/HWPF/Model/SectionTable.cs | 207 + scratchpad/HWPF/Model/ShapesTable.cs | 61 + scratchpad/HWPF/Model/SinglentonTextPiece.cs | 71 + scratchpad/HWPF/Model/SttbfUtils.cs | 90 + scratchpad/HWPF/Model/StyleDescription.cs | 261 ++ scratchpad/HWPF/Model/StyleSheet.cs | 354 ++ scratchpad/HWPF/Model/SubdocumentType.cs | 27 + scratchpad/HWPF/Model/TextPiece.cs | 229 ++ scratchpad/HWPF/Model/TextPieceTable.cs | 414 ++ .../HWPF/Model/Types/BKFAbstractType.cs | 196 + .../HWPF/Model/Types/CHPAbstractType.cs | 1382 +++++++ .../HWPF/Model/Types/DOPAbstractType.cs | 3362 +++++++++++++++++ .../HWPF/Model/Types/FIBAbstractType.cs | 823 ++++ .../HWPF/Model/Types/FLDAbstractType.cs | 354 ++ .../HWPF/Model/Types/FRDAbstractType.cs | 95 + .../HWPF/Model/Types/FSPAAbstractType.cs | 412 ++ .../HWPF/Model/Types/HRESIAbstractType.cs | 138 + .../HWPF/Model/Types/LFOAbstractType.cs | 399 ++ .../HWPF/Model/Types/PAPAbstractType.cs | 1689 +++++++++ .../HWPF/Model/Types/SEPAbstractType.cs | 1085 ++++++ .../HWPF/Model/Types/TAPAbstractType.cs | 331 ++ scratchpad/HWPF/Model/Types/TCAbstractType.cs | 789 ++++ .../HWPF/Model/Types/TLPAbstractType.cs | 293 ++ scratchpad/HWPF/Model/UPX.cs | 52 + .../HWPF/Model/UnhandledDataStructure.cs | 44 + scratchpad/HWPF/OldWordFileFormatException.cs | 28 + scratchpad/HWPF/Properties/AssemblyInfo.cs | 39 + .../HWPF/SPRM/CharacterSprmCompressor.cs | 290 ++ .../HWPF/SPRM/CharacterSprmUncompressor.cs | 604 +++ .../HWPF/SPRM/ParagraphSprmCompressor.cs | 386 ++ .../HWPF/SPRM/ParagraphSprmUncompressor.cs | 490 +++ scratchpad/HWPF/SPRM/SectionSprmCompressor.cs | 238 ++ .../HWPF/SPRM/SectionSprmUncompressor.cs | 219 ++ scratchpad/HWPF/SPRM/SprmBuffer.cs | 211 ++ scratchpad/HWPF/SPRM/SprmIterator.cs | 60 + scratchpad/HWPF/SPRM/SprmOperation.cs | 205 + scratchpad/HWPF/SPRM/SprmUncompressor.cs | 54 + scratchpad/HWPF/SPRM/SprmUtils.cs | 141 + scratchpad/HWPF/SPRM/TableSprmCompressor.cs | 108 + scratchpad/HWPF/SPRM/TableSprmUncompressor.cs | 303 ++ scratchpad/HWPF/UserModel/Bookmark.cs | 36 + scratchpad/HWPF/UserModel/Bookmarks.cs | 51 + scratchpad/HWPF/UserModel/BookmarksImpl.cs | 237 ++ scratchpad/HWPF/UserModel/BorderCode.cs | 212 ++ .../HWPF/UserModel/CharacterProperties.cs | 393 ++ scratchpad/HWPF/UserModel/CharacterRun.cs | 630 +++ scratchpad/HWPF/UserModel/DateAndTime.cs | 65 + scratchpad/HWPF/UserModel/DocumentPosition.cs | 31 + scratchpad/HWPF/UserModel/DropCapSpecifier.cs | 59 + scratchpad/HWPF/UserModel/Field.cs | 82 + scratchpad/HWPF/UserModel/FieldImpl.cs | 233 ++ scratchpad/HWPF/UserModel/Fields.cs | 15 + scratchpad/HWPF/UserModel/FieldsImpl.cs | 273 ++ scratchpad/HWPF/UserModel/HWPFList.cs | 109 + scratchpad/HWPF/UserModel/HeaderStories.cs | 274 ++ .../HWPF/UserModel/LineSpacingDescriptor.cs | 73 + scratchpad/HWPF/UserModel/ListEntry.cs | 56 + scratchpad/HWPF/UserModel/Notes.cs | 57 + scratchpad/HWPF/UserModel/NotesImpl.cs | 85 + scratchpad/HWPF/UserModel/ObjectPoolImpl.cs | 56 + scratchpad/HWPF/UserModel/ObjectsPool.cs | 29 + scratchpad/HWPF/UserModel/OfficeDrawing.cs | 189 + scratchpad/HWPF/UserModel/OfficeDrawings.cs | 33 + .../HWPF/UserModel/OfficeDrawingsImpl.cs | 309 ++ scratchpad/HWPF/UserModel/Paragraph.cs | 521 +++ .../HWPF/UserModel/ParagraphProperties.cs | 346 ++ scratchpad/HWPF/UserModel/Picture.cs | 539 +++ scratchpad/HWPF/UserModel/PictureType.cs | 131 + scratchpad/HWPF/UserModel/Range.cs | 1289 +++++++ scratchpad/HWPF/UserModel/Section.cs | 141 + .../HWPF/UserModel/SectionProperties.cs | 77 + .../HWPF/UserModel/ShadingDescriptor.cs | 59 + scratchpad/HWPF/UserModel/Shape.cs | 110 + scratchpad/HWPF/UserModel/Table.cs | 97 + .../UserModel/TableAutoformatLookSpecifier.cs | 70 + scratchpad/HWPF/UserModel/TableCell.cs | 116 + .../HWPF/UserModel/TableCellDescriptor.cs | 75 + scratchpad/HWPF/UserModel/TableIterator.cs | 74 + scratchpad/HWPF/UserModel/TableProperties.cs | 80 + scratchpad/HWPF/UserModel/TableRow.cs | 235 ++ scratchpad/HWPF/npoi.snk | Bin 0 -> 596 bytes 171 files changed, 41108 insertions(+) create mode 100644 scratchpad/HWPF/Converter/AbstractWordConverter.cs create mode 100644 scratchpad/HWPF/Converter/AbstractWordUtils.cs create mode 100644 scratchpad/HWPF/Converter/DefaultFontReplacer.cs create mode 100644 scratchpad/HWPF/Converter/FoDocumentFacade.cs create mode 100644 scratchpad/HWPF/Converter/FontReplacer.cs create mode 100644 scratchpad/HWPF/Converter/HtmlDocumentFacade.cs create mode 100644 scratchpad/HWPF/Converter/NumberFormatter.cs create mode 100644 scratchpad/HWPF/Converter/PicturesManager.cs create mode 100644 scratchpad/HWPF/Converter/TextDocumentFacade.cs create mode 100644 scratchpad/HWPF/Converter/WordToFoConverter.cs create mode 100644 scratchpad/HWPF/Converter/WordToFoUtils.cs create mode 100644 scratchpad/HWPF/Converter/WordToHtmlConverter.cs create mode 100644 scratchpad/HWPF/Converter/WordToHtmlUtils.cs create mode 100644 scratchpad/HWPF/Converter/WordToTextConverter.cs create mode 100644 scratchpad/HWPF/Extractor/Word6Extractor.cs create mode 100644 scratchpad/HWPF/Extractor/WordExtractor.cs create mode 100644 scratchpad/HWPF/HWPF.csproj create mode 100644 scratchpad/HWPF/HWPF.net2.csproj create mode 100644 scratchpad/HWPF/HWPFDocument.cs create mode 100644 scratchpad/HWPF/HWPFDocumentCore.cs create mode 100644 scratchpad/HWPF/HWPFOldDocument.cs create mode 100644 scratchpad/HWPF/Model/BaseObject.cs create mode 100644 scratchpad/HWPF/Model/BookmarkFirstDescriptor.cs create mode 100644 scratchpad/HWPF/Model/BookmarksTables.cs create mode 100644 scratchpad/HWPF/Model/BytePropertyNode.cs create mode 100644 scratchpad/HWPF/Model/CHPBinTable.cs create mode 100644 scratchpad/HWPF/Model/CHPFormattedDiskPage.cs create mode 100644 scratchpad/HWPF/Model/CHPX.cs create mode 100644 scratchpad/HWPF/Model/CPSplitCalculator.cs create mode 100644 scratchpad/HWPF/Model/CachedPropertyNode.cs create mode 100644 scratchpad/HWPF/Model/CharIndexTranslator.cs create mode 100644 scratchpad/HWPF/Model/ComplexFileTable.cs create mode 100644 scratchpad/HWPF/Model/DocumentProperties.cs create mode 100644 scratchpad/HWPF/Model/EscherRecordHolder.cs create mode 100644 scratchpad/HWPF/Model/FIB/FIB.cs create mode 100644 scratchpad/HWPF/Model/FIB/FIBBase.cs create mode 100644 scratchpad/HWPF/Model/FIB/FIBCswNew.cs create mode 100644 scratchpad/HWPF/Model/FIB/FibRgFcLcb.cs create mode 100644 scratchpad/HWPF/Model/FIB/FibRgFcLcb2000.cs create mode 100644 scratchpad/HWPF/Model/FIB/FibRgFcLcb2002.cs create mode 100644 scratchpad/HWPF/Model/FIB/FibRgFcLcb2003.cs create mode 100644 scratchpad/HWPF/Model/FIB/FibRgFcLcb2007.cs create mode 100644 scratchpad/HWPF/Model/FIB/FibRgFcLcb97.cs create mode 100644 scratchpad/HWPF/Model/FIB/FibRgLw97.cs create mode 100644 scratchpad/HWPF/Model/FIB/FibRgW97.cs create mode 100644 scratchpad/HWPF/Model/FIBFieldHandler.cs create mode 100644 scratchpad/HWPF/Model/FIBLongHandler.cs create mode 100644 scratchpad/HWPF/Model/FIBShortHandler.cs create mode 100644 scratchpad/HWPF/Model/FSPA.cs create mode 100644 scratchpad/HWPF/Model/FSPADocumentPart.cs create mode 100644 scratchpad/HWPF/Model/FSPATable.cs create mode 100644 scratchpad/HWPF/Model/Ffn.cs create mode 100644 scratchpad/HWPF/Model/FieldDescriptor.cs create mode 100644 scratchpad/HWPF/Model/FieldsDocumentPart.cs create mode 100644 scratchpad/HWPF/Model/FieldsTables.cs create mode 100644 scratchpad/HWPF/Model/FileInformationBlock.cs create mode 100644 scratchpad/HWPF/Model/FontTable.cs create mode 100644 scratchpad/HWPF/Model/FootnoteReferenceDescriptor.cs create mode 100644 scratchpad/HWPF/Model/FormattedDiskPage.cs create mode 100644 scratchpad/HWPF/Model/GenericPropertyNode.cs create mode 100644 scratchpad/HWPF/Model/HWPFStream.cs create mode 100644 scratchpad/HWPF/Model/IO/HWPFFileSystem.cs create mode 100644 scratchpad/HWPF/Model/IO/HWPFOutputStream.cs create mode 100644 scratchpad/HWPF/Model/ListData.cs create mode 100644 scratchpad/HWPF/Model/ListFormatOverride.cs create mode 100644 scratchpad/HWPF/Model/ListFormatOverrideLevel.cs create mode 100644 scratchpad/HWPF/Model/ListLevel.cs create mode 100644 scratchpad/HWPF/Model/ListTables.cs create mode 100644 scratchpad/HWPF/Model/NoteType.cs create mode 100644 scratchpad/HWPF/Model/NotesTables.cs create mode 100644 scratchpad/HWPF/Model/OldCHPBinTable.cs create mode 100644 scratchpad/HWPF/Model/OldPAPBinTable.cs create mode 100644 scratchpad/HWPF/Model/OldSectionTable.cs create mode 100644 scratchpad/HWPF/Model/PAPBinTable.cs create mode 100644 scratchpad/HWPF/Model/PAPFormattedDiskPage.cs create mode 100644 scratchpad/HWPF/Model/PAPX.cs create mode 100644 scratchpad/HWPF/Model/ParagraphHeight.cs create mode 100644 scratchpad/HWPF/Model/PictureDescriptor.cs create mode 100644 scratchpad/HWPF/Model/PicturesTable.cs create mode 100644 scratchpad/HWPF/Model/PieceDescriptor.cs create mode 100644 scratchpad/HWPF/Model/PlexOfCps.cs create mode 100644 scratchpad/HWPF/Model/PlexOfField.cs create mode 100644 scratchpad/HWPF/Model/Prm0.cs create mode 100644 scratchpad/HWPF/Model/PropertyModifier.cs create mode 100644 scratchpad/HWPF/Model/PropertyNode.cs create mode 100644 scratchpad/HWPF/Model/RevisionMarkAuthorTable.cs create mode 100644 scratchpad/HWPF/Model/SEPX.cs create mode 100644 scratchpad/HWPF/Model/SavedByEntry.cs create mode 100644 scratchpad/HWPF/Model/SavedByTable.cs create mode 100644 scratchpad/HWPF/Model/SectionDescriptor.cs create mode 100644 scratchpad/HWPF/Model/SectionTable.cs create mode 100644 scratchpad/HWPF/Model/ShapesTable.cs create mode 100644 scratchpad/HWPF/Model/SinglentonTextPiece.cs create mode 100644 scratchpad/HWPF/Model/SttbfUtils.cs create mode 100644 scratchpad/HWPF/Model/StyleDescription.cs create mode 100644 scratchpad/HWPF/Model/StyleSheet.cs create mode 100644 scratchpad/HWPF/Model/SubdocumentType.cs create mode 100644 scratchpad/HWPF/Model/TextPiece.cs create mode 100644 scratchpad/HWPF/Model/TextPieceTable.cs create mode 100644 scratchpad/HWPF/Model/Types/BKFAbstractType.cs create mode 100644 scratchpad/HWPF/Model/Types/CHPAbstractType.cs create mode 100644 scratchpad/HWPF/Model/Types/DOPAbstractType.cs create mode 100644 scratchpad/HWPF/Model/Types/FIBAbstractType.cs create mode 100644 scratchpad/HWPF/Model/Types/FLDAbstractType.cs create mode 100644 scratchpad/HWPF/Model/Types/FRDAbstractType.cs create mode 100644 scratchpad/HWPF/Model/Types/FSPAAbstractType.cs create mode 100644 scratchpad/HWPF/Model/Types/HRESIAbstractType.cs create mode 100644 scratchpad/HWPF/Model/Types/LFOAbstractType.cs create mode 100644 scratchpad/HWPF/Model/Types/PAPAbstractType.cs create mode 100644 scratchpad/HWPF/Model/Types/SEPAbstractType.cs create mode 100644 scratchpad/HWPF/Model/Types/TAPAbstractType.cs create mode 100644 scratchpad/HWPF/Model/Types/TCAbstractType.cs create mode 100644 scratchpad/HWPF/Model/Types/TLPAbstractType.cs create mode 100644 scratchpad/HWPF/Model/UPX.cs create mode 100644 scratchpad/HWPF/Model/UnhandledDataStructure.cs create mode 100644 scratchpad/HWPF/OldWordFileFormatException.cs create mode 100644 scratchpad/HWPF/Properties/AssemblyInfo.cs create mode 100644 scratchpad/HWPF/SPRM/CharacterSprmCompressor.cs create mode 100644 scratchpad/HWPF/SPRM/CharacterSprmUncompressor.cs create mode 100644 scratchpad/HWPF/SPRM/ParagraphSprmCompressor.cs create mode 100644 scratchpad/HWPF/SPRM/ParagraphSprmUncompressor.cs create mode 100644 scratchpad/HWPF/SPRM/SectionSprmCompressor.cs create mode 100644 scratchpad/HWPF/SPRM/SectionSprmUncompressor.cs create mode 100644 scratchpad/HWPF/SPRM/SprmBuffer.cs create mode 100644 scratchpad/HWPF/SPRM/SprmIterator.cs create mode 100644 scratchpad/HWPF/SPRM/SprmOperation.cs create mode 100644 scratchpad/HWPF/SPRM/SprmUncompressor.cs create mode 100644 scratchpad/HWPF/SPRM/SprmUtils.cs create mode 100644 scratchpad/HWPF/SPRM/TableSprmCompressor.cs create mode 100644 scratchpad/HWPF/SPRM/TableSprmUncompressor.cs create mode 100644 scratchpad/HWPF/UserModel/Bookmark.cs create mode 100644 scratchpad/HWPF/UserModel/Bookmarks.cs create mode 100644 scratchpad/HWPF/UserModel/BookmarksImpl.cs create mode 100644 scratchpad/HWPF/UserModel/BorderCode.cs create mode 100644 scratchpad/HWPF/UserModel/CharacterProperties.cs create mode 100644 scratchpad/HWPF/UserModel/CharacterRun.cs create mode 100644 scratchpad/HWPF/UserModel/DateAndTime.cs create mode 100644 scratchpad/HWPF/UserModel/DocumentPosition.cs create mode 100644 scratchpad/HWPF/UserModel/DropCapSpecifier.cs create mode 100644 scratchpad/HWPF/UserModel/Field.cs create mode 100644 scratchpad/HWPF/UserModel/FieldImpl.cs create mode 100644 scratchpad/HWPF/UserModel/Fields.cs create mode 100644 scratchpad/HWPF/UserModel/FieldsImpl.cs create mode 100644 scratchpad/HWPF/UserModel/HWPFList.cs create mode 100644 scratchpad/HWPF/UserModel/HeaderStories.cs create mode 100644 scratchpad/HWPF/UserModel/LineSpacingDescriptor.cs create mode 100644 scratchpad/HWPF/UserModel/ListEntry.cs create mode 100644 scratchpad/HWPF/UserModel/Notes.cs create mode 100644 scratchpad/HWPF/UserModel/NotesImpl.cs create mode 100644 scratchpad/HWPF/UserModel/ObjectPoolImpl.cs create mode 100644 scratchpad/HWPF/UserModel/ObjectsPool.cs create mode 100644 scratchpad/HWPF/UserModel/OfficeDrawing.cs create mode 100644 scratchpad/HWPF/UserModel/OfficeDrawings.cs create mode 100644 scratchpad/HWPF/UserModel/OfficeDrawingsImpl.cs create mode 100644 scratchpad/HWPF/UserModel/Paragraph.cs create mode 100644 scratchpad/HWPF/UserModel/ParagraphProperties.cs create mode 100644 scratchpad/HWPF/UserModel/Picture.cs create mode 100644 scratchpad/HWPF/UserModel/PictureType.cs create mode 100644 scratchpad/HWPF/UserModel/Range.cs create mode 100644 scratchpad/HWPF/UserModel/Section.cs create mode 100644 scratchpad/HWPF/UserModel/SectionProperties.cs create mode 100644 scratchpad/HWPF/UserModel/ShadingDescriptor.cs create mode 100644 scratchpad/HWPF/UserModel/Shape.cs create mode 100644 scratchpad/HWPF/UserModel/Table.cs create mode 100644 scratchpad/HWPF/UserModel/TableAutoformatLookSpecifier.cs create mode 100644 scratchpad/HWPF/UserModel/TableCell.cs create mode 100644 scratchpad/HWPF/UserModel/TableCellDescriptor.cs create mode 100644 scratchpad/HWPF/UserModel/TableIterator.cs create mode 100644 scratchpad/HWPF/UserModel/TableProperties.cs create mode 100644 scratchpad/HWPF/UserModel/TableRow.cs create mode 100644 scratchpad/HWPF/npoi.snk diff --git a/scratchpad/HWPF/Converter/AbstractWordConverter.cs b/scratchpad/HWPF/Converter/AbstractWordConverter.cs new file mode 100644 index 0000000..d4822d8 --- /dev/null +++ b/scratchpad/HWPF/Converter/AbstractWordConverter.cs @@ -0,0 +1,995 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using System; +using System.Collections.Generic; +using System.Text; +using NPOI.HWPF.UserModel; +using NPOI.Util; +using System.Xml; +using NPOI.HWPF.Model; +using System.Diagnostics; +using System.Text.RegularExpressions; +using NPOI.POIFS.FileSystem; + + +namespace NPOI.HWPF.Converter +{ + public abstract class AbstractWordConverter + { + private class Structure : IComparable + { + internal int End; + internal int Start; + internal Object StructureObject; + + public Structure(Bookmark bookmark) + { + this.Start = bookmark.Start; + this.End = bookmark.End; + this.StructureObject = bookmark; + } + + public Structure(Field field) + { + this.Start = field.GetFieldStartOffset(); + this.End = field.GetFieldEndOffset(); + this.StructureObject = field; + } + + public override String ToString() + { + return "Structure [" + Start + "; " + End + "]: " + + StructureObject.ToString(); + } + + #region IComparable 成员 + + public int CompareTo(Structure other) + { + return Start < other.Start ? -1 : Start == other.Start ? 0 : 1; + } + + #endregion + } + + private static byte BEL_MARK = 7; + + private static byte FIELD_BEGIN_MARK = 19; + + private static byte FIELD_END_MARK = 21; + + private static byte FIELD_SEPARATOR_MARK = 20; + + private static POILogger logger = POILogFactory.GetLogger(typeof(AbstractWordConverter)); + + private static byte SPECCHAR_AUTONUMBERED_FOOTNOTE_REFERENCE = 2; + + private static byte SPECCHAR_DRAWN_OBJECT = 8; + + protected static char UNICODECHAR_NONBREAKING_HYPHEN = '\u2011'; + + protected static char UNICODECHAR_ZERO_WIDTH_SPACE = '\u200b'; + + private static void AddToStructures(IList structures, Structure structure) + { + IList toRemove = new List(); + foreach (Structure another in structures) + { + + if (another.Start <= structure.Start + && another.End >= structure.Start) + { + return; + } + + if ((structure.Start < another.Start && another.Start < structure.End) + || (structure.Start < another.Start && another.End <= structure.End) + || (structure.Start <= another.Start && another.End < structure.End)) + { + //iterator.remove(); + toRemove.Add(another); + continue; + } + } + + foreach (Structure s in toRemove) + structures.Remove(s); + structures.Add(structure); + } + private List bookmarkStack = new List(); + + private FontReplacer fontReplacer = new DefaultFontReplacer(); + + private PicturesManager picturesManager; + + /** + * Special actions that need to be called after processing complete, like + * updating stylesheets or building document notes list. Usually they are + * called once, but it's okay to call them several times. + */ + protected virtual void AfterProcess() + { + // by default no such actions needed + } + protected Triplet GetCharacterRunTriplet(CharacterRun characterRun) + { + Triplet original = new Triplet(); + original.bold = characterRun.IsBold(); + original.italic = characterRun.IsItalic(); + original.fontName = characterRun.GetFontName(); + Triplet updated = GetFontReplacer().Update(original); + return updated; + } + public abstract XmlDocument Document { get; } + public FontReplacer GetFontReplacer() + { + return fontReplacer; + } + protected int GetNumberColumnsSpanned(int[] tableCellEdges, + int currentEdgeIndex, TableCell tableCell) + { + int nextEdgeIndex = currentEdgeIndex; + int colSpan = 0; + int cellRightEdge = tableCell.GetLeftEdge() + tableCell.GetWidth(); + while (tableCellEdges[nextEdgeIndex] < cellRightEdge) + { + colSpan++; + nextEdgeIndex++; + } + return colSpan; + } + protected int GetNumberRowsSpanned(Table table, int currentRowIndex, + int currentColumnIndex, TableCell tableCell) + { + if (!tableCell.IsFirstVerticallyMerged()) + return 1; + + int numRows = table.NumRows; + + int count = 1; + for (int r1 = currentRowIndex + 1; r1 < numRows; r1++) + { + TableRow nextRow = table.GetRow(r1); + if (currentColumnIndex >= nextRow.NumCells()) + break; + TableCell nextCell = nextRow.GetCell(currentColumnIndex); + if (!nextCell.IsVerticallyMerged() + || nextCell.IsFirstVerticallyMerged()) + break; + count++; + } + return count; + } + + public PicturesManager GetPicturesManager() + { + return picturesManager; + } + + protected int getTableCellEdgesIndexSkipCount(Table table, int r, + int[] tableCellEdges, int currentEdgeIndex, int c, TableCell tableCell) + { + TableCell upperCell = null; + for (int r1 = r - 1; r1 >= 0; r1--) + { + TableRow row = table.GetRow(r1); + if (row == null || c >= row.NumCells()) + continue; + + TableCell prevCell = row.GetCell(c); + if (prevCell != null && prevCell.IsFirstVerticallyMerged()) + { + upperCell = prevCell; + break; + } + } + if (upperCell == null) + { + logger.Log(POILogger.WARN, "First vertically merged cell for ", + tableCell, " not found"); + return 0; + } + + return GetNumberColumnsSpanned(tableCellEdges, currentEdgeIndex, + tableCell); + } + protected abstract void OutputCharacters(XmlElement block, + CharacterRun characterRun, String text); + + /** + * Wrap range into bookmark(s) and process it. All bookmarks have starts + * equal to range start and ends equal to range end. Usually it's only one + * bookmark. + */ + protected abstract void ProcessBookmarks(HWPFDocumentCore wordDocument, + XmlElement currentBlock, Range range, int currentTableLevel, + IList rangeBookmarks); + + protected bool ProcessCharacters(HWPFDocumentCore wordDocument, int currentTableLevel, Range range, XmlElement block) + { + if (range == null) + return false; + + bool haveAnyText = false; + + /* + * In text there can be fields, bookmarks, may be other structures (code + * below allows extension). Those structures can overlaps, so either we + * should process char-by-char (slow) or find a correct way to + * reconstruct the structure of range -- sergey + */ + IList structures = new List(); + if (wordDocument is HWPFDocument) + { + HWPFDocument doc = (HWPFDocument)wordDocument; + + Dictionary> rangeBookmarks = doc.GetBookmarks() + .GetBookmarksStartedBetween(range.StartOffset, range.EndOffset); + + if (rangeBookmarks != null) + { + foreach (KeyValuePair> kv in rangeBookmarks) + { + List lists = kv.Value; + foreach (Bookmark bookmark in lists) + { + if (!bookmarkStack.Contains(bookmark)) + AddToStructures(structures, new Structure(bookmark)); + } + } + } + + // TODO: dead fields? + for (int c = 0; c < range.NumCharacterRuns; c++) + { + CharacterRun characterRun = range.GetCharacterRun(c); + if (characterRun == null) + throw new NullReferenceException(); + Field aliveField = ((HWPFDocument)wordDocument).GetFields() + .GetFieldByStartOffset(FieldsDocumentPart.MAIN, + characterRun.StartOffset); + if (aliveField != null) + { + AddToStructures(structures, new Structure(aliveField)); + } + } + } + + //structures = new ArrayList( structures ); + //Collections.sort( structures ); + SortedList sl = new SortedList(); + foreach (Structure s in structures) + sl.Add(s, s); + structures.Clear(); + ((List)structures).AddRange(sl.Values); + + int previous = range.StartOffset; + foreach (Structure structure in structures) + { + if (structure.Start != previous) + { + Range subrange = new Range(previous, structure.Start, range); + //{ + // public String toString() + // { + // return "BetweenStructuresSubrange " + super.ToString(); + // } + //}; + ProcessCharacters(wordDocument, currentTableLevel, subrange, block); + } + + if (structure.StructureObject is Bookmark) + { + // other bookmarks with same boundaries + IList bookmarks = new List(); + IEnumerator> iterator = ((HWPFDocument)wordDocument).GetBookmarks().GetBookmarksStartedBetween(structure.Start, structure.Start + 1).Values.GetEnumerator(); + iterator.MoveNext(); + foreach (Bookmark bookmark in iterator.Current) + { + if (bookmark.Start == structure.Start + && bookmark.End == structure.End) + { + bookmarks.Add(bookmark); + } + } + + bookmarkStack.AddRange(bookmarks); + try + { + int end = Math.Min(range.EndOffset, structure.End); + Range subrange = new Range(structure.Start, end, range); + /*{ + public String toString() + { + return "BookmarksSubrange " + super.ToString(); + } + };*/ + + ProcessBookmarks(wordDocument, block, subrange, + currentTableLevel, bookmarks); + } + finally + { + bookmarkStack.RemoveAll((e) => { return bookmarks.Contains(e); }); + } + } + else if (structure.StructureObject is Field) + { + Field field = (Field)structure.StructureObject; + ProcessField((HWPFDocument)wordDocument, range, currentTableLevel, field, block); + } + else + { + throw new NotSupportedException("NYI: " + structure.StructureObject.GetType().ToString()); + } + + previous = Math.Min(range.EndOffset, structure.End); + } + + if (previous != range.StartOffset) + { + if (previous > range.EndOffset) + { + logger.Log(POILogger.WARN, "Latest structure in ", range, + " ended at #" + previous, " after range boundaries [", + range.StartOffset + "; " + range.EndOffset, + ")"); + return true; + } + + if (previous < range.EndOffset) + { + Range subrange = new Range(previous, range.EndOffset, range); + /*{ + @Override + public String toString() + { + return "AfterStructureSubrange " + super.ToString(); + } + };*/ + ProcessCharacters(wordDocument, currentTableLevel, subrange, + block); + } + return true; + } + + for (int c = 0; c < range.NumCharacterRuns; c++) + { + CharacterRun characterRun = range.GetCharacterRun(c); + + if (characterRun == null) + throw new NullReferenceException(); + + if (wordDocument is HWPFDocument && ((HWPFDocument)wordDocument).GetPicturesTable().HasPicture(characterRun)) + { + HWPFDocument newFormat = (HWPFDocument)wordDocument; + Picture picture = newFormat.GetPicturesTable().ExtractPicture(characterRun, true); + + ProcessImage(block, characterRun.Text[0] == 0x01, picture); + continue; + } + + string text = characterRun.Text; + byte[] textByte = System.Text.Encoding.GetEncoding("iso-8859-1").GetBytes(text); + //if ( text.getBytes().length == 0 ) + if (textByte.Length == 0) + continue; + + if (characterRun.IsSpecialCharacter()) + { + if (text[0] == SPECCHAR_AUTONUMBERED_FOOTNOTE_REFERENCE && (wordDocument is HWPFDocument)) + { + HWPFDocument doc = (HWPFDocument)wordDocument; + ProcessNoteAnchor(doc, characterRun, block); + continue; + } + if (text[0] == SPECCHAR_DRAWN_OBJECT + && (wordDocument is HWPFDocument)) + { + HWPFDocument doc = (HWPFDocument)wordDocument; + ProcessDrawnObject(doc, characterRun, block); + continue; + } + if (characterRun.IsOle2() && (wordDocument is HWPFDocument)) + { + HWPFDocument doc = (HWPFDocument)wordDocument; + ProcessOle2(doc, characterRun, block); + continue; + } + } + if (textByte[0] == FIELD_BEGIN_MARK) + //if ( text.getBytes()[0] == FIELD_BEGIN_MARK ) + { + if (wordDocument is HWPFDocument) + { + Field aliveField = ((HWPFDocument)wordDocument).GetFields().GetFieldByStartOffset( + FieldsDocumentPart.MAIN, characterRun.StartOffset); + if (aliveField != null) + { + ProcessField(((HWPFDocument)wordDocument), range, + currentTableLevel, aliveField, block); + + int continueAfter = aliveField.GetFieldEndOffset(); + while (c < range.NumCharacterRuns + && range.GetCharacterRun(c).EndOffset <= continueAfter) + c++; + + if (c < range.NumCharacterRuns) + c--; + + continue; + } + } + + int skipTo = TryDeadField(wordDocument, range, + currentTableLevel, c, block); + + if (skipTo != c) + { + c = skipTo; + continue; + } + + continue; + } + if (textByte[0] == FIELD_SEPARATOR_MARK) + { + // shall not appear without FIELD_BEGIN_MARK + continue; + } + if (textByte[0] == FIELD_END_MARK) + { + // shall not appear without FIELD_BEGIN_MARK + continue; + } + + if (characterRun.IsSpecialCharacter() || characterRun.IsObj() + || characterRun.IsOle2()) + { + continue; + } + + if (text.EndsWith("\r") + || (text[text.Length - 1] == BEL_MARK && currentTableLevel != int.MinValue)) + text = text.Substring(0, text.Length - 1); + + { + // line breaks + StringBuilder stringBuilder = new StringBuilder(); + foreach (char charChar in text.ToCharArray()) + { + if (charChar == 11) + { + if (stringBuilder.Length > 0) + { + OutputCharacters(block, characterRun, + stringBuilder.ToString()); + stringBuilder.Length = 0; + } + ProcessLineBreak(block, characterRun); + } + else if (charChar == 30) + { + // Non-breaking hyphens are stored as ASCII 30 + stringBuilder.Append(UNICODECHAR_NONBREAKING_HYPHEN); + } + else if (charChar == 31) + { + // Non-required hyphens to zero-width space + stringBuilder.Append(UNICODECHAR_ZERO_WIDTH_SPACE); + } + else if (charChar >= 0x20 || charChar == 0x09 + || charChar == 0x0A || charChar == 0x0D) + { + stringBuilder.Append(charChar); + } + } + if (stringBuilder.Length > 0) + { + OutputCharacters(block, characterRun, + stringBuilder.ToString()); + stringBuilder.Length = 0; + } + } + + haveAnyText |= text.Trim().Length != 0; + } + + return haveAnyText; + } + protected void ProcessDeadField(HWPFDocumentCore wordDocument, + XmlElement currentBlock, Range range, int currentTableLevel, + int beginMark, int separatorMark, int endMark) + { + StringBuilder debug = new StringBuilder("Unsupported field type: \n"); + for (int i = beginMark; i <= endMark; i++) + { + debug.Append("\t"); + debug.Append(range.GetCharacterRun(i)); + debug.Append("\n"); + } + logger.Log(POILogger.WARN, debug); + + Range deadFieldValueSubrage = new Range(range.GetCharacterRun( + separatorMark).StartOffset + 1, range.GetCharacterRun( + endMark).StartOffset, range); + //{ + // @Override + // public String toString() + // { + // return "DeadFieldValueSubrange (" + super.ToString() + ")"; + // } + //}; + + // just output field value + if (separatorMark + 1 < endMark) + ProcessCharacters(wordDocument, currentTableLevel, + deadFieldValueSubrage, currentBlock); + + return; + } + + protected Field ProcessDeadField(HWPFDocumentCore wordDocument, + Range charactersRange, int currentTableLevel, int startOffset, + XmlElement currentBlock) + { + if (!(wordDocument is HWPFDocument)) + return null; + + HWPFDocument hwpfDocument = (HWPFDocument)wordDocument; + Field field = hwpfDocument.GetFields().GetFieldByStartOffset( + FieldsDocumentPart.MAIN, startOffset); + if (field == null) + return null; + + ProcessField(hwpfDocument, charactersRange, currentTableLevel, field, + currentBlock); + + return field; + } + + public void ProcessDocument(HWPFDocumentCore wordDocument) + { + try + { + NPOI.HPSF.SummaryInformation summaryInformation = wordDocument.SummaryInformation; + if (summaryInformation != null) + { + ProcessDocumentInformation(summaryInformation); + } + } + catch (Exception exc) + { + logger.Log(POILogger.WARN, "Unable to process document summary information: ", exc, exc); + } + + Range docRange = wordDocument.GetRange(); + + if (docRange.NumSections == 1) + { + ProcessSingleSection(wordDocument, docRange.GetSection(0)); + AfterProcess(); + return; + } + + ProcessDocumentPart(wordDocument, docRange); + AfterProcess(); + } + + protected abstract void ProcessDocumentInformation(NPOI.HPSF.SummaryInformation summaryInformation); + + protected virtual void ProcessDocumentPart(HWPFDocumentCore wordDocument, + Range range) + { + for (int s = 0; s < range.NumSections; s++) + { + ProcessSection(wordDocument, range.GetSection(s), s); + } + } + + protected void ProcessDrawnObject(HWPFDocument doc, + CharacterRun characterRun, XmlElement block) + { + if (GetPicturesManager() == null) + return; + // TODO: support headers + OfficeDrawing officeDrawing = doc.GetOfficeDrawingsMain().GetOfficeDrawingAt(characterRun.StartOffset); + if (officeDrawing == null) + { + logger.Log(POILogger.WARN, "Characters #" + characterRun + + " references missing drawn object"); + return; + } + + byte[] pictureData = officeDrawing.GetPictureData(); + if (pictureData == null) + // usual shape? + return; + + PictureType type = PictureType.FindMatchingType(pictureData); + String path = GetPicturesManager().SavePicture(pictureData, type, + "s" + characterRun.StartOffset + "." + type); + + ProcessDrawnObject(doc, characterRun, officeDrawing, path, block); + } + + protected abstract void ProcessDrawnObject(HWPFDocument doc, + CharacterRun characterRun, OfficeDrawing officeDrawing, + String path, XmlElement block); + + protected abstract void ProcessEndnoteAutonumbered( + HWPFDocument wordDocument, int noteIndex, XmlElement block, + Range endnoteTextRange); + + protected void ProcessField(HWPFDocument wordDocument, Range parentRange, + int currentTableLevel, Field field, XmlElement currentBlock) + { + switch (field.Type) + { + case 37: // page reference + { + Range firstSubrange = field.FirstSubrange(parentRange); + if (firstSubrange != null) + { + String formula = firstSubrange.Text; + Regex pagerefPattern = new Regex("[ \\t\\r\\n]*PAGEREF ([^ ]*)[ \\t\\r\\n]*\\\\h[ \\t\\r\\n]*"); + Match match = pagerefPattern.Match(formula); + if (match.Success) + { + String pageref = match.Groups[1].Value; + ProcessPageref(wordDocument, currentBlock, + field.SecondSubrange(parentRange), + currentTableLevel, pageref); + return; + } + //Pattern pagerefPattern = Pattern + // .compile("[ \\t\\r\\n]*PAGEREF ([^ ]*)[ \\t\\r\\n]*\\\\h[ \\t\\r\\n]*"); + //Matcher matcher = pagerefPattern.matcher(formula); + //if (matcher.find()) + //{ + // String pageref = matcher.group(1); + // processPageref(wordDocument, currentBlock, + // field.secondSubrange(parentRange), + // currentTableLevel, pageref); + // return; + //} + } + break; + } + case 58: // Embedded Object + { + if (!field.HasSeparator()) + { + logger.Log(POILogger.WARN, parentRange + " contains " + field + + " with 'Embedded Object' but without separator mark"); + return; + } + + CharacterRun separator = field.GetMarkSeparatorCharacterRun(parentRange); + + if (separator.IsOle2()) + { + // the only supported so far + bool processed = ProcessOle2(wordDocument, separator, + currentBlock); + + // if we didn't output OLE - output field value + if (!processed) + { + ProcessCharacters(wordDocument, currentTableLevel, + field.SecondSubrange(parentRange), currentBlock); + } + + return; + } + + break; + } + case 88: // hyperlink + { + Range firstSubrange = field.FirstSubrange(parentRange); + if (firstSubrange != null) + { + String formula = firstSubrange.Text; + Regex hyperlinkPattern = new Regex("[ \\t\\r\\n]*HYPERLINK \"(.*)\"[ \\t\\r\\n]*"); + Match match = hyperlinkPattern.Match(formula); + if (match.Success) + { + String hyperlink = match.Groups[1].Value; + ProcessHyperlink(wordDocument, currentBlock, + field.SecondSubrange(parentRange), + currentTableLevel, hyperlink); + return; + } + //Pattern hyperlinkPattern = Pattern + // .compile("[ \\t\\r\\n]*HYPERLINK \"(.*)\"[ \\t\\r\\n]*"); + //Matcher matcher = hyperlinkPattern.matcher(formula); + //if (matcher.find()) + //{ + // String hyperlink = matcher.group(1); + // processHyperlink(wordDocument, currentBlock, + // field.secondSubrange(parentRange), + // currentTableLevel, hyperlink); + // return; + //} + } + break; + } + } + + logger.Log(POILogger.WARN, parentRange + " contains " + field + + " with unsupported type or format"); + ProcessCharacters(wordDocument, currentTableLevel, + field.SecondSubrange(parentRange), currentBlock); + } + + protected abstract void ProcessFootnoteAutonumbered( + HWPFDocument wordDocument, int noteIndex, XmlElement block, + Range footnoteTextRange); + + protected abstract void ProcessHyperlink(HWPFDocumentCore wordDocument, + XmlElement currentBlock, Range textRange, int currentTableLevel, + String hyperlink); + + protected abstract void ProcessImage(XmlElement currentBlock, + bool inlined, Picture picture); + + protected abstract void ProcessLineBreak(XmlElement block, + CharacterRun characterRun); + + protected void ProcessNoteAnchor(HWPFDocument doc, CharacterRun characterRun, XmlElement block) + { + { + + Notes footnotes = doc.GetFootnotes(); + int noteIndex = footnotes.GetNoteIndexByAnchorPosition(characterRun.StartOffset); + if (noteIndex != -1) + { + Range footnoteRange = doc.GetFootnoteRange(); + int rangeStartOffset = footnoteRange.StartOffset; + int noteTextStartOffset = footnotes.GetNoteTextStartOffSet(noteIndex); + int noteTextEndOffset = footnotes.GetNoteTextEndOffSet(noteIndex); + + Range noteTextRange = new Range(rangeStartOffset + noteTextStartOffset, rangeStartOffset + noteTextEndOffset, doc); + + ProcessFootnoteAutonumbered(doc, noteIndex, block, noteTextRange); + return; + } + } + { + Notes endnotes = doc.GetEndnotes(); + int noteIndex = endnotes.GetNoteIndexByAnchorPosition(characterRun.StartOffset); + if (noteIndex != -1) + { + Range endnoteRange = doc.GetEndnoteRange(); + int rangeStartOffset = endnoteRange.StartOffset; + int noteTextStartOffset = endnotes.GetNoteTextStartOffSet(noteIndex); + int noteTextEndOffset = endnotes.GetNoteTextEndOffSet(noteIndex); + + Range noteTextRange = new Range(rangeStartOffset + noteTextStartOffset, rangeStartOffset + noteTextEndOffset, doc); + + ProcessEndnoteAutonumbered(doc, noteIndex, block, noteTextRange); + return; + } + } + throw new NotImplementedException(); + } + + private bool ProcessOle2(HWPFDocument doc, CharacterRun characterRun, + XmlElement block) + { + Entry entry = doc.GetObjectsPool().GetObjectById("_" + characterRun.GetPicOffset()); + if (entry == null) + { + logger.Log(POILogger.WARN, "Referenced OLE2 object '", (characterRun.GetPicOffset()).ToString(), "' not found in ObjectPool"); + return false; + } + + try + { + return ProcessOle2(doc, block, entry); + } + catch (Exception exc) + { + logger.Log(POILogger.WARN, + "Unable to convert internal OLE2 object '", (characterRun.GetPicOffset()).ToString(), "': ", exc, exc); + return false; + } + } + + ////@SuppressWarnings( "unused" ) + protected virtual bool ProcessOle2(HWPFDocument wordDocument, XmlElement block, + NPOI.POIFS.FileSystem.Entry entry) + { + return false; + } + + protected abstract void ProcessPageBreak(HWPFDocumentCore wordDocument, + XmlElement flow); + + protected abstract void ProcessPageref(HWPFDocumentCore wordDocument, + XmlElement currentBlock, Range textRange, int currentTableLevel, + String pageref); + + protected abstract void ProcessParagraph(HWPFDocumentCore wordDocument, + XmlElement parentElement, int currentTableLevel, Paragraph paragraph, + String bulletText); + + protected void ProcessParagraphes(HWPFDocumentCore wordDocument, + XmlElement flow, Range range, int currentTableLevel) + { + + ListTables listTables = wordDocument.GetListTables(); + int currentListInfo = 0; + + int paragraphs = range.NumParagraphs; + for (int p = 0; p < paragraphs; p++) + { + Paragraph paragraph = range.GetParagraph(p); + + if (paragraph.IsInTable() && paragraph.GetTableLevel() != currentTableLevel) + { + if (paragraph.GetTableLevel() < currentTableLevel) + throw new InvalidOperationException( + "Trying to process table cell with higher level (" + + paragraph.GetTableLevel() + + ") than current table level (" + + currentTableLevel + + ") as inner table part"); + + Table table = range.GetTable(paragraph); + ProcessTable(wordDocument, flow, table); + + p += table.NumParagraphs; + p--; + continue; + } + + if (paragraph.Text.Equals("\u000c")) + { + ProcessPageBreak(wordDocument, flow); + } + + if (paragraph.GetIlfo() != currentListInfo) + { + currentListInfo = paragraph.GetIlfo(); + } + + if (currentListInfo != 0) + { + if (listTables != null) + { + ListFormatOverride listFormatOverride = listTables.GetOverride(paragraph.GetIlfo()); + + String label = AbstractWordUtils.GetBulletText(listTables, + paragraph, listFormatOverride.GetLsid()); + + ProcessParagraph(wordDocument, flow, currentTableLevel, + paragraph, label); + } + else + { + logger.Log(POILogger.WARN, + "Paragraph #" + paragraph.StartOffset + "-" + + paragraph.EndOffset + + " has reference to list structure #" + + currentListInfo + + ", but listTables not defined in file"); + + ProcessParagraph(wordDocument, flow, currentTableLevel, + paragraph, string.Empty); + } + } + else + { + ProcessParagraph(wordDocument, flow, currentTableLevel, + paragraph, string.Empty); + } + } + } + + protected abstract void ProcessSection(HWPFDocumentCore wordDocument, + Section section, int s); + + protected virtual void ProcessSingleSection(HWPFDocumentCore wordDocument, + Section section) + { + ProcessSection(wordDocument, section, 0); + } + + protected abstract void ProcessTable(HWPFDocumentCore wordDocument, + XmlElement flow, Table table); + + public void SetFontReplacer(FontReplacer fontReplacer) + { + this.fontReplacer = fontReplacer; + } + + public void SetPicturesManager(PicturesManager fileManager) + { + this.picturesManager = fileManager; + } + + protected int TryDeadField(HWPFDocumentCore wordDocument, Range range, + int currentTableLevel, int beginMark, XmlElement currentBlock) + { + int separatorMark = -1; + int endMark = -1; + for (int c = beginMark + 1; c < range.NumCharacterRuns; c++) + { + CharacterRun characterRun = range.GetCharacterRun(c); + + String text = characterRun.Text; + byte[] textByte = System.Text.Encoding.GetEncoding("iso-8859-1").GetBytes(text); + if (textByte.Length == 0) + //if (text.getBytes().length == 0) + continue; + + if (textByte[0] == FIELD_BEGIN_MARK) + { + // nested? + Field possibleField = ProcessDeadField(wordDocument, range, + currentTableLevel, characterRun.StartOffset, + currentBlock); + if (possibleField != null) + { + c = possibleField.GetFieldEndOffset(); + } + else + { + continue; + } + } + + if (textByte[0] == FIELD_SEPARATOR_MARK) + { + if (separatorMark != -1) + { + // double; + return beginMark; + } + + separatorMark = c; + continue; + } + + if (textByte[0] == FIELD_END_MARK) + { + if (endMark != -1) + { + // double; + return beginMark; + } + + endMark = c; + break; + } + + } + + if (separatorMark == -1 || endMark == -1) + return beginMark; + + ProcessDeadField(wordDocument, currentBlock, range, currentTableLevel, + beginMark, separatorMark, endMark); + + return endMark; + } + } + +} diff --git a/scratchpad/HWPF/Converter/AbstractWordUtils.cs b/scratchpad/HWPF/Converter/AbstractWordUtils.cs new file mode 100644 index 0000000..b904c15 --- /dev/null +++ b/scratchpad/HWPF/Converter/AbstractWordUtils.cs @@ -0,0 +1,454 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Xml; +using NPOI.HWPF.Model; +using NPOI.HWPF.UserModel; +using NPOI.POIFS.FileSystem; +using NPOI.Util; + + +namespace NPOI.HWPF.Converter +{ + public class AbstractWordUtils + { + static POILogger logger = POILogFactory.GetLogger(typeof(AbstractWordUtils)); + public static float TWIPS_PER_INCH = 1440.0f; + public static int TWIPS_PER_PT = 20; + + + /** + * Creates array of all possible cell edges. In HTML (and FO) cells from + * different rows and same column should have same width, otherwise spanning + * shall be used. + * + * @param table + * table to build cell edges array from + * @return array of cell edges (including leftest one) in twips + */ + public static int[] BuildTableCellEdgesArray(Table table) + { + SortedList edges = new SortedList(); + + for (int r = 0; r < table.NumRows; r++) + { + TableRow tableRow = table.GetRow(r); + for (int c = 0; c < tableRow.NumCells(); c++) + { + TableCell tableCell = tableRow.GetCell(c); + if (!edges.ContainsKey(tableCell.GetLeftEdge())) + edges.Add(tableCell.GetLeftEdge(), 0); + if (!edges.ContainsKey(tableCell.GetLeftEdge() + tableCell.GetWidth())) + edges.Add(tableCell.GetLeftEdge() + tableCell.GetWidth(), 0); + } + } + + int[] result = new int[edges.Count]; + + edges.Keys.CopyTo(result, 0); + return result; + } + static bool CanBeMerged(XmlNode node1, XmlNode node2, String requiredTagName) + { + if (node1.NodeType != XmlNodeType.Element || node2.NodeType != XmlNodeType.Element) + return false; + + XmlElement element1 = (XmlElement)node1; + XmlElement element2 = (XmlElement)node2; + + if (!StringEquals(requiredTagName, element1.Name) + || !StringEquals(requiredTagName, element2.Name)) + return false; + + if (element1.Attributes.Count != element2.Attributes.Count) + return false; + + for (int i = 0; i < element1.Attributes.Count; i++) + { + XmlAttribute attr1 = (XmlAttribute)element1.Attributes[i]; + XmlAttribute attr2; + if (string.IsNullOrEmpty(attr1.NamespaceURI)) + attr2 = (XmlAttribute)element2.Attributes.GetNamedItem(attr1.LocalName, attr1.NamespaceURI); + else + attr2 = (XmlAttribute)element2.Attributes.GetNamedItem(attr1.Name); + + if (attr2 == null || !StringEquals(attr1.InnerText, attr2.InnerText)) + //if (attr2 == null || !equals(attr1.getTextContent(), attr2.getTextContent())) + return false; + } + + return true; + } + + protected static void CompactChildNodesR(XmlElement parentElement, String childTagName) + { + XmlNodeList childNodes = parentElement.ChildNodes; + for (int i = 0; i < childNodes.Count - 1; i++) + { + XmlNode child1 = childNodes[i]; + XmlNode child2 = childNodes[i + 1]; + if (!CanBeMerged(child1, child2, childTagName)) + continue; + + // merge + while (child2.ChildNodes.Count > 0) + child1.AppendChild(child2.FirstChild); + child2.ParentNode.RemoveChild(child2); + i--; + } + + childNodes = parentElement.ChildNodes; + for (int i = 0; i < childNodes.Count - 1; i++) + { + XmlNode child = childNodes[i]; + if (child is XmlElement) + { + CompactChildNodesR((XmlElement)child, childTagName); + } + } + } + static bool StringEquals(String str1, String str2) + { + return str1 == null ? str2 == null : str1.Equals(str2); + } + public static String GetBorderType(BorderCode borderCode) + { + if (borderCode == null) + throw new ArgumentNullException("borderCode is null"); + + switch (borderCode.BorderType) + { + case 1: + case 2: + return "solid"; + case 3: + return "double"; + case 5: + return "solid"; + case 6: + return "dotted"; + case 7: + case 8: + return "dashed"; + case 9: + return "dotted"; + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + return "double"; + case 20: + return "solid"; + case 21: + return "double"; + case 22: + return "dashed"; + case 23: + return "dashed"; + case 24: + return "ridge"; + case 25: + return "grooved"; + default: + return "solid"; + } + } + + public static String GetBorderWidth(BorderCode borderCode) + { + int lineWidth = borderCode.LineWidth; + int pt = lineWidth / 8; + int pte = lineWidth - pt * 8; + + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.Append(pt); + stringBuilder.Append("."); + stringBuilder.Append(1000 / 8 * pte); + stringBuilder.Append("pt"); + return stringBuilder.ToString(); + } + + public static String GetBulletText(ListTables listTables, + Paragraph paragraph, int listId) + { + ListLevel listLevel = listTables.GetLevel(listId, + paragraph.GetIlvl()); + + if (listLevel.GetNumberText() == null) + return string.Empty; + + StringBuilder bulletBuffer = new StringBuilder(); + char[] xst = listLevel.GetNumberText().ToCharArray(); + foreach (char element in xst) + { + if (element < 9)//todo:review_antony + { + ListLevel numLevel = listTables.GetLevel(listId, element); + + int num = numLevel.GetStartAt(); + bulletBuffer.Append(NumberFormatter.GetNumber(num, + listLevel.GetNumberFormat())); + + if (numLevel == listLevel) + { + numLevel.SetStartAt(numLevel.GetStartAt() + 1); + } + + } + else + { + bulletBuffer.Append(element); + } + } + + byte follow = listLevel.GetTypeOfCharFollowingTheNumber(); + switch (follow) + { + case 0: + bulletBuffer.Append("\t"); + break; + case 1: + bulletBuffer.Append(" "); + break; + default: + break; + } + + return bulletBuffer.ToString(); + } + + public static String GetColor(int ico) + { + switch (ico) + { + case 1: + return "black"; + case 2: + return "blue"; + case 3: + return "cyan"; + case 4: + return "green"; + case 5: + return "magenta"; + case 6: + return "red"; + case 7: + return "yellow"; + case 8: + return "white"; + case 9: + return "darkblue"; + case 10: + return "darkcyan"; + case 11: + return "darkgreen"; + case 12: + return "darkmagenta"; + case 13: + return "darkred"; + case 14: + return "darkyellow"; + case 15: + return "darkgray"; + case 16: + return "lightgray"; + default: + return "black"; + } + } + + public static String GetOpacity(int argbValue) + { + int opacity = (int)((argbValue & 0xFF000000L) >> 24);// todo: review code, java use operater >>> + if (opacity == 0 || opacity == 0xFF) + return ".0"; + + return "" + (opacity / (float)0xFF); + } + + public static String GetColor24(int argbValue) + { + if (argbValue == -1) + throw new ArgumentException("This colorref is empty"); + + int bgrValue = argbValue & 0x00FFFFFF; + int rgbValue = (bgrValue & 0x0000FF) << 16 | (bgrValue & 0x00FF00) + | (bgrValue & 0xFF0000) >> 16; + + // http://www.w3.org/TR/REC-html40/types.html#h-6.5 + switch (rgbValue) + { + case 0xFFFFFF: + return "white"; + case 0xC0C0C0: + return "silver"; + case 0x808080: + return "gray"; + case 0x000000: + return "black"; + case 0xFF0000: + return "red"; + case 0x800000: + return "maroon"; + case 0xFFFF00: + return "yellow"; + case 0x808000: + return "olive"; + case 0x00FF00: + return "lime"; + case 0x008000: + return "green"; + case 0x00FFFF: + return "aqua"; + case 0x008080: + return "teal"; + case 0x0000FF: + return "blue"; + case 0x000080: + return "navy"; + case 0xFF00FF: + return "fuchsia"; + case 0x800080: + return "purple"; + } + + StringBuilder result = new StringBuilder("#"); + String hex = rgbValue.ToString("x"); + for (int i = hex.Length; i < 6; i++) + { + result.Append('0'); + } + result.Append(hex); + return result.ToString(); + } + + public static String GetJustification(int js) + { + switch (js) + { + case 0: + return "start"; + case 1: + return "center"; + case 2: + return "end"; + case 3: + case 4: + return "justify"; + case 5: + return "center"; + case 6: + return "left"; + case 7: + return "start"; + case 8: + return "end"; + case 9: + return "justify"; + } + return ""; + } + + public static String GetLanguage(int languageCode) + { + switch (languageCode) + { + case 1024: + return string.Empty; + case 1033: + return "en-us"; + case 1049: + return "ru-ru"; + case 2057: + return "en-uk"; + default: + logger.Log(POILogger.WARN, "Uknown or unmapped language code: ", languageCode); + return string.Empty; + } + } + + public static String GetListItemNumberLabel(int number, int format) + { + + if (format != 0) + System.Console.WriteLine("NYI: toListItemNumberLabel(): " + format); + + return number.ToString(); + } + + public static HWPFDocumentCore LoadDoc(DirectoryNode root) + { + try + { + return new HWPFDocument(root); + } + catch (OldWordFileFormatException exc) + { + return new HWPFOldDocument(root); + } + } + public static HWPFDocumentCore LoadDoc(POIFSFileSystem poifsFileSystem) + { + return LoadDoc( poifsFileSystem.Root ); + } + public static HWPFDocumentCore LoadDoc(Stream inputStream) + { + return LoadDoc(HWPFDocumentCore.VerifyAndBuildPOIFS(inputStream)); + } + public static HWPFDocumentCore LoadDoc(string docFile) + { + FileStream istream = new FileStream(docFile, FileMode.Open); + try + { + return LoadDoc(istream); + } + finally + { + if (istream != null) + istream.Close(); + istream = null; + } + } + + public static String SubstringBeforeLast(String str, String separator) + { + if (string.IsNullOrEmpty(str) || string.IsNullOrEmpty(separator)) + { + return str; + } + int pos = str.LastIndexOf(separator); + if (pos == -1) + { + return str; + } + return str.Substring(0, pos); + } + + } +} diff --git a/scratchpad/HWPF/Converter/DefaultFontReplacer.cs b/scratchpad/HWPF/Converter/DefaultFontReplacer.cs new file mode 100644 index 0000000..21ebe0d --- /dev/null +++ b/scratchpad/HWPF/Converter/DefaultFontReplacer.cs @@ -0,0 +1,97 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using System; +using System.Collections.Generic; +using System.Text; + +namespace NPOI.HWPF.Converter +{ + public class DefaultFontReplacer : FontReplacer + { + #region IFontReplacer 成员 + + public Triplet Update(Triplet original) + { + if (!string.IsNullOrEmpty(original.fontName)) + { + String fontName = original.fontName; + + if (fontName.EndsWith(" Regular")) + fontName = AbstractWordUtils.SubstringBeforeLast(fontName, + " Regular"); + + if (fontName + .EndsWith(" \u041F\u043E\u043B\u0443\u0436\u0438\u0440\u043D\u044B\u0439")) + fontName = AbstractWordUtils + .SubstringBeforeLast(fontName, + " \u041F\u043E\u043B\u0443\u0436\u0438\u0440\u043D\u044B\u0439") + + " Bold"; + + if (fontName + .EndsWith(" \u041F\u043E\u043B\u0443\u0436\u0438\u0440\u043D\u044B\u0439 \u041A\u0443\u0440\u0441\u0438\u0432")) + fontName = AbstractWordUtils + .SubstringBeforeLast( + fontName, + " \u041F\u043E\u043B\u0443\u0436\u0438\u0440\u043D\u044B\u0439 \u041A\u0443\u0440\u0441\u0438\u0432") + + " Bold Italic"; + + if (fontName.EndsWith(" \u041A\u0443\u0440\u0441\u0438\u0432")) + fontName = AbstractWordUtils.SubstringBeforeLast(fontName, + " \u041A\u0443\u0440\u0441\u0438\u0432") + " Italic"; + + original.fontName = fontName; + } + + if (!string.IsNullOrEmpty(original.fontName)) + { + if ("Times Regular".Equals(original.fontName) + || "Times-Regular".Equals(original.fontName)) + { + original.fontName = "Times"; + original.bold = false; + original.italic = false; + } + if ("Times Bold".Equals(original.fontName) + || "Times-Bold".Equals(original.fontName)) + { + original.fontName = "Times"; + original.bold = true; + original.italic = false; + } + if ("Times Italic".Equals(original.fontName) + || "Times-Italic".Equals(original.fontName)) + { + original.fontName = "Times"; + original.bold = false; + original.italic = true; + } + if ("Times Bold Italic".Equals(original.fontName) + || "Times-BoldItalic".Equals(original.fontName)) + { + original.fontName = "Times"; + original.bold = true; + original.italic = true; + } + } + + return original; + } + + #endregion + } +} diff --git a/scratchpad/HWPF/Converter/FoDocumentFacade.cs b/scratchpad/HWPF/Converter/FoDocumentFacade.cs new file mode 100644 index 0000000..1f2854d --- /dev/null +++ b/scratchpad/HWPF/Converter/FoDocumentFacade.cs @@ -0,0 +1,328 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +namespace NPOI.HWPF.Converter +{ + using System; + using System.Collections.Generic; + using System.Xml; + + public class FoDocumentFacade + { + private const String NS_RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; + + private const String NS_XSLFO = "http://www.w3.org/1999/XSL/Format"; + + protected XmlElement declarations; + protected XmlDocument document; + protected XmlElement layoutMasterSet; + protected XmlElement propertiesRoot; + protected XmlElement root; + + public FoDocumentFacade(XmlDocument document) + { + this.document = document; + root = document.CreateElement("fo:root", NS_XSLFO); + document.AppendChild(root); + + layoutMasterSet = document.CreateElement("fo:layout-master-set", NS_XSLFO); + root.AppendChild(layoutMasterSet); + + declarations = document.CreateElement("fo:declarations", NS_XSLFO); + root.AppendChild(declarations); + } + + public XmlElement AddFlowToPageSequence(XmlElement pageSequence, + String flowName) + { + XmlElement flow = document.CreateElement("fo:flow", NS_XSLFO); + flow.SetAttribute("flow-name", flowName); + pageSequence.AppendChild(flow); + + return flow; + } + + public XmlElement AddListItem(XmlElement listBlock) + { + XmlElement result = CreateListItem(); + listBlock.AppendChild(result); + return result; + } + + public XmlElement AddListItemBody(XmlElement listItem) + { + XmlElement result = CreateListItemBody(); + listItem.AppendChild(result); + return result; + } + + public XmlElement AddListItemLabel(XmlElement listItem, String text) + { + XmlElement result = CreateListItemLabel(text); + listItem.AppendChild(result); + return result; + } + + public XmlElement AddPageSequence(String pageMaster) + { + XmlElement pageSequence = document.CreateElement("fo:page-sequence", NS_XSLFO); + pageSequence.SetAttribute("master-reference", pageMaster); + root.AppendChild(pageSequence); + return pageSequence; + } + + public XmlElement AddRegionBody(XmlElement pageMaster) + { + XmlElement regionBody = document.CreateElement( + "fo:region-body", NS_XSLFO); + pageMaster.AppendChild(regionBody); + + return regionBody; + } + + public XmlElement AddSimplePageMaster(String masterName) + { + XmlElement simplePageMaster = document.CreateElement( + "fo:simple-page-master", NS_XSLFO); + simplePageMaster.SetAttribute("master-name", masterName); + layoutMasterSet.AppendChild(simplePageMaster); + + return simplePageMaster; + } + + public XmlElement CreateBasicLinkExternal(String externalDestination) + { + XmlElement basicLink = document.CreateElement( + "fo:basic-link", NS_XSLFO); + basicLink.SetAttribute("external-destination", externalDestination); + return basicLink; + } + + public XmlElement CreateBasicLinkInternal(String internalDestination) + { + XmlElement basicLink = document.CreateElement( + "fo:basic-link", NS_XSLFO); + basicLink.SetAttribute("internal-destination", internalDestination); + return basicLink; + } + + public XmlElement CreateBlock() + { + return document.CreateElement("fo:block", NS_XSLFO); + } + + public XmlElement CreateExternalGraphic(String source) + { + XmlElement result = document.CreateElement( + "fo:external-graphic", NS_XSLFO); + result.SetAttribute("src", "url('" + source + "')"); + return result; + } + + public XmlElement CreateFootnote() + { + return document.CreateElement("fo:footnote", NS_XSLFO); + } + + public XmlElement CreateFootnoteBody() + { + return document.CreateElement("fo:footnote-body", NS_XSLFO); + } + + public XmlElement CreateInline() + { + return document.CreateElement("fo:inline", NS_XSLFO); + } + + public XmlElement CreateLeader() + { + return document.CreateElement("fo:leader", NS_XSLFO); + } + + public XmlElement CreateListBlock() + { + return document.CreateElement("fo:list-block", NS_XSLFO); + } + + public XmlElement CreateListItem() + { + return document.CreateElement("fo:list-item", NS_XSLFO); + } + + public XmlElement CreateListItemBody() + { + return document.CreateElement("fo:list-item-body", NS_XSLFO); + } + + public XmlElement CreateListItemLabel(String text) + { + XmlElement result = document.CreateElement( + "fo:list-item-label", NS_XSLFO); + XmlElement block = CreateBlock(); + block.AppendChild(document.CreateTextNode(text)); + result.AppendChild(block); + return result; + } + + public XmlElement CreateTable() + { + return document.CreateElement("fo:table", NS_XSLFO); + } + + public XmlElement CreateTableBody() + { + return document.CreateElement("fo:table-body", NS_XSLFO); + } + + public XmlElement CreateTableCell() + { + return document.CreateElement("fo:table-cell", NS_XSLFO); + } + + public XmlElement CreateTableHeader() + { + return document.CreateElement("fo:table-header", NS_XSLFO); + } + + public XmlElement CreateTableRow() + { + return document.CreateElement("fo:table-row", NS_XSLFO); + } + + public XmlText CreateText(String data) + { + return document.CreateTextNode(data); + } + + public XmlDocument Document + { + get + { + return document; + } + } + + protected XmlElement GetOrCreatePropertiesRoot() + { + if (propertiesRoot != null) + return propertiesRoot; + + // See http://xmlgraphics.apache.org/fop/0.95/metadata.html + + XmlElement xmpmeta = document.CreateElement("adobe:ns:meta", + "x:xmpmeta", NS_XSLFO); + declarations.AppendChild(xmpmeta); + + XmlElement rdf = document.CreateElement("rdf:RDF", NS_RDF); + xmpmeta.AppendChild(rdf); + + propertiesRoot = document.CreateElement("rdf:Description", NS_RDF); + propertiesRoot.SetAttribute("rdf:about", NS_RDF, ""); + rdf.AppendChild(propertiesRoot); + + return propertiesRoot; + } + + public void SetCreator(String value) + { + SetDublinCoreProperty("creator", value); + } + + public void SetCreatorTool(String value) + { + SetXmpProperty("CreatorTool", value); + } + + public void SetDescription(String value) + { + XmlElement element = SetDublinCoreProperty("description", value); + + if (element != null) + { + element.SetAttribute("xml:lang", "http://www.w3.org/XML/1998/namespace", "x-default"); + } + } + + public XmlElement SetDublinCoreProperty(String name, String value) + { + return SetProperty("http://purl.org/dc/elements/1.1/", "dc", name, value); + } + + public void SetKeywords(String value) + { + SetPdfProperty("Keywords", value); + } + + public XmlElement SetPdfProperty(String name, String value) + { + return SetProperty("http://ns.adobe.com/pdf/1.3/", "pdf", name, value); + } + + public void SetProducer(String value) + { + SetPdfProperty("Producer", value); + } + + protected XmlElement SetProperty(String ns, String prefix, + String name, String value) + { + XmlElement propertiesRoot = GetOrCreatePropertiesRoot(); + XmlNodeList existingChildren = propertiesRoot.ChildNodes; + for (int i = 0; i < existingChildren.Count; i++) + { + XmlNode child = existingChildren[i]; + if (child.NodeType == XmlNodeType.Element) + { + XmlElement childElement = (XmlElement)child; + if (!string.IsNullOrEmpty(childElement.NamespaceURI) + && !string.IsNullOrEmpty(childElement.LocalName) + && ns.Equals(childElement.NamespaceURI) + && name.Equals(childElement.LocalName)) + { + propertiesRoot.RemoveChild(childElement); + break; + } + } + } + + if (string.IsNullOrEmpty(value)) + { + XmlElement property = document.CreateElement(ns, prefix + ":" + name); + property.AppendChild(document.CreateTextNode(value)); + propertiesRoot.AppendChild(property); + return property; + } + + return null; + } + + public void SetSubject(String value) + { + SetDublinCoreProperty("title", value); + } + + public void SetTitle(String value) + { + SetDublinCoreProperty("title", value); + } + + public XmlElement SetXmpProperty(String name, String value) + { + return SetProperty("http://ns.adobe.com/xap/1.0/", "xmp", name, value); + } + + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/Converter/FontReplacer.cs b/scratchpad/HWPF/Converter/FontReplacer.cs new file mode 100644 index 0000000..40dfcfe --- /dev/null +++ b/scratchpad/HWPF/Converter/FontReplacer.cs @@ -0,0 +1,34 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using System; +using System.Collections.Generic; +using System.Text; + +namespace NPOI.HWPF.Converter +{ + public interface FontReplacer + { + Triplet Update(Triplet original); + } + public class Triplet + { + public String fontName; + public bool bold; + public bool italic; + } +} diff --git a/scratchpad/HWPF/Converter/HtmlDocumentFacade.cs b/scratchpad/HWPF/Converter/HtmlDocumentFacade.cs new file mode 100644 index 0000000..45ed1a9 --- /dev/null +++ b/scratchpad/HWPF/Converter/HtmlDocumentFacade.cs @@ -0,0 +1,313 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +namespace NPOI.HWPF.Converter +{ + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + using System.Text; + using System.Xml; + + public class HtmlDocumentFacade + { + protected XmlElement body; + protected XmlDocument document; + protected XmlElement head; + protected XmlElement html; + + //Dictionary from tag name, to map linking known styles and css class names + private Dictionary> stylesheet = new Dictionary>(); + private XmlElement stylesheetElement; + + protected XmlElement title; + protected XmlText titleText; + + public HtmlDocumentFacade(XmlDocument document) + { + this.document = document; + + html = document.CreateElement("html"); + document.AppendChild(html); + + body = document.CreateElement("body"); + head = document.CreateElement("head"); + stylesheetElement = document.CreateElement("style"); + stylesheetElement.SetAttribute("type", "text/css"); + + html.AppendChild(head); + html.AppendChild(body); + head.AppendChild(stylesheetElement); + AddCharset(); + AddStyleClass(body, "b", "white-space-collapsing:preserve;"); + } + // add by Antony + // 不写charset,部分浏览器可能无法正确显示 + public void AddCharset() + { + XmlElement meta = document.CreateElement("meta"); + meta.SetAttribute("http-equiv", "Content-Type"); + meta.SetAttribute("content", "text/html; charset=UTF-8"); + head.AppendChild(meta); + } + public void AddAuthor(string value) + { + AddMeta("author", value); + } + public void AddDescription(string value) + { + AddMeta("description", value); + } + + public void AddKeywords(string value) + { + AddMeta("keywords", value); + } + + public void AddMeta(string name, string value) + { + XmlElement meta = document.CreateElement("meta"); + meta.SetAttribute("name", name); + meta.SetAttribute("content", value); + head.AppendChild(meta); + } + + public void AddStyleClass(XmlElement element, string classNamePrefix, string style) + { + string exising = element.GetAttribute("class"); + string addition = GetOrCreateCssClass(element.Name, classNamePrefix, style); + string newClassValue = string.IsNullOrEmpty(exising) ? addition + : (exising + " " + addition); + element.GetAttribute("class", newClassValue); + } + + public XmlElement CreateBlock() + { + return document.CreateElement("div"); + } + + public XmlElement CreateBookmark(string name) + { + XmlElement basicLink = document.CreateElement("a"); + basicLink.SetAttribute("name", name); + return basicLink; + } + + public XmlElement CreateHeader1() + { + return document.CreateElement("h1"); + } + + public XmlElement CreateHeader2() + { + return document.CreateElement("h2"); + } + + public XmlElement CreateHyperlink(string internalDestination) + { + XmlElement basicLink = document.CreateElement("a"); + basicLink.SetAttribute("href", internalDestination); + return basicLink; + } + + public XmlElement CreateImage(string src) + { + XmlElement result = document.CreateElement("img"); + result.SetAttribute("src", src); + return result; + } + + public XmlElement CreateLineBreak() + { + return document.CreateElement("br"); + } + + public XmlElement CreateListItem() + { + return document.CreateElement("li"); + } + + public XmlElement CreateParagraph() + { + return document.CreateElement("p"); + } + + public XmlElement CreateTable() + { + return document.CreateElement("table"); + } + + public XmlElement CreateTableBody() + { + return document.CreateElement("tbody"); + } + + public XmlElement CreateTableCell() + { + return document.CreateElement("td"); + } + + public XmlElement CreateTableColumn() + { + return document.CreateElement("col"); + } + + public XmlElement CreateTableColumnGroup() + { + return document.CreateElement("colgroup"); + } + + public XmlElement CreateTableHeader() + { + return document.CreateElement("thead"); + } + + public XmlElement CreateTableHeaderCell() + { + return document.CreateElement("th"); + } + + public XmlElement CreateTableRow() + { + return document.CreateElement("tr"); + } + + public XmlText CreateText(string data) + { + return document.CreateTextNode(data); + } + + public XmlElement CreateUnorderedList() + { + return document.CreateElement("ul"); + } + public XmlElement Body + { + get { return body; } + } + public XmlDocument Document + { + get { return document; } + } + public XmlElement Head + { + get { return head; } + } + + public string GetOrCreateCssClass(string tagName, string classNamePrefix, + string style) + { + if (!stylesheet.ContainsKey(tagName)) + stylesheet.Add(tagName, new Dictionary(1)); + + Dictionary styleToClassName = stylesheet[tagName]; + + string knownClass; + if (styleToClassName.ContainsKey(style)) + { + knownClass = styleToClassName[style]; + return knownClass; + } + + string newClassName = classNamePrefix + (styleToClassName.Count + 1); + styleToClassName.Add(style, newClassName); + return newClassName; + } + + public string Title + { + get + { + if (title == null) + return null; + return titleText.InnerText; + } + set + { + if (string.IsNullOrEmpty(value) && this.title != null) + { + this.head.RemoveChild(this.title); + this.title = null; + this.titleText = null; + } + + if (this.title == null) + { + this.title = document.CreateElement("title"); + this.titleText = document.CreateTextNode(value); + this.title.AppendChild(this.titleText); + this.head.AppendChild(title); + } + + this.titleText.InnerText = value; + } + } + + /* + + public string getTitle() + { + if (title == null) + return null; + + //return titleText.getTextContent(); + return titleText.InnerText; + } + + public void setTitle(string titleText) + { + if (string.IsNullOrEmpty(titleText) && this.title != null) + { + //this.head.removeChild(this.title); + this.title = null; + this.titleText = null; + } + + if (this.title == null) + { + this.title = document.CreateElement("title"); + this.titleText = document.CreateTextNode(titleText); + this.title.AppendChild(this.titleText); + this.head.AppendChild(title); + } + + //this.titleText.setData(titleText); + this.titleText.InnerXml = titleText; + } + */ + + public void UpdateStylesheet() + { + StringBuilder stringBuilder = new StringBuilder(); + foreach (KeyValuePair> kvTag in stylesheet) + { + string tagName = kvTag.Key; + foreach (KeyValuePair kvStyle in kvTag.Value) + { + string style = kvStyle.Key; + string className = kvStyle.Value; + + stringBuilder.Append(tagName + "." + className + "{" + style + + "}\n"); + } + } + //stylesheetElement.setTextContent( stringBuilder.toString() ); + stylesheetElement.InnerText = stringBuilder.ToString(); + } + } +} diff --git a/scratchpad/HWPF/Converter/NumberFormatter.cs b/scratchpad/HWPF/Converter/NumberFormatter.cs new file mode 100644 index 0000000..209ec51 --- /dev/null +++ b/scratchpad/HWPF/Converter/NumberFormatter.cs @@ -0,0 +1,134 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using System; +using System.Collections.Generic; +using System.Text; + +namespace NPOI.HWPF.Converter +{ + public class NumberFormatter + { + + private static String[] ENGLISH_LETTERS = new String[] { "a", "b", + "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", + "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" }; + + private static String[] ROMAN_LETTERS = { "m", "cm", "d", "cd", "c", + "xc", "l", "xl", "x", "ix", "v", "iv", "i" }; + + private static int[] ROMAN_VALUES = { 1000, 900, 500, 400, 100, 90, + 50, 40, 10, 9, 5, 4, 1 }; + + private const int T_ARABIC = 0; + private const int T_LOWER_LETTER = 4; + private const int T_LOWER_ROMAN = 2; + private const int T_ORDINAL = 5; + private const int T_UPPER_LETTER = 3; + private const int T_UPPER_ROMAN = 1; + + public static String GetNumber(int num, int style) + { + switch (style) + { + case T_UPPER_ROMAN: + return ToRoman(num).ToUpper(); + case T_LOWER_ROMAN: + return ToRoman(num); + case T_UPPER_LETTER: + return ToLetters(num).ToUpper(); + case T_LOWER_LETTER: + return ToLetters(num); + case T_ARABIC: + case T_ORDINAL: + default: + return num.ToString(); + } + } + + private static String ToLetters(int number) + { + int letterBase = 26; + + if (number <= 0) + throw new ArgumentOutOfRangeException("Unsupported number: " + number); + + if (number < letterBase + 1) + return ENGLISH_LETTERS[number - 1]; + + long toProcess = number; + + StringBuilder stringBuilder = new StringBuilder(); + int maxPower = 0; + { + int boundary = 0; + while (toProcess > boundary) + { + maxPower++; + boundary = boundary * letterBase + letterBase; + + if (boundary > int.MaxValue) + throw new ArgumentOutOfRangeException("Unsupported number: " + + toProcess); + } + } + maxPower--; + + for (int p = maxPower; p > 0; p--) + { + long boundary = 0; + long shift = 1; + for (int i = 0; i < p; i++) + { + shift *= letterBase; + boundary = boundary * letterBase + letterBase; + } + + int count = 0; + while (toProcess > boundary) + { + count++; + toProcess -= shift; + } + stringBuilder.Append(ENGLISH_LETTERS[count - 1]); + } + stringBuilder.Append(ENGLISH_LETTERS[(int)toProcess - 1]); + return stringBuilder.ToString(); + } + + private static String ToRoman(int number) + { + if (number <= 0) + throw new ArgumentOutOfRangeException("Unsupported number: " + number); + + StringBuilder result = new StringBuilder(); + + for (int i = 0; i < ROMAN_LETTERS.Length; i++) + { + String letter = ROMAN_LETTERS[i]; + int value = ROMAN_VALUES[i]; + while (number >= value) + { + number -= value; + result.Append(letter); + } + } + return result.ToString(); + } + } + +} diff --git a/scratchpad/HWPF/Converter/PicturesManager.cs b/scratchpad/HWPF/Converter/PicturesManager.cs new file mode 100644 index 0000000..d47bf8e --- /dev/null +++ b/scratchpad/HWPF/Converter/PicturesManager.cs @@ -0,0 +1,29 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using System; +using System.Collections.Generic; +using System.Text; +using NPOI.HWPF.UserModel; + +namespace NPOI.HWPF.Converter +{ + public interface PicturesManager + { + String SavePicture(byte[] content, PictureType pictureType, String suggestedName); + } +} diff --git a/scratchpad/HWPF/Converter/TextDocumentFacade.cs b/scratchpad/HWPF/Converter/TextDocumentFacade.cs new file mode 100644 index 0000000..455c60c --- /dev/null +++ b/scratchpad/HWPF/Converter/TextDocumentFacade.cs @@ -0,0 +1,191 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +namespace NPOI.HWPF.Converter +{ + using System; + using System.Xml; + using NPOI.Util; + + public class TextDocumentFacade + { + protected XmlElement body; + protected XmlDocument document; + protected XmlElement head; + protected XmlElement root; + + protected XmlElement title; + protected XmlText titleText; + + public TextDocumentFacade(XmlDocument document) + { + this.document = document; + + root = document.CreateElement("html"); + document.AppendChild(root); + + body = document.CreateElement("body"); + head = document.CreateElement("head"); + + root.AppendChild(head); + root.AppendChild(body); + + title = document.CreateElement("title"); + titleText = document.CreateTextNode(""); + head.AppendChild(title); + } + + public void AddAuthor(String value) + { + AddMeta("Author", value); + } + + public void AddDescription(String value) + { + AddMeta("Description", value); + } + + public void AddKeywords(String value) + { + AddMeta("Keywords", value); + } + + public void AddMeta(String name, String value) + { + XmlElement meta = document.CreateElement("meta"); + + XmlElement metaName = document.CreateElement("name"); + metaName.AppendChild(document.CreateTextNode(name + ": ")); + meta.AppendChild(metaName); + + XmlElement metaValue = document.CreateElement("value"); + metaValue.AppendChild(document.CreateTextNode(value + "\n")); + meta.AppendChild(metaValue); + + head.AppendChild(meta); + } + + public XmlElement CreateBlock() + { + return document.CreateElement("div"); + } + + public XmlElement CreateHeader1() + { + XmlElement result = document.CreateElement("h1"); + result.AppendChild(document.CreateTextNode(" ")); + return result; + } + + public XmlElement CreateHeader2() + { + XmlElement result = document.CreateElement("h2"); + result.AppendChild(document.CreateTextNode(" ")); + return result; + } + + public XmlElement CreateParagraph() + { + return document.CreateElement("p"); + } + + public XmlElement CreateTable() + { + return document.CreateElement("table"); + } + + public XmlElement CreateTableBody() + { + return document.CreateElement("tbody"); + } + + public XmlElement CreateTableCell() + { + return document.CreateElement("td"); + } + + public XmlElement CreateTableRow() + { + return document.CreateElement("tr"); + } + + public XmlText CreateText(String data) + { + return document.CreateTextNode(data); + } + + public XmlElement CreateUnorderedList() + { + return document.CreateElement("ul"); + } + + public XmlElement Body + { + get + { + return body; + } + } + + public XmlDocument Document + { + get + { + return document; + } + } + + public XmlElement Head + { + get + { + return head; + } + } + + public String Title + { + get + { + if (title == null) + return null; + + return titleText.InnerText; + } + set + { + if (string.IsNullOrEmpty(value) && this.title != null) + { + this.head.RemoveChild(this.title); + this.title = null; + this.titleText = null; + } + + if (this.title == null) + { + this.title = document.CreateElement("title"); + this.titleText = document.CreateTextNode(value); + this.title.AppendChild(this.titleText); + this.head.AppendChild(title); + } + + this.titleText.InnerText=(value); + } + } + + + } +} diff --git a/scratchpad/HWPF/Converter/WordToFoConverter.cs b/scratchpad/HWPF/Converter/WordToFoConverter.cs new file mode 100644 index 0000000..3d5781b --- /dev/null +++ b/scratchpad/HWPF/Converter/WordToFoConverter.cs @@ -0,0 +1,568 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +namespace NPOI.HWPF.Converter +{ + using System; + using System.Collections.Generic; + using System.Xml; + using NPOI.HPSF; + using NPOI.HWPF; + using NPOI.HWPF.UserModel; + using NPOI.Util; + + + /** + * @author Sergey Vladimirov (vlsergey {at} gmail {dot} com) + */ + + public class WordToFoConverter : AbstractWordConverter + { + + private static POILogger logger = POILogFactory.GetLogger(typeof(WordToFoConverter)); + + + public static XmlDocument Process(string docFile) + { + HWPFDocumentCore hwpfDocument = WordToFoUtils.LoadDoc(docFile); + WordToFoConverter wordToFoConverter = new WordToFoConverter(new XmlDocument()); + wordToFoConverter.ProcessDocument(hwpfDocument); + return wordToFoConverter.Document; + } + + private List endnotes = new List(0); + + protected FoDocumentFacade foDocumentFacade; + + private object objLinkCounter = new object(); + private int internalLinkCounter = 0; + + private bool outputCharactersLanguage = false; + + private LinkedList usedIds = new LinkedList(); + + /** + * Creates new instance of {@link WordToFoConverter}. Can be used for output + * several {@link HWPFDocument}s into single FO document. + * + * @param document + * XML DOM Document used as XSL FO document. Shall support + * namespaces + */ + public WordToFoConverter(XmlDocument document) + { + this.foDocumentFacade = new FoDocumentFacade(document); + } + + protected XmlElement CreateNoteInline(String noteIndexText) + { + XmlElement inline = foDocumentFacade.CreateInline(); + inline.InnerText = (noteIndexText); + inline.SetAttribute("baseline-shift", "super"); + inline.SetAttribute("font-size", "smaller"); + return inline; + } + + protected String CreatePageMaster(NPOI.HWPF.UserModel.Section section, String type, int sectionIndex) + { + float height = section.PageHeight / WordToFoUtils.TWIPS_PER_INCH; + float width = section.PageWidth / WordToFoUtils.TWIPS_PER_INCH; + float leftMargin = section.MarginLeft + / WordToFoUtils.TWIPS_PER_INCH; + float rightMargin = section.MarginRight + / WordToFoUtils.TWIPS_PER_INCH; + float topMargin = section.MarginTop / WordToFoUtils.TWIPS_PER_INCH; + float bottomMargin = section.MarginBottom + / WordToFoUtils.TWIPS_PER_INCH; + + // add these to the header + String pageMasterName = type + "-page" + sectionIndex; + + XmlElement pageMaster = foDocumentFacade.AddSimplePageMaster(pageMasterName); + pageMaster.SetAttribute("page-height", height + "in"); + pageMaster.SetAttribute("page-width", width + "in"); + + XmlElement regionBody = foDocumentFacade.AddRegionBody(pageMaster); + regionBody.SetAttribute("margin", topMargin + "in " + rightMargin + + "in " + bottomMargin + "in " + leftMargin + "in"); + + /* + * 6.4.14 fo:region-body + * + * The values of the padding and border-width traits must be "0". + */ + // WordToFoUtils.setBorder(regionBody, sep.getBrcTop(), "top"); + // WordToFoUtils.setBorder(regionBody, sep.getBrcBottom(), "bottom"); + // WordToFoUtils.setBorder(regionBody, sep.getBrcLeft(), "left"); + // WordToFoUtils.setBorder(regionBody, sep.getBrcRight(), "right"); + + if (section.NumColumns > 1) + { + regionBody.SetAttribute("column-count", "" + (section.NumColumns)); + if (section.IsColumnsEvenlySpaced) + { + float distance = section.DistanceBetweenColumns / WordToFoUtils.TWIPS_PER_INCH; + regionBody.SetAttribute("column-gap", distance + "in"); + } + else + { + regionBody.SetAttribute("column-gap", "0.25in"); + } + } + + return pageMasterName; + } + + public override XmlDocument Document + { + get + { + return foDocumentFacade.Document; + } + } + + public bool IsOutputCharactersLanguage() + { + return outputCharactersLanguage; + } + + protected override void OutputCharacters(XmlElement block, CharacterRun characterRun, + String text) + { + XmlElement inline = foDocumentFacade.CreateInline(); + + Triplet triplet = GetCharacterRunTriplet(characterRun); + + if (!string.IsNullOrEmpty(triplet.fontName)) + WordToFoUtils.SetFontFamily(inline, triplet.fontName); + WordToFoUtils.SetBold(inline, triplet.bold); + WordToFoUtils.SetItalic(inline, triplet.italic); + WordToFoUtils.SetFontSize(inline, characterRun.GetFontSize() / 2); + WordToFoUtils.SetCharactersProperties(characterRun, inline); + + if (IsOutputCharactersLanguage()) + WordToFoUtils.SetLanguage(characterRun, inline); + + block.AppendChild(inline); + + XmlText textNode = foDocumentFacade.CreateText(text); + inline.AppendChild(textNode); + } + + protected override void ProcessBookmarks(HWPFDocumentCore wordDocument, + XmlElement currentBlock, Range range, int currentTableLevel, + IList rangeBookmarks) + { + XmlElement parent = currentBlock; + foreach (Bookmark bookmark in rangeBookmarks) + { + XmlElement bookmarkElement = foDocumentFacade.CreateInline(); + String idName = "bookmark_" + bookmark.Name; + // make sure ID used once + if (SetId(bookmarkElement, idName)) + { + /* + * if it just empty fo:inline without "id" attribute doesn't + * making sense to add it to DOM + */ + parent.AppendChild(bookmarkElement); + parent = bookmarkElement; + } + } + + if (range != null) + ProcessCharacters(wordDocument, currentTableLevel, range, parent); + } + + protected override void ProcessDocumentInformation(SummaryInformation summaryInformation) + { + if (!string.IsNullOrEmpty(summaryInformation.Title)) + foDocumentFacade.SetTitle(summaryInformation.Title); + + if (!string.IsNullOrEmpty(summaryInformation.Author)) + foDocumentFacade.SetCreator(summaryInformation.Author); + + if (!string.IsNullOrEmpty(summaryInformation.Keywords)) + foDocumentFacade.SetKeywords(summaryInformation.Keywords); + + if (!string.IsNullOrEmpty(summaryInformation.Comments)) + foDocumentFacade.SetDescription(summaryInformation.Comments); + } + + protected override void ProcessDrawnObject(HWPFDocument doc, + CharacterRun characterRun, OfficeDrawing officeDrawing, + String path, XmlElement block) + { + XmlElement externalGraphic = foDocumentFacade.CreateExternalGraphic(path); + block.AppendChild(externalGraphic); + } + + protected override void ProcessEndnoteAutonumbered(HWPFDocument wordDocument, + int noteIndex, XmlElement block, Range endnoteTextRange) + { + String textIndex;// = (internalLinkCounter.incrementAndGet()).ToString(); + lock (objLinkCounter) + { + internalLinkCounter++; + + textIndex = internalLinkCounter.ToString(); + } + String forwardLinkName = "endnote_" + textIndex; + String backwardLinkName = "endnote_back_" + textIndex; + + XmlElement forwardLink = foDocumentFacade + .CreateBasicLinkInternal(forwardLinkName); + forwardLink.AppendChild(CreateNoteInline(textIndex)); + SetId(forwardLink, backwardLinkName); + block.AppendChild(forwardLink); + + XmlElement endnote = foDocumentFacade.CreateBlock(); + XmlElement backwardLink = foDocumentFacade + .CreateBasicLinkInternal(backwardLinkName); + backwardLink.AppendChild(CreateNoteInline(textIndex + " ")); + SetId(backwardLink, forwardLinkName); + endnote.AppendChild(backwardLink); + + ProcessCharacters(wordDocument, int.MinValue, endnoteTextRange, endnote); + + WordToFoUtils.CompactInlines(endnote); + this.endnotes.Add(endnote); + } + + protected override void ProcessFootnoteAutonumbered(HWPFDocument wordDocument, + int noteIndex, XmlElement block, Range footnoteTextRange) + { + String textIndex;// = (internalLinkCounter.incrementAndGet()).ToString(); + lock (objLinkCounter) + { + internalLinkCounter++; + + textIndex = internalLinkCounter.ToString(); + } + String forwardLinkName = "footnote_" + textIndex; + String backwardLinkName = "footnote_back_" + textIndex; + + XmlElement footNote = foDocumentFacade.CreateFootnote(); + block.AppendChild(footNote); + + XmlElement inline = foDocumentFacade.CreateInline(); + XmlElement forwardLink = foDocumentFacade + .CreateBasicLinkInternal(forwardLinkName); + forwardLink.AppendChild(CreateNoteInline(textIndex)); + SetId(forwardLink, backwardLinkName); + inline.AppendChild(forwardLink); + footNote.AppendChild(inline); + + XmlElement footnoteBody = foDocumentFacade.CreateFootnoteBody(); + XmlElement footnoteBlock = foDocumentFacade.CreateBlock(); + XmlElement backwardLink = foDocumentFacade + .CreateBasicLinkInternal(backwardLinkName); + backwardLink.AppendChild(CreateNoteInline(textIndex + " ")); + SetId(backwardLink, forwardLinkName); + footnoteBlock.AppendChild(backwardLink); + footnoteBody.AppendChild(footnoteBlock); + footNote.AppendChild(footnoteBody); + + ProcessCharacters(wordDocument, int.MinValue, footnoteTextRange, footnoteBlock); + + WordToFoUtils.CompactInlines(footnoteBlock); + } + + protected override void ProcessHyperlink(HWPFDocumentCore wordDocument, + XmlElement currentBlock, Range textRange, int currentTableLevel, + String hyperlink) + { + XmlElement basicLink = foDocumentFacade + .CreateBasicLinkExternal(hyperlink); + currentBlock.AppendChild(basicLink); + + if (textRange != null) + ProcessCharacters(wordDocument, currentTableLevel, textRange, basicLink); + } + + /** + * This method shall store image bytes in external file and convert it if + * necessary. Images shall be stored using PNG format (for bitmap) or SVG + * (for vector). Other formats may be not supported by your XSL FO + * processor. + *

+ * Please note the + * {@link WordToFoUtils#setPictureProperties(Picture, XmlElement)} method. + * + * @param currentBlock + * currently processed FO element, like fo:block. Shall + * be used as parent of newly created + * fo:external-graphic or + * fo:instream-foreign-object + * @param inlined + * if image is inlined + * @param picture + * HWPF object, contained picture data and properties + */ + protected override void ProcessImage(XmlElement currentBlock, bool inlined, + Picture picture) + { + PicturesManager fileManager = GetPicturesManager(); + if (fileManager != null) + { + String url = fileManager + .SavePicture(picture.GetContent(), + picture.SuggestPictureType(), + picture.SuggestFullFileName()); + + if (!string.IsNullOrEmpty(url)) + { + ProcessImage(currentBlock, inlined, picture, url); + return; + } + } + + // no default implementation -- skip + currentBlock.AppendChild(foDocumentFacade.Document + .CreateComment("Image link to '" + + picture.SuggestFullFileName() + "' can be here")); + } + + protected void ProcessImage(XmlElement currentBlock, bool inlined, + Picture picture, String url) + { + XmlElement externalGraphic = foDocumentFacade + .CreateExternalGraphic(url); + WordToFoUtils.SetPictureProperties(picture, externalGraphic); + currentBlock.AppendChild(externalGraphic); + } + + protected override void ProcessLineBreak(XmlElement block, CharacterRun characterRun) + { + block.AppendChild(foDocumentFacade.CreateBlock()); + } + + protected override void ProcessPageBreak(HWPFDocumentCore wordDocument, XmlElement flow) + { + XmlElement block = null; + XmlNodeList childNodes = flow.ChildNodes; + if (childNodes.Count > 0) + { + XmlNode lastChild = childNodes[childNodes.Count - 1]; + if (lastChild is XmlElement) + { + XmlElement lastElement = (XmlElement)lastChild; + if (!lastElement.HasAttribute("break-after")) + { + block = lastElement; + } + } + } + + if (block == null) + { + block = foDocumentFacade.CreateBlock(); + flow.AppendChild(block); + } + block.SetAttribute("break-after", "page"); + } + + protected override void ProcessPageref(HWPFDocumentCore hwpfDocument, + XmlElement currentBlock, Range textRange, int currentTableLevel, + String pageref) + { + XmlElement basicLink = foDocumentFacade + .CreateBasicLinkInternal("bookmark_" + pageref); + currentBlock.AppendChild(basicLink); + + if (textRange != null) + ProcessCharacters(hwpfDocument, currentTableLevel, textRange, + basicLink); + } + + protected override void ProcessParagraph(HWPFDocumentCore hwpfDocument, + XmlElement parentFopElement, int currentTableLevel, + Paragraph paragraph, String bulletText) + { + XmlElement block = foDocumentFacade.CreateBlock(); + parentFopElement.AppendChild(block); + + WordToFoUtils.SetParagraphProperties(paragraph, block); + + int charRuns = paragraph.NumCharacterRuns; + + if (charRuns == 0) + { + return; + } + + bool haveAnyText = false; + + if (!string.IsNullOrEmpty(bulletText)) + { + XmlElement inline = foDocumentFacade.CreateInline(); + block.AppendChild(inline); + + XmlText textNode = foDocumentFacade.CreateText(bulletText); + inline.AppendChild(textNode); + + haveAnyText |= bulletText.Trim().Length != 0; + } + + haveAnyText = ProcessCharacters(hwpfDocument, currentTableLevel, paragraph, block); + + if (!haveAnyText) + { + XmlElement leader = foDocumentFacade.CreateLeader(); + block.AppendChild(leader); + } + + WordToFoUtils.CompactInlines(block); + return; + } + + protected override void ProcessSection(HWPFDocumentCore wordDocument, + NPOI.HWPF.UserModel.Section section, int sectionCounter) + { + String regularPage = CreatePageMaster(section, "page", sectionCounter); + + XmlElement pageSequence = foDocumentFacade.AddPageSequence(regularPage); + XmlElement flow = foDocumentFacade.AddFlowToPageSequence(pageSequence, "xsl-region-body"); + + ProcessParagraphes(wordDocument, flow, section, int.MinValue); + + if (endnotes != null && endnotes.Count != 0) + { + foreach (XmlElement endnote in endnotes) + flow.AppendChild(endnote); + endnotes.Clear(); + } + } + + protected override void ProcessTable(HWPFDocumentCore wordDocument, XmlElement flow, + Table table) + { + XmlElement tableHeader = foDocumentFacade.CreateTableHeader(); + XmlElement tableBody = foDocumentFacade.CreateTableBody(); + + int[] tableCellEdges = WordToHtmlUtils.BuildTableCellEdgesArray(table); + int tableRows = table.NumRows; + + int maxColumns = int.MinValue; + for (int r = 0; r < tableRows; r++) + { + maxColumns = Math.Max(maxColumns, table.GetRow(r).NumCells()); + } + + for (int r = 0; r < tableRows; r++) + { + TableRow tableRow = table.GetRow(r); + + XmlElement tableRowElement = foDocumentFacade.CreateTableRow(); + WordToFoUtils.SetTableRowProperties(tableRow, tableRowElement); + + // index of current element in tableCellEdges[] + int currentEdgeIndex = 0; + int rowCells = tableRow.NumCells(); + for (int c = 0; c < rowCells; c++) + { + TableCell tableCell = tableRow.GetCell(c); + + if (tableCell.IsVerticallyMerged() && !tableCell.IsFirstVerticallyMerged()) + { + currentEdgeIndex += getTableCellEdgesIndexSkipCount(table, + r, tableCellEdges, currentEdgeIndex, c, tableCell); + continue; + } + + XmlElement tableCellElement = foDocumentFacade.CreateTableCell(); + WordToFoUtils.SetTableCellProperties(tableRow, tableCell, + tableCellElement, r == 0, r == tableRows - 1, c == 0, + c == rowCells - 1); + + int colSpan = GetNumberColumnsSpanned(tableCellEdges, + currentEdgeIndex, tableCell); + currentEdgeIndex += colSpan; + + if (colSpan == 0) + continue; + + if (colSpan != 1) + tableCellElement.SetAttribute("number-columns-spanned", (colSpan).ToString()); + + int rowSpan = GetNumberRowsSpanned(table, r, c, tableCell); + if (rowSpan > 1) + tableCellElement.SetAttribute("number-rows-spanned", (rowSpan).ToString()); + + ProcessParagraphes(wordDocument, tableCellElement, tableCell, + table.TableLevel); + + if (!tableCellElement.HasChildNodes) + { + tableCellElement.AppendChild(foDocumentFacade + .CreateBlock()); + } + + tableRowElement.AppendChild(tableCellElement); + } + + if (tableRowElement.HasChildNodes) + { + if (tableRow.isTableHeader()) + { + tableHeader.AppendChild(tableRowElement); + } + else + { + tableBody.AppendChild(tableRowElement); + } + } + } + + XmlElement tableElement = foDocumentFacade.CreateTable(); + tableElement.SetAttribute("table-layout", "fixed"); + if (tableHeader.HasChildNodes) + { + tableElement.AppendChild(tableHeader); + } + if (tableBody.HasChildNodes) + { + tableElement.AppendChild(tableBody); + flow.AppendChild(tableElement); + } + else + { + logger.Log(POILogger.WARN, "Table without body starting on offset " + table.StartOffset + " -- " + table.EndOffset); + } + } + + protected bool SetId(XmlElement element, String id) + { + // making sure ID used once + if (usedIds.Contains(id)) + { + logger.Log(POILogger.WARN, + "Tried to create element with same ID '", id, "'. Skipped"); + return false; + } + + element.SetAttribute("id", id); + usedIds.AddLast(id); + return true; + } + + public void SetOutputCharactersLanguage(bool outputCharactersLanguage) + { + this.outputCharactersLanguage = outputCharactersLanguage; + } + + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/Converter/WordToFoUtils.cs b/scratchpad/HWPF/Converter/WordToFoUtils.cs new file mode 100644 index 0000000..6bc12ca --- /dev/null +++ b/scratchpad/HWPF/Converter/WordToFoUtils.cs @@ -0,0 +1,329 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +namespace NPOI.HWPF.Converter +{ + using System; + using System.Collections.Generic; + using System.Xml; + using NPOI.HWPF; + using System.Text; + using NPOI.HWPF.UserModel; + public class WordToFoUtils : AbstractWordUtils + { + public static void CompactInlines(XmlElement blockXmlElement) + { + CompactChildNodesR(blockXmlElement, "fo:inline"); + } + + public static void SetBold(XmlElement XmlElement, bool bold) + { + XmlElement.SetAttribute("font-weight", bold ? "bold" : "normal"); + } + + public static void SetBorder(XmlElement XmlElement, BorderCode borderCode, String where) + { + if (XmlElement == null) + throw new ArgumentException("XmlElement is null"); + + if (borderCode == null || borderCode.BorderType == 0) + return; + + if (string.IsNullOrEmpty(where)) + { + XmlElement.SetAttribute("border-style", GetBorderType(borderCode)); + XmlElement.SetAttribute("border-color", + GetColor(borderCode.Color)); + XmlElement.SetAttribute("border-width", GetBorderWidth(borderCode)); + } + else + { + XmlElement.SetAttribute("border-" + where + "-style", + GetBorderType(borderCode)); + XmlElement.SetAttribute("border-" + where + "-color", + GetColor(borderCode.Color)); + XmlElement.SetAttribute("border-" + where + "-width", + GetBorderWidth(borderCode)); + } + } + + public static void SetCharactersProperties(CharacterRun characterRun, XmlElement inline) + { + StringBuilder textDecorations = new StringBuilder(); + + SetBorder(inline, characterRun.GetBorder(), string.Empty); + + if (characterRun.GetIco24() != -1) + { + inline.SetAttribute("color", GetColor24(characterRun.GetIco24())); + } + int opacity = (int)(characterRun.GetIco24() & 0xFF000000L) >> 24; + if (opacity != 0 && opacity != 0xFF) + { + inline.SetAttribute("opacity", + GetOpacity(characterRun.GetIco24())); + } + if (characterRun.IsCapitalized()) + { + inline.SetAttribute("text-transform", "uppercase"); + } + if (characterRun.isHighlighted()) + { + inline.SetAttribute("background-color", + GetColor(characterRun.GetHighlightedColor())); + } + if (characterRun.IsStrikeThrough()) + { + if (textDecorations.Length > 0) + textDecorations.Append(" "); + textDecorations.Append("line-through"); + } + if (characterRun.IsShadowed()) + { + inline.SetAttribute("text-shadow", characterRun.GetFontSize() / 24 + "pt"); + } + if (characterRun.IsSmallCaps()) + { + inline.SetAttribute("font-variant", "small-caps"); + } + if (characterRun.GetSubSuperScriptIndex() == 1) + { + inline.SetAttribute("baseline-shift", "super"); + inline.SetAttribute("font-size", "smaller"); + } + if (characterRun.GetSubSuperScriptIndex() == 2) + { + inline.SetAttribute("baseline-shift", "sub"); + inline.SetAttribute("font-size", "smaller"); + } + if (characterRun.GetUnderlineCode() > 0) + { + if (textDecorations.Length > 0) + textDecorations.Append(" "); + textDecorations.Append("underline"); + } + if (characterRun.IsVanished()) + { + inline.SetAttribute("visibility", "hidden"); + } + if (textDecorations.Length > 0) + { + inline.SetAttribute("text-decoration", textDecorations.ToString()); + } + } + + public static void SetFontFamily(XmlElement XmlElement, String fontFamily) + { + if (string.IsNullOrEmpty(fontFamily)) + return; + + XmlElement.SetAttribute("font-family", fontFamily); + } + + public static void SetFontSize(XmlElement XmlElement, int fontSize) + { + XmlElement.SetAttribute("font-size", fontSize.ToString()); + } + + public static void SetIndent(Paragraph paragraph, XmlElement block) + { + if (paragraph.GetFirstLineIndent() != 0) + { + block.SetAttribute( + "text-indent", + (paragraph.GetFirstLineIndent() / TWIPS_PER_PT).ToString() + "pt"); + } + if (paragraph.GetIndentFromLeft() != 0) + { + block.SetAttribute( + "start-indent", + (paragraph.GetIndentFromLeft() / TWIPS_PER_PT).ToString() + "pt"); + } + if (paragraph.GetIndentFromRight() != 0) + { + block.SetAttribute( + "end-indent", + (paragraph.GetIndentFromRight() / TWIPS_PER_PT).ToString() + "pt"); + } + if (paragraph.GetSpacingBefore() != 0) + { + block.SetAttribute( + "space-before", + (paragraph.GetSpacingBefore() / TWIPS_PER_PT).ToString() + "pt"); + } + if (paragraph.GetSpacingAfter() != 0) + { + block.SetAttribute("space-after", + (paragraph.GetSpacingAfter() / TWIPS_PER_PT) + "pt"); + } + } + + public static void SetItalic(XmlElement XmlElement, bool italic) + { + XmlElement.SetAttribute("font-style", italic ? "italic" : "normal"); + } + + public static void SetJustification(Paragraph paragraph, + XmlElement XmlElement) + { + String justification = GetJustification(paragraph.GetJustification()); + if (!string.IsNullOrEmpty(justification)) + XmlElement.SetAttribute("text-align", justification); + } + + public static void SetLanguage(CharacterRun characterRun, XmlElement inline) + { + if (characterRun.getLanguageCode() != 0) + { + String language = GetLanguage(characterRun.getLanguageCode()); + if (!string.IsNullOrEmpty(language)) + inline.SetAttribute("language", language); + } + } + + public static void SetParagraphProperties(Paragraph paragraph, XmlElement block) + { + SetIndent(paragraph, block); + SetJustification(paragraph, block); + + SetBorder(block, paragraph.GetBottomBorder(), "bottom"); + SetBorder(block, paragraph.GetLeftBorder(), "left"); + SetBorder(block, paragraph.GetRightBorder(), "right"); + SetBorder(block, paragraph.GetTopBorder(), "top"); + + if (paragraph.PageBreakBefore()) + { + block.SetAttribute("break-before", "page"); + } + + block.SetAttribute("hyphenate", paragraph.IsAutoHyphenated.ToString()); + + if (paragraph.KeepOnPage()) + { + block.SetAttribute("keep-together.within-page", "always"); + } + + if (paragraph.KeepWithNext()) + { + block.SetAttribute("keep-with-next.within-page", "always"); + } + + block.SetAttribute("linefeed-treatment", "preserve"); + block.SetAttribute("white-space-collapse", "false"); + } + + public static void SetPictureProperties(Picture picture, XmlElement graphicXmlElement) + { + int horizontalScale = picture.HorizontalScalingFactor; + int verticalScale = picture.VerticalScalingFactor; + + if (horizontalScale > 0) + { + graphicXmlElement + .SetAttribute("content-width", ((picture.DxaGoal + * horizontalScale / 1000) / TWIPS_PER_PT) + + "pt"); + } + else + graphicXmlElement.SetAttribute("content-width", + (picture.DxaGoal / TWIPS_PER_PT) + "pt"); + + if (verticalScale > 0) + graphicXmlElement + .SetAttribute("content-height", ((picture.DyaGoal + * verticalScale / 1000) / TWIPS_PER_PT) + + "pt"); + else + graphicXmlElement.SetAttribute("content-height", + (picture.DyaGoal / TWIPS_PER_PT) + "pt"); + + if (horizontalScale <= 0 || verticalScale <= 0) + { + graphicXmlElement.SetAttribute("scaling", "uniform"); + } + else + { + graphicXmlElement.SetAttribute("scaling", "non-uniform"); + } + + graphicXmlElement.SetAttribute("vertical-align", "text-bottom"); + + if (picture.DyaCropTop != 0 || picture.DxaCropRight != 0 + || picture.DyaCropBottom != 0 + || picture.DxaCropLeft != 0) + { + int rectTop = picture.DyaCropTop / TWIPS_PER_PT; + int rectRight = picture.DxaCropRight / TWIPS_PER_PT; + int rectBottom = picture.DyaCropBottom / TWIPS_PER_PT; + int rectLeft = picture.DxaCropLeft / TWIPS_PER_PT; + graphicXmlElement.SetAttribute("clip", "rect(" + rectTop + "pt, " + + rectRight + "pt, " + rectBottom + "pt, " + rectLeft + + "pt)"); + graphicXmlElement.SetAttribute("overflow", "hidden"); + } + } + + public static void SetTableCellProperties(TableRow tableRow, + TableCell tableCell, XmlElement XmlElement, bool toppest, + bool bottomest, bool leftest, bool rightest) + { + XmlElement.SetAttribute("width", (tableCell.GetWidth() / TWIPS_PER_INCH) + + "in"); + XmlElement.SetAttribute("padding-start", + (tableRow.GetGapHalf() / TWIPS_PER_INCH) + "in"); + XmlElement.SetAttribute("padding-end", + (tableRow.GetGapHalf() / TWIPS_PER_INCH) + "in"); + + BorderCode top = tableCell.GetBrcTop() != null + && tableCell.GetBrcTop().BorderType != 0 ? tableCell + .GetBrcTop() : toppest ? tableRow.GetTopBorder() : tableRow + .GetHorizontalBorder(); + BorderCode bottom = tableCell.GetBrcBottom() != null + && tableCell.GetBrcBottom().BorderType != 0 ? tableCell + .GetBrcBottom() : bottomest ? tableRow.GetBottomBorder() + : tableRow.GetHorizontalBorder(); + + BorderCode left = tableCell.GetBrcLeft() != null + && tableCell.GetBrcLeft().BorderType != 0 ? tableCell + .GetBrcLeft() : leftest ? tableRow.GetLeftBorder() : tableRow + .GetVerticalBorder(); + BorderCode right = tableCell.GetBrcRight() != null + && tableCell.GetBrcRight().BorderType != 0 ? tableCell + .GetBrcRight() : rightest ? tableRow.GetRightBorder() + : tableRow.GetVerticalBorder(); + + SetBorder(XmlElement, bottom, "bottom"); + SetBorder(XmlElement, left, "left"); + SetBorder(XmlElement, right, "right"); + SetBorder(XmlElement, top, "top"); + } + + public static void SetTableRowProperties(TableRow tableRow, XmlElement tableRowXmlElement) + { + if (tableRow.GetRowHeight() > 0) + { + tableRowXmlElement.SetAttribute("height", + (tableRow.GetRowHeight() / TWIPS_PER_INCH) + "in"); + } + if (!tableRow.cantSplit()) + { + tableRowXmlElement.SetAttribute("keep-together.within-column", + "always"); + } + } + + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/Converter/WordToHtmlConverter.cs b/scratchpad/HWPF/Converter/WordToHtmlConverter.cs new file mode 100644 index 0000000..e09e753 --- /dev/null +++ b/scratchpad/HWPF/Converter/WordToHtmlConverter.cs @@ -0,0 +1,575 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using System; +using System.Collections.Generic; +using System.Text; +using NPOI.Util; +using NPOI.HWPF.UserModel; +using System.Xml; + +namespace NPOI.HWPF.Converter +{ + /** + * Converts Word files (95-2007) into HTML files. + *

+ * This implementation doesn't create images or links to them. This can be + * changed by overriding {@link #processImage(XmlElement, boolean, Picture)} + * method. + * + * @author Sergey Vladimirov (vlsergey {at} gmail {dot} com) + */ + ///

+ /// Beta + /// + public class WordToHtmlConverter : AbstractWordConverter + { + /** + * Holds properties values, applied to current p element. Those + * properties shall not be doubled in children span elements. + */ + private class BlockProperies + { + public String pFontName; + public int pFontSize; + + public BlockProperies(String pFontName, int pFontSize) + { + this.pFontName = pFontName; + this.pFontSize = pFontSize; + } + } + + private static POILogger logger = POILogFactory.GetLogger(typeof(WordToHtmlConverter)); + + private static String GetSectionStyle(Section section) + { + float leftMargin = section.MarginLeft / AbstractWordUtils.TWIPS_PER_INCH; + float rightMargin = section.MarginRight / AbstractWordUtils.TWIPS_PER_INCH; + float topMargin = section.MarginTop / AbstractWordUtils.TWIPS_PER_INCH; + float bottomMargin = section.MarginBottom / AbstractWordUtils.TWIPS_PER_INCH; + + String style = "margin: " + topMargin + "in " + rightMargin + "in " + + bottomMargin + "in " + leftMargin + "in;"; + + if (section.NumColumns > 1) + { + style += "column-count: " + (section.NumColumns) + ";"; + if (section.IsColumnsEvenlySpaced) + { + float distance = section.DistanceBetweenColumns / AbstractWordUtils.TWIPS_PER_INCH; + style += "column-gap: " + distance + "in;"; + } + else + { + style += "column-gap: 0.25in;"; + } + } + return style; + } + + public static XmlDocument Process(string docFile) + { + HWPFDocumentCore wordDocument = WordToHtmlUtils.LoadDoc(docFile); + XmlDocument xmlDoc = new XmlDocument(); + //WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(xmlDoc); + // wordToHtmlConverter.ProcessDocument(wordDocument); + return xmlDoc; + } + + private Stack blocksProperies = new Stack(); + + private HtmlDocumentFacade htmlDocumentFacade; + + private XmlElement notes = null; + + /** + * Creates new instance of {@link WordToHtmlConverter}. Can be used for + * output several {@link HWPFDocument}s into single HTML document. + * + * @param document + * XML DOM Document used as HTML document + */ + public WordToHtmlConverter(XmlDocument document) + { + this.htmlDocumentFacade = new HtmlDocumentFacade(document); + } + + protected override void AfterProcess() + { + if (notes != null) + htmlDocumentFacade.Body.AppendChild(notes); + + htmlDocumentFacade.UpdateStylesheet(); + } + + public override XmlDocument Document + { + get + { + return htmlDocumentFacade.Document; + } + } + + protected override void OutputCharacters(XmlElement pElement, CharacterRun characterRun, string text) + { + XmlElement span = htmlDocumentFacade.Document.CreateElement("span"); + pElement.AppendChild(span); + + StringBuilder style = new StringBuilder(); + BlockProperies blockProperies = this.blocksProperies.Peek(); + Triplet triplet = GetCharacterRunTriplet(characterRun); + + if (!string.IsNullOrEmpty(triplet.fontName) + && !WordToHtmlUtils.Equals(triplet.fontName, + blockProperies.pFontName)) + { + style.Append("font-family:" + triplet.fontName + ";"); + } + if (characterRun.GetFontSize() / 2 != blockProperies.pFontSize) + { + style.Append("font-size:" + characterRun.GetFontSize() / 2 + "pt;"); + } + if (triplet.bold) + { + style.Append("font-weight:bold;"); + } + if (triplet.italic) + { + style.Append("font-style:italic;"); + } + + WordToHtmlUtils.AddCharactersProperties(characterRun, style); + if (style.Length != 0) + htmlDocumentFacade.AddStyleClass(span, "s", style.ToString()); + + XmlText textNode = htmlDocumentFacade.CreateText(text); + span.AppendChild(textNode); + } + + protected override void ProcessBookmarks(HWPFDocumentCore wordDocument, XmlElement currentBlock, Range range, int currentTableLevel, IList rangeBookmarks) + { + XmlElement parent = currentBlock; + foreach (Bookmark bookmark in rangeBookmarks) + { + XmlElement bookmarkElement = htmlDocumentFacade.CreateBookmark(bookmark.Name); + parent.AppendChild(bookmarkElement); + parent = bookmarkElement; + } + + if (range != null) + ProcessCharacters(wordDocument, currentTableLevel, range, parent); + throw new NotImplementedException(); + } + + protected override void ProcessDocumentInformation(NPOI.HPSF.SummaryInformation summaryInformation) + { + if (!string.IsNullOrEmpty(summaryInformation.Title)) + htmlDocumentFacade.Title = summaryInformation.Title; + + if (!string.IsNullOrEmpty(summaryInformation.Author)) + htmlDocumentFacade.AddAuthor(summaryInformation.Author); + + if (!string.IsNullOrEmpty(summaryInformation.Keywords)) + htmlDocumentFacade.AddKeywords(summaryInformation.Keywords); + + if (!string.IsNullOrEmpty(summaryInformation.Comments)) + htmlDocumentFacade.AddDescription(summaryInformation.Comments); + } + public void processDocumentPart(HWPFDocumentCore wordDocument, Range range) + { + base.ProcessDocumentPart(wordDocument, range); + AfterProcess(); + } + protected override void ProcessDrawnObject(HWPFDocument doc, CharacterRun characterRun, OfficeDrawing officeDrawing, string path, XmlElement block) + { + XmlElement img = htmlDocumentFacade.CreateImage(path); + block.AppendChild(img); + } + + protected override void ProcessEndnoteAutonumbered(HWPFDocument wordDocument, int noteIndex, XmlElement block, Range endnoteTextRange) + { + ProcessNoteAutonumbered(wordDocument, "end", noteIndex, block, endnoteTextRange); + } + + private void ProcessNoteAutonumbered(HWPFDocument wordDocument, string type, int noteIndex, XmlElement block, Range noteTextRange) + { + String textIndex = (noteIndex + 1).ToString(); + String textIndexClass = htmlDocumentFacade.GetOrCreateCssClass("a", "a", "vertical-align:super;font-size:smaller;"); + String forwardNoteLink = type + "note_" + textIndex; + String backwardNoteLink = type + "note_back_" + textIndex; + + XmlElement anchor = htmlDocumentFacade.CreateHyperlink("#" + forwardNoteLink); + anchor.SetAttribute("name", backwardNoteLink); + anchor.SetAttribute("class", textIndexClass + " " + type + "noteanchor"); + anchor.InnerText = textIndex; + block.AppendChild(anchor); + + if (notes == null) + { + notes = htmlDocumentFacade.CreateBlock(); + notes.SetAttribute("class", "notes"); + } + + XmlElement note = htmlDocumentFacade.CreateBlock(); + note.SetAttribute("class", type + "note"); + notes.AppendChild(note); + + XmlElement bookmark = htmlDocumentFacade.CreateBookmark(forwardNoteLink); + bookmark.SetAttribute("href", "#" + backwardNoteLink); + bookmark.InnerText = (textIndex); + bookmark.SetAttribute("class", textIndexClass + " " + type + "noteindex"); + note.AppendChild(bookmark); + note.AppendChild(htmlDocumentFacade.CreateText(" ")); + + XmlElement span = htmlDocumentFacade.Document.CreateElement("span"); + span.SetAttribute("class", type + "notetext"); + note.AppendChild(span); + + this.blocksProperies.Push(new BlockProperies("", -1)); + try + { + ProcessCharacters(wordDocument, int.MinValue, noteTextRange, span); + } + finally + { + this.blocksProperies.Pop(); + } + } + + protected override void ProcessFootnoteAutonumbered(HWPFDocument wordDocument, int noteIndex, XmlElement block, Range footnoteTextRange) + { + ProcessNoteAutonumbered(wordDocument, "foot", noteIndex, block, footnoteTextRange); + } + + protected override void ProcessHyperlink(HWPFDocumentCore wordDocument, XmlElement currentBlock, Range textRange, int currentTableLevel, string hyperlink) + { + XmlElement basicLink = htmlDocumentFacade.CreateHyperlink(hyperlink); + currentBlock.AppendChild(basicLink); + + if (textRange != null) + ProcessCharacters(wordDocument, currentTableLevel, textRange, basicLink); + } + /** + * This method shall store image bytes in external file and convert it if + * necessary. Images shall be stored using PNG format. Other formats may be + * not supported by user browser. + *

+ * Please note the {@link #processImage(XmlElement, boolean, Picture, String)}. + * + * @param currentBlock + * currently processed HTML element, like p. Shall be + * used as parent of newly created img + * @param inlined + * if image is inlined + * @param picture + * HWPF object, contained picture data and properties + */ + protected override void ProcessImage(XmlElement currentBlock, bool inlined, Picture picture) + { + PicturesManager fileManager = GetPicturesManager(); + if (fileManager != null) + { + String url = fileManager + .SavePicture(picture.GetContent(), + picture.SuggestPictureType(), + picture.SuggestFullFileName()); + + if (!string.IsNullOrEmpty(url)) + { + ProcessImage(currentBlock, inlined, picture, url); + return; + } + } + + // no default implementation -- skip + currentBlock.AppendChild(htmlDocumentFacade.Document + .CreateComment("Image link to '" + + picture.SuggestFullFileName() + "' can be here")); + } + protected void ProcessImage(XmlElement currentBlock, bool inlined, + Picture picture, String imageSourcePath) + { + int aspectRatioX = picture.HorizontalScalingFactor; + int aspectRatioY = picture.VerticalScalingFactor; + + StringBuilder style = new StringBuilder(); + + float imageWidth; + float imageHeight; + + float cropTop; + float cropBottom; + float cropLeft; + float cropRight; + + if (aspectRatioX > 0) + { + imageWidth = picture.DxaGoal * aspectRatioX / 1000 + / AbstractWordUtils.TWIPS_PER_INCH; + cropRight = picture.DxaCropRight * aspectRatioX / 1000 + / AbstractWordUtils.TWIPS_PER_INCH; + cropLeft = picture.DxaCropLeft * aspectRatioX / 1000 + / AbstractWordUtils.TWIPS_PER_INCH; + } + else + { + imageWidth = picture.DxaGoal / AbstractWordUtils.TWIPS_PER_INCH; + cropRight = picture.DxaCropRight / AbstractWordUtils.TWIPS_PER_INCH; + cropLeft = picture.DxaCropLeft / AbstractWordUtils.TWIPS_PER_INCH; + } + + if (aspectRatioY > 0) + { + imageHeight = picture.DyaGoal * aspectRatioY / 1000 + / AbstractWordUtils.TWIPS_PER_INCH; + cropTop = picture.DyaCropTop * aspectRatioY / 1000 + / AbstractWordUtils.TWIPS_PER_INCH; + cropBottom = picture.DyaCropBottom * aspectRatioY / 1000 + / AbstractWordUtils.TWIPS_PER_INCH; + } + else + { + imageHeight = picture.DyaGoal / AbstractWordUtils.TWIPS_PER_INCH; + cropTop = picture.DyaCropTop / AbstractWordUtils.TWIPS_PER_INCH; + cropBottom = picture.DyaCropBottom / AbstractWordUtils.TWIPS_PER_INCH; + } + + XmlElement root; + if (cropTop != 0 || cropRight != 0 || cropBottom != 0 || cropLeft != 0) + { + float visibleWidth = Math.Max(0, imageWidth - cropLeft - cropRight); + float visibleHeight = Math.Max(0, imageHeight - cropTop - cropBottom); + + root = htmlDocumentFacade.CreateBlock(); + htmlDocumentFacade.AddStyleClass(root, "d", "vertical-align:text-bottom;width:" + visibleWidth + "in;height:" + visibleHeight + "in;"); + + // complex + XmlElement inner = htmlDocumentFacade.CreateBlock(); + htmlDocumentFacade.AddStyleClass(inner, "d", "position:relative;width:" + visibleWidth + "in;height:" + visibleHeight + "in;overflow:hidden;"); + root.AppendChild(inner); + + XmlElement image = htmlDocumentFacade.CreateImage(imageSourcePath); + htmlDocumentFacade.AddStyleClass(image, "i", "position:absolute;left:-" + cropLeft + ";top:-" + cropTop + ";width:" + imageWidth + "in;height:" + imageHeight + "in;"); + inner.AppendChild(image); + + style.Append("overflow:hidden;"); + } + else + { + root = htmlDocumentFacade.CreateImage(imageSourcePath); + root.SetAttribute("style", "width:" + imageWidth + "in;height:" + imageHeight + "in;vertical-align:text-bottom;"); + } + + currentBlock.AppendChild(root); + } + protected override void ProcessLineBreak(XmlElement block, CharacterRun characterRun) + { + block.AppendChild(htmlDocumentFacade.CreateLineBreak()); + } + + protected override void ProcessPageBreak(HWPFDocumentCore wordDocument, XmlElement flow) + { + flow.AppendChild(htmlDocumentFacade.CreateLineBreak()); + } + + protected override void ProcessPageref(HWPFDocumentCore wordDocument, XmlElement currentBlock, Range textRange, int currentTableLevel, string pageref) + { + XmlElement basicLink = htmlDocumentFacade.CreateHyperlink("#" + pageref); + currentBlock.AppendChild(basicLink); + + if (textRange != null) + ProcessCharacters(wordDocument, currentTableLevel, textRange, basicLink); + } + + protected override void ProcessParagraph(HWPFDocumentCore wordDocument, XmlElement parentElement, int currentTableLevel, Paragraph paragraph, string bulletText) + { + XmlElement pElement = htmlDocumentFacade.CreateParagraph(); + parentElement.AppendChild(pElement); + + StringBuilder style = new StringBuilder(); + WordToHtmlUtils.AddParagraphProperties(paragraph, style); + + int charRuns = paragraph.NumCharacterRuns; + + if (charRuns == 0) + { + return; + } + + { + String pFontName; + int pFontSize; + CharacterRun characterRun = paragraph.GetCharacterRun(0); + if (characterRun != null) + { + Triplet triplet = GetCharacterRunTriplet(characterRun); + pFontSize = characterRun.GetFontSize() / 2; + pFontName = triplet.fontName; + WordToHtmlUtils.AddFontFamily(pFontName, style); + WordToHtmlUtils.AddFontSize(pFontSize, style); + } + else + { + pFontSize = -1; + pFontName = string.Empty; + } + blocksProperies.Push(new BlockProperies(pFontName, pFontSize)); + } + try + { + if (!string.IsNullOrEmpty(bulletText)) + { + XmlText textNode = htmlDocumentFacade.CreateText(bulletText); + pElement.AppendChild(textNode); + } + + ProcessCharacters(wordDocument, currentTableLevel, paragraph, pElement); + } + finally + { + blocksProperies.Pop(); + } + + if (style.Length > 0) + htmlDocumentFacade.AddStyleClass(pElement, "p", style.ToString()); + + WordToHtmlUtils.CompactSpans(pElement); + } + + protected override void ProcessSection(HWPFDocumentCore wordDocument, Section section, int s) + { + XmlElement div = htmlDocumentFacade.CreateBlock(); + htmlDocumentFacade.AddStyleClass(div, "d", GetSectionStyle(section)); + htmlDocumentFacade.Body.AppendChild(div); + + ProcessParagraphes(wordDocument, div, section, int.MinValue); + } + + protected void processSingleSection(HWPFDocumentCore wordDocument, + Section section) + { + htmlDocumentFacade.AddStyleClass(htmlDocumentFacade.Body, "b", GetSectionStyle(section)); + + ProcessParagraphes(wordDocument, htmlDocumentFacade.Body, section, int.MinValue); + } + + protected override void ProcessTable(HWPFDocumentCore wordDocument, XmlElement flow, Table table) + { + XmlElement tableHeader = htmlDocumentFacade.CreateTableHeader(); + XmlElement tableBody = htmlDocumentFacade.CreateTableBody(); + + int[] tableCellEdges = WordToHtmlUtils.BuildTableCellEdgesArray(table); + int tableRows = table.NumRows; + + int maxColumns = int.MinValue; + for (int r = 0; r < tableRows; r++) + { + maxColumns = Math.Max(maxColumns, table.GetRow(r).NumCells()); + } + + for (int r = 0; r < tableRows; r++) + { + TableRow tableRow = table.GetRow(r); + + XmlElement tableRowElement = htmlDocumentFacade.CreateTableRow(); + StringBuilder tableRowStyle = new StringBuilder(); + WordToHtmlUtils.AddTableRowProperties(tableRow, tableRowStyle); + + // index of current element in tableCellEdges[] + int currentEdgeIndex = 0; + int rowCells = tableRow.NumCells(); + for (int c = 0; c < rowCells; c++) + { + TableCell tableCell = tableRow.GetCell(c); + + if (tableCell.IsVerticallyMerged() && !tableCell.IsFirstVerticallyMerged()) + { + currentEdgeIndex += getTableCellEdgesIndexSkipCount(table, r, tableCellEdges, currentEdgeIndex, c, tableCell); + continue; + } + + XmlElement tableCellElement; + if (tableRow.isTableHeader()) + { + tableCellElement = htmlDocumentFacade.CreateTableHeaderCell(); + } + else + { + tableCellElement = htmlDocumentFacade.CreateTableCell(); + } + StringBuilder tableCellStyle = new StringBuilder(); + WordToHtmlUtils.AddTableCellProperties(tableRow, tableCell, r == 0, r == tableRows - 1, c == 0, c == rowCells - 1, tableCellStyle); + + int colSpan = GetNumberColumnsSpanned(tableCellEdges, currentEdgeIndex, tableCell); + currentEdgeIndex += colSpan; + + if (colSpan == 0) + continue; + + if (colSpan != 1) + tableCellElement.SetAttribute("colspan", colSpan.ToString()); + + int rowSpan = GetNumberRowsSpanned(table, r, c, + tableCell); + if (rowSpan > 1) + tableCellElement.SetAttribute("rowspan", rowSpan.ToString()); + + ProcessParagraphes(wordDocument, tableCellElement, tableCell, 0 /*table.TableLevel Todo: */); + + if (!tableCellElement.HasChildNodes) + { + tableCellElement.AppendChild(htmlDocumentFacade.CreateParagraph()); + } + if (tableCellStyle.Length > 0) + htmlDocumentFacade.AddStyleClass(tableCellElement, tableCellElement.LocalName, tableCellStyle.ToString()); + + tableRowElement.AppendChild(tableCellElement); + } + + if (tableRowStyle.Length > 0) + tableRowElement.SetAttribute("class", htmlDocumentFacade.GetOrCreateCssClass("tr", "r", tableRowStyle.ToString())); + + if (tableRow.isTableHeader()) + { + tableHeader.AppendChild(tableRowElement); + } + else + { + tableBody.AppendChild(tableRowElement); + } + } + + XmlElement tableElement = htmlDocumentFacade.CreateTable(); + tableElement.SetAttribute("class", + htmlDocumentFacade.GetOrCreateCssClass(tableElement.LocalName, "t", "table-layout:fixed;border-collapse:collapse;border-spacing:0;")); + if (tableHeader.HasChildNodes) + { + tableElement.AppendChild(tableHeader); + } + if (tableBody.HasChildNodes) + { + tableElement.AppendChild(tableBody); + flow.AppendChild(tableElement); + } + else + { + logger.Log(POILogger.WARN, "Table without body starting at [", table.StartOffset.ToString(), "; ", table.EndOffset.ToString(), ")"); + } + } + } +} diff --git a/scratchpad/HWPF/Converter/WordToHtmlUtils.cs b/scratchpad/HWPF/Converter/WordToHtmlUtils.cs new file mode 100644 index 0000000..26e0a91 --- /dev/null +++ b/scratchpad/HWPF/Converter/WordToHtmlUtils.cs @@ -0,0 +1,224 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using System; +using System.Collections.Generic; +using System.Text; +using NPOI.HWPF.UserModel; +using System.Xml; + +namespace NPOI.HWPF.Converter +{ + ///

+ /// Beta + /// + public class WordToHtmlUtils : AbstractWordUtils + { + public static void AddBold(bool bold, StringBuilder style) + { + style.Append("font-weight:" + (bold ? "bold" : "normal") + ";"); + } + + public static void AddBorder(BorderCode borderCode, String where, StringBuilder style) + { + if (borderCode == null || borderCode.IsEmpty) + return; + + if (string.IsNullOrEmpty(where)) + { + style.Append("border:"); + } + else + { + style.Append("border-"); + style.Append(where); + } + + style.Append(":"); + if (borderCode.LineWidth < 8) + style.Append("thin"); + else + style.Append(GetBorderWidth(borderCode)); + style.Append(' '); + style.Append(GetBorderType(borderCode)); + style.Append(' '); + style.Append(GetColor(borderCode.Color)); + style.Append(';'); + } + public static void AddCharactersProperties(CharacterRun characterRun, StringBuilder style) + { + AddBorder(characterRun.GetBorder(), string.Empty, style); + + if (characterRun.IsCapitalized()) + { + style.Append("text-transform:uppercase;"); + } + if (characterRun.GetIco24() != -1) + { + style.Append("color:" + GetColor24(characterRun.GetIco24()) + ";"); + } + if (characterRun.IsHighlighted()) + { + style.Append("background-color:" + GetColor(characterRun.GetHighlightedColor()) + ";"); + } + if (characterRun.IsStrikeThrough()) + { + style.Append("text-decoration:line-through;"); + } + if (characterRun.IsShadowed()) + { + style.Append("text-shadow:" + characterRun.GetFontSize() / 24 + "pt;"); + } + if (characterRun.IsSmallCaps()) + { + style.Append("font-variant:small-caps;"); + } + if (characterRun.GetSubSuperScriptIndex() == 1) + { + style.Append("vertical-align:super;"); + style.Append("font-size:smaller;"); + } + if (characterRun.GetSubSuperScriptIndex() == 2) + { + style.Append("vertical-align:sub;"); + style.Append("font-size:smaller;"); + } + if (characterRun.GetUnderlineCode() > 0) + { + style.Append("text-decoration:underline;"); + } + if (characterRun.IsVanished()) + { + style.Append("visibility:hidden;"); + } + } + + public static void AddFontFamily(String fontFamily, StringBuilder style) + { + if (string.IsNullOrEmpty(fontFamily)) + return; + + style.Append("font-family:" + fontFamily + ";"); + } + + public static void AddFontSize(int fontSize, StringBuilder style) + { + style.Append("font-size:" + fontSize + "pt;"); + } + + public static void AddIndent(Paragraph paragraph, StringBuilder style) + { + AddIndent(style, "text-indent", paragraph.GetFirstLineIndent()); + AddIndent(style, "start-indent", paragraph.GetIndentFromLeft()); + AddIndent(style, "end-indent", paragraph.GetIndentFromRight()); + AddIndent(style, "space-before", paragraph.GetSpacingBefore()); + AddIndent(style, "space-after", paragraph.GetSpacingAfter()); + } + + private static void AddIndent(StringBuilder style, String cssName, int twipsValue) + { + if (twipsValue == 0) + return; + + style.Append(cssName + ":" + (twipsValue / TWIPS_PER_PT) + "pt;"); + } + + public static void AddJustification(Paragraph paragraph, StringBuilder style) + { + String justification = GetJustification(paragraph.GetJustification()); + if (!string.IsNullOrEmpty(justification)) + style.Append("text-align:" + justification + ";"); + } + + public static void AddParagraphProperties(Paragraph paragraph, StringBuilder style) + { + AddIndent(paragraph, style); + AddJustification(paragraph, style); + + AddBorder(paragraph.GetBottomBorder(), "bottom", style); + AddBorder(paragraph.GetLeftBorder(), "left", style); + AddBorder(paragraph.GetRightBorder(), "right", style); + AddBorder(paragraph.GetTopBorder(), "top", style); + + if (paragraph.PageBreakBefore()) + { + style.Append("break-before:page;"); + } + + style.Append("hyphenate:" + (paragraph.IsAutoHyphenated ? "auto" : "none") + ";"); + + if (paragraph.KeepOnPage()) + { + style.Append("keep-together.within-page:always;"); + } + + if (paragraph.KeepWithNext()) + { + style.Append("keep-with-next.within-page:always;"); + } + } + + public static void AddTableCellProperties(TableRow tableRow, + TableCell tableCell, bool toppest, bool bottomest, + bool leftest, bool rightest, StringBuilder style) + { + style.Append("width:" + (tableCell.GetWidth() / TWIPS_PER_INCH) + "in;"); + style.Append("padding-start:" + (tableRow.GetGapHalf() / TWIPS_PER_INCH) + "in;"); + style.Append("padding-end:" + (tableRow.GetGapHalf() / TWIPS_PER_INCH) + "in;"); + + BorderCode top = tableCell.GetBrcTop() != null + && tableCell.GetBrcTop().BorderType != 0 ? tableCell + .GetBrcTop() : toppest ? tableRow.GetTopBorder() : tableRow + .GetHorizontalBorder(); + BorderCode bottom = tableCell.GetBrcBottom() != null + && tableCell.GetBrcBottom().BorderType != 0 ? tableCell + .GetBrcBottom() : bottomest ? tableRow.GetBottomBorder() + : tableRow.GetHorizontalBorder(); + + BorderCode left = tableCell.GetBrcLeft() != null + && tableCell.GetBrcLeft().BorderType != 0 ? tableCell + .GetBrcLeft() : leftest ? tableRow.GetLeftBorder() : tableRow + .GetVerticalBorder(); + BorderCode right = tableCell.GetBrcRight() != null + && tableCell.GetBrcRight().BorderType != 0 ? tableCell + .GetBrcRight() : rightest ? tableRow.GetRightBorder() + : tableRow.GetVerticalBorder(); + + AddBorder(bottom, "bottom", style); + AddBorder(left, "left", style); + AddBorder(right, "right", style); + AddBorder(top, "top", style); + } + + public static void AddTableRowProperties(TableRow tableRow, StringBuilder style) + { + if (tableRow.GetRowHeight() > 0) + { + style.Append("height:" + (tableRow.GetRowHeight() / TWIPS_PER_INCH) + "in;"); + } + if (!tableRow.cantSplit()) + { + style.Append("keep-together:always;"); + } + } + + public static void CompactSpans(XmlElement pElement) + { + CompactChildNodesR(pElement, "span"); + } + } +} diff --git a/scratchpad/HWPF/Converter/WordToTextConverter.cs b/scratchpad/HWPF/Converter/WordToTextConverter.cs new file mode 100644 index 0000000..e5e3837 --- /dev/null +++ b/scratchpad/HWPF/Converter/WordToTextConverter.cs @@ -0,0 +1,376 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +namespace NPOI.HWPF.Converter +{ + using System; + using System.Collections.Generic; + using System.Xml; + using NPOI.HPSF; + using NPOI.HWPF; + using NPOI.HWPF.UserModel; + using NPOI.POIFS.FileSystem; + using NPOI.Util; + using System.Reflection; + + + + public class WordToTextConverter : AbstractWordConverter + { + private static POILogger logger = POILogFactory + .GetLogger(typeof(WordToTextConverter)); + + public static String GetText( DirectoryNode root ) + { + HWPFDocumentCore wordDocument = AbstractWordUtils.LoadDoc( root ); + return GetText( wordDocument ); + } + + public static String GetText(string docFile) + { + HWPFDocumentCore wordDocument = AbstractWordUtils + .LoadDoc(docFile); + return GetText(wordDocument); + } + + public static String GetText(HWPFDocumentCore wordDocument) + { + WordToTextConverter wordToTextConverter = new WordToTextConverter(new XmlDocument()); + wordToTextConverter.ProcessDocument(wordDocument); + return wordToTextConverter.GetText(); + } + + + + public static XmlDocument Process(string docFile) + { + HWPFDocumentCore wordDocument = AbstractWordUtils + .LoadDoc(docFile); + WordToTextConverter wordToTextConverter = new WordToTextConverter(new XmlDocument()); + wordToTextConverter.ProcessDocument(wordDocument); + return wordToTextConverter.Document; + } + + //private AtomicInteger noteCounters = new AtomicInteger(1); + private int noteCounters = 1; + private object objCounters = new object(); + + private XmlElement notes = null; + + private bool outputSummaryInformation = false; + + private TextDocumentFacade textDocumentFacade; + + /** + * Creates new instance of {@link WordToTextConverter}. Can be used for + * output several {@link HWPFDocument}s into single text document. + * + * @throws ParserConfigurationException + * if an internal {@link DocumentBuilder} cannot be created + */ + public WordToTextConverter() + { + this.textDocumentFacade = new TextDocumentFacade(new XmlDocument()); + } + + /** + * Creates new instance of {@link WordToTextConverter}. Can be used for + * output several {@link HWPFDocument}s into single text document. + * + * @param document + * XML DOM XmlDocument used as storage for text pieces + */ + public WordToTextConverter(XmlDocument document) + { + this.textDocumentFacade = new TextDocumentFacade(document); + } + + protected override void AfterProcess() + { + if (notes != null) + textDocumentFacade.Body.AppendChild(notes); + } + + public override XmlDocument Document + { + get + { + return textDocumentFacade.Document; + } + } + + public String GetText() + { + //StringWriter stringWriter = new StringWriter(); + //DOMSource domSource = new DOMSource( GetDocument() ); + //StreamResult streamResult = new StreamResult( stringWriter ); + + //TransformerFactory tf = TransformerFactory.NewInstance(); + //Transformer serializer = tf.NewTransformer(); + //// TODO set encoding from a command argument + //serializer.SetOutputProperty( OutputKeys.ENCODING, "UTF-8" ); + //serializer.SetOutputProperty( OutputKeys.INDENT, "no" ); + //serializer.SetOutputProperty( OutputKeys.METHOD, "text" ); + //serializer.Transform( domSource, streamResult ); + + //return stringWriter.ToString(); + return textDocumentFacade.Document.InnerText; + } + + public bool IsOutputSummaryInformation() + { + return outputSummaryInformation; + } + + protected override void OutputCharacters(XmlElement block, CharacterRun characterRun, + String text) + { + block.AppendChild(textDocumentFacade.CreateText(text)); + } + + protected override void ProcessBookmarks(HWPFDocumentCore wordDocument, + XmlElement currentBlock, Range range, int currentTableLevel, + IList rangeBookmarks) + { + ProcessCharacters(wordDocument, currentTableLevel, range, currentBlock); + } + + protected override void ProcessDocumentInformation( + SummaryInformation summaryInformation) + { + if (IsOutputSummaryInformation()) + { + if (!string.IsNullOrEmpty(summaryInformation.Title)) + textDocumentFacade.Title = (summaryInformation.Title); + + if (!string.IsNullOrEmpty(summaryInformation.Author)) + textDocumentFacade.AddAuthor(summaryInformation.Author); + + if (!string.IsNullOrEmpty(summaryInformation.Comments)) + textDocumentFacade.AddDescription(summaryInformation.Comments); + + if (!string.IsNullOrEmpty(summaryInformation.Keywords)) + textDocumentFacade.AddKeywords(summaryInformation.Keywords); + } + } + + protected override void ProcessDocumentPart(HWPFDocumentCore wordDocument, + Range range) + { + base.ProcessDocumentPart(wordDocument, range); + AfterProcess(); + } + + protected override void ProcessDrawnObject(HWPFDocument doc, + CharacterRun characterRun, OfficeDrawing officeDrawing, + String path, XmlElement block) + { + // ignore + } + + protected override void ProcessEndnoteAutonumbered(HWPFDocument wordDocument, + int noteIndex, XmlElement block, Range endnoteTextRange) + { + ProcessNote(wordDocument, block, endnoteTextRange); + } + protected override void ProcessFootnoteAutonumbered(HWPFDocument wordDocument, + int noteIndex, XmlElement block, Range footnoteTextRange) + { + ProcessNote(wordDocument, block, footnoteTextRange); + } + + protected override void ProcessHyperlink(HWPFDocumentCore wordDocument, + XmlElement currentBlock, Range textRange, int currentTableLevel, + String hyperlink) + { + ProcessCharacters(wordDocument, currentTableLevel, textRange, + currentBlock); + + currentBlock.AppendChild(textDocumentFacade.CreateText(" (" + + UNICODECHAR_ZERO_WIDTH_SPACE + + hyperlink.Replace("\\/", UNICODECHAR_ZERO_WIDTH_SPACE + + "\\/" + UNICODECHAR_ZERO_WIDTH_SPACE) + + UNICODECHAR_ZERO_WIDTH_SPACE + ")")); + } + + protected override void ProcessImage(XmlElement currentBlock, bool inlined, + Picture picture) + { + // ignore + } + + protected override void ProcessLineBreak(XmlElement block, CharacterRun characterRun) + { + block.AppendChild(textDocumentFacade.CreateText("\n")); + } + + protected void ProcessNote(HWPFDocument wordDocument, XmlElement block, + Range noteTextRange) + { + int noteIndex; + lock (objCounters) + { + noteIndex = noteCounters++; + } + block.AppendChild(textDocumentFacade + .CreateText(UNICODECHAR_ZERO_WIDTH_SPACE + "[" + noteIndex + + "]" + UNICODECHAR_ZERO_WIDTH_SPACE)); + + if (notes == null) + notes = textDocumentFacade.CreateBlock(); + + XmlElement note = textDocumentFacade.CreateBlock(); + notes.AppendChild(note); + + note.AppendChild(textDocumentFacade.CreateText("^" + noteIndex + + "\t ")); + ProcessCharacters(wordDocument, int.MinValue, noteTextRange, note); + note.AppendChild(textDocumentFacade.CreateText("\n")); + } + + protected override bool ProcessOle2(HWPFDocument wordDocument, XmlElement block, Entry entry) + { + if (!(entry is DirectoryNode)) + return false; + DirectoryNode directoryNode = (DirectoryNode)entry; + + /* + * even if there is no ExtractorFactory in classpath, still support + * included Word's objects + */ + + //TODO: Not completed + if ( directoryNode.HasEntry( "WordDocument" ) ) + { + String text = WordToTextConverter.GetText( (DirectoryNode) entry ); + block.AppendChild( textDocumentFacade + .CreateText( UNICODECHAR_ZERO_WIDTH_SPACE + text + + UNICODECHAR_ZERO_WIDTH_SPACE ) ); + return true; + } + + Object extractor; + + /*try + { + Class cls = Class + .ForName( "org.apache.poi.extractor.ExtractorFactory" ); + Method createExtractor = cls.GetMethod( "createExtractor", + DirectoryNode.class ); + extractor = createExtractor.Invoke( null, directoryNode ); + } + catch ( Error exc ) + { + // no extractor in classpath + logger.Log( POILogger.WARN, "There is an OLE object entry '", + entry.GetName(), + "', but there is no text extractor for this object type ", + "or text extractor factory is not available: ", "" + exc ); + return false; + } + + try + { + Method getText = extractor.GetClass().GetMethod( "getText" ); + String text = (String) getText.Invoke( extractor ); + + block.AppendChild( textDocumentFacade + .CreateText( UNICODECHAR_ZERO_WIDTH_SPACE + text + + UNICODECHAR_ZERO_WIDTH_SPACE ) ); + return true; + } + catch ( Exception exc ) + { + logger.Log( POILogger.ERROR, + "Unable to extract text from OLE entry '", entry.GetName(), + "': ", exc, exc ); + return false; + } + * */ + return false; + } + + protected override void ProcessPageBreak(HWPFDocumentCore wordDocument, XmlElement flow) + { + XmlElement block = textDocumentFacade.CreateBlock(); + block.AppendChild(textDocumentFacade.CreateText("\n")); + flow.AppendChild(block); + } + + protected override void ProcessPageref(HWPFDocumentCore wordDocument, + XmlElement currentBlock, Range textRange, int currentTableLevel, + String pageref) + { + ProcessCharacters(wordDocument, currentTableLevel, textRange, + currentBlock); + } + + protected override void ProcessParagraph(HWPFDocumentCore wordDocument, + XmlElement parentElement, int currentTableLevel, Paragraph paragraph, + String bulletText) + { + XmlElement pElement = textDocumentFacade.CreateParagraph(); + pElement.AppendChild(textDocumentFacade.CreateText(bulletText)); + ProcessCharacters(wordDocument, currentTableLevel, paragraph, pElement); + pElement.AppendChild(textDocumentFacade.CreateText("\n")); + parentElement.AppendChild(pElement); + } + + protected override void ProcessSection(HWPFDocumentCore wordDocument, + NPOI.HWPF.UserModel.Section section, int s) + { + XmlElement sectionElement = textDocumentFacade.CreateBlock(); + ProcessParagraphes(wordDocument, sectionElement, section, int.MinValue); + sectionElement.AppendChild(textDocumentFacade.CreateText("\n")); + textDocumentFacade.Body.AppendChild(sectionElement); + } + + protected override void ProcessTable(HWPFDocumentCore wordDocument, XmlElement flow, + Table table) + { + int tableRows = table.NumRows; + for (int r = 0; r < tableRows; r++) + { + TableRow tableRow = table.GetRow(r); + + XmlElement tableRowElement = textDocumentFacade.CreateTableRow(); + + int rowCells = tableRow.NumCells(); + for (int c = 0; c < rowCells; c++) + { + TableCell tableCell = tableRow.GetCell(c); + + XmlElement tableCellElement = textDocumentFacade.CreateTableCell(); + + if (c != 0) + tableCellElement.AppendChild(textDocumentFacade + .CreateText("\t")); + ProcessCharacters(wordDocument, table.TableLevel, tableCell, tableCellElement); + tableRowElement.AppendChild(tableCellElement); + } + + tableRowElement.AppendChild(textDocumentFacade.CreateText("\n")); + flow.AppendChild(tableRowElement); + } + } + + public void SetOutputSummaryInformation(bool outputDocumentInformation) + { + this.outputSummaryInformation = outputDocumentInformation; + } + + } +} diff --git a/scratchpad/HWPF/Extractor/Word6Extractor.cs b/scratchpad/HWPF/Extractor/Word6Extractor.cs new file mode 100644 index 0000000..2d3781c --- /dev/null +++ b/scratchpad/HWPF/Extractor/Word6Extractor.cs @@ -0,0 +1,127 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using NPOI.POIFS.FileSystem; +using System.IO; +using System; +using System.Text; +using NPOI.HWPF.UserModel; +namespace NPOI.HWPF.Extractor +{ + + + /** + * Class to extract the text from old (Word 6 / Word 95) Word Documents. + * + * This should only be used on the older files, for most uses you + * should call {@link WordExtractor} which deals properly + * with HWPF. + * + * @author Nick Burch + */ + public class Word6Extractor : POIOLE2TextExtractor + { + private HWPFOldDocument doc; + + /** + * Create a new Word Extractor + * @param is InputStream Containing the word file + */ + public Word6Extractor(Stream is1) + : this(new POIFSFileSystem(is1)) + { + + } + + /** + * Create a new Word Extractor + * @param fs POIFSFileSystem Containing the word file + */ + public Word6Extractor(POIFSFileSystem fs) + : this(fs.Root, fs) + { + + } + public Word6Extractor(DirectoryNode dir, POIFSFileSystem fs) + : this(new HWPFOldDocument(dir, fs)) + { + + } + + /** + * Create a new Word Extractor + * @param doc The HWPFOldDocument to extract from + */ + public Word6Extractor(HWPFOldDocument doc) + : base(doc) + { + + this.doc = doc; + } + + /** + * Get the text from the word file, as an array with one String + * per paragraph + */ + public String[] ParagraphText + { + get + { + String[] ret; + + // Extract using the model code + try + { + Range r = doc.GetRange(); + + ret = WordExtractor.GetParagraphText(r); + } + catch (Exception) + { + // Something's up with turning the text pieces into paragraphs + // Fall back to ripping out the text pieces + ret = new String[doc.TextTable.TextPieces.Count]; + for (int i = 0; i < ret.Length; i++) + { + ret[i] = doc.TextTable.TextPieces[i].GetStringBuilder().ToString(); + + // Fix the line endings + ret[i].Replace("\r", "\ufffe"); + ret[i].Replace("\ufffe", "\r\n"); + } + } + + return ret; + } + } + + public override String Text + { + get + { + StringBuilder text = new StringBuilder(); + + foreach (String t in ParagraphText) + { + text.Append(t); + } + + return text.ToString(); + } + } + } +} diff --git a/scratchpad/HWPF/Extractor/WordExtractor.cs b/scratchpad/HWPF/Extractor/WordExtractor.cs new file mode 100644 index 0000000..dc43083 --- /dev/null +++ b/scratchpad/HWPF/Extractor/WordExtractor.cs @@ -0,0 +1,321 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +namespace NPOI.HWPF.Extractor +{ + using System.IO; + using System; + using NPOI.HWPF.UserModel; + using System.Text; + using NPOI.HWPF.Model; + using System.Collections.Generic; + using NPOI.POIFS.FileSystem; + /** + * Class to extract the text from a Word Document. + * + * You should use either GetParagraphText() or GetText() unless + * you have a strong reason otherwise. + * + * @author Nick Burch + */ + public class WordExtractor : POIOLE2TextExtractor + { + private POIFSFileSystem fs; + private HWPFDocument doc; + + /** + * Create a new Word Extractor + * @param is InputStream Containing the word file + */ + public WordExtractor(Stream is1) + : this(HWPFDocument.VerifyAndBuildPOIFS(is1)) + { + + } + + /** + * Create a new Word Extractor + * @param fs POIFSFileSystem Containing the word file + */ + public WordExtractor(POIFSFileSystem fs) + : this(new HWPFDocument(fs)) + { + + this.fs = fs; + } + public WordExtractor(DirectoryNode dir, POIFSFileSystem fs) + : this(new HWPFDocument(dir, fs)) + { + + this.fs = fs; + } + + /** + * Create a new Word Extractor + * @param doc The HWPFDocument to extract from + */ + public WordExtractor(HWPFDocument doc) + : base(doc) + { + + this.doc = doc; + } + + /** + * Get the text from the word file, as an array with one String + * per paragraph + */ + public String[] ParagraphText + { + get + { + String[] ret; + + // Extract using the model code + try + { + Range r = doc.GetRange(); + + ret = GetParagraphText(r); + } + catch (Exception) + { + // Something's up with turning the text pieces into paragraphs + // Fall back to ripping out the text pieces + ret = new String[1]; + ret[0] = this.TextFromPieces; + } + + return ret; + } + } + + public String[] FootnoteText + { + get + { + Range r = doc.GetFootnoteRange(); + + return GetParagraphText(r); + } + } + public String[] MainTextboxText + { + get + { + Range r = doc.GetMainTextboxRange(); + + return GetParagraphText(r); + } + } + public String[] EndnoteText + { + get + { + Range r = doc.GetEndnoteRange(); + + return GetParagraphText(r); + } + } + + public String[] CommentsText + { + get + { + Range r = doc.GetCommentsRange(); + + return GetParagraphText(r); + } + } + + public static String[] GetParagraphText(Range r) + { + String[] ret; + ret = new String[r.NumParagraphs]; + for (int i = 0; i < ret.Length; i++) + { + Paragraph p = r.GetParagraph(i); + ret[i] = p.Text; + + // Fix the line ending + if (ret[i].EndsWith("\r")) + { + ret[i] = ret[i] + "\n"; + } + } + return ret; + } + + /** + * Add the header/footer text, if it's not empty + */ + private void AppendHeaderFooter(String text, StringBuilder out1) + { + if (text == null || text.Length == 0) + return; + + text = text.Replace('\r', '\n'); + if (!text.EndsWith("\n")) + { + out1.Append(text); + out1.Append('\n'); + return; + } + if (text.EndsWith("\n\n")) + { + out1.Append(text.Substring(0, text.Length - 1)); + return; + } + out1.Append(text); + return; + } + /** + * Grab the text from the headers + */ + public String HeaderText + { + get + { + HeaderStories hs = new HeaderStories(doc); + + StringBuilder ret = new StringBuilder(); + if (hs.FirstHeader != null) + { + AppendHeaderFooter(hs.FirstHeader, ret); + } + if (hs.EvenHeader != null) + { + AppendHeaderFooter(hs.EvenHeader, ret); + } + if (hs.OddHeader != null) + { + AppendHeaderFooter(hs.OddHeader, ret); + } + + return ret.ToString(); + } + } + /** + * Grab the text from the footers + */ + public String FooterText + { + get + { + HeaderStories hs = new HeaderStories(doc); + + StringBuilder ret = new StringBuilder(); + if (hs.FirstFooter != null) + { + AppendHeaderFooter(hs.FirstFooter, ret); + } + if (hs.EvenFooter != null) + { + AppendHeaderFooter(hs.EvenFooter, ret); + } + if (hs.OddFooter != null) + { + AppendHeaderFooter(hs.OddFooter, ret); + } + + return ret.ToString(); + } + } + + /** + * Grab the text out of the text pieces. Might also include various + * bits of crud, but will work in cases where the text piece -> paragraph + * mapping is broken. Fast too. + */ + public String TextFromPieces + { + get + { + StringBuilder textBuf = new StringBuilder(); + + foreach (TextPiece piece in doc.TextTable.TextPieces) + { + String encoding = "Windows-1252"; + if (piece.IsUnicode) + { + encoding = "UTF-16LE"; + } + try + { + String text1 = Encoding.GetEncoding(encoding).GetString(piece.RawBytes); + textBuf.Append(text1); + } + catch (EncoderFallbackException) + { + throw new Exception("Standard Encoding " + encoding + " not found, JVM broken"); + } + } + + String text = textBuf.ToString(); + + // Fix line endings (Note - won't get all of them + text = text.Replace("\r\r\r", "\r\n\r\n\r\n"); + text = text.Replace("\r\r", "\r\n\r\n"); + + if (text.EndsWith("\r")) + { + text += "\n"; + } + + return text; + } + } + + /** + * Grab the text, based on the paragraphs. Shouldn't include any crud, + * but slightly slower than GetTextFromPieces(). + */ + public override String Text + { + get + { + StringBuilder ret = new StringBuilder(); + + ret.Append(HeaderText); + + List text = new List(); + text.AddRange(ParagraphText); + text.AddRange(FootnoteText); + text.AddRange(EndnoteText); + + foreach (String p in text) + { + ret.Append(p); + } + + ret.Append(FooterText); + + return ret.ToString(); + } + } + + /** + * Removes any fields (eg macros, page markers etc) + * from the string. + */ + public static String StripFields(String text) + { + return Range.StripFields(text); + } + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/HWPF.csproj b/scratchpad/HWPF/HWPF.csproj new file mode 100644 index 0000000..63f57d5 --- /dev/null +++ b/scratchpad/HWPF/HWPF.csproj @@ -0,0 +1,299 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {F040162E-F6F3-4B09-809B-3095A07A6687} + Library + Properties + NPOI.HWPF + NPOI.ScratchPad.HWPF + v2.0 + 512 + + + + + + + + + + + + + 3.5 + + + + true + full + false + ..\..\solution\Lib\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + true + + + npoi.snk + + + + False + ..\..\build\Release\Net20\ICSharpCode.SharpZipLib.dll + + + False + ..\..\build\Release\Net20\NPOI.dll + + + + + + + + + + Code + + + + + + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + + + + + + + + + + + + + + Code + + + Code + + + Code + + + + + + + + + + + + + + + + + Code + + + Code + + + + + + Code + + + + Code + + + Code + + + + + + Code + + + + + + + + + + Code + + + Code + + + Code + + + + + + + + Code + + + Code + + + Code + + + Code + + + + + Code + + + + + Code + + + + Code + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + + + + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/scratchpad/HWPF/HWPF.net2.csproj b/scratchpad/HWPF/HWPF.net2.csproj new file mode 100644 index 0000000..798c80f --- /dev/null +++ b/scratchpad/HWPF/HWPF.net2.csproj @@ -0,0 +1,299 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {F040162E-F6F3-4B09-809B-3095A07A6687} + Library + Properties + NPOI.HWPF + NPOI.ScratchPad.HWPF + v2.0 + 512 + + + + + + + + + + + + + 3.5 + + + + true + full + false + ..\..\solution\Lib\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + true + + + npoi.snk + + + + False + ..\..\build\Release\Net20\ICSharpCode.SharpZipLib.dll + + + False + ..\..\build\Release\Net20\NPOI.dll + + + + + + + + + + Code + + + + + + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + + + + + + + + + + + + + + Code + + + Code + + + Code + + + + + + + + + + + + + + + + + Code + + + Code + + + + + + Code + + + + Code + + + Code + + + + + + Code + + + + + + + + + + Code + + + Code + + + Code + + + + + + + + Code + + + Code + + + Code + + + Code + + + + + Code + + + + + Code + + + + Code + + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + Code + + + + + + + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + Code + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/scratchpad/HWPF/HWPFDocument.cs b/scratchpad/HWPF/HWPFDocument.cs new file mode 100644 index 0000000..a65e9aa --- /dev/null +++ b/scratchpad/HWPF/HWPFDocument.cs @@ -0,0 +1,814 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +namespace NPOI.HWPF +{ + + using NPOI.HWPF.Model.IO; + using NPOI.HWPF.Model; + using NPOI.HWPF.UserModel; + using System.IO; + using System; + using NPOI.POIFS.FileSystem; + using NPOI.POIFS.Common; + using System.Collections.Generic; + using System.Text; + using System.Configuration; + + + /** + * + * This class acts as the bucket that we throw all of the Word data structures + * into. + * + * @author Ryan Ackley + */ + public class HWPFDocument : HWPFDocumentCore + { + private const String PROPERTY_PRESERVE_BIN_TABLES = "org.apache.poi.hwpf.preserveBinTables"; + private const String PROPERTY_PRESERVE_TEXT_TABLE = "org.apache.poi.hwpf.preserveTextTable"; + + + /** And for making sense of CP lengths in the FIB */ + internal CPSplitCalculator _cpSplit; + + /** table stream buffer*/ + protected byte[] _tableStream; + + /** data stream buffer*/ + protected byte[] _dataStream; + + /** Contains text buffer linked directly to single-piece document text piece */ + protected StringBuilder _text; + + /** Document wide Properties*/ + protected DocumentProperties _dop; + + /** Contains text of the document wrapped in a obfuscated Word data + * structure*/ + protected ComplexFileTable _cft; + + /** Holds the save history for this document. */ + protected SavedByTable _sbt; + + /** Holds the revision mark authors for this document. */ + protected RevisionMarkAuthorTable _rmat; + + /** Holds FSBA (shape) information */ + private FSPATable _fspaHeaders; + + /** Holds FSBA (shape) information */ + private FSPATable _fspaMain; + + /** Holds pictures table */ + protected PicturesTable _pictures; + + /** Holds FSBA (shape) information */ + protected FSPATable _fspa; + + /** Escher Drawing Group information */ + protected EscherRecordHolder _dgg; + + /** Holds Office Art objects */ + [Obsolete] + protected ShapesTable _officeArts; + + /** Holds Office Art objects */ + protected OfficeDrawingsImpl _officeDrawingsHeaders; + + /** Holds Office Art objects */ + protected OfficeDrawingsImpl _officeDrawingsMain; + + /** Holds the bookmarks tables */ + protected BookmarksTables _bookmarksTables; + + /** Holds the bookmarks */ + protected Bookmarks _bookmarks; + + /** Holds the ending notes tables */ + protected NotesTables _endnotesTables = new NotesTables(NoteType.ENDNOTE); + + /** Holds the footnotes */ + protected Notes _endnotes; + + /** Holds the footnotes tables */ + protected NotesTables _footnotesTables = new NotesTables(NoteType.FOOTNOTE); + + /** Holds the footnotes */ + protected Notes _footnotes; + + /** Holds the fields PLCFs */ + protected FieldsTables _fieldsTables; + + /** Holds the fields */ + protected Fields _fields; + + public HWPFDocument() + : base() + { + _endnotes = new NotesImpl(_endnotesTables); + _footnotes = new NotesImpl(_footnotesTables); + this._text = new StringBuilder("\r"); + } + + /** + * This constructor loads a Word document from an InputStream. + * + * @param istream The InputStream that Contains the Word document. + * @throws IOException If there is an unexpected IOException from the passed + * in InputStream. + */ + public HWPFDocument(Stream istream) + : this(VerifyAndBuildPOIFS(istream)) + { + //do Ole stuff + + } + + /** + * This constructor loads a Word document from a POIFSFileSystem + * + * @param pfilesystem The POIFSFileSystem that Contains the Word document. + * @throws IOException If there is an unexpected IOException from the passed + * in POIFSFileSystem. + */ + public HWPFDocument(POIFSFileSystem pfilesystem) + : this(pfilesystem.Root) + { + + } + + /** + * This constructor loads a Word document from a specific point + * in a POIFSFileSystem, probably not the default. + * Used typically to open embeded documents. + * + * @param pfilesystem The POIFSFileSystem that Contains the Word document. + * @throws IOException If there is an unexpected IOException from the passed + * in POIFSFileSystem. + */ + [Obsolete] + public HWPFDocument(DirectoryNode directory, POIFSFileSystem pfilesystem) + : this(directory) + { + + } + /// + /// Initializes a new instance of the class. + /// + /// The directory. + public HWPFDocument(DirectoryNode directory) + : base(directory) + { + _endnotes = new NotesImpl(_endnotesTables); + _footnotes = new NotesImpl(_footnotesTables); + + // Load the main stream and FIB + // Also handles HPSF bits + + // Do the CP Split + _cpSplit = new CPSplitCalculator(_fib); + + // Is this document too old for us? + if (_fib.GetNFib() < 106) + { + throw new OldWordFileFormatException("The document is too old - Word 95 or older. Try HWPFOldDocument instead?"); + } + + // use the fib to determine the name of the table stream. + String name = "0Table"; + if (_fib.IsFWhichTblStm()) + { + name = "1Table"; + } + + // Grab the table stream. + DocumentEntry tableProps; + try + { + tableProps = + (DocumentEntry)directory.GetEntry(name); + } + catch (FileNotFoundException) + { + throw new InvalidOperationException("Table Stream '" + name + "' wasn't found - Either the document is corrupt, or is Word95 (or earlier)"); + } + + // read in the table stream. + _tableStream = new byte[tableProps.Size]; + directory.CreatePOIFSDocumentReader(name).Read(_tableStream); + + _fib.FillVariableFields(_mainStream, _tableStream); + + // read in the data stream. + try + { + DocumentEntry dataProps = + (DocumentEntry)directory.GetEntry("Data"); + _dataStream = new byte[dataProps.Size]; + directory.CreatePOIFSDocumentReader("Data").Read(_dataStream); + } + catch (FileNotFoundException) + { + _dataStream = new byte[0]; + } + + // Get the cp of the start of text in the main stream + // The latest spec doc says this is always zero! + int fcMin = 0; + //fcMin = _fib.GetFcMin() + + // Start to load up our standard structures. + _dop = new DocumentProperties(_tableStream, _fib.GetFcDop()); + _cft = new ComplexFileTable(_mainStream, _tableStream, _fib.GetFcClx(), fcMin); + TextPieceTable _tpt = _cft.GetTextPieceTable(); + + + // Now load the rest of the properties, which need to be adjusted + // for where text really begin + _cbt = new CHPBinTable(_mainStream, _tableStream, _fib.GetFcPlcfbteChpx(), _fib.GetLcbPlcfbteChpx(), _tpt); + _pbt = new PAPBinTable(_mainStream, _tableStream, _dataStream, _fib.GetFcPlcfbtePapx(), _fib.GetLcbPlcfbtePapx(), _tpt); + + _text = _tpt.Text; + + /* + * in this mode we preserving PAPX/CHPX structure from file, so text may + * miss from output, and text order may be corrupted + */ + bool preserveBinTables = false; + try + { + preserveBinTables = Boolean.Parse( + ConfigurationManager.AppSettings[PROPERTY_PRESERVE_BIN_TABLES]); + } + catch (Exception) + { + // ignore; + } + + if (!preserveBinTables) + { + _cbt.Rebuild(_cft); + _pbt.Rebuild(_text, _cft); + } + + /* + * Property to disable text rebuilding. In this mode changing the text + * will lead to unpredictable behavior + */ + bool preserveTextTable = false; + try + { + preserveTextTable = Boolean.Parse( + ConfigurationManager.AppSettings[PROPERTY_PRESERVE_TEXT_TABLE]); + } + catch (Exception) + { + // ignore; + } + if (!preserveTextTable) + { + _cft = new ComplexFileTable(); + _tpt = _cft.GetTextPieceTable(); + TextPiece textPiece = new SinglentonTextPiece(_text); + _tpt.Add(textPiece); + _text = textPiece.GetStringBuilder(); + } + + // Read FSPA and Escher information + // _fspa = new FSPATable(_tableStream, _fib.getFcPlcspaMom(), + // _fib.getLcbPlcspaMom(), getTextTable().getTextPieces()); + _fspaHeaders = new FSPATable(_tableStream, _fib, + FSPADocumentPart.HEADER); + _fspaMain = new FSPATable(_tableStream, _fib, FSPADocumentPart.MAIN); + + if (_fib.GetFcDggInfo() != 0) + { + _dgg = new EscherRecordHolder(_tableStream, _fib.GetFcDggInfo(), _fib.GetLcbDggInfo()); + } + else + { + _dgg = new EscherRecordHolder(); + } + + // read in the pictures stream + _pictures = new PicturesTable(this, _dataStream, _mainStream, _fspa, _dgg); + // And the art shapes stream + _officeArts = new ShapesTable(_tableStream, _fib); + + // And escher pictures + _officeDrawingsHeaders = new OfficeDrawingsImpl(_fspaHeaders, _dgg, _mainStream); + _officeDrawingsMain = new OfficeDrawingsImpl(_fspaMain, _dgg, _mainStream); + + _st = new SectionTable(_mainStream, _tableStream, _fib.GetFcPlcfsed(), _fib.GetLcbPlcfsed(), fcMin, _tpt, _fib.GetSubdocumentTextStreamLength(SubdocumentType.MAIN)); + _ss = new StyleSheet(_tableStream, _fib.GetFcStshf()); + _ft = new FontTable(_tableStream, _fib.GetFcSttbfffn(), _fib.GetLcbSttbfffn()); + + int listOffset = _fib.GetFcPlcfLst(); + int lfoOffset = _fib.GetFcPlfLfo(); + if (listOffset != 0 && _fib.GetLcbPlcfLst() != 0) + { + _lt = new ListTables(_tableStream, _fib.GetFcPlcfLst(), _fib.GetFcPlfLfo()); + } + + int sbtOffset = _fib.GetFcSttbSavedBy(); + int sbtLength = _fib.GetLcbSttbSavedBy(); + if (sbtOffset != 0 && sbtLength != 0) + { + _sbt = new SavedByTable(_tableStream, sbtOffset, sbtLength); + } + + int rmarkOffset = _fib.GetFcSttbfRMark(); + int rmarkLength = _fib.GetLcbSttbfRMark(); + if (rmarkOffset != 0 && rmarkLength != 0) + { + _rmat = new RevisionMarkAuthorTable(_tableStream, rmarkOffset, rmarkLength); + } + + + _bookmarksTables = new BookmarksTables(_tableStream, _fib); + _bookmarks = new BookmarksImpl(_bookmarksTables); + + _endnotesTables = new NotesTables(NoteType.ENDNOTE, _tableStream, _fib); + _endnotes = new NotesImpl(_endnotesTables); + _footnotesTables = new NotesTables(NoteType.FOOTNOTE, _tableStream, _fib); + _footnotes = new NotesImpl(_footnotesTables); + + _fieldsTables = new FieldsTables(_tableStream, _fib); + _fields = new FieldsImpl(_fieldsTables); + } + + public override TextPieceTable TextTable + { + get + { + return _cft.GetTextPieceTable(); + } + } + + public CPSplitCalculator GetCPSplitCalculator() + { + return _cpSplit; + } + + public DocumentProperties GetDocProperties() + { + return _dop; + } + + public override StringBuilder Text + { + get + { + return _text; + } + } + + /** + * Returns the range that covers all text in the + * file, including main text, footnotes, headers + * and comments + */ + public override Range GetOverallRange() + { + return new Range(0, _text.Length, this); + } + /** + * Array of {@link SubdocumentType}s ordered by document position and FIB + * field order + */ + public static SubdocumentType[] ORDERED = new SubdocumentType[] { + SubdocumentType.MAIN, SubdocumentType.FOOTNOTE, + SubdocumentType.HEADER, SubdocumentType.MACRO, + SubdocumentType.ANNOTATION, SubdocumentType.ENDNOTE, SubdocumentType.TEXTBOX, + SubdocumentType.HEADER_TEXTBOX }; + /** + * Returns the range which covers the whole of the + * document, but excludes any headers and footers. + */ + public override Range GetRange() + { + return GetRange(SubdocumentType.MAIN); + } + + private Range GetRange(SubdocumentType subdocument) + { + int startCp = 0; + foreach (SubdocumentType previos in ORDERED) + { + int length = GetFileInformationBlock() + .GetSubdocumentTextStreamLength(previos); + if (subdocument == previos) + return new Range(startCp, startCp + length, this); + startCp += length; + } + throw new NotSupportedException( + "Subdocument type not supported: " + subdocument); + } + + + /** + * Returns the range which covers all the Footnotes. + */ + public Range GetFootnoteRange() + { + return GetRange(SubdocumentType.FOOTNOTE); + } + + /** + * Returns the range which covers all the Endnotes. + */ + public Range GetEndnoteRange() + { + return GetRange(SubdocumentType.ENDNOTE); + } + + /** + * Returns the range which covers all the Endnotes. + */ + public Range GetCommentsRange() + { + return GetRange(SubdocumentType.ANNOTATION); + } + /** + * Returns the {@link Range} which covers all textboxes. + * + * @return the {@link Range} which covers all textboxes. + */ + public Range GetMainTextboxRange() + { + return GetRange(SubdocumentType.TEXTBOX); + } + /** + * Returns the range which covers all "Header Stories". + * A header story Contains a header, footer, end note + * separators and footnote separators. + */ + public Range GetHeaderStoryRange() + { + return GetRange(SubdocumentType.HEADER); + } + + /** + * Returns the character length of a document. + * @return the character length of a document + */ + public int CharacterLength + { + get + { + return _text.Length; + } + } + + /** + * Gets a reference to the saved -by table, which holds the save history for the document. + * + * @return the saved-by table. + */ + public SavedByTable GetSavedByTable() + { + return _sbt; + } + + /** + * Gets a reference to the revision mark author table, which holds the revision mark authors for the document. + * + * @return the saved-by table. + */ + public RevisionMarkAuthorTable GetRevisionMarkAuthorTable() + { + return _rmat; + } + + /** + * @return PicturesTable object, that is able to extract images from this document + */ + public PicturesTable GetPicturesTable() + { + return _pictures; + } + + /** + * @return ShapesTable object, that is able to extract office are shapes from this document + */ + public ShapesTable GetShapesTable() + { + return _officeArts; + } + + public OfficeDrawings GetOfficeDrawingsHeaders() + { + return _officeDrawingsHeaders; + } + + public OfficeDrawings GetOfficeDrawingsMain() + { + return _officeDrawingsMain; + } + + /** + * Writes out the word file that is represented by an instance of this class. + * + * @param out The OutputStream to write to. + * @throws IOException If there is an unexpected IOException from the passed + * in OutputStream. + */ + public override void Write(Stream out1) + { + // Initialize our streams for writing. + HWPFFileSystem docSys = new HWPFFileSystem(); + HWPFStream mainStream = docSys.GetStream("WordDocument"); + HWPFStream tableStream = docSys.GetStream("1Table"); + //HWPFOutputStream dataStream = docSys.GetStream("Data"); + int tableOffset = 0; + + // FileInformationBlock fib = (FileInformationBlock)_fib.Clone(); + // clear the offSets and sizes in our FileInformationBlock. + _fib.ClearOffsetsSizes(); + + // determine the FileInformationBLock size + int fibSize = _fib.GetSize(); + fibSize += POIFSConstants.SMALLER_BIG_BLOCK_SIZE - + (fibSize % POIFSConstants.SMALLER_BIG_BLOCK_SIZE); + + // preserve space for the FileInformationBlock because we will be writing + // it after we write everything else. + byte[] placeHolder = new byte[fibSize]; + mainStream.Write(placeHolder); + int mainOffset = mainStream.Offset; + + // write out the StyleSheet. + _fib.SetFcStshf(tableOffset); + _ss.WriteTo(tableStream); + _fib.SetLcbStshf(tableStream.Offset - tableOffset); + tableOffset = tableStream.Offset; + + // get fcMin and fcMac because we will be writing the actual text with the + // complex table. + int fcMin = mainOffset; + + // write out the Complex table, includes text. + _fib.SetFcClx(tableOffset); + _cft.WriteTo(mainStream, tableStream); + _fib.SetLcbClx(tableStream.Offset - tableOffset); + tableOffset = tableStream.Offset; + int fcMac = mainStream.Offset; + + // write out the CHPBinTable. + _fib.SetFcPlcfbteChpx(tableOffset); + _cbt.WriteTo(docSys, fcMin); + _fib.SetLcbPlcfbteChpx(tableStream.Offset - tableOffset); + tableOffset = tableStream.Offset; + + + // write out the PAPBinTable. + _fib.SetFcPlcfbtePapx(tableOffset); + _pbt.WriteTo(mainStream, tableStream, _cft.GetTextPieceTable()); + _fib.SetLcbPlcfbtePapx(tableStream.Offset - tableOffset); + tableOffset = tableStream.Offset; + /* + * plcfendRef (endnote reference position table) Written immediately + * after the previously recorded table if the document contains endnotes + * + * plcfendTxt (endnote text position table) Written immediately after + * the plcfendRef if the document contains endnotes + * + * Microsoft Office Word 97-2007 Binary File Format (.doc) + * Specification; Page 24 of 210 + */ + _endnotesTables.WriteRef(_fib, tableStream); + _endnotesTables.WriteTxt(_fib, tableStream); + tableOffset = tableStream.Offset; + + + /* + * plcffndRef (footnote reference position table) Written immediately + * after the stsh if the document contains footnotes + * + * plcffndTxt (footnote text position table) Written immediately after + * the plcffndRef if the document contains footnotes + * + * Microsoft Office Word 97-2007 Binary File Format (.doc) + * Specification; Page 24 of 210 + */ + _footnotesTables.WriteRef(_fib, tableStream); + _footnotesTables.WriteTxt(_fib, tableStream); + tableOffset = tableStream.Offset; + + + // write out the SectionTable. + _fib.SetFcPlcfsed(tableOffset); + _st.WriteTo(docSys, fcMin); + _fib.SetLcbPlcfsed(tableStream.Offset - tableOffset); + tableOffset = tableStream.Offset; + + // write out the list tables + if (_lt != null) + { + _fib.SetFcPlcfLst(tableOffset); + _lt.WriteListDataTo(tableStream); + _fib.SetLcbPlcfLst(tableStream.Offset - tableOffset); + } + + /* + * plflfo (more list formats) Written immediately after the end of the + * plcflst and its accompanying data, if there are any lists defined in + * the document. This consists first of a PL of LFO records, followed by + * the allocated data (if any) hanging off the LFOs. The allocated data + * consists of the array of LFOLVLFs for each LFO (and each LFOLVLF is + * immediately followed by some LVLs). + * + * Microsoft Office Word 97-2007 Binary File Format (.doc) + * Specification; Page 26 of 210 + */ + + if (_lt != null) + { + _fib.SetFcPlfLfo(tableStream.Offset); + _lt.WriteListOverridesTo(tableStream); + _fib.SetLcbPlfLfo(tableStream.Offset - tableOffset); + tableOffset = tableStream.Offset; + } + + /* + * sttbfBkmk (table of bookmark name strings) Written immediately after + * the previously recorded table, if the document contains bookmarks. + * + * Microsoft Office Word 97-2007 Binary File Format (.doc) + * Specification; Page 27 of 210 + */ + if (_bookmarksTables != null) + { + _bookmarksTables.WriteSttbfBkmk(_fib, tableStream); + tableOffset = tableStream.Offset; + } + + // write out the saved-by table. + if (_sbt != null) + { + _fib.SetFcSttbSavedBy(tableOffset); + _sbt.WriteTo(tableStream); + _fib.SetLcbSttbSavedBy(tableStream.Offset - tableOffset); + + tableOffset = tableStream.Offset; + } + + // write out the revision mark authors table. + if (_rmat != null) + { + _fib.SetFcSttbfRMark(tableOffset); + _rmat.WriteTo(tableStream); + _fib.SetLcbSttbfRMark(tableStream.Offset - tableOffset); + + tableOffset = tableStream.Offset; + } + + // write out the FontTable. + _fib.SetFcSttbfffn(tableOffset); + _ft.WriteTo(docSys); + _fib.SetLcbSttbfffn(tableStream.Offset - tableOffset); + tableOffset = tableStream.Offset; + + // write out the DocumentProperties. + _fib.SetFcDop(tableOffset); + byte[] buf = new byte[_dop.GetSize()]; + _fib.SetLcbDop(_dop.GetSize()); + _dop.Serialize(buf, 0); + tableStream.Write(buf); + + + + // set some variables in the FileInformationBlock. + _fib.SetFcMin(fcMin); + _fib.SetFcMac(fcMac); + _fib.SetCbMac(mainStream.Offset); + + // make sure that the table, doc and data streams use big blocks. + byte[] mainBuf = mainStream.ToArray(); + if (mainBuf.Length < 4096) + { + byte[] tempBuf = new byte[4096]; + Array.Copy(mainBuf, 0, tempBuf, 0, mainBuf.Length); + mainBuf = tempBuf; + } + + // write out the FileInformationBlock. + //_fib.Serialize(mainBuf, 0); + _fib.WriteTo(mainBuf, tableStream); + + byte[] tableBuf = tableStream.ToArray(); + if (tableBuf.Length < 4096) + { + byte[] tempBuf = new byte[4096]; + Array.Copy(tableBuf, 0, tempBuf, 0, tableBuf.Length); + tableBuf = tempBuf; + } + + byte[] dataBuf = _dataStream; + if (dataBuf == null) + { + dataBuf = new byte[4096]; + } + if (dataBuf.Length < 4096) + { + byte[] tempBuf = new byte[4096]; + Array.Copy(dataBuf, 0, tempBuf, 0, dataBuf.Length); + dataBuf = tempBuf; + } + + + // spit out the Word document. + POIFSFileSystem pfs = new POIFSFileSystem(); + pfs.CreateDocument(new MemoryStream(mainBuf), "WordDocument"); + pfs.CreateDocument(new MemoryStream(tableBuf), "1Table"); + pfs.CreateDocument(new MemoryStream(dataBuf), "Data"); + WriteProperties(pfs); + + pfs.WriteFileSystem(out1); + } + + public byte[] GetDataStream() + { + return _dataStream; + } + public byte[] GetTableStream() + { + return _tableStream; + } + + public int RegisterList(HWPFList list) + { + if (_lt == null) + { + _lt = new ListTables(); + } + return _lt.AddList(list.GetListData(), list.GetOverride()); + } + + public void Delete(int start, int length) + { + Range r = new Range(start, start + length, this); + r.Delete(); + } + /** + * @return user-friendly interface to access document bookmarks + */ + public Bookmarks GetBookmarks() + { + return _bookmarks; + } + + + /** + * @return user-friendly interface to access document endnotes + */ + public Notes GetEndnotes() + { + return _endnotes; + } + + /** + * @return user-friendly interface to access document footnotes + */ + public Notes GetFootnotes() + { + return _footnotes; + } + /** + * @return FieldsTables object, that is able to extract fields descriptors from this document + * @deprecated + */ + [Obsolete] + public FieldsTables GetFieldsTables() + { + return _fieldsTables; + } + + /** + * Returns user-friendly interface to access document {@link Field}s + * + * @return user-friendly interface to access document {@link Field}s + */ + public Fields GetFields() + { + return _fields; + } + } + +} \ No newline at end of file diff --git a/scratchpad/HWPF/HWPFDocumentCore.cs b/scratchpad/HWPF/HWPFDocumentCore.cs new file mode 100644 index 0000000..278fbfe --- /dev/null +++ b/scratchpad/HWPF/HWPFDocumentCore.cs @@ -0,0 +1,225 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF +{ + using NPOI.POIFS.FileSystem; + using System; + using System.IO; + using NPOI.Util; + using NPOI.HWPF.Model; + using NPOI.HWPF.UserModel; + using System.Text; + + /// + /// This class holds much of the core of a Word document, but without some of the table structure information. You generally want to work with one of HWPFDocument or HWPFOldDocument + /// + public abstract class HWPFDocumentCore : POIDocument + { + protected const String STREAM_OBJECT_POOL = "ObjectPool"; + protected const String STREAM_WORD_DOCUMENT = "WordDocument"; + /** Holds OLE2 objects */ + protected ObjectPoolImpl _objectPool; + + /** The FIB */ + protected FileInformationBlock _fib; + + /** Holds styles for this document.*/ + protected StyleSheet _ss; + + /** Contains formatting properties for text*/ + protected CHPBinTable _cbt; + + /** Contains formatting properties for paragraphs*/ + protected PAPBinTable _pbt; + + /** Contains formatting properties for sections.*/ + protected SectionTable _st; + + /** Holds fonts for this document.*/ + protected FontTable _ft; + + /** Hold list tables */ + protected ListTables _lt; + + /** main document stream buffer*/ + protected byte[] _mainStream; + + protected HWPFDocumentCore() + : base(null, null) + { + + } + + /** + * Takens an InputStream, verifies that it's not RTF, builds a + * POIFSFileSystem from it, and returns that. + */ + public static POIFSFileSystem VerifyAndBuildPOIFS(Stream istream) + { + // Open a PushbackInputStream, so we can peek at the first few bytes + PushbackStream pis = new PushbackStream(istream); + byte[] first6 = new byte[6]; + pis.Read(first6, 0, 6); + + // Does it start with {\rtf ? If so, it's really RTF + if (first6[0] == '{' && first6[1] == '\\' && first6[2] == 'r' + && first6[3] == 't' && first6[4] == 'f') + { + throw new ArgumentException("The document is really a RTF file"); + } + + // OK, so it's not RTF + // Open a POIFSFileSystem on the (pushed back) stream + pis.Unread(6); + return new POIFSFileSystem(istream); + } + + /// + /// This constructor loads a Word document from an stream. + /// + /// The InputStream that Contains the Word document. + public HWPFDocumentCore(Stream istream) + : this(VerifyAndBuildPOIFS(istream)) + { + //do Ole stuff + + } + + /// + /// This constructor loads a Word document from a POIFSFileSystem + /// + /// The POIFSFileSystem that Contains the Word document. + public HWPFDocumentCore(POIFSFileSystem pfilesystem) + : this(pfilesystem.Root) + { + + } + /// + /// This constructor loads a Word document from a specific point in a POIFSFileSystem, probably not the default.Used typically to open embeded documents. + /// + /// The POIFSFileSystem that Contains the Word document. + /// If there is an unexpected IOException from the passed in POIFSFileSystem. + public HWPFDocumentCore(DirectoryNode directory) + : base(directory) + { + // Sort out the hpsf properties + + + // read in the main stream. + DocumentEntry documentProps = (DocumentEntry) + directory.GetEntry(STREAM_WORD_DOCUMENT); + _mainStream = new byte[documentProps.Size]; + + directory.CreatePOIFSDocumentReader(STREAM_WORD_DOCUMENT).Read(_mainStream); + + // Create our FIB, and check for the doc being encrypted + _fib = new FileInformationBlock(_mainStream); + if (_fib.IsFEncrypted()) + { + throw new EncryptedDocumentException("Cannot process encrypted word files!"); + } + + DirectoryEntry objectPoolEntry; + try + { + objectPoolEntry = (DirectoryEntry)directory.GetEntry(STREAM_OBJECT_POOL); + } + catch (FileNotFoundException exc) + { + objectPoolEntry = null; + } + _objectPool = new ObjectPoolImpl(objectPoolEntry); + } + + /// + /// the range which covers the whole of the document, but excludes any headers and footers. + /// + public abstract Range GetRange(); + + /// + /// the range that covers all text in the file, including main text,footnotes, headers and comments + /// + public abstract Range GetOverallRange(); + + /** + * Returns document text, i.e. text information from all text pieces, + * including OLE descriptions and field codes + */ + public String GetDocumentText() { + return Text.ToString(); + } + + /** + * Internal method to access document text + */ + + public abstract StringBuilder Text{get;} + + public abstract TextPieceTable TextTable { get; } + + + public CHPBinTable CharacterTable + { + get + { + return _cbt; + } + } + + public PAPBinTable ParagraphTable + { + get + { + return _pbt; + } + } + + public SectionTable SectionTable + { + get + { + return _st; + } + } + + public StyleSheet GetStyleSheet() + { + return _ss; + } + + public ListTables GetListTables() + { + return _lt; + } + + public FontTable GetFontTable() + { + return _ft; + } + + public FileInformationBlock GetFileInformationBlock() + { + return _fib; + } + + public ObjectsPool GetObjectsPool() + { + return _objectPool; + } + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/HWPFOldDocument.cs b/scratchpad/HWPF/HWPFOldDocument.cs new file mode 100644 index 0000000..02e538b --- /dev/null +++ b/scratchpad/HWPF/HWPFOldDocument.cs @@ -0,0 +1,147 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +using NPOI.Util; +using System.Text; +using NPOI.HWPF.Model; +using System; +using NPOI.HWPF.UserModel; +using NPOI.POIFS.FileSystem; +using System.IO; +namespace NPOI.HWPF +{ + + /** + * Provides very simple support for old (Word 6 / Word 95) + * files. + */ + public class HWPFOldDocument : HWPFDocumentCore + { + private TextPieceTable tpt; + + public HWPFOldDocument(POIFSFileSystem fs) + : this(fs.Root) + { + + } + [Obsolete] + public HWPFOldDocument(DirectoryNode directory, POIFSFileSystem fs):this(directory) + { + + } + + public HWPFOldDocument(DirectoryNode directory) + : base(directory) + { + + + // Where are things? + int sedTableOffset = LittleEndian.GetInt(_mainStream, 0x88); + int sedTableSize = LittleEndian.GetInt(_mainStream, 0x8c); + int chpTableOffset = LittleEndian.GetInt(_mainStream, 0xb8); + int chpTableSize = LittleEndian.GetInt(_mainStream, 0xbc); + int papTableOffset = LittleEndian.GetInt(_mainStream, 0xc0); + int papTableSize = LittleEndian.GetInt(_mainStream, 0xc4); + //int shfTableOffset = LittleEndian.GetInt(_mainStream, 0x60); + //int shfTableSize = LittleEndian.GetInt(_mainStream, 0x64); + int complexTableOffset = LittleEndian.GetInt(_mainStream, 0x160); + + // We need to get hold of the text that Makes up the + // document, which might be regular or fast-saved + StringBuilder text = new StringBuilder(); + if (_fib.IsFComplex()) + { + ComplexFileTable cft = new ComplexFileTable( + _mainStream, _mainStream, + complexTableOffset, _fib.GetFcMin() + ); + tpt = cft.GetTextPieceTable(); + + foreach (TextPiece tp in tpt.TextPieces) + { + text.Append(tp.GetStringBuilder()); + } + } + else + { + // TODO Discover if these older documents can ever hold Unicode Strings? + // (We think not, because they seem to lack a Piece table) + // TODO Build the Piece Descriptor properly + // (We have to fake it, as they don't seem to have a proper Piece table) + PieceDescriptor pd = new PieceDescriptor(new byte[] { 0, 0, 0, 0, 0, 127, 0, 0 }, 0); + pd.FilePosition = _fib.GetFcMin(); + + // Generate a single Text Piece Table, with a single Text Piece + // which covers all the (8 bit only) text in the file + tpt = new TextPieceTable(); + byte[] textData = new byte[_fib.GetFcMac() - _fib.GetFcMin()]; + Array.Copy(_mainStream, _fib.GetFcMin(), textData, 0, textData.Length); + TextPiece tp = new TextPiece( + 0, textData.Length, textData, pd + ); + tpt.Add(tp); + + text.Append(tp.GetStringBuilder()); + } + + _text = tpt.Text; + + // Now we can fetch the character and paragraph properties + _cbt = new OldCHPBinTable( + _mainStream, chpTableOffset, chpTableSize, + _fib.GetFcMin(), tpt + ); + _pbt = new OldPAPBinTable( + _mainStream, chpTableOffset, papTableSize, + _fib.GetFcMin(), tpt + ); + _st = new OldSectionTable( + _mainStream, chpTableOffset, sedTableSize, + _fib.GetFcMin(), tpt + ); + } + public override Range GetOverallRange() + { + // Life is easy when we have no footers, headers or unicode! + return new Range(0, _fib.GetFcMac() - _fib.GetFcMin(), this); + } + public override Range GetRange() + { + return GetOverallRange(); + } + public override TextPieceTable TextTable + { + get + { + return tpt; + } + } + private StringBuilder _text; + public override StringBuilder Text + { + get + { + return _text; + } + } + + + public override void Write(Stream out1) + { + throw new InvalidOperationException("Writing is not available for the older file formats"); + } + } +} diff --git a/scratchpad/HWPF/Model/BaseObject.cs b/scratchpad/HWPF/Model/BaseObject.cs new file mode 100644 index 0000000..f443c83 --- /dev/null +++ b/scratchpad/HWPF/Model/BaseObject.cs @@ -0,0 +1,177 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Reflection; +using System.Collections; + +namespace NPOI.HWPF.Model +{ + /// + + /// BaseObject class is an abstract class for you to derive from. + + /// Every class that will be dirived from this class will support the + + /// Clone method automaticly. + + /// The class implements the interface ICloneable and there + + /// for every object that will be derived + + /// from this object will support the ICloneable interface as well. + + /// + + + public abstract class BaseObject : ICloneable + { + /// + + /// Clone the object, and returning a reference to a cloned object. + + /// + + /// Reference to the new cloned + + /// object. + + public virtual object Clone() + { + //First we create an instance of this specific type. + + object newObject = Activator.CreateInstance(this.GetType()); + + //We get the array of fields for the new type instance. + + FieldInfo[] fields = newObject.GetType().GetFields(); + + int i = 0; + + foreach (FieldInfo fi in this.GetType().GetFields()) + { + //We query if the fiels support the ICloneable interface. + + Type ICloneType = fi.FieldType. + GetInterface("ICloneable", true); + + if (ICloneType != null) + { + //Getting the ICloneable interface from the object. + + ICloneable IClone = (ICloneable)fi.GetValue(this); + + //We use the clone method to set the new value to the field. + + fields[i].SetValue(newObject, IClone.Clone()); + } + else + { + // If the field doesn't support the ICloneable + + // interface then just set it. + + fields[i].SetValue(newObject, fi.GetValue(this)); + } + + //Now we check if the object support the + + //IEnumerable interface, so if it does + + //we need to enumerate all its items and check if + + //they support the ICloneable interface. + + Type IEnumerableType = fi.FieldType.GetInterface + ("IEnumerable", true); + if (IEnumerableType != null) + { + //Get the IEnumerable interface from the field. + + IEnumerable IEnum = (IEnumerable)fi.GetValue(this); + + //This version support the IList and the + + //IDictionary interfaces to iterate on collections. + + Type IListType = fields[i].FieldType.GetInterface + ("IList", true); + Type IDicType = fields[i].FieldType.GetInterface + ("IDictionary", true); + + int j = 0; + if (IListType != null) + { + //Getting the IList interface. + + IList list = (IList)fields[i].GetValue(newObject); + + foreach (object obj in IEnum) + { + //Checking to see if the current item + + //support the ICloneable interface. + + ICloneType = obj.GetType(). + GetInterface("ICloneable", true); + + if (ICloneType != null) + { + //If it does support the ICloneable interface, + + //we use it to set the clone of + + //the object in the list. + + ICloneable clone = (ICloneable)obj; + + list[j] = clone.Clone(); + } + + //NOTE: If the item in the list is not + + //support the ICloneable interface then in the + + //cloned list this item will be the same + + //item as in the original list + + //(as long as this type is a reference type). + + + j++; + } + } + else if (IDicType != null) + { + //Getting the dictionary interface. + + IDictionary dic = (IDictionary)fields[i]. + GetValue(newObject); + j = 0; + + foreach (DictionaryEntry de in IEnum) + { + //Checking to see if the item + + //support the ICloneable interface. + + ICloneType = de.Value.GetType(). + GetInterface("ICloneable", true); + + if (ICloneType != null) + { + ICloneable clone = (ICloneable)de.Value; + + dic[de.Key] = clone.Clone(); + } + j++; + } + } + } + i++; + } + return newObject; + } + } + +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/BookmarkFirstDescriptor.cs b/scratchpad/HWPF/Model/BookmarkFirstDescriptor.cs new file mode 100644 index 0000000..59e46f0 --- /dev/null +++ b/scratchpad/HWPF/Model/BookmarkFirstDescriptor.cs @@ -0,0 +1,84 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +namespace NPOI.HWPF.Model +{ + + using System; + using NPOI.HWPF.Model.Types; + + + public class BookmarkFirstDescriptor : BKFAbstractType, ICloneable + { + public BookmarkFirstDescriptor() + { + } + + public BookmarkFirstDescriptor(byte[] data, int offset) + { + FillFields(data, offset); + } + + + public override bool Equals(Object obj) + { + if (this == obj) + return true; + if (obj == null) + return false; + if (this.GetType() != obj.GetType()) + return false; + BookmarkFirstDescriptor other = (BookmarkFirstDescriptor)obj; + if (field_1_ibkl != other.field_1_ibkl) + return false; + if (field_2_bkf_flags != other.field_2_bkf_flags) + return false; + return true; + } + + + public override int GetHashCode() + { + int prime = 31; + int result = 1; + result = prime * result + field_1_ibkl; + result = prime * result + field_2_bkf_flags; + return result; + } + + public bool IsEmpty + { + get + { + return field_1_ibkl == 0 && field_2_bkf_flags == 0; + } + } + + + public override String ToString() + { + if (IsEmpty) + return "[BKF] EMPTY"; + + return base.ToString(); + } + } + +} + + + + diff --git a/scratchpad/HWPF/Model/BookmarksTables.cs b/scratchpad/HWPF/Model/BookmarksTables.cs new file mode 100644 index 0000000..7715b23 --- /dev/null +++ b/scratchpad/HWPF/Model/BookmarksTables.cs @@ -0,0 +1,171 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +using System; +using NPOI.Util; +using NPOI.HWPF.Model.IO; +namespace NPOI.HWPF.Model +{ + + + public class BookmarksTables + { + private PlexOfCps descriptorsFirst = new PlexOfCps(4); + + private PlexOfCps descriptorsLim = new PlexOfCps(0); + + private String[] names = new String[0]; + + public BookmarksTables(byte[] tableStream, FileInformationBlock fib) + { + Read(tableStream, fib); + } + + public int GetBookmarksCount() + { + return descriptorsFirst.Length; + } + + public GenericPropertyNode GetDescriptorFirst(int index) + { + return descriptorsFirst.GetProperty(index); + } + + public int GetDescriptorFirstIndex(GenericPropertyNode descriptorFirst) + { + // TODO: very non-optimal + return Arrays.AsList(descriptorsFirst.ToPropertiesArray()).IndexOf( + descriptorFirst); + } + + public GenericPropertyNode GetDescriptorLim(int index) + { + return descriptorsLim.GetProperty(index); + } + + public int GetDescriptorsFirstCount() + { + return descriptorsFirst.Length; + } + + public int GetDescriptorsLimCount() + { + return descriptorsLim.Length; + } + + public String GetName(int index) + { + return names[index]; + } + + public int GetNamesCount() + { + return names.Length; + } + + private void Read(byte[] tableStream, FileInformationBlock fib) + { + int namesStart = fib.GetFcSttbfbkmk(); + int namesLength = fib.GetLcbSttbfbkmk(); + + if (namesStart != 0 && namesLength != 0) + this.names = SttbfUtils.Read(tableStream, namesStart); + + int firstDescriptorsStart = fib.GetFcPlcfbkf(); + int firstDescriptorsLength = fib.GetLcbPlcfbkf(); + if (firstDescriptorsStart != 0 && firstDescriptorsLength != 0) + descriptorsFirst = new PlexOfCps(tableStream, + firstDescriptorsStart, firstDescriptorsLength, + BookmarkFirstDescriptor.GetSize()); + + int limDescriptorsStart = fib.GetFcPlcfbkl(); + int limDescriptorsLength = fib.GetLcbPlcfbkl(); + if (limDescriptorsStart != 0 && limDescriptorsLength != 0) + descriptorsLim = new PlexOfCps(tableStream, limDescriptorsStart, + limDescriptorsLength, 0); + } + + public void SetName(int index, String name) + { + if (index < names.Length) + { + String[] newNames = new String[index + 1]; + Array.Copy(names, 0, newNames, 0, names.Length); + names = newNames; + } + names[index] = name; + } + + public void WritePlcfBkmkf(FileInformationBlock fib, + HWPFStream tableStream) + { + if (descriptorsFirst == null || descriptorsFirst.Length == 0) + { + fib.SetFcPlcfbkf(0); + fib.SetLcbPlcfbkf(0); + return; + } + + int start = tableStream.Offset; + tableStream.Write(descriptorsFirst.ToByteArray()); + int end = tableStream.Offset; + + fib.SetFcPlcfbkf(start); + fib.SetLcbPlcfbkf(end - start); + } + + public void WritePlcfBkmkl(FileInformationBlock fib, + HWPFStream tableStream) + { + if (descriptorsLim == null || descriptorsLim.Length == 0) + { + fib.SetFcPlcfbkl(0); + fib.SetLcbPlcfbkl(0); + return; + } + + int start = tableStream.Offset; + tableStream.Write(descriptorsLim.ToByteArray()); + int end = tableStream.Offset; + + fib.SetFcPlcfbkl(start); + fib.SetLcbPlcfbkl(end - start); + } + + public void WriteSttbfBkmk(FileInformationBlock fib, + HWPFStream tableStream) + { + if (names == null || names.Length == 0) + { + fib.SetFcSttbfbkmk(0); + fib.SetLcbSttbfbkmk(0); + return; + } + + int start = tableStream.Offset; + SttbfUtils.Write(tableStream, names); + int end = tableStream.Offset; + + fib.SetFcSttbfbkmk(start); + fib.SetLcbSttbfbkmk(end - start); + } + } +} + + + + + diff --git a/scratchpad/HWPF/Model/BytePropertyNode.cs b/scratchpad/HWPF/Model/BytePropertyNode.cs new file mode 100644 index 0000000..32e1049 --- /dev/null +++ b/scratchpad/HWPF/Model/BytePropertyNode.cs @@ -0,0 +1,78 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using System; +namespace NPOI.HWPF.Model +{ + /** + * Normally PropertyNodes only ever work in characters, but + * a few cases actually store bytes, and this lets everything + * still work despite that. + * It handles the conversion as required between bytes + * and characters. + */ + public abstract class BytePropertyNode : PropertyNode + { + private int startBytes; + private int endBytes; + + /** + * @param fcStart The start of the text for this property, in _bytes_ + * @param fcEnd The end of the text for this property, in _bytes_ + */ + public BytePropertyNode(int fcStart, int fcEnd, CharIndexTranslator translator, object buf) + : base( + translator.GetCharIndex(fcStart), + translator.GetCharIndex(fcEnd, translator.GetCharIndex(fcStart)), buf) + { + + if (fcStart > fcEnd) + throw new ArgumentException("fcStart (" + fcStart + + ") > fcEnd (" + fcEnd + ")"); + + this.startBytes = fcStart; + this.endBytes = fcEnd; + } + public BytePropertyNode(int charStart, int charEnd, object buf) + :base(charStart, charEnd, buf) + { + + if (charStart > charEnd) + throw new ArgumentException("charStart (" + charStart + + ") > charEnd (" + charEnd + ")"); + + this.startBytes = -1; + this.endBytes = -1; + } + [Obsolete] + public int StartBytes + { + get + { + return startBytes; + } + } + [Obsolete] + public int EndBytes + { + get + { + return endBytes; + } + } + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/CHPBinTable.cs b/scratchpad/HWPF/Model/CHPBinTable.cs new file mode 100644 index 0000000..27d0a01 --- /dev/null +++ b/scratchpad/HWPF/Model/CHPBinTable.cs @@ -0,0 +1,485 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using System.Collections.Generic; +using NPOI.POIFS.Common; +using NPOI.Util; +using NPOI.HWPF.Model.IO; +using System.IO; +using NPOI.HWPF.SPRM; +using System; +namespace NPOI.HWPF.Model +{ + + + /** + * This class holds all of the character formatting properties. + * + * @author Ryan Ackley + */ + public class CHPBinTable + { + /** List of character properties.*/ + internal List _textRuns = new List(); + + + public CHPBinTable() + { + } + + /** + * Constructor used to read a binTable in from a Word document. + * + * @param documentStream + * @param tableStream + * @param offset + * @param size + * @param fcMin + */ + [Obsolete] + public CHPBinTable(byte[] documentStream, byte[] tableStream, int offset, + int size, int fcMin, TextPieceTable tpt):this( documentStream, tableStream, offset, size, tpt ) + { + + } + /** + * Constructor used to read a binTable in from a Word document. + */ + public CHPBinTable(byte[] documentStream, byte[] tableStream, int offset, + int size, CharIndexTranslator translator) + { + PlexOfCps binTable = new PlexOfCps(tableStream, offset, size, 4); + + int length = binTable.Length; + for (int x = 0; x < length; x++) + { + GenericPropertyNode node = binTable.GetProperty(x); + + int pageNum = LittleEndian.GetInt(node.Bytes); + int pageOffset = POIFSConstants.SMALLER_BIG_BLOCK_SIZE * pageNum; + + CHPFormattedDiskPage cfkp = new CHPFormattedDiskPage(documentStream, + pageOffset, translator); + + int fkpSize = cfkp.Size(); + + for (int y = 0; y < fkpSize; y++) + { + CHPX chpx = cfkp.GetCHPX(y); + if (chpx != null) + _textRuns.Add(chpx); + } + } + } + + internal class CHPXToFileComparer : IComparer + { + Dictionary list; + public CHPXToFileComparer(Dictionary list) + { + this.list = list; + } + #region IComparer Members + + public int Compare(CHPX o1, CHPX o2) + { + int i1 = list[o1]; + int i2 = list[o2]; + return i1.CompareTo(i2); + } + #endregion + } + + private static POILogger logger = POILogFactory + .GetLogger(typeof(CHPBinTable)); + + public void Rebuild(ComplexFileTable complexFileTable) + { + long start = DateTime.Now.Ticks; + + if (complexFileTable != null) + { + SprmBuffer[] sprmBuffers = complexFileTable.GetGrpprls(); + + // adding CHPX from fast-saved SPRMs + foreach (TextPiece textPiece in complexFileTable.GetTextPieceTable() + .TextPieces) + { + PropertyModifier prm = textPiece.PieceDescriptor.Prm; + if (!prm.IsComplex()) + continue; + int igrpprl = prm.GetIgrpprl(); + + if (igrpprl < 0 || igrpprl >= sprmBuffers.Length) + { + logger.Log(POILogger.WARN, textPiece + + "'s PRM references to unknown grpprl"); + continue; + } + + bool hasChp = false; + SprmBuffer sprmBuffer = sprmBuffers[igrpprl]; + for (SprmIterator iterator = sprmBuffer.Iterator(); ; iterator + .HasNext()) + { + SprmOperation sprmOperation = iterator.Next(); + if (sprmOperation.Type == SprmOperation.TYPE_CHP) + { + hasChp = true; + break; + } + } + + if (hasChp) + { + SprmBuffer newSprmBuffer; + newSprmBuffer = (SprmBuffer)sprmBuffer.Clone(); + + + CHPX chpx = new CHPX(textPiece.Start, + textPiece.End, newSprmBuffer); + _textRuns.Add(chpx); + } + } + logger.Log(POILogger.DEBUG, + "Merged with CHPX from complex file table in ", + DateTime.Now.Ticks - start, + " ms (", _textRuns.Count, + " elements in total)"); + start = DateTime.Now.Ticks; + } + + List oldChpxSortedByStartPos = new List(_textRuns); + oldChpxSortedByStartPos.Sort( + (IComparer)PropertyNode.CHPXComparator.instance); + + logger.Log(POILogger.DEBUG, "CHPX sorted by start position in ", + DateTime.Now.Ticks - start, " ms"); + start = DateTime.Now.Ticks; + + Dictionary chpxToFileOrder = new Dictionary(); + + int counter = 0; + foreach (CHPX chpx in _textRuns) + { + chpxToFileOrder.Add(chpx, counter++); + } + + + logger.Log(POILogger.DEBUG, "CHPX's order map created in ", + DateTime.Now.Ticks - start, " ms"); + start = DateTime.Now.Ticks; + + List textRunsBoundariesList; + + List textRunsBoundariesSet = new List(); + foreach (CHPX chpx in _textRuns) + { + textRunsBoundariesSet.Add(chpx.Start); + textRunsBoundariesSet.Add(chpx.End); + } + textRunsBoundariesSet.Remove(0); + textRunsBoundariesList = new List( + textRunsBoundariesSet); + textRunsBoundariesList.Sort(); + + + logger.Log(POILogger.DEBUG, "Texts CHPX boundaries collected in ", + DateTime.Now.Ticks - start, " ms"); + start = DateTime.Now.Ticks; + + List newChpxs = new List(); + int lastTextRunStart = 0; + foreach (int objBoundary in textRunsBoundariesList) + { + int boundary = objBoundary; + + int startInclusive = lastTextRunStart; + int endExclusive = boundary; + lastTextRunStart = endExclusive; + + int startPosition = BinarySearch(oldChpxSortedByStartPos, boundary); + startPosition = Math.Abs(startPosition); + while (startPosition >= oldChpxSortedByStartPos.Count) + startPosition--; + while (startPosition > 0 + && oldChpxSortedByStartPos[startPosition].Start >= boundary) + startPosition--; + + List chpxs = new List(); + for (int c = startPosition; c < oldChpxSortedByStartPos.Count; c++) + { + CHPX chpx = oldChpxSortedByStartPos[c]; + + if (boundary < chpx.Start) + break; + + int left = Math.Max(startInclusive, chpx.Start); + int right = Math.Min(endExclusive, chpx.End); + + if (left < right) + { + chpxs.Add(chpx); + } + } + + if (chpxs.Count == 0) + { + logger.Log(POILogger.WARN, "Text piece [", + startInclusive, "; ", + endExclusive, + ") has no CHPX. Creating new one."); + // create it manually + CHPX chpx = new CHPX(startInclusive, endExclusive, + new SprmBuffer(0)); + newChpxs.Add(chpx); + continue; + } + + if (chpxs.Count == 1) + { + // can we reuse existing? + CHPX existing = chpxs[0]; + if (existing.Start == startInclusive + && existing.End == endExclusive) + { + newChpxs.Add(existing); + continue; + } + } + CHPXToFileComparer chpxFileOrderComparator = new CHPXToFileComparer(chpxToFileOrder); + chpxs.Sort(chpxFileOrderComparator); + + SprmBuffer sprmBuffer = new SprmBuffer(0); + foreach (CHPX chpx in chpxs) + { + sprmBuffer.Append(chpx.GetGrpprl(), 0); + } + CHPX newChpx = new CHPX(startInclusive, endExclusive, sprmBuffer); + newChpxs.Add(newChpx); + + continue; + } + this._textRuns = new List(newChpxs); + + logger.Log(POILogger.DEBUG, "CHPX rebuilded in ", + DateTime.Now.Ticks - start, " ms (", + _textRuns.Count, " elements)"); + start = DateTime.Now.Ticks; + + CHPX previous = null; + for (List.Enumerator iterator = _textRuns.GetEnumerator(); iterator + .MoveNext(); ) + { + CHPX current = iterator.Current; + if (previous == null) + { + previous = current; + continue; + } + + if (previous.End == current.Start + && Arrays + .Equals(previous.GetGrpprl(), current.GetGrpprl())) + { + previous.End = current.End; + _textRuns.Remove(current); + continue; + } + + previous = current; + } + + logger.Log(POILogger.DEBUG, "CHPX compacted in ", + DateTime.Now.Ticks - start, " ms (", + _textRuns.Count, " elements)"); + } + + private static int BinarySearch(List chpxs, int startPosition) + { + int low = 0; + int high = chpxs.Count - 1; + + while (low <= high) + { + int mid = (low + high) >> 1; + CHPX midVal = chpxs[mid]; + int midValue = midVal.Start; + + if (midValue < startPosition) + low = mid + 1; + else if (midValue > startPosition) + high = mid - 1; + else + return mid; // key found + } + return -(low + 1); // key not found. + } + + public void AdjustForDelete(int listIndex, int offset, int Length) + { + int size = _textRuns.Count; + int endMark = offset + Length; + int endIndex = listIndex; + + CHPX chpx = _textRuns[endIndex]; + while (chpx.End < endMark) + { + chpx = _textRuns[++endIndex]; + } + if (listIndex == endIndex) + { + chpx = _textRuns[endIndex]; + chpx.End = ((chpx.End - endMark) + offset); + } + else + { + chpx = _textRuns[listIndex]; + chpx.End = (offset); + for (int x = listIndex + 1; x < endIndex; x++) + { + chpx = _textRuns[x]; + chpx.Start = (offset); + chpx.End = (offset); + } + chpx = _textRuns[endIndex]; + chpx.End = ((chpx.End - endMark) + offset); + } + + for (int x = endIndex + 1; x < size; x++) + { + chpx = _textRuns[x]; + chpx.Start = (chpx.Start - Length); + chpx.End = (chpx.End - Length); + } + } + + public void Insert(int listIndex, int cpStart, SprmBuffer buf) + { + + CHPX insertChpx = new CHPX(0, 0, buf); + + // Ensure character OffSets are really characters + insertChpx.Start = (cpStart); + insertChpx.End = (cpStart); + + if (listIndex == _textRuns.Count) + { + _textRuns.Add(insertChpx); + } + else + { + CHPX chpx = _textRuns[listIndex]; + if (chpx.Start < cpStart) + { + // Copy the properties of the one before to afterwards + // Will go: + // Original, until insert at point + // New one + // Clone of original, on to the old end + CHPX clone = new CHPX(0, 0, chpx.GetSprmBuf()); + // Again ensure Contains character based OffSets no matter what + clone.Start = (cpStart); + clone.End = (chpx.End); + + chpx.End = (cpStart); + + _textRuns.Insert(listIndex + 1, insertChpx); + _textRuns.Insert(listIndex + 2, clone); + } + else + { + _textRuns.Insert(listIndex, insertChpx); + } + } + } + + public void AdjustForInsert(int listIndex, int Length) + { + int size = _textRuns.Count; + CHPX chpx = _textRuns[listIndex]; + chpx.End = (chpx.End + Length); + + for (int x = listIndex + 1; x < size; x++) + { + chpx = _textRuns[x]; + chpx.Start = (chpx.Start + Length); + chpx.End = (chpx.End + Length); + } + } + + public List GetTextRuns() + { + return _textRuns; + } + + public void WriteTo(HWPFFileSystem sys, int fcMin) + { + + HWPFStream docStream = sys.GetStream("WordDocument"); + Stream tableStream = sys.GetStream("1Table"); + + PlexOfCps binTable = new PlexOfCps(4); + + // each FKP must start on a 512 byte page. + int docOffset = docStream.Offset; + int mod = docOffset % POIFSConstants.SMALLER_BIG_BLOCK_SIZE; + if (mod != 0) + { + byte[] pAdding = new byte[POIFSConstants.SMALLER_BIG_BLOCK_SIZE - mod]; + docStream.Write(pAdding); + } + + // get the page number for the first fkp + docOffset = docStream.Offset; + int pageNum = docOffset / POIFSConstants.SMALLER_BIG_BLOCK_SIZE; + + // get the ending fc + int endingFc = ((PropertyNode)_textRuns[_textRuns.Count - 1]).End; + endingFc += fcMin; + + + List overflow = _textRuns; + do + { + PropertyNode startingProp = (PropertyNode)overflow[0]; + int start = startingProp.Start + fcMin; + + CHPFormattedDiskPage cfkp = new CHPFormattedDiskPage(); + cfkp.Fill(overflow); + + byte[] bufFkp = cfkp.ToArray(fcMin); + docStream.Write(bufFkp); + overflow = cfkp.GetOverflow(); + + int end = endingFc; + if (overflow != null) + { + end = ((PropertyNode)overflow[0]).Start + fcMin; + } + + byte[] intHolder = new byte[4]; + LittleEndian.PutInt(intHolder, pageNum++); + binTable.AddProperty(new GenericPropertyNode(start, end, intHolder)); + + } + while (overflow != null); + byte[] bytes = binTable.ToByteArray(); + tableStream.Write(bytes, 0, bytes.Length); + } + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/CHPFormattedDiskPage.cs b/scratchpad/HWPF/Model/CHPFormattedDiskPage.cs new file mode 100644 index 0000000..daf8a4b --- /dev/null +++ b/scratchpad/HWPF/Model/CHPFormattedDiskPage.cs @@ -0,0 +1,197 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +namespace NPOI.HWPF.Model +{ + using System.Collections.Generic; + using NPOI.Util; + using System; + using NPOI.HWPF.SPRM; +/** + * Represents a CHP fkp. The style properties for paragraph and character Runs + * are stored in fkps. There are PAP fkps for paragraph properties and CHP fkps + * for character run properties. The first part of the fkp for both CHP and PAP + * fkps consists of an array of 4 byte int offsets that represent a + * Paragraph's or Character Run's text offset in the main stream. The ending + * offset is the next value in the array. For example, if an fkp has X number of + * Paragraph's stored in it then there are (x + 1) 4 byte ints in the beginning + * array. The number X is determined by the last byte in a 512 byte fkp. + * + * CHP and PAP fkps also store the compressed styles(grpprl) that correspond to + * the offsets on the front of the fkp. The offset of the grpprls is determined + * differently for CHP fkps and PAP fkps. + * + * @author Ryan Ackley + */ + public class CHPFormattedDiskPage : FormattedDiskPage + { + private static int FC_SIZE = 4; + + private List _chpxList = new List(); + private List _overFlow; + + + public CHPFormattedDiskPage() + { + } + + /** + * This constructs a CHPFormattedDiskPage from a raw fkp (512 byte array + * read from a Word file). + */ + public CHPFormattedDiskPage(byte[] documentStream, int offset, int fcMin, TextPieceTable tpt) + : this( documentStream, offset, tpt ) + { + } + + + /** + * This constructs a CHPFormattedDiskPage from a raw fkp (512 byte array + * read from a Word file). + */ + public CHPFormattedDiskPage(byte[] documentStream, int offset, + CharIndexTranslator translator) + : base(documentStream, offset) + { + for (int x = 0; x < _crun; x++) + { + int bytesStartAt = GetStart(x); + int bytesEndAt = GetEnd(x); + + int charStartAt = translator.GetCharIndex(bytesStartAt); + int charEndAt = translator.GetCharIndex(bytesEndAt, charStartAt); + + CHPX chpx = new CHPX(charStartAt, charEndAt, new SprmBuffer( + GetGrpprl(x), 0)); + _chpxList.Add(chpx); + } + } + + public CHPX GetCHPX(int index) + { + return _chpxList[index]; + } + public List GetCHPXs() + { + return _chpxList; + } + public void Fill(List Filler) + { + _chpxList.AddRange(Filler); + } + + public List GetOverflow() + { + return _overFlow; + } + + /** + * Gets the chpx for the character run at index in this fkp. + * + * @param index The index of the chpx to Get. + * @return a chpx grpprl. + */ + protected override byte[] GetGrpprl(int index) + { + int chpxOffset = 2 * LittleEndian.GetUByte(_fkp, _offset + (((_crun + 1) * 4) + index)); + + //optimization if offset == 0 use "Normal" style + if (chpxOffset == 0) + { + return new byte[0]; + } + + int size = LittleEndian.GetUByte(_fkp, _offset + chpxOffset); + + byte[] chpx = new byte[size]; + + Array.Copy(_fkp, _offset + ++chpxOffset, chpx, 0, size); + return chpx; + } + + internal byte[] ToArray(int fcMin) + { + byte[] buf = new byte[512]; + int size = _chpxList.Count; + int grpprlOffset = 511; + int offsetOffset = 0; + int fcOffset = 0; + + // total size is currently the size of one FC + int totalSize = FC_SIZE + 2; + + int index = 0; + for (; index < size; index++) + { + int grpprlLength = (_chpxList[index]).GetGrpprl().Length; + + // check to see if we have enough room for an FC, the grpprl offset, + // the grpprl size byte and the grpprl. + totalSize += (FC_SIZE + 2 + grpprlLength); + // if size is uneven we will have to add one so the first grpprl falls + // on a word boundary + if (totalSize > 511 + (index % 2)) + { + totalSize -= (FC_SIZE + 2 + grpprlLength); + break; + } + + // grpprls must fall on word boundaries + if ((1 + grpprlLength) % 2 > 0) + { + totalSize += 1; + } + } + + // see if we couldn't fit some + if (index != size) + { + _overFlow = new List(); + _overFlow.AddRange(_chpxList.GetRange(index, size-index)); + } + + // index should equal number of CHPXs that will be in this fkp now. + buf[511] = (byte)index; + + offsetOffset = (FC_SIZE * index) + FC_SIZE; + //grpprlOffset = offsetOffset + index + (grpprlOffset % 2); + + CHPX chpx = null; + for (int x = 0; x < index; x++) + { + chpx = (CHPX)_chpxList[x]; + byte[] grpprl = chpx.GetGrpprl(); + + LittleEndian.PutInt(buf, fcOffset, chpx.StartBytes + fcMin); + grpprlOffset -= (1 + grpprl.Length); + grpprlOffset -= (grpprlOffset % 2); + buf[offsetOffset] = (byte)(grpprlOffset / 2); + buf[grpprlOffset] = (byte)grpprl.Length; + Array.Copy(grpprl, 0, buf, grpprlOffset + 1, grpprl.Length); + + offsetOffset += 1; + fcOffset += FC_SIZE; + } + // put the last chpx's end in + LittleEndian.PutInt(buf, fcOffset, chpx.EndBytes + fcMin); + return buf; + } + } +} + + diff --git a/scratchpad/HWPF/Model/CHPX.cs b/scratchpad/HWPF/Model/CHPX.cs new file mode 100644 index 0000000..ade62cb --- /dev/null +++ b/scratchpad/HWPF/Model/CHPX.cs @@ -0,0 +1,90 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + using System; + using NPOI.HWPF.UserModel; + using NPOI.HWPF.SPRM; + + /** + * DANGER - works in bytes! + * + * Make sure you call GetStart() / GetEnd() when you want characters + * (normal use), but GetStartByte() / GetEndByte() when you're + * Reading in / writing out! + * + * @author Ryan Ackley + */ + + public class CHPX : BytePropertyNode + { + internal CHPX(int charStart, int charEnd, SprmBuffer buf): + base(charStart, charEnd, buf) + { + + } + [Obsolete] + public CHPX(int fcStart, int fcEnd, CharIndexTranslator translator, byte[] grpprl) + : base(fcStart, translator.LookIndexBackward(fcEnd), translator, new SprmBuffer(grpprl)) + { + + } + [Obsolete] + public CHPX(int fcStart, int fcEnd, CharIndexTranslator translator, SprmBuffer buf) + : base(fcStart, translator.LookIndexBackward(fcEnd), translator, buf) + { + + } + + + public byte[] GetGrpprl() + { + return ((SprmBuffer)_buf).ToByteArray(); + } + + public SprmBuffer GetSprmBuf() + { + return (SprmBuffer)_buf; + } + + public CharacterProperties GetCharacterProperties(StyleSheet ss, short istd) + { + if (ss == null) + { + // TODO Fix up for Word 6/95 + return new CharacterProperties(); + } + + CharacterProperties baseStyle = ss.GetCharacterStyle(istd); + if (baseStyle == null) + baseStyle = new CharacterProperties(); + + CharacterProperties props = + CharacterSprmUncompressor.UncompressCHP(baseStyle, GetGrpprl(), 0); + return props; + } + + public override String ToString() + { + return "CHPX from " + Start + " to " + End + + " (in bytes " + StartBytes + " to " + EndBytes + ")"; + } + } +} + + diff --git a/scratchpad/HWPF/Model/CPSplitCalculator.cs b/scratchpad/HWPF/Model/CPSplitCalculator.cs new file mode 100644 index 0000000..38581a8 --- /dev/null +++ b/scratchpad/HWPF/Model/CPSplitCalculator.cs @@ -0,0 +1,161 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + + using NPOI.HWPF; + + /** + * Helper class for {@link HWPFDocument}, which figures out + * where different kinds of text can be found within the + * overall CP splurge. + */ + public class CPSplitCalculator + { + private FileInformationBlock fib; + public CPSplitCalculator(FileInformationBlock fib) + { + this.fib = fib; + } + + /** + * Where the main document text starts. Always 0. + */ + public int GetMainDocumentStart() + { + return 0; + } + /** + * Where the main document text ends. + * Given by FibRgLw97.ccpText + */ + public int GetMainDocumentEnd() + { + return fib.GetCcpText(); + } + + /** + * Where the Footnotes text starts. + * Follows straight on from the main text. + */ + public int GetFootnoteStart() + { + return GetMainDocumentEnd(); + } + /** + * Where the Footnotes text ends. + * Length comes from FibRgLw97.ccpFtn + */ + public int GetFootnoteEnd() + { + return GetFootnoteStart() + + fib.GetCcpFtn(); + } + + /** + * Where the "Header Story" text starts. + * Follows straight on from the footnotes. + */ + public int GetHeaderStoryStart() + { + return GetFootnoteEnd(); + } + /** + * Where the "Header Story" text ends. + * Length comes from FibRgLw97.ccpHdd + */ + public int GetHeaderStoryEnd() + { + return GetHeaderStoryStart() + + fib.GetCcpHdd(); + } + + /** + * Where the Comment (Atn) text starts. + * Follows straight on from the header stories. + */ + public int GetCommentsStart() + { + return GetHeaderStoryEnd(); + } + /** + * Where the Comment (Atn) text ends. + * Length comes from FibRgLw97.ccpAtn + */ + public int GetCommentsEnd() + { + return GetCommentsStart() + + fib.GetCcpCommentAtn(); + } + + /** + * Where the End Note text starts. + * Follows straight on from the comments. + */ + public int GetEndNoteStart() + { + return GetCommentsEnd(); + } + /** + * Where the End Note text ends. + * Length comes from FibRgLw97.ccpEdn + */ + public int GetEndNoteEnd() + { + return GetEndNoteStart() + + fib.GetCcpEdn(); + } + + /** + * Where the Main Textbox text starts. + * Follows straight on from the end note. + */ + public int GetMainTextboxStart() + { + return GetEndNoteEnd(); + } + /** + * Where the Main textbox text ends. + * Length comes from FibRgLw97.ccpTxBx + */ + public int GetMainTextboxEnd() + { + return GetMainTextboxStart() + + fib.GetCcpTxtBx(); + } + + /** + * Where the Header Textbox text starts. + * Follows straight on from the main textbox. + */ + public int GetHeaderTextboxStart() + { + return GetMainTextboxEnd(); + } + /** + * Where the Header textbox text ends. + * Length comes from FibRgLw97.ccpHdrTxBx + */ + public int GetHeaderTextboxEnd() + { + return GetHeaderTextboxStart() + + fib.GetCcpHdrTxtBx(); + } + } +} + diff --git a/scratchpad/HWPF/Model/CachedPropertyNode.cs b/scratchpad/HWPF/Model/CachedPropertyNode.cs new file mode 100644 index 0000000..d9ba414 --- /dev/null +++ b/scratchpad/HWPF/Model/CachedPropertyNode.cs @@ -0,0 +1,58 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + + using NPOI.HWPF.SPRM; + using System; + + + public class CachedPropertyNode + : PropertyNode + { + protected object _propCache; + + public CachedPropertyNode(int start, int end, SprmBuffer buf) + : base(start, end, buf) + { + + } + + protected void FillCache(Object ref1) + { + _propCache = ref1; + } + + protected Object GetCacheContents() + { + return _propCache == null ? null : _propCache; + } + + /** + * @return This property's property in compressed form. + */ + public SprmBuffer GetSprmBuf() + { + return (SprmBuffer)_buf; + } + + + } +} + + diff --git a/scratchpad/HWPF/Model/CharIndexTranslator.cs b/scratchpad/HWPF/Model/CharIndexTranslator.cs new file mode 100644 index 0000000..d3ce661 --- /dev/null +++ b/scratchpad/HWPF/Model/CharIndexTranslator.cs @@ -0,0 +1,87 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + + public interface CharIndexTranslator + { + /** + * Calculates the byte index of the given char index. + * + * @param charPos + * The char position + * @return The byte index + */ + int GetByteIndex(int charPos); + /** + * Calculates the char index of the given byte index. + * Look forward if index is not in table + * + * @param bytePos The character offset to check + * @return the char index + */ + int GetCharIndex(int bytePos); + + /** + * Calculates the char index of the given byte index. + * Look forward if index is not in table + * + * @param bytePos The character offset to check + * @param startCP look from this characted position + * @return the char index + */ + int GetCharIndex(int bytePos, int startCP); + /** + * Finds character ranges that includes specified byte range. + * + * @param startBytePosInclusive + * start byte range + * @param endBytePosExclusive + * end byte range + */ +// int[][] GetCharIndexRanges(int startBytePosInclusive, int endBytePosExclusive); + + /** + * Check if index is in table + * + * @param bytePos + * @return true if index in table, false if not + */ + + bool IsIndexInTable(int bytePos); + + /** + * Return first index >= bytePos that is in table + * + * @param bytePos + * @return first index greater or equal to bytePos that is in table + */ + int LookIndexForward(int bytePos); + + /** + * Return last index <= bytePos that is in table + * + * @param bytePos + * @return last index less of equal to bytePos that is in table + */ + int LookIndexBackward(int bytePos); + + } + + +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/ComplexFileTable.cs b/scratchpad/HWPF/Model/ComplexFileTable.cs new file mode 100644 index 0000000..d7bbe34 --- /dev/null +++ b/scratchpad/HWPF/Model/ComplexFileTable.cs @@ -0,0 +1,101 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +namespace NPOI.HWPF.Model +{ + using NPOI.Util; + using System.IO; + using NPOI.HWPF.Model.IO; + using NPOI.HWPF.SPRM; + using System.Collections.Generic; + using System; + + public class ComplexFileTable + { + + private static byte GRPPRL_TYPE = 1; + private static byte TEXT_PIECE_TABLE_TYPE = 2; + private SprmBuffer[] _grpprls; + protected TextPieceTable _tpt; + + public ComplexFileTable() + { + _tpt = new TextPieceTable(); + } + + public ComplexFileTable(byte[] documentStream, byte[] tableStream, int offset, int fcMin) + { + //skips through the prms before we reach the piece table. These contain data + //for actual fast saved files + List sprmBuffers = new List(); + //skips through the prms before we reach the piece table. These contain data + //for actual fast saved files + while (tableStream[offset] == GRPPRL_TYPE) + { + offset++; + int size = LittleEndian.GetShort(tableStream, offset); + offset += LittleEndianConsts.SHORT_SIZE; + byte[] bs = LittleEndian.GetByteArray(tableStream, offset, size); + offset += size; + + SprmBuffer sprmBuffer = new SprmBuffer(bs, false, 0); + sprmBuffers.Add(sprmBuffer); + } + this._grpprls = sprmBuffers.ToArray(); + + if (tableStream[offset] != TEXT_PIECE_TABLE_TYPE) + { + throw new IOException("The text piece table is corrupted"); + } + int pieceTableSize = LittleEndian.GetInt(tableStream, ++offset); + offset += LittleEndianConsts.INT_SIZE; + _tpt = new TextPieceTable(documentStream, tableStream, offset, pieceTableSize, fcMin); + } + + public TextPieceTable GetTextPieceTable() + { + return _tpt; + } + + public SprmBuffer[] GetGrpprls() + { + return _grpprls; + } + + [Obsolete] + public void WriteTo(HWPFFileSystem sys) + { + HWPFStream docStream = sys.GetStream("WordDocument"); + HWPFStream tableStream = sys.GetStream("1Table"); + WriteTo(docStream, tableStream); + } + + public void WriteTo(HWPFStream wordDocumentStream,HWPFStream tableStream) + { + tableStream.Write(TEXT_PIECE_TABLE_TYPE); + + byte[] table = _tpt.WriteTo(wordDocumentStream); + + byte[] numHolder = new byte[LittleEndianConsts.INT_SIZE]; + LittleEndian.PutInt(numHolder, table.Length); + tableStream.Write(numHolder); + tableStream.Write(table); + } + } +} + diff --git a/scratchpad/HWPF/Model/DocumentProperties.cs b/scratchpad/HWPF/Model/DocumentProperties.cs new file mode 100644 index 0000000..8d6cc61 --- /dev/null +++ b/scratchpad/HWPF/Model/DocumentProperties.cs @@ -0,0 +1,36 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +namespace NPOI.HWPF.Model +{ + using NPOI.HWPF.Model.Types; + +/** + * Comment me + * + * @author Ryan Ackley + */ +public class DocumentProperties : DOPAbstractType { + + + public DocumentProperties(byte[] tableStream, int OffSet) { + base.FillFields(tableStream, OffSet); + + } + } +} diff --git a/scratchpad/HWPF/Model/EscherRecordHolder.cs b/scratchpad/HWPF/Model/EscherRecordHolder.cs new file mode 100644 index 0000000..a082336 --- /dev/null +++ b/scratchpad/HWPF/Model/EscherRecordHolder.cs @@ -0,0 +1,215 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ +namespace NPOI.HWPF.Model +{ + using System; + using System.Text; + using System.Collections; + using NPOI.DDF; + using System.Collections.Generic; + + /** + * Based on AbstractEscherRecordHolder fomr HSSF. + * + * @author Squeeself + */ + public class EscherRecordHolder + { + protected List escherRecords = new List(); + + public EscherRecordHolder() + { + + } + + public EscherRecordHolder(byte[] data, int offset, int size) + { + FillEscherRecords(data, offset, size); + } + + private void FillEscherRecords(byte[] data, int offset, int size) + { + IEscherRecordFactory recordFactory = new DefaultEscherRecordFactory(); + int pos = offset; + while (pos < offset + size) + { + EscherRecord r = recordFactory.CreateRecord(data, pos); + escherRecords.Add(r); + int bytesRead = r.FillFields(data, pos, recordFactory); + pos += bytesRead + 1; // There Is an empty byte between each top-level record in a Word doc + } + } + + public List EscherRecords + { + get + { + return escherRecords; + } + } + + public override String ToString() + { + StringBuilder buffer = new StringBuilder(); + + String nl = System.Environment.NewLine; + if (escherRecords.Count == 0) + buffer.Append("No Escher Records Decoded" + nl); + for (IEnumerator iterator = escherRecords.GetEnumerator(); iterator.MoveNext(); ) + { + EscherRecord r = (EscherRecord)iterator.Current; + buffer.Append(r.ToString()); + } + + return buffer.ToString(); + } + + /** + * If we have a EscherContainerRecord as one of our + * children (and most top level escher holders do), + * then return that. + */ + public EscherContainerRecord EscherContainer + { + get + { + for (IEnumerator it = escherRecords.GetEnumerator(); it.MoveNext(); ) + { + Object er = it.Current; + if (er is EscherContainerRecord) + { + return (EscherContainerRecord)er; + } + } + return null; + } + } + + /** + * Descends into all our children, returning the + * first EscherRecord with the given id, or null + * if none found + */ + public EscherRecord FindFirstWithId(short id) + { + return FindFirstWithId(id, this.EscherRecords); + } + private EscherRecord FindFirstWithId(short id, IList records) + { + // Check at our level + for (IEnumerator it = records.GetEnumerator(); it.MoveNext(); ) + { + EscherRecord r = (EscherRecord)it.Current; + if (r.RecordId == id) + { + return r; + } + } + + // Then check our children in turn + for (IEnumerator it = records.GetEnumerator(); it.MoveNext(); ) + { + EscherRecord r = (EscherRecord)it.Current; + if (r.IsContainerRecord) + { + EscherRecord found = + FindFirstWithId(id, r.ChildRecords); + if (found != null) + { + return found; + } + } + } + + // Not found in this lot + return null; + } + + public List GetEscherRecords() + { + return escherRecords; + } + + + public List GetDgContainers() + { + List dgContainers = new List( + 1); + foreach (EscherRecord escherRecord in GetEscherRecords()) + { + if (escherRecord.RecordId == unchecked((short)0xF002)) + { + dgContainers.Add((EscherContainerRecord)escherRecord); + } + } + return dgContainers; + } + + public List GetDggContainers() + { + List dggContainers = new List( + 1); + foreach (EscherRecord escherRecord in GetEscherRecords()) + { + if (escherRecord.RecordId == unchecked((short)0xF000)) + { + dggContainers.Add((EscherContainerRecord)escherRecord); + } + } + return dggContainers; + } + + public List GetBStoreContainers() + { + List bStoreContainers = new List( + 1); + foreach (EscherContainerRecord dggContainer in GetDggContainers()) + { + foreach (EscherRecord escherRecord in dggContainer.ChildRecords) + { + if (escherRecord.RecordId == unchecked((short)0xF001)) + { + bStoreContainers.Add((EscherContainerRecord)escherRecord); + } + } + } + return bStoreContainers; + } + + public List GetSpgrContainers() + { + List spgrContainers = new List( + 1); + foreach (EscherContainerRecord dgContainer in GetDgContainers()) + { + foreach (EscherRecord escherRecord in dgContainer.ChildRecords) + { + if (escherRecord.RecordId == unchecked((short)0xF003)) + { + spgrContainers.Add((EscherContainerRecord)escherRecord); + } + } + } + return spgrContainers; + } + + public List GetSpContainers() + { + List spContainers = new List( + 1); + foreach (EscherContainerRecord spgrContainer in GetSpgrContainers()) + { + foreach (EscherRecord escherRecord in spgrContainer.ChildRecords) + { + if (escherRecord.RecordId == unchecked((short)0xF004)) + { + spContainers.Add((EscherContainerRecord)escherRecord); + } + } + } + return spContainers; + } + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/FIB/FIB.cs b/scratchpad/HWPF/Model/FIB/FIB.cs new file mode 100644 index 0000000..2bcd850 --- /dev/null +++ b/scratchpad/HWPF/Model/FIB/FIB.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NPOI.HWPF.Model +{ + public class FIB + { + public FIBBase fibBase; + public short csw = 0; + public FibRgW97 fibRgW97; + public short cslw = 0; + public FibRgLw97 fibRgLw97; + + public FibRgFcLcb fibRgFcLcb; + public short cswNew = 0; + public FIBCswNew fibCswNew; + + public FIB() + { + + } + + public void Deserialize(HWPFStream stream) + { + fibBase = new FIBBase(); + fibBase.Deserialize(stream); + csw = stream.ReadShort(); + if (csw != 0x000E) + { + throw new ArgumentOutOfRangeException("csw must be 0x000E"); + } + fibRgW97 = new FibRgW97(); + fibRgW97.Deserialize(stream); + cslw = stream.ReadShort(); + if (cslw != 0x0016) + { + throw new ArgumentOutOfRangeException("cslw must be 0x0016"); + } + fibRgLw97 = new FibRgLw97(); + fibRgLw97.Deserialize(stream); + + fibRgFcLcb = new FibRgFcLcb(); + fibRgFcLcb.Deserialize(stream); + cswNew = stream.ReadShort(); + fibCswNew = new FIBCswNew(); + fibCswNew.Deserialize(stream); + } + } +} diff --git a/scratchpad/HWPF/Model/FIB/FIBBase.cs b/scratchpad/HWPF/Model/FIB/FIBBase.cs new file mode 100644 index 0000000..0cc3030 --- /dev/null +++ b/scratchpad/HWPF/Model/FIB/FIBBase.cs @@ -0,0 +1,176 @@ +using System; +using System.Text; +using NPOI.Util; + +namespace NPOI.HWPF.Model +{ + public class FIBBase + { + short field_1_wIdent; + short field_2_nFib; + short field_4_lid; + short field_5_pnNext; + short field_6_flags=0; + + static BitField field_6_fDot = BitFieldFactory.GetInstance(0x01); + static BitField field_6_fGlsy = BitFieldFactory.GetInstance(0x02); + static BitField field_6_fComplex = BitFieldFactory.GetInstance(0x04); + static BitField field_6_fHasPic = BitFieldFactory.GetInstance(0x08); + static BitField field_6_cQuickSaves = BitFieldFactory.GetInstance(0xF0); + static BitField field_6_fEncrypted = BitFieldFactory.GetInstance(0x100); + static BitField field_6_fWhichTblStm = BitFieldFactory.GetInstance(0x200); + static BitField field_6_fReadOnlyRecommended = BitFieldFactory.GetInstance(0x400); + static BitField field_6_fWriteReservation = BitFieldFactory.GetInstance(0x800); + static BitField field_6_fExtChar = BitFieldFactory.GetInstance(0x1000); + static BitField field_6_fLoadOverride = BitFieldFactory.GetInstance(0x2000); + static BitField field_6_fFarEast = BitFieldFactory.GetInstance(0x4000); + static BitField field_6_fObfuscated = BitFieldFactory.GetInstance(0x8000); + + short field_7_nFibBack; + int field_8_lKey; + //byte field_9_envr; + byte field_10_flags=0; + + //BitField field_10_fMac = BitFieldFactory.GetInstance(0x01); + //BitField field_10_fEmptySpecial = BitFieldFactory.GetInstance(0x02); + BitField field_10_fLoadOverridePage = BitFieldFactory.GetInstance(0x04); + + + + public FIBBase() + { + + } + + public void Deserialize(HWPFStream stream) + { + field_1_wIdent = stream.ReadShort(); + field_2_nFib = stream.ReadShort(); + stream.ReadShort(); + field_4_lid = stream.ReadShort(); + field_5_pnNext = stream.ReadShort(); + field_6_flags = stream.ReadShort(); + field_7_nFibBack = stream.ReadShort(); + field_8_lKey = stream.ReadInt(); + stream.ReadByte(); //field 9 + field_10_flags = (byte)stream.ReadByte(); + stream.ReadShort(); //reserved3 + stream.ReadShort(); //reserved4 + stream.ReadInt(); //reserved5 + stream.ReadInt(); //reserved6 + } + + public short wIdent + { + get { return field_1_wIdent; } + set { field_1_wIdent = value; } + } + + public short nFib + { + get { return field_2_nFib; } + set { field_2_nFib = value; } + } + + public short lid + { + get { return field_4_lid; } + set { field_4_lid = value; } + } + + public short pnNext + { + get { return field_5_pnNext; } + set { field_5_pnNext = value; } + } + + public bool IsDocumentTemplate + { + get { return field_6_fDot.IsSet(field_6_flags); } + set { field_6_flags = field_6_fDot.SetShortBoolean(field_6_flags, value); } + } + + public bool IsComplex + { + get { return field_6_fComplex.IsSet(field_6_flags); } + set { field_6_flags = field_6_fComplex.SetShortBoolean(field_6_flags, value); } + } + + public bool HasPicture + { + get { return field_6_fHasPic.IsSet(field_6_flags); } + set { field_6_flags = field_6_fHasPic.SetShortBoolean(field_6_flags, value); } + } + + public short QuickSavesTimes + { + get { return field_6_cQuickSaves.GetShortValue(field_6_flags); } + set { field_6_flags = field_6_cQuickSaves.SetShortValue(field_6_flags, value); } + } + + public bool IsEncrypted + { + get { return field_6_fEncrypted.IsSet(field_6_flags); } + set { field_6_flags = field_6_fEncrypted.SetShortBoolean(field_6_flags, value); } + } + + public short WhichTableStream + { + get { return field_6_fWhichTblStm.GetShortValue(field_6_flags); } + set { field_6_flags = field_6_fWhichTblStm.SetShortValue(field_6_flags, value); } + } + + public bool IsReadOnlyRecommended + { + get { return field_6_fReadOnlyRecommended.IsSet(field_6_flags); } + set { field_6_flags = field_6_fReadOnlyRecommended.SetShortBoolean(field_6_flags, value); } + } + + public bool HasWriteReservationPassword + { + get { return field_6_fWriteReservation.IsSet(field_6_flags); } + set { field_6_flags = field_6_fWriteReservation.SetShortBoolean(field_6_flags, value); } + } + + public bool IsLoadOverride + { + get { return field_6_fLoadOverride.IsSet(field_6_flags); } + set { field_6_flags = field_6_fLoadOverride.SetShortBoolean(field_6_flags, value); } + } + + public bool IsFarEast + { + get { return field_6_fFarEast.IsSet(field_6_flags); } + set { field_6_flags = field_6_fFarEast.SetShortBoolean(field_6_flags, value); } + } + + public bool UseXORObfuscation + { + get { return field_6_fObfuscated.IsSet(field_6_flags); } + set { field_6_flags = field_6_fObfuscated.SetShortBoolean(field_6_flags, value); } + } + + public short nFibBack + { + get { return field_7_nFibBack; } + set { field_7_nFibBack = value; } + } + + public int lKey + { + get { return field_8_lKey; } + set { field_8_lKey = value; } + } + + public bool IsLoadOverridePage + { + get { return field_10_fLoadOverridePage.IsSet(field_10_flags); } + set { field_10_flags = field_10_fLoadOverridePage.SetByteBoolean(field_10_flags, value); } + } + + public int fExtChar + { + get { return field_6_fExtChar.GetValue(field_6_flags); } + } + } +} diff --git a/scratchpad/HWPF/Model/FIB/FIBCswNew.cs b/scratchpad/HWPF/Model/FIB/FIBCswNew.cs new file mode 100644 index 0000000..02e9623 --- /dev/null +++ b/scratchpad/HWPF/Model/FIB/FIBCswNew.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NPOI.HWPF.Model +{ + public class FIBCswNew + { + public short nFibNew=0; + private short cQuickSavesNew=0; + + + public FIBCswNew() + { + + } + + public void Deserialize(HWPFStream stream) + { + nFibNew = stream.ReadShort(); + if (nFibNew == (short)0x0112) + { + ReadFibRgCswNewData2007(stream); + } + else + { + ReadFibRgCswNewData2000(stream); + } + } + + private void ReadFibRgCswNewData2000(HWPFStream stream) + { + this.cQuickSavesNew = stream.ReadShort(); + } + + private void ReadFibRgCswNewData2007(HWPFStream stream) + { + ReadFibRgCswNewData2000(stream); + stream.ReadShort(); //lidThemeOther + stream.ReadShort(); //lidThemeFE + stream.ReadShort(); //lidThemeCS + } + + public short QuickSavesTimes + { + get { return cQuickSavesNew; } + set { cQuickSavesNew = value; } + } + } +} diff --git a/scratchpad/HWPF/Model/FIB/FibRgFcLcb.cs b/scratchpad/HWPF/Model/FIB/FibRgFcLcb.cs new file mode 100644 index 0000000..d0ada8c --- /dev/null +++ b/scratchpad/HWPF/Model/FIB/FibRgFcLcb.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NPOI.HWPF.Model +{ + public class FibRgFcLcb + { + public FibRgFcLcb97 fibRgFcLcb97; + public FibRgFcLcb2000 fibRgFcLcb2000; + public FibRgFcLcb2002 fibRgFcLcb2002; + public FibRgFcLcb2003 fibRgFcLcb2003; + public FibRgFcLcb2007 fibRgFcLcb2007; + public short cbRgFcLcb = 0; + + public FibRgFcLcb() + { + + } + + public void Deserialize(HWPFStream stream) + { + cbRgFcLcb = stream.ReadShort(); + switch (cbRgFcLcb) + { + case 0x005D: + fibRgFcLcb97 = new FibRgFcLcb97(); + fibRgFcLcb97.Deserialize(stream); + break; + case 0x006C: + fibRgFcLcb2000 = new FibRgFcLcb2000(); + fibRgFcLcb2000.Deserialize(stream); + fibRgFcLcb97 = fibRgFcLcb2000.fibRgFcLcb97; + break; + case 0x0088: + fibRgFcLcb2002 = new FibRgFcLcb2002(); + fibRgFcLcb2002.Deserialize(stream); + fibRgFcLcb97 = fibRgFcLcb2002.fibRgFcLcb2000.fibRgFcLcb97; + fibRgFcLcb2000 = fibRgFcLcb2002.fibRgFcLcb2000; + break; + case 0x00A4 : + fibRgFcLcb2003 = new FibRgFcLcb2003(); + fibRgFcLcb2003.Deserialize(stream); + fibRgFcLcb97 = fibRgFcLcb2003.fibRgFcLcb2002.fibRgFcLcb2000.fibRgFcLcb97; + fibRgFcLcb2000 = fibRgFcLcb2003.fibRgFcLcb2002.fibRgFcLcb2000; + fibRgFcLcb2002 = fibRgFcLcb2003.fibRgFcLcb2002; + break; + case 0x00B7: + fibRgFcLcb2007 = new FibRgFcLcb2007(); + fibRgFcLcb2007.Deserialize(stream); + fibRgFcLcb97 = fibRgFcLcb2007.fibRgFcLcb2003.fibRgFcLcb2002.fibRgFcLcb2000.fibRgFcLcb97; + fibRgFcLcb2000 = fibRgFcLcb2007.fibRgFcLcb2003.fibRgFcLcb2002.fibRgFcLcb2000; + fibRgFcLcb2002 = fibRgFcLcb2007.fibRgFcLcb2003.fibRgFcLcb2002; + fibRgFcLcb2003 = fibRgFcLcb2007.fibRgFcLcb2003; + break; + } + } + } +} diff --git a/scratchpad/HWPF/Model/FIB/FibRgFcLcb2000.cs b/scratchpad/HWPF/Model/FIB/FibRgFcLcb2000.cs new file mode 100644 index 0000000..afec77a --- /dev/null +++ b/scratchpad/HWPF/Model/FIB/FibRgFcLcb2000.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NPOI.HWPF.Model +{ + public class FibRgFcLcb2000 + { + public int fcPlcfTch = 0; + public int lcbPlcfTch = 0; + public int fcRmdThreading = 0; + public int lcbRmdThreading = 0; + public int fcMid = 0; + public int lcbMid = 0; + public int fcSttbRgtplc = 0; + public int lcbSttbRgtplc = 0; + public int fcMsoEnvelope = 0; + public int lcbMsoEnvelope = 0; + public int fcPlcfLad = 0; + public int lcbPlcfLad = 0; + public int fcRgDofr = 0; + public int lcbRgDofr = 0; + public int fcPlcosl = 0; + public int lcbPlcosl = 0; + public int fcPlcfCookieOld = 0; + public int lcbPlcfCookieOld = 0; + public int fcPgdMotherOld = 0; + public int lcbPgdMotherOld = 0; + public int fcBkdMotherOld = 0; + public int lcbBkdMotherOld = 0; + public int fcPgdFtnOld = 0; + public int lcbPgdFtnOld = 0; + public int fcBkdFtnOld = 0; + public int lcbBkdFtnOld = 0; + public int fcPgdEdnOld = 0; + public int lcbPgdEdnOld = 0; + public int fcBkdEdnOld = 0; + public int lcbBkdEdnOld = 0; + + public FibRgFcLcb97 fibRgFcLcb97; + + public FibRgFcLcb2000() + { + } + + public void Deserialize(HWPFStream stream) + { + fibRgFcLcb97 = new FibRgFcLcb97(); + fibRgFcLcb97.Deserialize(stream); + + fcPlcfTch = stream.ReadInt(); + lcbPlcfTch = stream.ReadInt(); + fcRmdThreading = stream.ReadInt(); + lcbRmdThreading = stream.ReadInt(); + fcMid = stream.ReadInt(); + lcbMid = stream.ReadInt(); + fcSttbRgtplc = stream.ReadInt(); + lcbSttbRgtplc = stream.ReadInt(); + fcMsoEnvelope = stream.ReadInt(); + lcbMsoEnvelope = stream.ReadInt(); + fcPlcfLad = stream.ReadInt(); + lcbPlcfLad = stream.ReadInt(); + fcRgDofr = stream.ReadInt(); + lcbRgDofr = stream.ReadInt(); + fcPlcosl = stream.ReadInt(); + lcbPlcosl = stream.ReadInt(); + fcPlcfCookieOld = stream.ReadInt(); + lcbPlcfCookieOld = stream.ReadInt(); + fcPgdMotherOld = stream.ReadInt(); + lcbPgdMotherOld = stream.ReadInt(); + fcBkdMotherOld = stream.ReadInt(); + lcbBkdMotherOld = stream.ReadInt(); + fcPgdFtnOld = stream.ReadInt(); + lcbPgdFtnOld = stream.ReadInt(); + fcBkdFtnOld = stream.ReadInt(); + lcbBkdFtnOld = stream.ReadInt(); + fcPgdEdnOld = stream.ReadInt(); + lcbPgdEdnOld = stream.ReadInt(); + fcBkdEdnOld = stream.ReadInt(); + lcbBkdEdnOld = stream.ReadInt(); + + } + } +} diff --git a/scratchpad/HWPF/Model/FIB/FibRgFcLcb2002.cs b/scratchpad/HWPF/Model/FIB/FibRgFcLcb2002.cs new file mode 100644 index 0000000..cf10e93 --- /dev/null +++ b/scratchpad/HWPF/Model/FIB/FibRgFcLcb2002.cs @@ -0,0 +1,136 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NPOI.HWPF.Model +{ + public class FibRgFcLcb2002 + { + public int fcUnused1 = 0; + public int lcbUnused1 = 0; + public int fcPlcfPgp = 0; + public int lcbPlcfPgp = 0; + public int fcPlcfuim = 0; + public int lcbPlcfuim = 0; + public int fcPlfguidUim = 0; + public int lcbPlfguidUim = 0; + public int fcAtrdExtra = 0; + public int lcbAtrdExtra = 0; + public int fcPlrsid = 0; + public int lcbPlrsid = 0; + public int fcSttbfBkmkFactoid = 0; + public int lcbSttbfBkmkFactoid = 0; + public int fcPlcfBkfFactoid = 0; + public int lcbPlcfBkfFactoid = 0; + public int fcPlcpublicfcookie = 0; + public int lcbPlcpublicfcookie = 0; + public int fcPlcfBklFactoid = 0; + public int lcbPlcfBklFactoid = 0; + public int fcFactoidData = 0; + public int lcbFactoidData = 0; + public int fcDocUndo = 0; + public int lcbDocUndo = 0; + public int fcSttbfBkmkFcc = 0; + public int lcbSttbfBkmkFcc = 0; + public int fcPlcfBkfFcc = 0; + public int lcbPlcfBkfFcc = 0; + public int fcPlcfBklFcc = 0; + public int lcbPlcfBklFcc = 0; + public int fcSttbfbkmkBPRepairs = 0; + public int lcbSttbfbkmkBPRepairs = 0; + public int fcPlcfbkfBPRepairs = 0; + public int lcbPlcfbkfBPRepairs = 0; + public int fcPlcfbklBPRepairs = 0; + public int lcbPlcfbklBPRepairs = 0; + public int fcPmsNew = 0; + public int lcbPmsNew = 0; + public int fcODSO = 0; + public int lcbODSO = 0; + public int fcPlcfpmiOldXP = 0; + public int lcbPlcfpmiOldXP = 0; + public int fcPlcfpmiNewXP = 0; + public int lcbPlcfpmiNewXP = 0; + public int fcPlcfpmiMixedXP = 0; + public int lcbPlcfpmiMixedXP = 0; + public int fcUnused2 = 0; + public int lcbUnused2 = 0; + public int fcPlcffactoid = 0; + public int lcbPlcffactoid = 0; + public int fcPlcflvcOldXP = 0; + public int lcbPlcflvcOldXP = 0; + public int fcPlcflvcNewXP = 0; + public int lcbPlcflvcNewXP = 0; + public int fcPlcflvcMixedXP = 0; + public int lcbPlcflvcMixedXP = 0; + + public FibRgFcLcb2000 fibRgFcLcb2000; + + public FibRgFcLcb2002() + { + + + } + public void Deserialize(HWPFStream stream) + { + fibRgFcLcb2000 = new FibRgFcLcb2000(); + fibRgFcLcb2000.Deserialize(stream); + + fcUnused1 = stream.ReadInt(); + lcbUnused1 = stream.ReadInt(); + fcPlcfPgp = stream.ReadInt(); + lcbPlcfPgp = stream.ReadInt(); + fcPlcfuim = stream.ReadInt(); + lcbPlcfuim = stream.ReadInt(); + fcPlfguidUim = stream.ReadInt(); + lcbPlfguidUim = stream.ReadInt(); + fcAtrdExtra = stream.ReadInt(); + lcbAtrdExtra = stream.ReadInt(); + fcPlrsid = stream.ReadInt(); + lcbPlrsid = stream.ReadInt(); + fcSttbfBkmkFactoid = stream.ReadInt(); + lcbSttbfBkmkFactoid = stream.ReadInt(); + fcPlcfBkfFactoid = stream.ReadInt(); + lcbPlcfBkfFactoid = stream.ReadInt(); + fcPlcpublicfcookie = stream.ReadInt(); + lcbPlcpublicfcookie = stream.ReadInt(); + fcPlcfBklFactoid = stream.ReadInt(); + lcbPlcfBklFactoid = stream.ReadInt(); + fcFactoidData = stream.ReadInt(); + lcbFactoidData = stream.ReadInt(); + fcDocUndo = stream.ReadInt(); + lcbDocUndo = stream.ReadInt(); + fcSttbfBkmkFcc = stream.ReadInt(); + lcbSttbfBkmkFcc = stream.ReadInt(); + fcPlcfBkfFcc = stream.ReadInt(); + lcbPlcfBkfFcc = stream.ReadInt(); + fcPlcfBklFcc = stream.ReadInt(); + lcbPlcfBklFcc = stream.ReadInt(); + fcSttbfbkmkBPRepairs = stream.ReadInt(); + lcbSttbfbkmkBPRepairs = stream.ReadInt(); + fcPlcfbkfBPRepairs = stream.ReadInt(); + lcbPlcfbkfBPRepairs = stream.ReadInt(); + fcPlcfbklBPRepairs = stream.ReadInt(); + lcbPlcfbklBPRepairs = stream.ReadInt(); + fcPmsNew = stream.ReadInt(); + lcbPmsNew = stream.ReadInt(); + fcODSO = stream.ReadInt(); + lcbODSO = stream.ReadInt(); + fcPlcfpmiOldXP = stream.ReadInt(); + lcbPlcfpmiOldXP = stream.ReadInt(); + fcPlcfpmiNewXP = stream.ReadInt(); + lcbPlcfpmiNewXP = stream.ReadInt(); + fcPlcfpmiMixedXP = stream.ReadInt(); + lcbPlcfpmiMixedXP = stream.ReadInt(); + fcUnused2 = stream.ReadInt(); + lcbUnused2 = stream.ReadInt(); + fcPlcffactoid = stream.ReadInt(); + lcbPlcffactoid = stream.ReadInt(); + fcPlcflvcOldXP = stream.ReadInt(); + lcbPlcflvcOldXP = stream.ReadInt(); + fcPlcflvcNewXP = stream.ReadInt(); + lcbPlcflvcNewXP = stream.ReadInt(); + fcPlcflvcMixedXP = stream.ReadInt(); + lcbPlcflvcMixedXP = stream.ReadInt(); + } + } +} diff --git a/scratchpad/HWPF/Model/FIB/FibRgFcLcb2003.cs b/scratchpad/HWPF/Model/FIB/FibRgFcLcb2003.cs new file mode 100644 index 0000000..30ed879 --- /dev/null +++ b/scratchpad/HWPF/Model/FIB/FibRgFcLcb2003.cs @@ -0,0 +1,136 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NPOI.HWPF.Model +{ + public class FibRgFcLcb2003 + { + public int fcHplxsdr= 0; + public int lcbHplxsdr= 0; + public int fcSttbfBkmkSdt= 0; + public int lcbSttbfBkmkSdt= 0; + public int fcPlcfBkfSdt= 0; + public int lcbPlcfBkfSdt= 0; + public int fcPlcfBklSdt= 0; + public int lcbPlcfBklSdt= 0; + public int fcCustomXForm= 0; + public int lcbCustomXForm= 0; + public int fcSttbfBkmkProt= 0; + public int lcbSttbfBkmkProt= 0; + public int fcPlcfBkfProt= 0; + public int lcbPlcfBkfProt= 0; + public int fcPlcfBklProt= 0; + public int lcbPlcfBklProt= 0; + public int fcSttbProtUser= 0; + public int lcbSttbProtUser= 0; + public int fcUnused= 0; + public int lcbUnused= 0; + public int fcPlcfpmiOld= 0; + public int lcbPlcfpmiOld= 0; + public int fcPlcfpmiOldInline= 0; + public int lcbPlcfpmiOldInline= 0; + public int fcPlcfpmiNew= 0; + public int lcbPlcfpmiNew= 0; + public int fcPlcfpmiNewInline= 0; + public int lcbPlcfpmiNewInline= 0; + public int fcPlcflvcOld= 0; + public int lcbPlcflvcOld= 0; + public int fcPlcflvcOldInline= 0; + public int lcbPlcflvcOldInline= 0; + public int fcPlcflvcNew= 0; + public int lcbPlcflvcNew= 0; + public int fcPlcflvcNewInline= 0; + public int lcbPlcflvcNewInline= 0; + public int fcPgdMother= 0; + public int lcbPgdMother= 0; + public int fcBkdMother= 0; + public int lcbBkdMother= 0; + public int fcAfdMother= 0; + public int lcbAfdMother= 0; + public int fcPgdFtn= 0; + public int lcbPgdFtn= 0; + public int fcBkdFtn= 0; + public int lcbBkdFtn= 0; + public int fcAfdFtn= 0; + public int lcbAfdFtn= 0; + public int fcPgdEdn= 0; + public int lcbPgdEdn= 0; + public int fcBkdEdn= 0; + public int lcbBkdEdn= 0; + public int fcAfdEdn= 0; + public int lcbAfdEdn= 0; + public int fcAfd= 0; + public int lcbAfd= 0; + + public FibRgFcLcb2002 fibRgFcLcb2002; + + public FibRgFcLcb2003() + { + + } + + public void Deserialize(HWPFStream stream) + { + fibRgFcLcb2002 = new FibRgFcLcb2002(); + fibRgFcLcb2002.Deserialize(stream); + + fcHplxsdr = stream.ReadInt(); + lcbHplxsdr = stream.ReadInt(); + fcSttbfBkmkSdt = stream.ReadInt(); + lcbSttbfBkmkSdt = stream.ReadInt(); + fcPlcfBkfSdt = stream.ReadInt(); + lcbPlcfBkfSdt = stream.ReadInt(); + fcPlcfBklSdt = stream.ReadInt(); + lcbPlcfBklSdt = stream.ReadInt(); + fcCustomXForm = stream.ReadInt(); + lcbCustomXForm = stream.ReadInt(); + fcSttbfBkmkProt = stream.ReadInt(); + lcbSttbfBkmkProt = stream.ReadInt(); + fcPlcfBkfProt = stream.ReadInt(); + lcbPlcfBkfProt = stream.ReadInt(); + fcPlcfBklProt = stream.ReadInt(); + lcbPlcfBklProt = stream.ReadInt(); + fcSttbProtUser = stream.ReadInt(); + lcbSttbProtUser = stream.ReadInt(); + fcUnused = stream.ReadInt(); + lcbUnused = stream.ReadInt(); + fcPlcfpmiOld = stream.ReadInt(); + lcbPlcfpmiOld = stream.ReadInt(); + fcPlcfpmiOldInline = stream.ReadInt(); + lcbPlcfpmiOldInline = stream.ReadInt(); + fcPlcfpmiNew = stream.ReadInt(); + lcbPlcfpmiNew = stream.ReadInt(); + fcPlcfpmiNewInline = stream.ReadInt(); + lcbPlcfpmiNewInline = stream.ReadInt(); + fcPlcflvcOld = stream.ReadInt(); + lcbPlcflvcOld = stream.ReadInt(); + fcPlcflvcOldInline = stream.ReadInt(); + lcbPlcflvcOldInline = stream.ReadInt(); + fcPlcflvcNew = stream.ReadInt(); + lcbPlcflvcNew = stream.ReadInt(); + fcPlcflvcNewInline = stream.ReadInt(); + lcbPlcflvcNewInline = stream.ReadInt(); + fcPgdMother = stream.ReadInt(); + lcbPgdMother = stream.ReadInt(); + fcBkdMother = stream.ReadInt(); + lcbBkdMother = stream.ReadInt(); + fcAfdMother = stream.ReadInt(); + lcbAfdMother = stream.ReadInt(); + fcPgdFtn = stream.ReadInt(); + lcbPgdFtn = stream.ReadInt(); + fcBkdFtn = stream.ReadInt(); + lcbBkdFtn = stream.ReadInt(); + fcAfdFtn = stream.ReadInt(); + lcbAfdFtn = stream.ReadInt(); + fcPgdEdn = stream.ReadInt(); + lcbPgdEdn = stream.ReadInt(); + fcBkdEdn = stream.ReadInt(); + lcbBkdEdn = stream.ReadInt(); + fcAfdEdn = stream.ReadInt(); + lcbAfdEdn = stream.ReadInt(); + fcAfd = stream.ReadInt(); + lcbAfd = stream.ReadInt(); + } + } +} diff --git a/scratchpad/HWPF/Model/FIB/FibRgFcLcb2007.cs b/scratchpad/HWPF/Model/FIB/FibRgFcLcb2007.cs new file mode 100644 index 0000000..8595579 --- /dev/null +++ b/scratchpad/HWPF/Model/FIB/FibRgFcLcb2007.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NPOI.HWPF.Model +{ + public class FibRgFcLcb2007 + { + public int fcPlcfmthd; + public int lcbPlcfmthd; + public int fcSttbfBkmkMoveFrom; + public int lcbSttbfBkmkMoveFrom; + public int fcPlcfBkfMoveFrom; + public int lcbPlcfBkfMoveFrom; + public int fcPlcfBklMoveFrom; + public int lcbPlcfBklMoveFrom; + public int fcSttbfBkmkMoveTo; + public int lcbSttbfBkmkMoveTo; + public int fcPlcfBkfMoveTo; + public int lcbPlcfBkfMoveTo; + public int fcPlcfBklMoveTo; + public int lcbPlcfBklMoveTo; + public int fcUnused1; + public int lcbUnused1; + public int fcUnused2; + public int lcbUnused2; + public int fcUnused3; + public int lcbUnused3; + public int fcSttbfBkmkArto; + public int lcbSttbfBkmkArto; + public int fcPlcfBkfArto; + public int lcbPlcfBkfArto; + public int fcPlcfBklArto; + public int lcbPlcfBklArto; + public int fcArtoData; + public int lcbArtoData; + public int fcUnused4; + public int lcbUnused4; + public int fcUnused5; + public int lcbUnused5; + public int fcUnused6; + public int lcbUnused6; + public int fcOssTheme; + public int lcbOssTheme; + public int fcColorSchemeMapping; + public int lcbColorSchemeMapping; + + public FibRgFcLcb2003 fibRgFcLcb2003; + + public FibRgFcLcb2007() + { + } + public void Deserialize(HWPFStream stream) + { + fibRgFcLcb2003 = new FibRgFcLcb2003(); + fibRgFcLcb2003.Deserialize(stream); + + fcPlcfmthd = stream.ReadInt(); + lcbPlcfmthd = stream.ReadInt(); + fcSttbfBkmkMoveFrom = stream.ReadInt(); + lcbSttbfBkmkMoveFrom = stream.ReadInt(); + fcPlcfBkfMoveFrom = stream.ReadInt(); + lcbPlcfBkfMoveFrom = stream.ReadInt(); + fcPlcfBklMoveFrom = stream.ReadInt(); + lcbPlcfBklMoveFrom = stream.ReadInt(); + fcSttbfBkmkMoveTo = stream.ReadInt(); + lcbSttbfBkmkMoveTo = stream.ReadInt(); + fcPlcfBkfMoveTo = stream.ReadInt(); + lcbPlcfBkfMoveTo = stream.ReadInt(); + fcPlcfBklMoveTo = stream.ReadInt(); + lcbPlcfBklMoveTo = stream.ReadInt(); + fcUnused1 = stream.ReadInt(); + lcbUnused1 = stream.ReadInt(); + fcUnused2 = stream.ReadInt(); + lcbUnused2 = stream.ReadInt(); + fcUnused3 = stream.ReadInt(); + lcbUnused3 = stream.ReadInt(); + fcSttbfBkmkArto = stream.ReadInt(); + lcbSttbfBkmkArto = stream.ReadInt(); + fcPlcfBkfArto = stream.ReadInt(); + lcbPlcfBkfArto = stream.ReadInt(); + fcPlcfBklArto = stream.ReadInt(); + lcbPlcfBklArto = stream.ReadInt(); + fcArtoData = stream.ReadInt(); + lcbArtoData = stream.ReadInt(); + fcUnused4 = stream.ReadInt(); + lcbUnused4 = stream.ReadInt(); + fcUnused5 = stream.ReadInt(); + lcbUnused5 = stream.ReadInt(); + fcUnused6 = stream.ReadInt(); + lcbUnused6 = stream.ReadInt(); + fcOssTheme = stream.ReadInt(); + lcbOssTheme = stream.ReadInt(); + fcColorSchemeMapping = stream.ReadInt(); + lcbColorSchemeMapping = stream.ReadInt(); + } + } +} diff --git a/scratchpad/HWPF/Model/FIB/FibRgFcLcb97.cs b/scratchpad/HWPF/Model/FIB/FibRgFcLcb97.cs new file mode 100644 index 0000000..9352e69 --- /dev/null +++ b/scratchpad/HWPF/Model/FIB/FibRgFcLcb97.cs @@ -0,0 +1,397 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NPOI.HWPF.Model +{ + public class FibRgFcLcb97 + { + public int fcStshfOrig = 0; + public int lcbStshfOrig = 0; + public int fcStshf = 0; + public int lcbStshf = 0; + public int fcPlcffndRef = 0; + public int lcbPlcffndRef = 0; + public int fcPlcffndTxt = 0; + public int lcbPlcffndTxt = 0; + public int fcPlcfandRef = 0; + public int lcbPlcfandRef = 0; + public int fcPlcfandTxt = 0; + public int lcbPlcfandTxt = 0; + public int fcPlcfSed = 0; + public int lcbPlcfSed = 0; + public int fcPlcPad = 0; + + public int lcbPlcPad = 0; + public int fcPlcfPhe = 0; + public int lcbPlcfPhe = 0; + public int fcSttbfGlsy = 0; + public int lcbSttbfGlsy = 0; + public int fcPlcfGlsy = 0; + public int lcbPlcfGlsy = 0; + public int fcPlcfHdd = 0; + public int lcbPlcfHdd = 0; + public int fcPlcfBteChpx = 0; + public int lcbPlcfBteChpx = 0; + public int fcPlcfBtePapx = 0; + public int lcbPlcfBtePapx = 0; + public int fcPlcfSea = 0; + public int lcbPlcfSea = 0; + public int fcSttbfFfn = 0; + public int lcbSttbfFfn = 0; + public int fcPlcfFldMom = 0; + public int lcbPlcfFldMom = 0; + public int fcPlcfFldHdr = 0; + public int lcbPlcfFldHdr = 0; + public int fcPlcfFldFtn = 0; + public int lcbPlcfFldFtn = 0; + public int fcPlcfFldAtn = 0; + public int lcbPlcfFldAtn = 0; + + public int fcPlcfFldMcr = 0; + public int lcbPlcfFldMcr = 0; + public int fcSttbfBkmk = 0; + public int lcbSttbfBkmk = 0; + public int fcPlcfBkf = 0; + public int lcbPlcfBkf = 0; + public int fcPlcfBkl = 0; + public int lcbPlcfBkl = 0; + public int fcCmds = 0; + public int lcbCmds = 0; + public int fcUnused1 = 0; + public int lcbUnused1 = 0; + public int fcSttbfMcr = 0; + public int lcbSttbfMcr = 0; + public int fcPrDrvr = 0; + public int lcbPrDrvr = 0; + public int fcPrEnvPort = 0; + public int lcbPrEnvPort = 0; + public int fcPrEnvLand = 0; + public int lcbPrEnvLand = 0; + public int fcWss = 0; + public int lcbWss = 0; + public int fcDop = 0; + public int lcbDop = 0; + public int fcSttbfAssoc = 0; + + public int lcbSttbfAssoc = 0; + public int fcClx = 0; + public int lcbClx = 0; + public int fcPlcfPgdFtn = 0; + public int lcbPlcfPgdFtn = 0; + public int fcAutosaveSource = 0; + public int lcbAutosaveSource = 0; + public int fcGrpXstAtnOwners = 0; + public int lcbGrpXstAtnOwners = 0; + public int fcSttbfAtnBkmk = 0; + public int lcbSttbfAtnBkmk = 0; + public int fcUnused2 = 0; + public int lcbUnused2 = 0; + public int fcUnused3 = 0; + public int lcbUnused3 = 0; + public int fcPlcSpaMom = 0; + public int lcbPlcSpaMom = 0; + public int fcPlcSpaHdr = 0; + public int lcbPlcSpaHdr = 0; + public int fcPlcfAtnBkf = 0; + public int lcbPlcfAtnBkf = 0; + public int fcPlcfAtnBkl = 0; + public int lcbPlcfAtnBkl = 0; + public int fcPms = 0; + public int lcbPms = 0; + + public int fcFormFldSttbs = 0; + public int lcbFormFldSttbs = 0; + public int fcPlcfendRef = 0; + public int lcbPlcfendRef = 0; + public int fcPlcfendTxt = 0; + public int lcbPlcfendTxt = 0; + public int fcPlcfFldEdn = 0; + public int lcbPlcfFldEdn = 0; + public int fcUnused4 = 0; + public int lcbUnused4 = 0; + public int fcDggInfo = 0; + public int lcbDggInfo = 0; + public int fcSttbfRMark = 0; + public int lcbSttbfRMark = 0; + public int fcSttbfCaption = 0; + public int lcbSttbfCaption = 0; + public int fcSttbfAutoCaption = 0; + public int lcbSttbfAutoCaption = 0; + public int fcPlcfWkb = 0; + public int lcbPlcfWkb = 0; + public int fcPlcfSpl = 0; + public int lcbPlcfSpl = 0; + public int fcPlcftxbxTxt = 0; + public int lcbPlcftxbxTxt = 0; + public int fcPlcfFldTxbx = 0; + + public int lcbPlcfFldTxbx = 0; + public int fcPlcfHdrtxbxTxt = 0; + public int lcbPlcfHdrtxbxTxt = 0; + public int fcPlcffldHdrTxbx = 0; + public int lcbPlcffldHdrTxbx = 0; + public int fcStwUser = 0; + public int lcbStwUser = 0; + public int fcSttbTtmbd = 0; + public int lcbSttbTtmbd = 0; + public int fcCookieData = 0; + public int lcbCookieData = 0; + public int fcPgdMotherOldOld = 0; + public int lcbPgdMotherOldOld = 0; + public int fcBkdMotherOldOld = 0; + public int lcbBkdMotherOldOld = 0; + public int fcPgdFtnOldOld = 0; + public int lcbPgdFtnOldOld = 0; + public int fcBkdFtnOldOld = 0; + public int lcbBkdFtnOldOld = 0; + public int fcPgdEdnOldOld = 0; + public int lcbPgdEdnOldOld = 0; + public int fcBkdEdnOldOld = 0; + public int lcbBkdEdnOldOld = 0; + public int fcSttbfIntlFld = 0; + public int lcbSttbfIntlFld = 0; + + public int fcRouteSlip = 0; + public int lcbRouteSlip = 0; + public int fcSttbSavedBy = 0; + public int lcbSttbSavedBy = 0; + public int fcSttbFnm = 0; + public int lcbSttbFnm = 0; + public int fcPlfLst = 0; + public int lcbPlfLst = 0; + public int fcPlfLfo = 0; + public int lcbPlfLfo = 0; + public int fcPlcfTxbxBkd = 0; + public int lcbPlcfTxbxBkd = 0; + public int fcPlcfTxbxHdrBkd = 0; + public int lcbPlcfTxbxHdrBkd = 0; + public int fcDocUndoWord9 = 0; + public int lcbDocUndoWord9 = 0; + public int fcRgbUse = 0; + public int lcbRgbUse = 0; + public int fcUsp = 0; + public int lcbUsp = 0; + public int fcUskf = 0; + public int lcbUskf = 0; + public int fcPlcupcRgbUse = 0; + public int lcbPlcupcRgbUse = 0; + public int fcPlcupcUsp = 0; + + public int lcbPlcupcUsp = 0; + public int fcSttbGlsyStyle = 0; + public int lcbSttbGlsyStyle = 0; + public int fcPlgosl = 0; + public int lcbPlgosl = 0; + public int fcPlcocx = 0; + public int lcbPlcocx = 0; + public int fcPlcfBteLvc = 0; + public int lcbPlcfBteLvc = 0; + public int dwLowDateTime = 0; + public int dwHighDateTime = 0; + public int fcPlcfLvcPre10 = 0; + public int lcbPlcfLvcPre10 = 0; + public int fcPlcfAsumy = 0; + public int lcbPlcfAsumy = 0; + public int fcPlcfGram = 0; + public int lcbPlcfGram = 0; + public int fcSttbListNames = 0; + public int lcbSttbListNames = 0; + public int fcSttbfUssr = 0; + public int lcbSttbfUssr = 0; + + public FibRgFcLcb97() + { + } + + public void Deserialize(HWPFStream stream) + { + fcStshfOrig = stream.ReadInt(); + lcbStshfOrig = stream.ReadInt(); + fcStshf = stream.ReadInt(); + lcbStshf = stream.ReadInt(); + fcPlcffndRef = stream.ReadInt(); + lcbPlcffndRef = stream.ReadInt(); + fcPlcffndTxt = stream.ReadInt(); + lcbPlcffndTxt = stream.ReadInt(); + fcPlcfandRef = stream.ReadInt(); + lcbPlcfandRef = stream.ReadInt(); + fcPlcfandTxt = stream.ReadInt(); + lcbPlcfandTxt = stream.ReadInt(); + fcPlcfSed = stream.ReadInt(); + lcbPlcfSed = stream.ReadInt(); + fcPlcPad = stream.ReadInt(); + lcbPlcPad = stream.ReadInt(); + fcPlcfPhe = stream.ReadInt(); + lcbPlcfPhe = stream.ReadInt(); + fcSttbfGlsy = stream.ReadInt(); + lcbSttbfGlsy = stream.ReadInt(); + fcPlcfGlsy = stream.ReadInt(); + lcbPlcfGlsy = stream.ReadInt(); + fcPlcfHdd = stream.ReadInt(); + lcbPlcfHdd = stream.ReadInt(); + fcPlcfBteChpx = stream.ReadInt(); + lcbPlcfBteChpx = stream.ReadInt(); + fcPlcfBtePapx = stream.ReadInt(); + lcbPlcfBtePapx = stream.ReadInt(); + fcPlcfSea = stream.ReadInt(); + lcbPlcfSea = stream.ReadInt(); + fcSttbfFfn = stream.ReadInt(); + lcbSttbfFfn = stream.ReadInt(); + fcPlcfFldMom = stream.ReadInt(); + lcbPlcfFldMom = stream.ReadInt(); + fcPlcfFldHdr = stream.ReadInt(); + lcbPlcfFldHdr = stream.ReadInt(); + fcPlcfFldFtn = stream.ReadInt(); + lcbPlcfFldFtn = stream.ReadInt(); + fcPlcfFldAtn = stream.ReadInt(); + lcbPlcfFldAtn = stream.ReadInt(); + fcPlcfFldMcr = stream.ReadInt(); + lcbPlcfFldMcr = stream.ReadInt(); + fcSttbfBkmk = stream.ReadInt(); + lcbSttbfBkmk = stream.ReadInt(); + fcPlcfBkf = stream.ReadInt(); + lcbPlcfBkf = stream.ReadInt(); + fcPlcfBkl = stream.ReadInt(); + lcbPlcfBkl = stream.ReadInt(); + fcCmds = stream.ReadInt(); + lcbCmds = stream.ReadInt(); + fcUnused1 = stream.ReadInt(); + lcbUnused1 = stream.ReadInt(); + fcSttbfMcr = stream.ReadInt(); + lcbSttbfMcr = stream.ReadInt(); + fcPrDrvr = stream.ReadInt(); + lcbPrDrvr = stream.ReadInt(); + fcPrEnvPort = stream.ReadInt(); + lcbPrEnvPort = stream.ReadInt(); + fcPrEnvLand = stream.ReadInt(); + lcbPrEnvLand = stream.ReadInt(); + fcWss = stream.ReadInt(); + lcbWss = stream.ReadInt(); + fcDop = stream.ReadInt(); + lcbDop = stream.ReadInt(); + fcSttbfAssoc = stream.ReadInt(); + lcbSttbfAssoc = stream.ReadInt(); + fcClx = stream.ReadInt(); + lcbClx = stream.ReadInt(); + fcPlcfPgdFtn = stream.ReadInt(); + lcbPlcfPgdFtn = stream.ReadInt(); + fcAutosaveSource = stream.ReadInt(); + lcbAutosaveSource = stream.ReadInt(); + fcGrpXstAtnOwners = stream.ReadInt(); + lcbGrpXstAtnOwners = stream.ReadInt(); + fcSttbfAtnBkmk = stream.ReadInt(); + lcbSttbfAtnBkmk = stream.ReadInt(); + fcUnused2 = stream.ReadInt(); + lcbUnused2 = stream.ReadInt(); + fcUnused3 = stream.ReadInt(); + lcbUnused3 = stream.ReadInt(); + fcPlcSpaMom = stream.ReadInt(); + lcbPlcSpaMom = stream.ReadInt(); + fcPlcSpaHdr = stream.ReadInt(); + lcbPlcSpaHdr = stream.ReadInt(); + fcPlcfAtnBkf = stream.ReadInt(); + lcbPlcfAtnBkf = stream.ReadInt(); + fcPlcfAtnBkl = stream.ReadInt(); + lcbPlcfAtnBkl = stream.ReadInt(); + fcPms = stream.ReadInt(); + lcbPms = stream.ReadInt(); + fcFormFldSttbs = stream.ReadInt(); + lcbFormFldSttbs = stream.ReadInt(); + fcPlcfendRef = stream.ReadInt(); + lcbPlcfendRef = stream.ReadInt(); + fcPlcfendTxt = stream.ReadInt(); + lcbPlcfendTxt = stream.ReadInt(); + fcPlcfFldEdn = stream.ReadInt(); + lcbPlcfFldEdn = stream.ReadInt(); + fcUnused4 = stream.ReadInt(); + lcbUnused4 = stream.ReadInt(); + fcDggInfo = stream.ReadInt(); + lcbDggInfo = stream.ReadInt(); + fcSttbfRMark = stream.ReadInt(); + lcbSttbfRMark = stream.ReadInt(); + fcSttbfCaption = stream.ReadInt(); + lcbSttbfCaption = stream.ReadInt(); + fcSttbfAutoCaption = stream.ReadInt(); + lcbSttbfAutoCaption = stream.ReadInt(); + fcPlcfWkb = stream.ReadInt(); + lcbPlcfWkb = stream.ReadInt(); + fcPlcfSpl = stream.ReadInt(); + lcbPlcfSpl = stream.ReadInt(); + fcPlcftxbxTxt = stream.ReadInt(); + lcbPlcftxbxTxt = stream.ReadInt(); + fcPlcfFldTxbx = stream.ReadInt(); + lcbPlcfFldTxbx = stream.ReadInt(); + fcPlcfHdrtxbxTxt = stream.ReadInt(); + lcbPlcfHdrtxbxTxt = stream.ReadInt(); + fcPlcffldHdrTxbx = stream.ReadInt(); + lcbPlcffldHdrTxbx = stream.ReadInt(); + fcStwUser = stream.ReadInt(); + lcbStwUser = stream.ReadInt(); + fcSttbTtmbd = stream.ReadInt(); + lcbSttbTtmbd = stream.ReadInt(); + fcCookieData = stream.ReadInt(); + lcbCookieData = stream.ReadInt(); + fcPgdMotherOldOld = stream.ReadInt(); + lcbPgdMotherOldOld = stream.ReadInt(); + fcBkdMotherOldOld = stream.ReadInt(); + lcbBkdMotherOldOld = stream.ReadInt(); + fcPgdFtnOldOld = stream.ReadInt(); + lcbPgdFtnOldOld = stream.ReadInt(); + fcBkdFtnOldOld = stream.ReadInt(); + lcbBkdFtnOldOld = stream.ReadInt(); + fcPgdEdnOldOld = stream.ReadInt(); + lcbPgdEdnOldOld = stream.ReadInt(); + fcBkdEdnOldOld = stream.ReadInt(); + lcbBkdEdnOldOld = stream.ReadInt(); + fcSttbfIntlFld = stream.ReadInt(); + lcbSttbfIntlFld = stream.ReadInt(); + fcRouteSlip = stream.ReadInt(); + lcbRouteSlip = stream.ReadInt(); + fcSttbSavedBy = stream.ReadInt(); + lcbSttbSavedBy = stream.ReadInt(); + fcSttbFnm = stream.ReadInt(); + lcbSttbFnm = stream.ReadInt(); + fcPlfLst = stream.ReadInt(); + lcbPlfLst = stream.ReadInt(); + fcPlfLfo = stream.ReadInt(); + lcbPlfLfo = stream.ReadInt(); + fcPlcfTxbxBkd = stream.ReadInt(); + lcbPlcfTxbxBkd = stream.ReadInt(); + fcPlcfTxbxHdrBkd = stream.ReadInt(); + lcbPlcfTxbxHdrBkd = stream.ReadInt(); + fcDocUndoWord9 = stream.ReadInt(); + lcbDocUndoWord9 = stream.ReadInt(); + fcRgbUse = stream.ReadInt(); + lcbRgbUse = stream.ReadInt(); + fcUsp = stream.ReadInt(); + lcbUsp = stream.ReadInt(); + fcUskf = stream.ReadInt(); + lcbUskf = stream.ReadInt(); + fcPlcupcRgbUse = stream.ReadInt(); + lcbPlcupcRgbUse = stream.ReadInt(); + fcPlcupcUsp = stream.ReadInt(); + lcbPlcupcUsp = stream.ReadInt(); + fcSttbGlsyStyle = stream.ReadInt(); + lcbSttbGlsyStyle = stream.ReadInt(); + fcPlgosl = stream.ReadInt(); + lcbPlgosl = stream.ReadInt(); + fcPlcocx = stream.ReadInt(); + lcbPlcocx = stream.ReadInt(); + fcPlcfBteLvc = stream.ReadInt(); + lcbPlcfBteLvc = stream.ReadInt(); + dwLowDateTime = stream.ReadInt(); + dwHighDateTime = stream.ReadInt(); + fcPlcfLvcPre10 = stream.ReadInt(); + lcbPlcfLvcPre10 = stream.ReadInt(); + fcPlcfAsumy = stream.ReadInt(); + lcbPlcfAsumy = stream.ReadInt(); + fcPlcfGram = stream.ReadInt(); + lcbPlcfGram = stream.ReadInt(); + fcSttbListNames = stream.ReadInt(); + lcbSttbListNames = stream.ReadInt(); + fcSttbfUssr = stream.ReadInt(); + lcbSttbfUssr = stream.ReadInt(); + } + } +} diff --git a/scratchpad/HWPF/Model/FIB/FibRgLw97.cs b/scratchpad/HWPF/Model/FIB/FibRgLw97.cs new file mode 100644 index 0000000..ac3496b --- /dev/null +++ b/scratchpad/HWPF/Model/FIB/FibRgLw97.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NPOI.HWPF.Model +{ + public class FibRgLw97 + { + int cbMac=0; + int ccpText=0; + int ccpFtn=0; + int ccpHdd=0; + int ccpAtn=0; + int ccpEdn = 0; + int ccpTxbx = 0; + int ccpHdrTxbx = 0; + + public FibRgLw97() + { + + } + + public void Deserialize(HWPFStream stream) + { + cbMac = stream.ReadInt(); + stream.ReadInt(); + stream.ReadInt(); + ccpText = stream.ReadInt(); + ccpFtn = stream.ReadInt(); + ccpHdd = stream.ReadInt(); + stream.ReadInt(); + ccpAtn = stream.ReadInt(); + ccpEdn = stream.ReadInt(); + ccpTxbx = stream.ReadInt(); + ccpHdrTxbx = stream.ReadInt(); + + stream.ReadInt(); //reserved4 + stream.ReadInt(); //reserved5 + stream.ReadInt();//reserved6 + stream.ReadInt();//reserved7 + stream.ReadInt();//reserved8 + stream.ReadInt();//reserved9 + stream.ReadInt();//reserved10 + stream.ReadInt();//reserved11 + stream.ReadInt();//reserved12 + stream.ReadInt();//reserved13 + stream.ReadInt();//reserved14 + } + } +} diff --git a/scratchpad/HWPF/Model/FIB/FibRgW97.cs b/scratchpad/HWPF/Model/FIB/FibRgW97.cs new file mode 100644 index 0000000..50b05f2 --- /dev/null +++ b/scratchpad/HWPF/Model/FIB/FibRgW97.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NPOI.HWPF.Model +{ + public class FibRgW97 + { + private short lidFE; + + public FibRgW97() + { + } + + public void Deserialize(HWPFStream stream) + { + stream.ReadShort(); + stream.ReadShort(); + stream.ReadShort(); + stream.ReadShort(); + stream.ReadShort(); + stream.ReadShort(); + stream.ReadShort(); + stream.ReadShort(); + stream.ReadShort(); + stream.ReadShort(); + stream.ReadShort(); + stream.ReadShort(); + stream.ReadShort(); + lidFE = stream.ReadShort(); + } + + public short LIDOfStoredStyleName + { + get { return lidFE; } + set { lidFE = value; } + } + + + } +} diff --git a/scratchpad/HWPF/Model/FIBFieldHandler.cs b/scratchpad/HWPF/Model/FIBFieldHandler.cs new file mode 100644 index 0000000..e3c4556 --- /dev/null +++ b/scratchpad/HWPF/Model/FIBFieldHandler.cs @@ -0,0 +1,226 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + using System; + using System.Collections; + using NPOI.Util; + using NPOI.HWPF.Model.IO; + using System.Collections.Generic; + + public class FIBFieldHandler + { + public const int STSHFORIG = 0; + public const int STSHF = 1; + public const int PLCFFNDREF = 2; + public const int PLCFFNDTXT = 3; + public const int PLCFANDREF = 4; + public const int PLCFANDTXT = 5; + public const int PLCFSED = 6; + public const int PLCFPAD = 7; + public const int PLCFPHE = 8; + public const int STTBGLSY = 9; + public const int PLCFGLSY = 10; + public const int PLCFHDD = 11; + public const int PLCFBTECHPX = 12; + public const int PLCFBTEPAPX = 13; + public const int PLCFSEA = 14; + public const int STTBFFFN = 15; + public const int PLCFFLDMOM = 16; + public const int PLCFFLDHDR = 17; + public const int PLCFFLDFTN = 18; + public const int PLCFFLDATN = 19; + public const int PLCFFLDMCR = 20; + public const int STTBFBKMK = 21; + public const int PLCFBKF = 22; + public const int PLCFBKL = 23; + public const int CMDS = 24; + public const int PLCMCR = 25; + public const int STTBFMCR = 26; + public const int PRDRVR = 27; + public const int PRENVPORT = 28; + public const int PRENVLAND = 29; + public const int WSS = 30; + public const int DOP = 31; + public const int STTBFASSOC = 32; + public const int CLX = 33; + public const int PLCFPGDFTN = 34; + public const int AUTOSAVESOURCE = 35; + public const int GRPXSTATNOWNERS = 36;//validated + public const int STTBFATNBKMK = 37; + public const int PLCFDOAMOM = 38; + public const int PLCDOAHDR = 39; + public const int PLCSPAMOM = 40; + public const int PLCSPAHDR = 41; + public const int PLCFATNBKF = 42; + public const int PLCFATNBKL = 43; + public const int PMS = 44; + public const int FORMFLDSTTBS = 45; + public const int PLCFENDREF = 46; + public const int PLCFENDTXT = 47; + public const int PLCFFLDEDN = 48; + public const int PLCFPGDEDN = 49; + public const int DGGINFO = 50; + public const int STTBFRMARK = 51; + public const int STTBCAPTION = 52; + public const int STTBAUTOCAPTION = 53; + public const int PLCFWKB = 54; + public const int PLCFSPL = 55; + public const int PLCFTXBXTXT = 56; + public const int PLCFFLDTXBX = 57;//validated + public const int PLCFHDRTXBXTXT = 58; + public const int PLCFFLDHDRTXBX = 59; + public const int STWUSER = 60; + public const int STTBTTMBD = 61; + public const int UNUSED = 62; + public const int PGDMOTHER = 63; + public const int BKDMOTHER = 64; + public const int PGDFTN = 65; + public const int BKDFTN = 66; + public const int PGDEDN = 67; + public const int BKDEDN = 68; + public const int STTBFINTFLD = 69; + public const int ROUTESLIP = 70; + public const int STTBSAVEDBY = 71; + public const int STTBFNM = 72; + public const int PLCFLST = 73; + public const int PLFLFO = 74; + public const int PLCFTXBXBKD = 75;//validated + public const int PLCFTXBXHDRBKD = 76; + public const int DOCUNDO = 77; + public const int RGBUSE = 78; + public const int USP = 79; + public const int USKF = 80; + public const int PLCUPCRGBUSE = 81; + public const int PLCUPCUSP = 82; + public const int STTBGLSYSTYLE = 83; + public const int PLGOSL = 84; + public const int PLCOCX = 85; + public const int PLCFBTELVC = 86; + public const int MODIFIED = 87; + public const int PLCFLVC = 88; + public const int PLCASUMY = 89; + public const int PLCFGRAM = 90; + public const int STTBLISTNAMES = 91; + public const int STTBFUSSR = 92; + + //private static POILogger log = POILogFactory.GetLogger(FIBFieldHandler.class); + + private static int FIELD_SIZE = LittleEndianConsts.INT_SIZE * 2; + + private Hashtable _unknownMap = new Hashtable(); + private int[] _fields; + + + public FIBFieldHandler(byte[] mainStream, int offset, byte[] tableStream, + List offsetList, bool areKnown) + { + int numFields = LittleEndian.GetShort(mainStream, offset); + offset += LittleEndianConsts.SHORT_SIZE; + _fields = new int[numFields * 2]; + + for (int x = 0; x < numFields; x++) + { + int fieldOffset = (x * FIELD_SIZE) + offset; + int dsOffset = LittleEndian.GetInt(mainStream, fieldOffset); + fieldOffset += LittleEndianConsts.INT_SIZE; + int dsSize = LittleEndian.GetInt(mainStream, fieldOffset); + + if (offsetList.Contains(x) ^ areKnown) + { + if (dsSize > 0) + { + if (dsOffset + dsSize > tableStream.Length) + { + //log.log(POILogger.WARN, "Unhandled data structure points to outside the buffer. " + + // "offset = " + dsOffset + ", length = " + dsSize + + // ", buffer length = " + tableStream.Length); + } + else + { + UnhandledDataStructure unhandled = new UnhandledDataStructure( + tableStream, dsOffset, dsSize); + _unknownMap.Add(x, unhandled); + } + } + } + _fields[x * 2] = dsOffset; + _fields[(x * 2) + 1] = dsSize; + } + } + + public void ClearFields() + { + Arrays.Fill(_fields, 0); + } + + public int GetFieldOffset(int field) + { + return _fields[field * 2]; + } + + public int GetFieldSize(int field) + { + return _fields[(field * 2) + 1]; + } + + public void SetFieldOffset(int field, int offset) + { + _fields[field * 2] = offset; + } + + public void SetFieldSize(int field, int size) + { + _fields[(field * 2) + 1] = size; + } + + public int SizeInBytes() + { + return (_fields.Length * LittleEndianConsts.INT_SIZE) + LittleEndianConsts.SHORT_SIZE; + } + + internal void WriteTo(byte[] mainStream, int offset, HWPFStream tableStream) + { + int length = _fields.Length / 2; + LittleEndian.PutShort(mainStream, offset, (short)length); + offset += LittleEndianConsts.SHORT_SIZE; + + for (int x = 0; x < length; x++) + { + UnhandledDataStructure ds = (UnhandledDataStructure)_unknownMap[x]; + if (ds != null) + { + LittleEndian.PutInt(mainStream, offset, tableStream.Offset); + offset += LittleEndianConsts.INT_SIZE; + byte[] buf = ds.GetBuf(); + tableStream.Write(buf); + LittleEndian.PutInt(mainStream, offset, buf.Length); + offset += LittleEndianConsts.INT_SIZE; + } + else + { + LittleEndian.PutInt(mainStream, offset, _fields[x * 2]); + offset += LittleEndianConsts.INT_SIZE; + LittleEndian.PutInt(mainStream, offset, _fields[(x * 2) + 1]); + offset += LittleEndianConsts.INT_SIZE; + } + } + } + } + +} diff --git a/scratchpad/HWPF/Model/FIBLongHandler.cs b/scratchpad/HWPF/Model/FIBLongHandler.cs new file mode 100644 index 0000000..fe41365 --- /dev/null +++ b/scratchpad/HWPF/Model/FIBLongHandler.cs @@ -0,0 +1,100 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using NPOI.Util; +namespace NPOI.HWPF.Model +{ + + /** + * Handles the fibRgLw / The FibRgLw97 part of + * the FIB (File Information Block) + */ + public class FIBLongHandler + { + public const int CBMAC = 0; + public const int PRODUCTCREATED = 1; + public const int PRODUCTREVISED = 2; + public const int CCPTEXT = 3; + public const int CCPFTN = 4; + public const int CCPHDD = 5; + public const int CCPMCR = 6; + public const int CCPATN = 7; + public const int CCPEDN = 8; + public const int CCPTXBX = 9; + public const int CCPHDRTXBX = 10; + public const int PNFBPCHPFIRST = 11; + public const int PNCHPFIRST = 12; + public const int CPNBTECHP = 13; + public const int PNFBPPAPFIRST = 14; + public const int PNPAPFIRST = 15; + public const int CPNBTEPAP = 16; + public const int PNFBPLVCFIRST = 17; + public const int PNLVCFIRST = 18; + public const int CPNBTELVC = 19; + public const int FCISLANDFIRST = 20; + public const int FCISLANDLIM = 21; + + int[] _longs; + + public FIBLongHandler(byte[] mainStream, int offset) + { + int longCount = LittleEndian.GetShort(mainStream, offset); + offset += LittleEndianConsts.SHORT_SIZE; + _longs = new int[longCount]; + + for (int x = 0; x < longCount; x++) + { + _longs[x] = LittleEndian.GetInt(mainStream, offset + (x * LittleEndianConsts.INT_SIZE)); + } + } + + /** + * Refers to a 32 bit windows "long" same as a Java int + * @param longCode FIXME: Document this! + * @return FIXME: Document this! + */ + public int GetLong(int longCode) + { + return _longs[longCode]; + } + + public void SetLong(int longCode, int value) + { + _longs[longCode] = value; + } + + internal void Serialize(byte[] mainStream, int offset) + { + LittleEndian.PutShort(mainStream, offset, (short)_longs.Length); + offset += LittleEndianConsts.SHORT_SIZE; + + for (int x = 0; x < _longs.Length; x++) + { + LittleEndian.PutInt(mainStream, offset, _longs[x]); + offset += LittleEndianConsts.INT_SIZE; + } + } + + internal int SizeInBytes() + { + return (_longs.Length * LittleEndianConsts.INT_SIZE) + LittleEndianConsts.SHORT_SIZE; + } + + + } +} + diff --git a/scratchpad/HWPF/Model/FIBShortHandler.cs b/scratchpad/HWPF/Model/FIBShortHandler.cs new file mode 100644 index 0000000..1865648 --- /dev/null +++ b/scratchpad/HWPF/Model/FIBShortHandler.cs @@ -0,0 +1,81 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + using System; + using NPOI.Util; + + /** + * Handles the fibRgW / FibRgW97 part of + * the FIB (File Information Block) + */ + public class FIBshortHandler + { + public const int MAGICCREATED = 0; + public const int MAGICREVISED = 1; + public const int MAGICCREATEDPRIVATE = 2; + public const int MAGICREVISEDPRIVATE = 3; + public const int LIDFE = 13; + + internal const int START = 0x20; + + short[] _shorts; + + public FIBshortHandler(byte[] mainStream) + { + int offset = START; + int shortCount = LittleEndian.GetShort(mainStream, offset); + offset += LittleEndianConsts.SHORT_SIZE; + _shorts = new short[shortCount]; + + for (int x = 0; x < shortCount; x++) + { + _shorts[x] = LittleEndian.GetShort(mainStream, offset); + offset += LittleEndianConsts.SHORT_SIZE; + } + } + + public short Getshort(int shortCode) + { + return _shorts[shortCode]; + } + + internal int SizeInBytes() + { + return (_shorts.Length * LittleEndianConsts.SHORT_SIZE) + LittleEndianConsts.SHORT_SIZE; + } + + internal void Serialize(byte[] mainStream) + { + int offset = START; + LittleEndian.PutShort(mainStream, offset, (short)_shorts.Length); + offset += LittleEndianConsts.SHORT_SIZE; + //mainStream.Write(holder); + + for (int x = 0; x < _shorts.Length; x++) + { + LittleEndian.PutShort(mainStream, offset, _shorts[x]); + offset += LittleEndianConsts.SHORT_SIZE; + } + } + + + } + + +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/FSPA.cs b/scratchpad/HWPF/Model/FSPA.cs new file mode 100644 index 0000000..09d34e6 --- /dev/null +++ b/scratchpad/HWPF/Model/FSPA.cs @@ -0,0 +1,187 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + using NPOI.Util; + using System.Text; + using System; + + + /** + * File Shape Address structure + * + * @author Squeeself + */ + public class FSPA + { + public static int FSPA_SIZE = 26; + private int spid; // Shape identifier. Used to get data position + private int xaLeft; // Enclosing rectangle + private int yaTop; // Enclosing rectangle + private int xaRight; // Enclosing rectangle + private int yaBottom; // Enclosing rectangle + private short options; + private static BitField fHdr = BitFieldFactory.GetInstance(0x0001); // 1 in undo when in header + private static BitField bx = BitFieldFactory.GetInstance(0x0006); // x pos relative to anchor CP: 0 - page margin, 1 - top of page, 2 - text, 3 - reserved + private static BitField by = BitFieldFactory.GetInstance(0x0018); // y pos relative to anchor CP: ditto + private static BitField wr = BitFieldFactory.GetInstance(0x01E0); // Text wrapping mode: 0 - like 2 w/o absolute, 1 - no text next to shape, 2 - wrap around absolute object, 3 - wrap as if no object, 4 - wrap tightly around object, 5 - wrap tightly, allow holes, 6-15 - reserved + private static BitField wrk = BitFieldFactory.GetInstance(0x1E00); // Text wrapping mode type (for modes 2&4): 0 - wrap both sides, 1 - wrap only left, 2 - wrap only right, 3 - wrap largest side + private static BitField fRcaSimple = BitFieldFactory.GetInstance(0x2000); // OverWrites bx if Set, forcing rectangle to be page relative + private static BitField fBelowText = BitFieldFactory.GetInstance(0x4000); // if true, shape is below text, otherwise above + private static BitField fAnchorLock = BitFieldFactory.GetInstance(0x8000); // if true, anchor is locked + private int cTxbx; // Count of textboxes in shape (undo doc only) + + public FSPA() + { + } + + public FSPA(byte[] bytes, int offset) + { + spid = LittleEndian.GetInt(bytes, offset); + offset += LittleEndianConsts.INT_SIZE; + xaLeft = LittleEndian.GetInt(bytes, offset); + offset += LittleEndianConsts.INT_SIZE; + yaTop = LittleEndian.GetInt(bytes, offset); + offset += LittleEndianConsts.INT_SIZE; + xaRight = LittleEndian.GetInt(bytes, offset); + offset += LittleEndianConsts.INT_SIZE; + yaBottom = LittleEndian.GetInt(bytes, offset); + offset += LittleEndianConsts.INT_SIZE; + options = LittleEndian.GetShort(bytes, offset); + offset += LittleEndianConsts.SHORT_SIZE; + cTxbx = LittleEndian.GetInt(bytes, offset); + } + + public int GetSpid() + { + return spid; + } + + public int GetXaLeft() + { + return xaLeft; + } + + public int GetYaTop() + { + return yaTop; + } + + public int GetXaRight() + { + return xaRight; + } + + public int GetYaBottom() + { + return yaBottom; + } + + public bool IsFHdr() + { + return fHdr.IsSet(options); + } + + public short GetBx() + { + return bx.GetShortValue(options); + } + + public short GetBy() + { + return by.GetShortValue(options); + } + + public short GetWr() + { + return wr.GetShortValue(options); + } + + public short GetWrk() + { + return wrk.GetShortValue(options); + } + + public bool IsFRcaSimple() + { + return fRcaSimple.IsSet(options); + } + + public bool IsFBelowText() + { + return fBelowText.IsSet(options); + } + + public bool IsFAnchorLock() + { + return fAnchorLock.IsSet(options); + } + + public int GetCTxbx() + { + return cTxbx; + } + + public byte[] ToArray() + { + int offset = 0; + byte[] buf = new byte[FSPA_SIZE]; + + LittleEndian.PutInt(buf, offset, spid); + offset += LittleEndianConsts.INT_SIZE; + LittleEndian.PutInt(buf, offset, xaLeft); + offset += LittleEndianConsts.INT_SIZE; + LittleEndian.PutInt(buf, offset, yaTop); + offset += LittleEndianConsts.INT_SIZE; + LittleEndian.PutInt(buf, offset, xaRight); + offset += LittleEndianConsts.INT_SIZE; + LittleEndian.PutInt(buf, offset, yaBottom); + offset += LittleEndianConsts.INT_SIZE; + LittleEndian.PutShort(buf, offset, options); + offset += LittleEndianConsts.SHORT_SIZE; + LittleEndian.PutInt(buf, offset, cTxbx); + offset += LittleEndianConsts.INT_SIZE; + + return buf; + } + + public override String ToString() + { + StringBuilder buf = new StringBuilder(); + buf.Append("spid: ").Append(spid); + buf.Append(", xaLeft: ").Append(xaLeft); + buf.Append(", yaTop: ").Append(yaTop); + buf.Append(", xaRight: ").Append(xaRight); + buf.Append(", yaBottom: ").Append(yaBottom); + buf.Append(", options: ").Append(options); + buf.Append(" (fHdr: ").Append(IsFHdr()); + buf.Append(", bx: ").Append(GetBx()); + buf.Append(", by: ").Append(GetBy()); + buf.Append(", wr: ").Append(GetWr()); + buf.Append(", wrk: ").Append(GetWrk()); + buf.Append(", fRcaSimple: ").Append(IsFRcaSimple()); + buf.Append(", fBelowText: ").Append(IsFBelowText()); + buf.Append(", fAnchorLock: ").Append(IsFAnchorLock()); + buf.Append("), cTxbx: ").Append(cTxbx); + return buf.ToString(); + } + } + + + +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/FSPADocumentPart.cs b/scratchpad/HWPF/Model/FSPADocumentPart.cs new file mode 100644 index 0000000..3828154 --- /dev/null +++ b/scratchpad/HWPF/Model/FSPADocumentPart.cs @@ -0,0 +1,37 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +namespace NPOI.HWPF.Model +{ + public class FSPADocumentPart + { + public static FSPADocumentPart HEADER = new FSPADocumentPart(FIBFieldHandler.PLCSPAHDR); + + public static FSPADocumentPart MAIN = new FSPADocumentPart(FIBFieldHandler.PLCSPAMOM); + + private int fibFieldsField; + + private FSPADocumentPart(int fibHandlerField) + { + this.fibFieldsField = fibHandlerField; + } + + public int GetFibFieldsField() + { + return fibFieldsField; + } + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/FSPATable.cs b/scratchpad/HWPF/Model/FSPATable.cs new file mode 100644 index 0000000..8b6f63f --- /dev/null +++ b/scratchpad/HWPF/Model/FSPATable.cs @@ -0,0 +1,112 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + using System; + using System.Collections; + using System.Text; + using System.Collections.Generic; + + /** + * This class holds all the FSPA (File Shape Address) structures. + * + * @author Squeeself + */ + public class FSPATable + { + private Dictionary _byStart + = new Dictionary(); + + public FSPATable(byte[] tableStream, FileInformationBlock fib, + FSPADocumentPart part) + { + int offset = fib.GetFSPAPlcfOffset(part); + int length = fib.GetFSPAPlcfLength(part); + + PlexOfCps plex = new PlexOfCps(tableStream, offset, length, + FSPA.FSPA_SIZE); + for (int i = 0; i < plex.Length; i++) + { + GenericPropertyNode property = plex.GetProperty(i); + _byStart.Add(property.Start, property); + } + } + + + [Obsolete] + public FSPATable(byte[] tableStream, int fcPlcspa, int lcbPlcspa, List tpt) + { + // Will be 0 if no drawing objects in document + if (fcPlcspa == 0) + return; + + PlexOfCps plex = new PlexOfCps(tableStream, fcPlcspa, lcbPlcspa, FSPA.FSPA_SIZE); + for (int i = 0; i < plex.Length; i++) + { + GenericPropertyNode property = plex.GetProperty(i); + _byStart.Add(property.Start, property); + } + } + + public FSPA GetFspaFromCp(int cp) + { + if (!_byStart.ContainsKey(cp)) + { + return null; + } + + return new FSPA(_byStart[cp].Bytes, 0); + } + + public FSPA[] GetShapes() + { + List result = new List(_byStart.Count); + foreach (GenericPropertyNode propertyNode in _byStart.Values) + { + result.Add(new FSPA(propertyNode.Bytes, 0)); + } + return result.ToArray(); + } + + public override String ToString() + { + StringBuilder buf = new StringBuilder(); + buf.Append("[FPSA PLC size=").Append(_byStart.Count).Append("]\n"); + foreach (KeyValuePair entry in _byStart + ) + { + int i = entry.Key; + buf.Append(" ").Append(i.ToString()).Append(" => \t"); + + try + { + FSPA fspa = GetFspaFromCp(i); + buf.Append(fspa.ToString()); + } + catch (Exception exc) + { + buf.Append(exc.Message); + } + buf.Append("\n"); + } + buf.Append("[/FSPA PLC]"); + return buf.ToString(); + } + } +} + diff --git a/scratchpad/HWPF/Model/Ffn.cs b/scratchpad/HWPF/Model/Ffn.cs new file mode 100644 index 0000000..45575e9 --- /dev/null +++ b/scratchpad/HWPF/Model/Ffn.cs @@ -0,0 +1,229 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + using NPOI.Util; + using System; + + /** + * FFN - Font Family Name. FFN is a data structure that stores the names of the Main + * Font and that of Alternate font as an array of characters. It has also a header + * that stores info about the whole structure and the fonts + * + * @author Praveen Mathew + */ + public class Ffn + { + private int _cbFfnM1;//total length of FFN - 1. + private byte _info; + private static BitField _prq = BitFieldFactory.GetInstance(0x0003);// pitch request + private static BitField _fTrueType = BitFieldFactory.GetInstance(0x0004);// when 1, font is a TrueType font + private static BitField _ff = BitFieldFactory.GetInstance(0x0070); + private short _wWeight;// base weight of font + private byte _chs;// character set identifier + private byte _ixchSzAlt; // index into ffn.szFfn to the name of + // the alternate font + private byte[] _panose = new byte[10];//???? + private byte[] _fontSig = new byte[24];//???? + + // zero terminated string that records name of font, cuurently not + // supporting Extended chars + private char[] _xszFfn; + + // extra facilitator members + private int _xszFfnLength; + + public Ffn(byte[] buf, int offset) + { + int offsetTmp = offset; + + _cbFfnM1 = LittleEndian.GetUByte(buf, offset); + offset += LittleEndianConsts.BYTE_SIZE; + _info = buf[offset]; + offset += LittleEndianConsts.BYTE_SIZE; + _wWeight = LittleEndian.GetShort(buf, offset); + offset += LittleEndianConsts.SHORT_SIZE; + _chs = buf[offset]; + offset += LittleEndianConsts.BYTE_SIZE; + _ixchSzAlt = buf[offset]; + offset += LittleEndianConsts.BYTE_SIZE; + + // read panose and fs so we can write them back out. + Array.Copy(buf, offset, _panose, 0, _panose.Length); + offset += _panose.Length; + Array.Copy(buf, offset, _fontSig, 0, _fontSig.Length); + offset += _fontSig.Length; + + offsetTmp = offset - offsetTmp; + _xszFfnLength = (this.GetSize() - offsetTmp) / 2; + _xszFfn = new char[_xszFfnLength]; + + for (int i = 0; i < _xszFfnLength; i++) + { + _xszFfn[i] = (char)LittleEndian.GetShort(buf, offset); + offset += LittleEndianConsts.SHORT_SIZE; + } + + + } + + public int Get_cbFfnM1() + { + return _cbFfnM1; + } + + public short GetWeight() + { + return _wWeight; + } + + public byte GetChs() + { + return _chs; + } + + public byte[] GetPanose() + { + return _panose; + } + + public byte[] GetFontSig() + { + return _fontSig; + } + + public int GetSize() + { + return (_cbFfnM1 + 1); + } + + public String GetMainFontName() + { + int index = 0; + for (; index < _xszFfnLength; index++) + { + if (_xszFfn[index] == '\0') + { + break; + } + } + return new String(_xszFfn, 0, index); + } + + public String GetAltFontName() + { + int index = _ixchSzAlt; + for (; index < _xszFfnLength; index++) + { + if (_xszFfn[index] == '\0') + { + break; + } + } + return new String(_xszFfn, _ixchSzAlt, index); + + } + + public void Set_cbFfnM1(int _cbFfnM1) + { + this._cbFfnM1 = _cbFfnM1; + } + + // Changed protected to public + public byte[] ToArray() + { + int offset = 0; + byte[] buf = new byte[this.GetSize()]; + + buf[offset] = (byte)_cbFfnM1; + offset += LittleEndianConsts.BYTE_SIZE; + buf[offset] = _info; + offset += LittleEndianConsts.BYTE_SIZE; + LittleEndian.PutShort(buf, offset, _wWeight); + offset += LittleEndianConsts.SHORT_SIZE; + buf[offset] = _chs; + offset += LittleEndianConsts.BYTE_SIZE; + buf[offset] = _ixchSzAlt; + offset += LittleEndianConsts.BYTE_SIZE; + + Array.Copy(_panose, 0, buf, offset, _panose.Length); + offset += _panose.Length; + Array.Copy(_fontSig, 0, buf, offset, _fontSig.Length); + offset += _fontSig.Length; + + for (int i = 0; i < _xszFfn.Length; i++) + { + LittleEndian.PutShort(buf, offset, (short)_xszFfn[i]); + offset += LittleEndianConsts.SHORT_SIZE; + } + + return buf; + + } + + public override bool Equals(Object o) + { + bool retVal = true; + + if (((Ffn)o).Get_cbFfnM1() == _cbFfnM1) + { + if (((Ffn)o)._info == _info) + { + if (((Ffn)o)._wWeight == _wWeight) + { + if (((Ffn)o)._chs == _chs) + { + if (((Ffn)o)._ixchSzAlt == _ixchSzAlt) + { + if (Arrays.Equals(((Ffn)o)._panose, _panose)) + { + if (Arrays.Equals(((Ffn)o)._fontSig, _fontSig)) + { + if (!(Arrays.Equals(((Ffn)o)._xszFfn, _xszFfn))) + retVal = false; + } + else + retVal = false; + } + else + retVal = false; + } + else + retVal = false; + } + else + retVal = false; + } + else + retVal = false; + } + else + retVal = false; + } + else + retVal = false; + + return retVal; + } + + + } + +} + + diff --git a/scratchpad/HWPF/Model/FieldDescriptor.cs b/scratchpad/HWPF/Model/FieldDescriptor.cs new file mode 100644 index 0000000..71d5d61 --- /dev/null +++ b/scratchpad/HWPF/Model/FieldDescriptor.cs @@ -0,0 +1,105 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using NPOI.Util; +using System; +using NPOI.HWPF.Model.Types; +namespace NPOI.HWPF.Model +{ + + public class FieldDescriptor : FLDAbstractType + { + public const int FIELD_BEGIN_MARK = 0x13; + public const int FIELD_SEPARATOR_MARK = 0x14; + public const int FIELD_END_MARK = 0x15; + + public FieldDescriptor(byte[] data) + { + FillFields(data, 0); + } + + public int GetBoundaryType() + { + return GetCh(); + } + + public int GetFieldType() + { + if (GetCh() != FIELD_BEGIN_MARK) + throw new NotSupportedException( + "This field Is only defined for begin marks."); + return GetFlt(); + } + + public bool IsZombieEmbed() + { + if (GetCh() != FIELD_END_MARK) + throw new NotSupportedException( + "This field Is only defined for end marks."); + return IsFZombieEmbed(); + } + + public bool IsResultDirty() + { + if (GetCh() != FIELD_END_MARK) + throw new NotSupportedException( + "This field Is only defined for end marks."); + return IsFResultDirty(); + } + + public bool IsResultEdited() + { + if (GetCh() != FIELD_END_MARK) + throw new NotSupportedException( + "This field Is only defined for end marks."); + return IsFResultEdited(); + } + + public bool IsLocked() + { + if (GetCh() != FIELD_END_MARK) + throw new NotSupportedException( + "This field Is only defined for end marks."); + return IsFLocked(); + } + + public bool IsPrivateResult() + { + if (GetCh() != FIELD_END_MARK) + throw new NotSupportedException( + "This field Is only defined for end marks."); + return IsFPrivateResult(); + } + + public bool IsNested() + { + if (GetCh() != FIELD_END_MARK) + throw new NotSupportedException( + "This field Is only defined for end marks."); + return IsFNested(); + } + + public bool IsHasSep() + { + if (GetCh() != FIELD_END_MARK) + throw new NotSupportedException( + "This field Is only defined for end marks."); + return IsFHasSep(); + } + } +} + diff --git a/scratchpad/HWPF/Model/FieldsDocumentPart.cs b/scratchpad/HWPF/Model/FieldsDocumentPart.cs new file mode 100644 index 0000000..79b02e4 --- /dev/null +++ b/scratchpad/HWPF/Model/FieldsDocumentPart.cs @@ -0,0 +1,59 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"), you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +namespace NPOI.HWPF.Model +{ + public enum FieldsDocumentPart:int + { + + /** + * annotation subdocument + */ + ANNOTATIONS = FIBFieldHandler.PLCFFLDATN, + + /** + * endnote subdocument + */ + ENDNOTES = FIBFieldHandler.PLCFFLDEDN, + + /** + * footnote subdocument + */ + FOOTNOTES = FIBFieldHandler.PLCFFLDFTN, + + /** + * header subdocument + */ + HEADER = FIBFieldHandler.PLCFFLDHDR, + + /** + * header textbox subdoc + */ + HEADER_TEXTBOX = FIBFieldHandler.PLCFFLDHDRTXBX, + + /** + * main document + */ + MAIN = FIBFieldHandler.PLCFFLDMOM, + + /** + * textbox subdoc + */ + TEXTBOX = FIBFieldHandler.PLCFFLDTXBX, + + } + +} diff --git a/scratchpad/HWPF/Model/FieldsTables.cs b/scratchpad/HWPF/Model/FieldsTables.cs new file mode 100644 index 0000000..2644300 --- /dev/null +++ b/scratchpad/HWPF/Model/FieldsTables.cs @@ -0,0 +1,120 @@ +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for Additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ==================================================================== + */ + +using System.Collections.Generic; +using System; +using NPOI.HWPF.Model.IO; +namespace NPOI.HWPF.Model +{ + + /** + * This class provides access to all the fields Plex. + * + * @author Cedric Bosdonnat + * + */ + public class FieldsTables + { + // The size in bytes of the FLD data structure + private static int FLD_SIZE = 2; + + private static List ToArrayList(PlexOfCps plexOfCps) + { + if (plexOfCps == null) + return new List(); + + List fields = new List( + plexOfCps.Length); + for (int i = 0; i < plexOfCps.Length; i++) + { + GenericPropertyNode propNode = plexOfCps.GetProperty(i); + PlexOfField plex = new PlexOfField(propNode); + fields.Add(plex); + } + + return fields; + } + + private Dictionary _tables; + + public FieldsTables(byte[] tableStream, FileInformationBlock fib) + { + Array values = Enum.GetValues(typeof(FieldsDocumentPart)); + _tables = new Dictionary( + values.Length); + + foreach (FieldsDocumentPart part in values) + { + PlexOfCps plexOfCps = ReadPLCF(tableStream, fib, part); + _tables.Add(part, plexOfCps); + } + } + + public List GetFieldsPLCF(FieldsDocumentPart part) + { + return ToArrayList(_tables[part]); + } + + private PlexOfCps ReadPLCF(byte[] tableStream, FileInformationBlock fib, + FieldsDocumentPart documentPart) + { + int start = fib.GetFieldsPlcfOffset(documentPart); + int length = fib.GetFieldsPlcfLength(documentPart); + + if (start <= 0 || length <= 0) + return null; + + return new PlexOfCps(tableStream, start, length, FLD_SIZE); + } + + private int SavePlex(FileInformationBlock fib, FieldsDocumentPart part, + PlexOfCps plexOfCps, HWPFStream outputStream) + { + if (plexOfCps == null || plexOfCps.Length == 0) + { + fib.SetFieldsPlcfOffset(part, outputStream.Offset); + fib.SetFieldsPlcfLength(part, 0); + return 0; + } + + byte[] data = plexOfCps.ToByteArray(); + + int start = outputStream.Offset; + int length = data.Length; + + outputStream.Write(data); + + fib.SetFieldsPlcfOffset(part, start); + fib.SetFieldsPlcfLength(part, length); + + return length; + } + + public void Write(FileInformationBlock fib, HWPFStream tableStream) + { + Array values = Enum.GetValues(typeof(FieldsDocumentPart)); + foreach (FieldsDocumentPart part in values) + { + PlexOfCps plexOfCps = _tables[part]; + SavePlex(fib, part, plexOfCps, tableStream); + } + } + + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/FileInformationBlock.cs b/scratchpad/HWPF/Model/FileInformationBlock.cs new file mode 100644 index 0000000..a0b210d --- /dev/null +++ b/scratchpad/HWPF/Model/FileInformationBlock.cs @@ -0,0 +1,979 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using NPOI.HWPF.Model.Types; +using System.Collections; +using NPOI.HWPF.Model.IO; +using System; +using System.Collections.Generic; +using System.Text; +using System.Reflection; +namespace NPOI.HWPF.Model +{ + + /** + * The File Information Block (FIB). Holds pointers + * to various bits of the file, and lots of flags which + * specify properties of the document. + * + * The parent class, {@link FIBAbstractType}, holds the + * first 32 bytes, which make up the FibBase. + * The next part, the fibRgW / FibRgW97, is handled + * by {@link FIBshortHandler}. + * The next part, the fibRgLw / The FibRgLw97, is + * handled by the {@link FIBLongHandler}. + * Finally, the rest of the fields are handled by + * the {@link FIBFieldHandler}. + * + * @author andy + */ + public class FileInformationBlock : FIBAbstractType + { + + + FIBLongHandler _longHandler; + FIBshortHandler _shortHandler; + FIBFieldHandler _fieldHandler; + + /** Creates a new instance of FileInformationBlock */ + public FileInformationBlock(byte[] mainDocument) + { + FillFields(mainDocument, 0); + } + + public void FillVariableFields(byte[] mainDocument, byte[] tableStream) + { + _shortHandler = new FIBshortHandler(mainDocument); + _longHandler = new FIBLongHandler(mainDocument, FIBshortHandler.START + _shortHandler.SizeInBytes()); + + List knownFieldSet = new List(); + knownFieldSet.Add(FIBFieldHandler.STSHF); + knownFieldSet.Add(FIBFieldHandler.CLX); + knownFieldSet.Add(FIBFieldHandler.DOP); + knownFieldSet.Add(FIBFieldHandler.PLCFBTECHPX); + knownFieldSet.Add(FIBFieldHandler.PLCFBTEPAPX); + knownFieldSet.Add(FIBFieldHandler.PLCFSED); + knownFieldSet.Add(FIBFieldHandler.PLCFLST); + knownFieldSet.Add(FIBFieldHandler.PLFLFO); + + // field info + foreach ( FieldsDocumentPart part in Enum.GetValues(typeof(FieldsDocumentPart)) ) + knownFieldSet.Add((int)part); + + // bookmarks + knownFieldSet.Add(FIBFieldHandler.PLCFBKF); + knownFieldSet.Add(FIBFieldHandler.PLCFBKL); + knownFieldSet.Add(FIBFieldHandler.STTBFBKMK); + + + // notes + foreach (NoteType noteType in NoteType.Values) + { + knownFieldSet.Add(noteType + .GetFibDescriptorsFieldIndex()); + knownFieldSet.Add(noteType + .GetFibTextPositionsFieldIndex()); + } + + knownFieldSet.Add(FIBFieldHandler.STTBFFFN); + knownFieldSet.Add(FIBFieldHandler.STTBFRMARK); + knownFieldSet.Add(FIBFieldHandler.STTBSAVEDBY); + knownFieldSet.Add(FIBFieldHandler.MODIFIED); + + + _fieldHandler = new FIBFieldHandler(mainDocument, + FIBshortHandler.START + _shortHandler.SizeInBytes() + _longHandler.SizeInBytes(), + tableStream, knownFieldSet, true); + } + public override String ToString() + { + StringBuilder stringBuilder = new StringBuilder(base.ToString()); + stringBuilder.Append("[FIB2]\n"); + stringBuilder.Append("\tSubdocuments info:\n"); + foreach (SubdocumentType type in Enum.GetValues(typeof(SubdocumentType))) + { + stringBuilder.Append("\t\t"); + stringBuilder.Append(type); + stringBuilder.Append(" has length of "); + stringBuilder.Append(GetSubdocumentTextStreamLength(type)); + stringBuilder.Append(" char(s)\n"); + } + stringBuilder.Append("\tFields PLCF info:\n"); + foreach (FieldsDocumentPart part in Enum.GetValues(typeof(FieldsDocumentPart))) + { + stringBuilder.Append("\t\t"); + stringBuilder.Append(part); + stringBuilder.Append(": PLCF starts at "); + stringBuilder.Append(GetFieldsPlcfOffset(part)); + stringBuilder.Append(" and have length of "); + stringBuilder.Append(GetFieldsPlcfLength(part)); + stringBuilder.Append("\n"); + } + stringBuilder.Append("\tNotes PLCF info:\n"); + foreach (NoteType noteType in NoteType.Values) + { + stringBuilder.Append("\t\t"); + stringBuilder.Append(noteType); + stringBuilder.Append(": descriptions starts "); + stringBuilder.Append(GetNotesDescriptorsOffset(noteType)); + stringBuilder.Append(" and have length of "); + stringBuilder.Append(GetNotesDescriptorsSize(noteType)); + stringBuilder.Append(" bytes\n"); + stringBuilder.Append("\t\t"); + stringBuilder.Append(noteType); + stringBuilder.Append(": text positions starts "); + stringBuilder.Append(GetNotesTextPositionsOffset(noteType)); + stringBuilder.Append(" and have length of "); + stringBuilder.Append(GetNotesTextPositionsSize(noteType)); + stringBuilder.Append(" bytes\n"); + } + try + { + stringBuilder.Append("\t.Net reflection info:\n"); + foreach (MethodInfo method in typeof(FileInformationBlock).GetMethods()) + { + if (!method.Name.StartsWith("get") + || !method.IsPublic + || method.IsStatic + || method.GetParameters().Length > 0) + continue; + stringBuilder.Append("\t\t"); + stringBuilder.Append(method.Name); + stringBuilder.Append(" => "); + stringBuilder.Append(method.Invoke(this, null)); + stringBuilder.Append("\n"); + } + } + catch (Exception exc) + { + stringBuilder.Append("(exc: " + exc.Message + ")"); + } + stringBuilder.Append("[/FIB2]\n"); + return stringBuilder.ToString(); + } + + public int GetFcDop() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.DOP); + } + + public void SetFcDop(int fcDop) + { + _fieldHandler.SetFieldOffset(FIBFieldHandler.DOP, fcDop); + } + + public int GetLcbDop() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.DOP); + } + + public void SetLcbDop(int lcbDop) + { + _fieldHandler.SetFieldSize(FIBFieldHandler.DOP, lcbDop); + } + + public int GetFcStshf() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.STSHF); + } + + public int GetLcbStshf() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.STSHF); + } + + public void SetFcStshf(int fcStshf) + { + _fieldHandler.SetFieldOffset(FIBFieldHandler.STSHF, fcStshf); + } + + public void SetLcbStshf(int lcbStshf) + { + _fieldHandler.SetFieldSize(FIBFieldHandler.STSHF, lcbStshf); + } + + public int GetFcClx() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.CLX); + } + + public int GetLcbClx() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.CLX); + } + + public void SetFcClx(int fcClx) + { + _fieldHandler.SetFieldOffset(FIBFieldHandler.CLX, fcClx); + } + + public void SetLcbClx(int lcbClx) + { + _fieldHandler.SetFieldSize(FIBFieldHandler.CLX, lcbClx); + } + + public int GetFcPlcfbteChpx() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.PLCFBTECHPX); + } + + public int GetLcbPlcfbteChpx() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.PLCFBTECHPX); + } + + public void SetFcPlcfbteChpx(int fcPlcfBteChpx) + { + _fieldHandler.SetFieldOffset(FIBFieldHandler.PLCFBTECHPX, fcPlcfBteChpx); + } + + public void SetLcbPlcfbteChpx(int lcbPlcfBteChpx) + { + _fieldHandler.SetFieldSize(FIBFieldHandler.PLCFBTECHPX, lcbPlcfBteChpx); + } + + public int GetFcPlcfbtePapx() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.PLCFBTEPAPX); + } + + public int GetLcbPlcfbtePapx() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.PLCFBTEPAPX); + } + + public void SetFcPlcfbtePapx(int fcPlcfBtePapx) + { + _fieldHandler.SetFieldOffset(FIBFieldHandler.PLCFBTEPAPX, fcPlcfBtePapx); + } + + public void SetLcbPlcfbtePapx(int lcbPlcfBtePapx) + { + _fieldHandler.SetFieldSize(FIBFieldHandler.PLCFBTEPAPX, lcbPlcfBtePapx); + } + + public int GetFcPlcfsed() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.PLCFSED); + } + + public int GetLcbPlcfsed() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.PLCFSED); + } + + public void SetFcPlcfsed(int fcPlcfSed) + { + _fieldHandler.SetFieldOffset(FIBFieldHandler.PLCFSED, fcPlcfSed); + } + + public void SetLcbPlcfsed(int lcbPlcfSed) + { + _fieldHandler.SetFieldSize(FIBFieldHandler.PLCFSED, lcbPlcfSed); + } + + public int GetFcPlcfLst() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.PLCFLST); + } + + public int GetLcbPlcfLst() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.PLCFLST); + } + + public void SetFcPlcfLst(int fcPlcfLst) + { + _fieldHandler.SetFieldOffset(FIBFieldHandler.PLCFLST, fcPlcfLst); + } + + public void SetLcbPlcfLst(int lcbPlcfLst) + { + _fieldHandler.SetFieldSize(FIBFieldHandler.PLCFLST, lcbPlcfLst); + } + + public int GetFcPlfLfo() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.PLFLFO); + } + + public int GetLcbPlfLfo() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.PLFLFO); + } + + /** + * @return Offset in table stream of the STTBF that records bookmark names + * in the main document + */ + public int GetFcSttbfbkmk() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.STTBFBKMK); + } + + public void SetFcSttbfbkmk(int offset) + { + _fieldHandler.SetFieldOffset(FIBFieldHandler.STTBFBKMK, offset); + } + + /** + * @return Count of bytes in Sttbfbkmk + */ + public int GetLcbSttbfbkmk() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.STTBFBKMK); + } + + public void SetLcbSttbfbkmk(int length) + { + _fieldHandler.SetFieldSize(FIBFieldHandler.STTBFBKMK, length); + } + + /** + * @return Offset in table stream of the PLCF that records the beginning CP + * offsets of bookmarks in the main document. See BKF structure + * definition. + */ + public int GetFcPlcfbkf() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.PLCFBKF); + } + + public void SetFcPlcfbkf(int offset) + { + _fieldHandler.SetFieldOffset(FIBFieldHandler.PLCFBKF, offset); + } + + /** + * @return Count of bytes in Plcfbkf + */ + public int GetLcbPlcfbkf() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.PLCFBKF); + } + + public void SetLcbPlcfbkf(int length) + { + _fieldHandler.SetFieldSize(FIBFieldHandler.PLCFBKF, length); + } + + /** + * @return Offset in table stream of the PLCF that records the ending CP + * offsets of bookmarks recorded in the main document. No structure + * is stored in this PLCF. + */ + public int GetFcPlcfbkl() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.PLCFBKL); + } + + public void SetFcPlcfbkl(int offset) + { + _fieldHandler.SetFieldOffset(FIBFieldHandler.PLCFBKL, offset); + } + + /** + * @return Count of bytes in Plcfbkl + */ + public int GetLcbPlcfbkl() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.PLCFBKL); + } + + public void SetLcbPlcfbkl(int length) + { + _fieldHandler.SetFieldSize(FIBFieldHandler.PLCFBKL, length); + } + + public void SetFcPlfLfo(int fcPlfLfo) + { + _fieldHandler.SetFieldOffset(FIBFieldHandler.PLFLFO, fcPlfLfo); + } + + public void SetLcbPlfLfo(int lcbPlfLfo) + { + _fieldHandler.SetFieldSize(FIBFieldHandler.PLFLFO, lcbPlfLfo); + } + + public int GetFcSttbfffn() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.STTBFFFN); + } + + public int GetLcbSttbfffn() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.STTBFFFN); + } + + public void SetFcSttbfffn(int fcSttbFffn) + { + _fieldHandler.SetFieldOffset(FIBFieldHandler.STTBFFFN, fcSttbFffn); + } + + public void SetLcbSttbfffn(int lcbSttbFffn) + { + _fieldHandler.SetFieldSize(FIBFieldHandler.STTBFFFN, lcbSttbFffn); + } + + public int GetFcSttbfRMark() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.STTBFRMARK); + } + + public int GetLcbSttbfRMark() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.STTBFRMARK); + } + + public void SetFcSttbfRMark(int fcSttbfRMark) + { + _fieldHandler.SetFieldOffset(FIBFieldHandler.STTBFRMARK, fcSttbfRMark); + } + + public void SetLcbSttbfRMark(int lcbSttbfRMark) + { + _fieldHandler.SetFieldSize(FIBFieldHandler.STTBFRMARK, lcbSttbfRMark); + } + + /** + * Return the offset to the PlcfHdd, in the table stream, + * i.e. fcPlcfHdd + */ + public int GetPlcfHddOffset() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.PLCFHDD); + } + /** + * Return the size of the PlcfHdd, in the table stream, + * i.e. lcbPlcfHdd + */ + public int GetPlcfHddSize() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.PLCFHDD); + } + public void SetPlcfHddOffset(int fcPlcfHdd) + { + _fieldHandler.SetFieldOffset(FIBFieldHandler.PLCFHDD, fcPlcfHdd); + } + public void SetPlcfHddSize(int lcbPlcfHdd) + { + _fieldHandler.SetFieldSize(FIBFieldHandler.PLCFHDD, lcbPlcfHdd); + } + + public int GetFcSttbSavedBy() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.STTBSAVEDBY); + } + + public int GetLcbSttbSavedBy() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.STTBSAVEDBY); + } + + public void SetFcSttbSavedBy(int fcSttbSavedBy) + { + _fieldHandler.SetFieldOffset(FIBFieldHandler.STTBSAVEDBY, fcSttbSavedBy); + } + + public void SetLcbSttbSavedBy(int fcSttbSavedBy) + { + _fieldHandler.SetFieldSize(FIBFieldHandler.STTBSAVEDBY, fcSttbSavedBy); + } + + public int GetModifiedLow() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.PLFLFO); + } + + public int GetModifiedHigh() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.PLFLFO); + } + + public void SetModifiedLow(int modifiedLow) + { + _fieldHandler.SetFieldOffset(FIBFieldHandler.PLFLFO, modifiedLow); + } + + public void SetModifiedHigh(int modifiedHigh) + { + _fieldHandler.SetFieldSize(FIBFieldHandler.PLFLFO, modifiedHigh); + } + + + /** + * How many bytes of the main stream contain real data. + */ + public int GetCbMac() + { + return _longHandler.GetLong(FIBLongHandler.CBMAC); + } + /** + * Updates the count of the number of bytes in the + * main stream which contain real data + */ + public void SetCbMac(int cbMac) + { + _longHandler.SetLong(FIBLongHandler.CBMAC, cbMac); + } + /** + * @return length of specified subdocument text stream in characters + */ + public int GetSubdocumentTextStreamLength(SubdocumentType type) + { + return _longHandler.GetLong((int)type); + } + public void SetSubdocumentTextStreamLength(SubdocumentType type, int length) + { + if (length < 0) + throw new ArgumentException( + "Subdocument length can't be less than 0 (passed value is " + + length + "). " + "If there is no subdocument " + + "length must be Set to zero."); + + _longHandler.SetLong((int)type, length); + } + /** + * The count of CPs in the main document + */ + public int GetCcpText() + { + return _longHandler.GetLong(FIBLongHandler.CCPTEXT); + } + /** + * Updates the count of CPs in the main document + */ + public void SetCcpText(int ccpText) + { + _longHandler.SetLong(FIBLongHandler.CCPTEXT, ccpText); + } + + /** + * The count of CPs in the footnote subdocument + */ + public int GetCcpFtn() + { + return _longHandler.GetLong(FIBLongHandler.CCPFTN); + } + /** + * Updates the count of CPs in the footnote subdocument + */ + public void SetCcpFtn(int ccpFtn) + { + _longHandler.SetLong(FIBLongHandler.CCPFTN, ccpFtn); + } + + /** + * The count of CPs in the header story subdocument + */ + public int GetCcpHdd() + { + return _longHandler.GetLong(FIBLongHandler.CCPHDD); + } + /** + * Updates the count of CPs in the header story subdocument + */ + public void SetCcpHdd(int ccpHdd) + { + _longHandler.SetLong(FIBLongHandler.CCPHDD, ccpHdd); + } + + /** + * The count of CPs in the comments (atn) subdocument + */ + public int GetCcpAtn() + { + return _longHandler.GetLong(FIBLongHandler.CCPATN); + } + public int GetCcpCommentAtn() + { + return GetCcpAtn(); + } + /** + * Updates the count of CPs in the comments (atn) story subdocument + */ + public void SetCcpAtn(int ccpAtn) + { + _longHandler.SetLong(FIBLongHandler.CCPATN, ccpAtn); + } + + /** + * The count of CPs in the end note subdocument + */ + public int GetCcpEdn() + { + return _longHandler.GetLong(FIBLongHandler.CCPEDN); + } + /** + * Updates the count of CPs in the end note subdocument + */ + public void SetCcpEdn(int ccpEdn) + { + _longHandler.SetLong(FIBLongHandler.CCPEDN, ccpEdn); + } + + /** + * The count of CPs in the main document textboxes + */ + public int GetCcpTxtBx() + { + return _longHandler.GetLong(FIBLongHandler.CCPTXBX); + } + /** + * Updates the count of CPs in the main document textboxes + */ + public void SetCcpTxtBx(int ccpTxtBx) + { + _longHandler.SetLong(FIBLongHandler.CCPTXBX, ccpTxtBx); + } + + /** + * The count of CPs in the header textboxes + */ + public int GetCcpHdrTxtBx() + { + return _longHandler.GetLong(FIBLongHandler.CCPHDRTXBX); + } + /** + * Updates the count of CPs in the header textboxes + */ + public void SetCcpHdrTxtBx(int ccpTxtBx) + { + _longHandler.SetLong(FIBLongHandler.CCPHDRTXBX, ccpTxtBx); + } + + + public void ClearOffsetsSizes() + { + _fieldHandler.ClearFields(); + } + + public int GetFieldsPlcfOffset(FieldsDocumentPart part) + { + return _fieldHandler.GetFieldOffset((int)part); + } + + public int GetFieldsPlcfLength(FieldsDocumentPart part) + { + return _fieldHandler.GetFieldSize((int)part); + } + + public void SetFieldsPlcfOffset(FieldsDocumentPart part, int offSet) + { + _fieldHandler.SetFieldOffset((int)part, offSet); + } + + public void SetFieldsPlcfLength(FieldsDocumentPart part, int length) + { + _fieldHandler.SetFieldSize((int)part, length); + } + + [Obsolete] + public int GetFcPlcffldAtn() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.PLCFFLDATN); + } + + [Obsolete] + public int GetLcbPlcffldAtn() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.PLCFFLDATN); + } + + [Obsolete] + public void SetFcPlcffldAtn(int offset) + { + _fieldHandler.SetFieldOffset(FIBFieldHandler.PLCFFLDATN, offset); + } + + [Obsolete] + public void SetLcbPlcffldAtn(int size) + { + _fieldHandler.SetFieldSize(FIBFieldHandler.PLCFFLDATN, size); + } + + [Obsolete] + public int GetFcPlcffldEdn() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.PLCFFLDEDN); + } + + [Obsolete] + public int GetLcbPlcffldEdn() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.PLCFFLDEDN); + } + + [Obsolete] + public void SetFcPlcffldEdn(int offset) + { + _fieldHandler.SetFieldOffset(FIBFieldHandler.PLCFFLDEDN, offset); + } + + [Obsolete] + public void SetLcbPlcffldEdn(int size) + { + _fieldHandler.SetFieldSize(FIBFieldHandler.PLCFFLDEDN, size); + } + + [Obsolete] + public int GetFcPlcffldFtn() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.PLCFFLDFTN); + } + + [Obsolete] + public int GetLcbPlcffldFtn() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.PLCFFLDFTN); + } + + [Obsolete] + public void SetFcPlcffldFtn(int offset) + { + _fieldHandler.SetFieldOffset(FIBFieldHandler.PLCFFLDFTN, offset); + } + + [Obsolete] + public void SetLcbPlcffldFtn(int size) + { + _fieldHandler.SetFieldSize(FIBFieldHandler.PLCFFLDFTN, size); + } + + [Obsolete] + public int GetFcPlcffldHdr() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.PLCFFLDHDR); + } + + [Obsolete] + public int GetLcbPlcffldHdr() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.PLCFFLDHDR); + } + + [Obsolete] + public void SetFcPlcffldHdr(int offset) + { + _fieldHandler.SetFieldOffset(FIBFieldHandler.PLCFFLDHDR, offset); + } + + [Obsolete] + public void SetLcbPlcffldHdr(int size) + { + _fieldHandler.SetFieldSize(FIBFieldHandler.PLCFFLDHDR, size); + } + + [Obsolete] + public int GetFcPlcffldHdrtxbx() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.PLCFFLDHDRTXBX); + } + + [Obsolete] + public int GetLcbPlcffldHdrtxbx() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.PLCFFLDHDRTXBX); + } + + [Obsolete] + public void SetFcPlcffldHdrtxbx(int offset) + { + _fieldHandler.SetFieldOffset(FIBFieldHandler.PLCFFLDHDRTXBX, offset); + } + + [Obsolete] + public void SetLcbPlcffldHdrtxbx(int size) + { + _fieldHandler.SetFieldSize(FIBFieldHandler.PLCFFLDHDRTXBX, size); + } + + [Obsolete] + public int GetFcPlcffldMom() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.PLCFFLDMOM); + } + + public int GetLcbPlcffldMom() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.PLCFFLDMOM); + } + + [Obsolete] + public void SetFcPlcffldMom(int offset) + { + _fieldHandler.SetFieldOffset(FIBFieldHandler.PLCFFLDMOM, offset); + } + + [Obsolete] + public void SetLcbPlcffldMom(int size) + { + _fieldHandler.SetFieldSize(FIBFieldHandler.PLCFFLDMOM, size); + } + + [Obsolete] + public int GetFcPlcffldTxbx() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.PLCFFLDTXBX); + } + + [Obsolete] + public int GetLcbPlcffldTxbx() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.PLCFFLDTXBX); + } + + [Obsolete] + public void SetFcPlcffldTxbx(int offset) + { + _fieldHandler.SetFieldOffset(FIBFieldHandler.PLCFFLDTXBX, offset); + } + + [Obsolete] + public void SetLcbPlcffldTxbx(int size) + { + _fieldHandler.SetFieldSize(FIBFieldHandler.PLCFFLDTXBX, size); + } + + + public int GetFSPAPlcfOffset(FSPADocumentPart part) + { + return _fieldHandler.GetFieldOffset(part.GetFibFieldsField()); + } + + public int GetFSPAPlcfLength(FSPADocumentPart part) + { + return _fieldHandler.GetFieldSize(part.GetFibFieldsField()); + } + + public void SetFSPAPlcfOffset(FSPADocumentPart part, int offset) + { + _fieldHandler.SetFieldOffset(part.GetFibFieldsField(), offset); + } + + public void SetFSPAPlcfLength(FSPADocumentPart part, int length) + { + _fieldHandler.SetFieldSize(part.GetFibFieldsField(), length); + } + + [Obsolete] + public int GetFcPlcspaMom() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.PLCSPAMOM); + } + + [Obsolete] + public int GetLcbPlcspaMom() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.PLCSPAMOM); + } + + public int GetFcDggInfo() + { + return _fieldHandler.GetFieldOffset(FIBFieldHandler.DGGINFO); + } + + public int GetLcbDggInfo() + { + return _fieldHandler.GetFieldSize(FIBFieldHandler.DGGINFO); + } + + public int GetNotesDescriptorsOffset(NoteType noteType) + { + return _fieldHandler.GetFieldOffset(noteType + .GetFibDescriptorsFieldIndex()); + } + + public void SetNotesDescriptorsOffset(NoteType noteType, int offset) + { + _fieldHandler.SetFieldOffset(noteType.GetFibDescriptorsFieldIndex(), + offset); + } + + public int GetNotesDescriptorsSize(NoteType noteType) + { + return _fieldHandler.GetFieldSize(noteType + .GetFibDescriptorsFieldIndex()); + } + + public void SetNotesDescriptorsSize(NoteType noteType, int offset) + { + _fieldHandler.SetFieldSize(noteType.GetFibDescriptorsFieldIndex(), + offset); + } + + public int GetNotesTextPositionsOffset(NoteType noteType) + { + return _fieldHandler.GetFieldOffset(noteType + .GetFibTextPositionsFieldIndex()); + } + + public void SetNotesTextPositionsOffset(NoteType noteType, int offset) + { + _fieldHandler.SetFieldOffset(noteType.GetFibTextPositionsFieldIndex(), + offset); + } + + public int GetNotesTextPositionsSize(NoteType noteType) + { + return _fieldHandler.GetFieldSize(noteType + .GetFibTextPositionsFieldIndex()); + } + + public void SetNotesTextPositionsSize(NoteType noteType, int offset) + { + _fieldHandler.SetFieldSize(noteType.GetFibTextPositionsFieldIndex(), + offset); + } + + public void WriteTo(byte[] mainStream, HWPFStream tableStream) + { + //HWPFOutputStream mainDocument = sys.GetStream("WordDocument"); + //HWPFOutputStream tableStream = sys.GetStream("1Table"); + + base.Serialize(mainStream, 0); + + int size = base.GetSize(); + _shortHandler.Serialize(mainStream); + _longHandler.Serialize(mainStream, size + _shortHandler.SizeInBytes()); + _fieldHandler.WriteTo(mainStream, + base.GetSize() + _shortHandler.SizeInBytes() + _longHandler.SizeInBytes(), tableStream); + + } + + public override int GetSize() + { + return base.GetSize() + _shortHandler.SizeInBytes() + + _longHandler.SizeInBytes() + _fieldHandler.SizeInBytes(); + } + // public Object Clone() + // { + // try + // { + // return super.Clone(); + // } + // catch (CloneNotSupportedException e) + // { + // e.printStackTrace(); + // return null; + // } + // } + } + + + +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/FontTable.cs b/scratchpad/HWPF/Model/FontTable.cs new file mode 100644 index 0000000..54a798f --- /dev/null +++ b/scratchpad/HWPF/Model/FontTable.cs @@ -0,0 +1,160 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + using NPOI.Util; + using NPOI.HWPF.Model.IO; + using System; + + /** + * FontTable or in MS terminology sttbfffn is a common data structure written in all + * Word files. The sttbfffn is an sttbf where each string is an FFN structure instead + * of pascal-style strings. An sttbf is a string Table stored in file. Thus sttbffn + * is like an Sttbf with an array of FFN structures that stores the font name strings + * + * @author Praveen Mathew + */ + public class FontTable + { + private short _stringCount;// how many strings are included in the string table + private short _extraDataSz;// size in bytes of the extra data + + // Added extra facilitator members + private int lcbSttbfffn;// count of bytes in sttbfffn + private int fcSttbfffn;// table stream offset for sttbfffn + + // FFN structure Containing strings of font names + private Ffn[] _fontNames = null; + + + public FontTable(byte[] buf, int offset, int lcbSttbfffn) + { + this.lcbSttbfffn = lcbSttbfffn; + this.fcSttbfffn = offset; + + _stringCount = LittleEndian.GetShort(buf, offset); + offset += LittleEndianConsts.SHORT_SIZE; + _extraDataSz = LittleEndian.GetShort(buf, offset); + offset += LittleEndianConsts.SHORT_SIZE; + + _fontNames = new Ffn[_stringCount]; //Ffn corresponds to a Pascal style String in STTBF. + + for (int i = 0; i < _stringCount; i++) + { + _fontNames[i] = new Ffn(buf, offset); + offset += _fontNames[i].GetSize(); + } + } + + public short GetStringCount() + { + return _stringCount; + } + + public short GetExtraDataSz() + { + return _extraDataSz; + } + + public Ffn[] GetFontNames() + { + return _fontNames; + } + + public int GetSize() + { + return lcbSttbfffn; + } + + public String GetMainFont(int chpFtc) + { + if (chpFtc >= _stringCount) + { + //Console.WriteLine("Mismatch in chpFtc with stringCount"); + return null; + } + + return _fontNames[chpFtc].GetMainFontName(); + } + + public String GetAltFont(int chpFtc) + { + if (chpFtc >= _stringCount) + { + //Console.WriteLine("Mismatch in chpFtc with stringCount"); + return null; + } + + return _fontNames[chpFtc].GetAltFontName(); + } + + public void SetStringCount(short stringCount) + { + this._stringCount = stringCount; + } + + public void WriteTo(HWPFFileSystem sys) + { + HWPFStream tableStream = sys.GetStream("1Table"); + + byte[] buf = new byte[LittleEndianConsts.SHORT_SIZE]; + LittleEndian.PutShort(buf, _stringCount); + tableStream.Write(buf); + LittleEndian.PutShort(buf, _extraDataSz); + tableStream.Write(buf); + + for (int i = 0; i < _fontNames.Length; i++) + { + tableStream.Write(_fontNames[i].ToArray()); + } + + } + + public override bool Equals(Object o) + { + bool retVal = true; + + if (((FontTable)o).GetStringCount() == _stringCount) + { + if (((FontTable)o).GetExtraDataSz() == _extraDataSz) + { + Ffn[] fontNamesNew = ((FontTable)o).GetFontNames(); + for (int i = 0; i < _stringCount; i++) + { + if (!(_fontNames[i].Equals(fontNamesNew[i]))) + retVal = false; + } + } + else + retVal = false; + } + else + retVal = false; + + + return retVal; + } + + + + } +} + + + + diff --git a/scratchpad/HWPF/Model/FootnoteReferenceDescriptor.cs b/scratchpad/HWPF/Model/FootnoteReferenceDescriptor.cs new file mode 100644 index 0000000..c07f71c --- /dev/null +++ b/scratchpad/HWPF/Model/FootnoteReferenceDescriptor.cs @@ -0,0 +1,80 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +using System; +using NPOI.HWPF.Model.Types; +namespace NPOI.HWPF.Model +{ + + + public class FootnoteReferenceDescriptor : FRDAbstractType + { + public FootnoteReferenceDescriptor() + { + } + + public FootnoteReferenceDescriptor(byte[] data, int offset) + { + FillFields(data, offset); + } + + + public override bool Equals(Object obj) + { + if (this == obj) + return true; + if (obj == null) + return false; + if (this.GetType() != obj.GetType()) + return false; + FootnoteReferenceDescriptor other = (FootnoteReferenceDescriptor)obj; + if (field_1_nAuto != other.field_1_nAuto) + return false; + return true; + } + + + public override int GetHashCode() + { + int prime = 31; + int result = 1; + result = prime * result + field_1_nAuto; + return result; + } + + public bool IsEmpty + { + get + { + return field_1_nAuto == 0; + } + } + + + public override String ToString() + { + if (IsEmpty) + return "[FRD] EMPTY"; + + return base.ToString(); + } + } +} + + + + + diff --git a/scratchpad/HWPF/Model/FormattedDiskPage.cs b/scratchpad/HWPF/Model/FormattedDiskPage.cs new file mode 100644 index 0000000..0c979d1 --- /dev/null +++ b/scratchpad/HWPF/Model/FormattedDiskPage.cs @@ -0,0 +1,94 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + using NPOI.Util; + + /** + * Represents an FKP data structure. This data structure is used to store the + * grpprls of the paragraph and character properties of the document. A grpprl + * is a list of sprms(decompression operations) to perform on a parent style. + * + * The style properties for paragraph and character Runs + * are stored in fkps. There are PAP fkps for paragraph properties and CHP fkps + * for character run properties. The first part of the fkp for both CHP and PAP + * fkps consists of an array of 4 byte int OffSets in the main stream for that + * Paragraph's or Character Run's text. The ending offset is the next + * value in the array. For example, if an fkp has X number of Paragraph's + * stored in it then there are (x + 1) 4 byte ints in the beginning array. The + * number X is determined by the last byte in a 512 byte fkp. + * + * CHP and PAP fkps also store the compressed styles(grpprl) that correspond to + * the OffSets on the front of the fkp. The offset of the grpprls is determined + * differently for CHP fkps and PAP fkps. + * + * @author Ryan Ackley + */ + public abstract class FormattedDiskPage + { + protected byte[] _fkp; + protected int _crun; + protected int _offset; + + + public FormattedDiskPage() + { + + } + + /** + * Uses a 512-byte array to create a FKP + */ + public FormattedDiskPage(byte[] documentStream, int offset) + { + _crun = LittleEndian.GetUByte(documentStream, offset + 511); + _fkp = documentStream; + _offset = offset; + } + /** + * Used to get a text offset corresponding to a grpprl in this fkp. + * @param index The index of the property in this FKP + * @return an int representing an offset in the "WordDocument" stream + */ + protected int GetStart(int index) + { + return LittleEndian.GetInt(_fkp, _offset + (index * 4)); + } + /** + * Used to get the end of the text corresponding to a grpprl in this fkp. + * @param index The index of the property in this fkp. + * @return an int representing an offset in the "WordDocument" stream + */ + protected int GetEnd(int index) + { + return LittleEndian.GetInt(_fkp, _offset + ((index + 1) * 4)); + } + /** + * Used to get the total number of grrprl's stored int this FKP + * @return The number of grpprls in this FKP + */ + public int Size() + { + return _crun; + } + + protected abstract byte[] GetGrpprl(int index); + } + + +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/GenericPropertyNode.cs b/scratchpad/HWPF/Model/GenericPropertyNode.cs new file mode 100644 index 0000000..93b575e --- /dev/null +++ b/scratchpad/HWPF/Model/GenericPropertyNode.cs @@ -0,0 +1,42 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + using System; + + + public class GenericPropertyNode : PropertyNode + { + public GenericPropertyNode(int start, int end, byte[] buf) + : base(start, end, buf) + { + + } + + public byte[] Bytes + { + get + { + return (byte[])_buf; + } + } + + + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/HWPFStream.cs b/scratchpad/HWPF/Model/HWPFStream.cs new file mode 100644 index 0000000..b1788b9 --- /dev/null +++ b/scratchpad/HWPF/Model/HWPFStream.cs @@ -0,0 +1,105 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + using System; + using System.IO; + using NPOI.Util; + using NPOI.Util.IO; + + public class HWPFStream : LittleEndianInput + { + private LittleEndianInput _le; + private int _currentDataOffset = 0; + + public HWPFStream(Stream stream) + { + _le = new LittleEndianInputStream(stream); + } + + #region LittleEndianInput Members + + public int Available() + { + throw new NotImplementedException(); + } + + public int ReadByte() + { + _currentDataOffset += LittleEndianConstants.BYTE_SIZE; + return _le.ReadByte(); + } + + public int ReadUByte() + { + int s = ReadByte(); + if (s < 0) + { + s += 256; + } + return s; + } + + public short ReadShort() + { + _currentDataOffset += LittleEndianConstants.SHORT_SIZE; + return _le.ReadShort(); + } + + public int ReadUShort() + { + _currentDataOffset += LittleEndianConstants.SHORT_SIZE; + return _le.ReadUShort(); + } + + public int ReadInt() + { + _currentDataOffset += LittleEndianConstants.INT_SIZE; + return _le.ReadInt(); + } + + public long ReadLong() + { + _currentDataOffset += LittleEndianConstants.LONG_SIZE; + return _le.ReadLong(); + } + + public double ReadDouble() + { + _currentDataOffset += LittleEndianConstants.DOUBLE_SIZE; + + long valueLongBits = _le.ReadLong(); + double result = BitConverter.Int64BitsToDouble(valueLongBits); + return result; + } + + public void ReadFully(byte[] buf) + { + ReadFully(buf, 0, buf.Length); + } + + public void ReadFully(byte[] buf, int off, int len) + { + _le.ReadFully(buf, off, len); + _currentDataOffset += len; + } + + #endregion + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/IO/HWPFFileSystem.cs b/scratchpad/HWPF/Model/IO/HWPFFileSystem.cs new file mode 100644 index 0000000..2116520 --- /dev/null +++ b/scratchpad/HWPF/Model/IO/HWPFFileSystem.cs @@ -0,0 +1,43 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model.IO +{ + using System; + using System.IO; + using System.Collections; + + + public class HWPFFileSystem + { + Hashtable _streams = new Hashtable(); + + public HWPFFileSystem() + { + _streams["WordDocument"] = new HWPFStream(); + _streams["1Table"] = new HWPFStream(); + _streams["Data"] = new HWPFStream(); + } + + public HWPFStream GetStream(String name) + { + return (HWPFStream)_streams[name]; + } + + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/IO/HWPFOutputStream.cs b/scratchpad/HWPF/Model/IO/HWPFOutputStream.cs new file mode 100644 index 0000000..c988711 --- /dev/null +++ b/scratchpad/HWPF/Model/IO/HWPFOutputStream.cs @@ -0,0 +1,67 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model.IO +{ + using System; + using System.IO; + using System.Collections; + + public class HWPFStream : MemoryStream + { + + int _offset; + + public HWPFStream() + : base() + { + + } + + public int Offset + { + get + { + return _offset; + } + } + + public void Reset() + { + _offset = 0; + } + + public override void Write(byte[] buf, int off, int len) + { + base.Write(buf, off, len); + _offset += len; + } + + public void Write(byte[] buf) + { + base.Write(buf, 0, buf.Length); + _offset += buf.Length; + } + + public void Write(int b) + { + base.WriteByte((byte)b); + _offset++; + } + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/ListData.cs b/scratchpad/HWPF/Model/ListData.cs new file mode 100644 index 0000000..7605b97 --- /dev/null +++ b/scratchpad/HWPF/Model/ListData.cs @@ -0,0 +1,159 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + + + using NPOI.Util; + using System; + + public class ListData + { + private int _lsid; + private int _tplc; + private short[] _rgistd; + private byte _info; + private static BitField _fSimpleList = BitFieldFactory.GetInstance(0x1); + private static BitField _fRestartHdn = BitFieldFactory.GetInstance(0x2); + private byte _reserved; + ListLevel[] _levels; + + public ListData(int listID, bool numbered) + { + _lsid = listID; + _rgistd = new short[9]; + + for (int x = 0; x < 9; x++) + { + _rgistd[x] = (short)StyleSheet.NIL_STYLE; + } + + _levels = new ListLevel[9]; + + for (int x = 0; x < _levels.Length; x++) + { + _levels[x] = new ListLevel(x, numbered); + } + } + + public ListData(byte[] buf, int offset) + { + _lsid = LittleEndian.GetInt(buf, offset); + offset += LittleEndianConsts.INT_SIZE; + _tplc = LittleEndian.GetInt(buf, offset); + offset += LittleEndianConsts.INT_SIZE; + _rgistd = new short[9]; + for (int x = 0; x < 9; x++) + { + _rgistd[x] = LittleEndian.GetShort(buf, offset); + offset += LittleEndianConsts.SHORT_SIZE; + } + _info = buf[offset++]; + _reserved = buf[offset]; + if (_fSimpleList.GetValue(_info) > 0) + { + _levels = new ListLevel[1]; + } + else + { + _levels = new ListLevel[9]; + } + + } + + public int GetLsid() + { + return _lsid; + } + + public int numLevels() + { + return _levels.Length; + } + + public void SetLevel(int index, ListLevel level) + { + _levels[index] = level; + } + + public ListLevel[] GetLevels() + { + return _levels; + } + + /** + * Gets the level associated to a particular List at a particular index. + * + * @param index 1-based index + * @return a list level + */ + public ListLevel GetLevel(int index) + { + return _levels[index - 1]; + } + + public int GetLevelStyle(int index) + { + return _rgistd[index]; + } + + public void SetLevelStyle(int index, int styleIndex) + { + _rgistd[index] = (short)styleIndex; + } + + public override bool Equals(Object obj) + { + if (obj == null) + { + return false; + } + + ListData lst = (ListData)obj; + return lst._info == _info && Arrays.Equals(lst._levels, _levels) && + lst._lsid == _lsid && lst._reserved == _reserved && lst._tplc == _tplc && + Arrays.Equals(lst._rgistd, _rgistd); + } + + internal int ResetListID() + { + _lsid = (int)((new Random((int)DateTime.Now.Ticks)).Next(0,100)/100 * DateTime.Now.Millisecond); + return _lsid; + } + + public byte[] ToArray() + { + byte[] buf = new byte[28]; + int offset = 0; + LittleEndian.PutInt(buf, _lsid); + offset += LittleEndianConsts.INT_SIZE; + LittleEndian.PutInt(buf, offset, _tplc); + offset += LittleEndianConsts.INT_SIZE; + for (int x = 0; x < 9; x++) + { + LittleEndian.PutShort(buf, offset, _rgistd[x]); + offset += LittleEndianConsts.SHORT_SIZE; + } + buf[offset++] = _info; + buf[offset] = _reserved; + return buf; + } + } +} + + diff --git a/scratchpad/HWPF/Model/ListFormatOverride.cs b/scratchpad/HWPF/Model/ListFormatOverride.cs new file mode 100644 index 0000000..f5b7d7e --- /dev/null +++ b/scratchpad/HWPF/Model/ListFormatOverride.cs @@ -0,0 +1,122 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + using NPOI.Util; + using System; + + public class ListFormatOverride + { + int _lsid; + int _reserved1; + int _reserved2; + byte _clfolvl; + byte[] _reserved3 = new byte[3]; + ListFormatOverrideLevel[] _levelOverrides; + + public ListFormatOverride(int lsid) + { + _lsid = lsid; + _levelOverrides = new ListFormatOverrideLevel[0]; + } + + public ListFormatOverride(byte[] buf, int offset) + { + _lsid = LittleEndian.GetInt(buf, offset); + offset += LittleEndianConsts.INT_SIZE; + _reserved1 = LittleEndian.GetInt(buf, offset); + offset += LittleEndianConsts.INT_SIZE; + _reserved2 = LittleEndian.GetInt(buf, offset); + offset += LittleEndianConsts.INT_SIZE; + _clfolvl = buf[offset++]; + Array.Copy(buf, offset, _reserved3, 0, _reserved3.Length); + _levelOverrides = new ListFormatOverrideLevel[_clfolvl]; + } + + public int numOverrides() + { + return _clfolvl; + } + + public int GetLsid() + { + return _lsid; + } + + internal void SetLsid(int lsid) + { + _lsid = lsid; + } + + public ListFormatOverrideLevel[] GetLevelOverrides() + { + return _levelOverrides; + } + + public void SetOverride(int index, ListFormatOverrideLevel lfolvl) + { + _levelOverrides[index] = lfolvl; + } + + public ListFormatOverrideLevel GetOverrideLevel(int level) + { + + ListFormatOverrideLevel retLevel = null; + + for (int x = 0; x < _levelOverrides.Length; x++) + { + if (_levelOverrides[x].GetLevelNum() == level) + { + retLevel = _levelOverrides[x]; + } + } + return retLevel; + } + + public override bool Equals(Object obj) + { + if (obj == null) + { + return false; + } + + ListFormatOverride lfo = (ListFormatOverride)obj; + return lfo._clfolvl == _clfolvl && lfo._lsid == _lsid && + lfo._reserved1 == _reserved1 && lfo._reserved2 == _reserved2 && + Arrays.Equals(lfo._reserved3, _reserved3) && + Arrays.Equals(lfo._levelOverrides, _levelOverrides); + } + + public byte[] ToArray() + { + byte[] buf = new byte[16]; + int offset = 0; + LittleEndian.PutInt(buf, offset, _lsid); + offset += LittleEndianConsts.INT_SIZE; + LittleEndian.PutInt(buf, offset, _reserved1); + offset += LittleEndianConsts.INT_SIZE; + LittleEndian.PutInt(buf, offset, _reserved2); + offset += LittleEndianConsts.INT_SIZE; + buf[offset++] = _clfolvl; + Array.Copy(_reserved3, 0, buf, offset, 3); + + return buf; + } + } +} + diff --git a/scratchpad/HWPF/Model/ListFormatOverrideLevel.cs b/scratchpad/HWPF/Model/ListFormatOverrideLevel.cs new file mode 100644 index 0000000..e876c67 --- /dev/null +++ b/scratchpad/HWPF/Model/ListFormatOverrideLevel.cs @@ -0,0 +1,122 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + using System; + using NPOI.Util; + + public class ListFormatOverrideLevel + { + private static int BASE_SIZE = 8; + + int _iStartAt; + byte _info; + private static BitField _ilvl = BitFieldFactory.GetInstance(0xf); + private static BitField _fStartAt = BitFieldFactory.GetInstance(0x10); + private static BitField _fFormatting = BitFieldFactory.GetInstance(0x20); + byte[] _reserved = new byte[3]; + ListLevel _lvl; + + public ListFormatOverrideLevel(byte[] buf, int offset) + { + _iStartAt = LittleEndian.GetInt(buf, offset); + offset += LittleEndianConsts.INT_SIZE; + _info = buf[offset++]; + Array.Copy(buf, offset, _reserved, 0, _reserved.Length); + offset += _reserved.Length; + + if (_fFormatting.GetValue(_info) > 0) + { + _lvl = new ListLevel(buf, offset); + } + } + + public ListLevel GetLevel() + { + return _lvl; + } + + public int GetLevelNum() + { + return _ilvl.GetValue(_info); + } + + public bool IsFormatting() + { + return _fFormatting.GetValue(_info) != 0; + } + + public bool IsStartAt() + { + return _fStartAt.GetValue(_info) != 0; + } + + public int GetSizeInBytes() + { + return (_lvl == null ? BASE_SIZE : BASE_SIZE + _lvl.GetSizeInBytes()); + } + + public override bool Equals(Object obj) + { + if (obj == null) + { + return false; + } + ListFormatOverrideLevel lfolvl = (ListFormatOverrideLevel)obj; + bool lvlEquality = false; + if (_lvl != null) + { + lvlEquality = _lvl.Equals(lfolvl._lvl); + } + else + { + lvlEquality = lfolvl._lvl == null; + } + + return lvlEquality && lfolvl._iStartAt == _iStartAt && lfolvl._info == _info && + Arrays.Equals(lfolvl._reserved, _reserved); + } + + public byte[] ToArray() + { + byte[] buf = new byte[GetSizeInBytes()]; + + int offset = 0; + LittleEndian.PutInt(buf, _iStartAt); + offset += LittleEndianConsts.INT_SIZE; + buf[offset++] = _info; + Array.Copy(_reserved, 0, buf, offset, 3); + offset += 3; + + if (_lvl != null) + { + byte[] levelBuf = _lvl.ToArray(); + Array.Copy(levelBuf, 0, buf, offset, levelBuf.Length); + } + + return buf; + } + + public int GetIStartAt() + { + return _iStartAt; + } + } +} + + diff --git a/scratchpad/HWPF/Model/ListLevel.cs b/scratchpad/HWPF/Model/ListLevel.cs new file mode 100644 index 0000000..b00140b --- /dev/null +++ b/scratchpad/HWPF/Model/ListLevel.cs @@ -0,0 +1,266 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + using NPOI.Util; + using System; + + /** + * + */ + public class ListLevel + { + private static int RGBXCH_NUMS_SIZE = 9; + + private int _iStartAt; + private byte _nfc; + private byte _info; + private static BitField _jc; + private static BitField _fLegal; + private static BitField _fNoRestart; + private static BitField _fPrev; + private static BitField _fPrevSpace; + private static BitField _fWord6; + private byte[] _rgbxchNums; + private byte _ixchFollow; + private int _dxaSpace; + private int _dxaIndent; + private int _cbGrpprlChpx; + private int _cbGrpprlPapx; + private short _reserved; + private byte[] _grpprlPapx; + private byte[] _grpprlChpx; + private char[] _numberText = null; + + public ListLevel(int startAt, int numberFormatCode, int alignment, + byte[] numberProperties, byte[] entryProperties, + String numberText) + { + _iStartAt = startAt; + _nfc = (byte)numberFormatCode; + _jc.SetValue(_info, alignment); + _grpprlChpx = numberProperties; + _grpprlPapx = entryProperties; + _numberText = numberText.ToCharArray(); + } + + public ListLevel(int level, bool numbered) + { + _iStartAt = 1; + _grpprlPapx = new byte[0]; + _grpprlChpx = new byte[0]; + _numberText = new char[0]; + _rgbxchNums = new byte[RGBXCH_NUMS_SIZE]; + + if (numbered) + { + _rgbxchNums[0] = 1; + _numberText = new char[] { (char)level, '.' }; + } + else + { + _numberText = new char[] { '\u2022' }; + } + } + + public ListLevel(byte[] buf, int offset) + { + _iStartAt = LittleEndian.GetInt(buf, offset); + offset += LittleEndianConsts.INT_SIZE; + _nfc = buf[offset++]; + _info = buf[offset++]; + + _rgbxchNums = new byte[RGBXCH_NUMS_SIZE]; + Array.Copy(buf, offset, _rgbxchNums, 0, RGBXCH_NUMS_SIZE); + offset += RGBXCH_NUMS_SIZE; + + _ixchFollow = buf[offset++]; + _dxaSpace = LittleEndian.GetInt(buf, offset); + offset += LittleEndianConsts.INT_SIZE; + _dxaIndent = LittleEndian.GetInt(buf, offset); + offset += LittleEndianConsts.INT_SIZE; + _cbGrpprlChpx = LittleEndian.GetUByte(buf, offset++); + _cbGrpprlPapx = LittleEndian.GetUByte(buf, offset++); + _reserved = LittleEndian.GetShort(buf, offset); + offset += LittleEndianConsts.SHORT_SIZE; + + _grpprlPapx = new byte[_cbGrpprlPapx]; + _grpprlChpx = new byte[_cbGrpprlChpx]; + Array.Copy(buf, offset, _grpprlPapx, 0, _cbGrpprlPapx); + offset += _cbGrpprlPapx; + Array.Copy(buf, offset, _grpprlChpx, 0, _cbGrpprlChpx); + offset += _cbGrpprlChpx; + + int numberTextLength = LittleEndian.GetShort(buf, offset); + /* sometimes numberTextLength<0 */ + /* by derjohng */ + if (numberTextLength > 0) + { + _numberText = new char[numberTextLength]; + offset += LittleEndianConsts.SHORT_SIZE; + for (int x = 0; x < numberTextLength; x++) + { + _numberText[x] = (char)LittleEndian.GetShort(buf, offset); + offset += LittleEndianConsts.SHORT_SIZE; + } + } + + } + + public int GetStartAt() + { + return _iStartAt; + } + + public int GetNumberFormat() + { + return _nfc; + } + + public int GetAlignment() + { + return _jc.GetValue(_info); + } + + public String GetNumberText() + { + if (_numberText != null) + return new String(_numberText); + else + return null; + } + /** + * "The type of character following the number text for the paragraph: 0 == tab, 1 == space, 2 == nothing." + */ + public byte GetTypeOfCharFollowingTheNumber() + { + return this._ixchFollow; + } + public void SetStartAt(int startAt) + { + _iStartAt = startAt; + } + + public void SetNumberFormat(int numberFormatCode) + { + _nfc = (byte)numberFormatCode; + } + + public void SetAlignment(int alignment) + { + _jc.SetValue(_info, alignment); + } + + public void SetNumberProperties(byte[] grpprl) + { + _grpprlChpx = grpprl; + + } + + public void SetLevelProperties(byte[] grpprl) + { + _grpprlPapx = grpprl; + } + + public byte[] GetLevelProperties() + { + return _grpprlPapx; + } + + public override bool Equals(Object obj) + { + if (obj == null) + { + return false; + } + + ListLevel lvl = (ListLevel)obj; + return _cbGrpprlChpx == lvl._cbGrpprlChpx && lvl._cbGrpprlPapx == _cbGrpprlPapx && + lvl._dxaIndent == _dxaIndent && lvl._dxaSpace == _dxaSpace && + Arrays.Equals(lvl._grpprlChpx, _grpprlChpx) && + Arrays.Equals(lvl._grpprlPapx, _grpprlPapx) && + lvl._info == _info && lvl._iStartAt == _iStartAt && + lvl._ixchFollow == _ixchFollow && lvl._nfc == _nfc && + Arrays.Equals(lvl._numberText, _numberText) && + Arrays.Equals(lvl._rgbxchNums, _rgbxchNums) && + lvl._reserved == _reserved; + + + } + public byte[] ToArray() + { + byte[] buf = new byte[GetSizeInBytes()]; + int offset = 0; + LittleEndian.PutInt(buf, offset, _iStartAt); + offset += LittleEndianConsts.INT_SIZE; + buf[offset++] = _nfc; + buf[offset++] = _info; + Array.Copy(_rgbxchNums, 0, buf, offset, RGBXCH_NUMS_SIZE); + offset += RGBXCH_NUMS_SIZE; + buf[offset++] = _ixchFollow; + LittleEndian.PutInt(buf, offset, _dxaSpace); + offset += LittleEndianConsts.INT_SIZE; + LittleEndian.PutInt(buf, offset, _dxaIndent); + offset += LittleEndianConsts.INT_SIZE; + + buf[offset++] = (byte)_cbGrpprlChpx; + buf[offset++] = (byte)_cbGrpprlPapx; + LittleEndian.PutShort(buf, offset, _reserved); + offset += LittleEndianConsts.SHORT_SIZE; + + Array.Copy(_grpprlPapx, 0, buf, offset, _cbGrpprlPapx); + offset += _cbGrpprlPapx; + Array.Copy(_grpprlChpx, 0, buf, offset, _cbGrpprlChpx); + offset += _cbGrpprlChpx; + + if (_numberText == null) + { + // TODO - write junit to test this flow + LittleEndian.PutUShort(buf, offset, 0); + } + else + { + LittleEndian.PutUShort(buf, offset, _numberText.Length); + offset += LittleEndianConsts.SHORT_SIZE; + for (int x = 0; x < _numberText.Length; x++) + { + LittleEndian.PutUShort(buf, offset, _numberText[x]); + offset += LittleEndianConsts.SHORT_SIZE; + } + } + return buf; + } + public int GetSizeInBytes() + { + int result = + 6 // int byte byte + + RGBXCH_NUMS_SIZE + + 13 // byte int int byte byte short + + _cbGrpprlChpx + + _cbGrpprlPapx + + 2; // numberText length + if (_numberText != null) + { + result += _numberText.Length * LittleEndianConsts.SHORT_SIZE; + } + return result; + } + + } +} + diff --git a/scratchpad/HWPF/Model/ListTables.cs b/scratchpad/HWPF/Model/ListTables.cs new file mode 100644 index 0000000..be83275 --- /dev/null +++ b/scratchpad/HWPF/Model/ListTables.cs @@ -0,0 +1,233 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using NPOI.Util; +using System.Collections.Generic; +using System.IO; +using System; +using NPOI.HWPF.Model.IO; +namespace NPOI.HWPF.Model +{ + + + /** + * @author Ryan Ackley + */ + public class ListTables + { + private static int LIST_DATA_SIZE = 28; + private static int LIST_FORMAT_OVERRIDE_SIZE = 16; + //private static POILogger log = POILogFactory.GetLogger(ListTables.class); + + Dictionary _listMap = new Dictionary(); + List _overrideList = new List(); + + public ListTables() + { + + } + + public ListTables(byte[] tableStream, int lstOffset, int lfoOffset) + { + // get the list data + int length = LittleEndian.GetShort(tableStream, lstOffset); + lstOffset += LittleEndianConsts.SHORT_SIZE; + int levelOffset = lstOffset + (length * LIST_DATA_SIZE); + + for (int x = 0; x < length; x++) + { + ListData lst = new ListData(tableStream, lstOffset); + _listMap.Add(lst.GetLsid(), lst); + lstOffset += LIST_DATA_SIZE; + + int num = lst.numLevels(); + for (int y = 0; y < num; y++) + { + ListLevel lvl = new ListLevel(tableStream, levelOffset); + lst.SetLevel(y, lvl); + levelOffset += lvl.GetSizeInBytes(); + } + } + + // now get the list format overrides. The size is an int unlike the LST size + length = LittleEndian.GetInt(tableStream, lfoOffset); + lfoOffset += LittleEndianConsts.INT_SIZE; + int lfolvlOffset = lfoOffset + (LIST_FORMAT_OVERRIDE_SIZE * length); + for (int x = 0; x < length; x++) + { + ListFormatOverride lfo = new ListFormatOverride(tableStream, lfoOffset); + lfoOffset += LIST_FORMAT_OVERRIDE_SIZE; + int num = lfo.numOverrides(); + for (int y = 0; y < num; y++) + { + while (tableStream[lfolvlOffset] == 255) + { + lfolvlOffset++; + } + ListFormatOverrideLevel lfolvl = new ListFormatOverrideLevel(tableStream, lfolvlOffset); + lfo.SetOverride(y, lfolvl); + lfolvlOffset += lfolvl.GetSizeInBytes(); + } + _overrideList.Add(lfo); + } + } + + public int AddList(ListData lst, ListFormatOverride override1) + { + int lsid = lst.GetLsid(); + while (_listMap[lsid] != null) + { + lsid = lst.ResetListID(); + override1.SetLsid(lsid); + } + _listMap.Add(lsid, lst); + _overrideList.Add(override1); + return lsid; + } + + public void WriteListDataTo(HWPFStream tableStream) + { + int listSize = _listMap.Count; + + // use this stream as a buffer for the levels since their size varies. + MemoryStream levelBuf = new MemoryStream(); + + byte[] shortHolder = new byte[2]; + LittleEndian.PutShort(shortHolder, (short)listSize); + tableStream.Write(shortHolder); + //TODO:: sort the keys + foreach (int x in _listMap.Keys) + { + ListData lst = _listMap[x]; + tableStream.Write(lst.ToArray()); + ListLevel[] lvls = lst.GetLevels(); + for (int y = 0; y < lvls.Length; y++) + { + byte[] bytes = lvls[y].ToArray(); + levelBuf.Write(bytes, 0, bytes.Length); + } + } + tableStream.Write(levelBuf.ToArray()); + } + + public void WriteListOverridesTo(HWPFStream tableStream) + { + + // use this stream as a buffer for the levels since their size varies. + MemoryStream levelBuf = new MemoryStream(); + + int size = _overrideList.Count; + + byte[] intHolder = new byte[4]; + LittleEndian.PutInt(intHolder, size); + tableStream.Write(intHolder); + + for (int x = 0; x < size; x++) + { + ListFormatOverride lfo = _overrideList[x]; + tableStream.Write(lfo.ToArray()); + ListFormatOverrideLevel[] lfolvls = lfo.GetLevelOverrides(); + for (int y = 0; y < lfolvls.Length; y++) + { + byte[] bytes = lfolvls[y].ToArray(); + levelBuf.Write(bytes, 0, bytes.Length); + } + } + tableStream.Write(levelBuf.ToArray()); + + } + + public ListFormatOverride GetOverride(int lfoIndex) + { + return _overrideList[lfoIndex - 1]; + } + + public int GetOverrideIndexFromListID(int lstid) + { + int returnVal = -1; + int size = _overrideList.Count; + for (int x = 0; x < size; x++) + { + ListFormatOverride next = _overrideList[x]; + if (next.GetLsid() == lstid) + { + // 1-based index I think + returnVal = x + 1; + break; + } + } + if (returnVal == -1) + { + throw new InvalidDataException("No list found with the specified ID"); + } + return returnVal; + } + + public ListLevel GetLevel(int listID, int level) + { + ListData lst = _listMap[listID]; + if (level < lst.numLevels()) + { + ListLevel lvl = lst.GetLevels()[level]; + return lvl; + } + //log.log(POILogger.WARN, "Requested level " + level + " which was greater than the maximum defined (" + lst.numLevels() + ")"); + return null; + } + + public ListData GetListData(int listID) + { + return _listMap[listID]; + } + + public override bool Equals(Object obj) + { + if (obj == null) + { + return false; + } + + ListTables tables = (ListTables)obj; + + if (_listMap.Count == tables._listMap.Count) + { + foreach (int key in _listMap.Keys) + { + ListData lst1 = _listMap[key]; + ListData lst2 = tables._listMap[key]; + if (!lst1.Equals(lst2)) + { + return false; + } + } + int size = _overrideList.Count; + if (size == tables._overrideList.Count) + { + for (int x = 0; x < size; x++) + { + if (!_overrideList[x].Equals(tables._overrideList[x])) + { + return false; + } + } + return true; + } + } + return false; + } + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/NoteType.cs b/scratchpad/HWPF/Model/NoteType.cs new file mode 100644 index 0000000..dead651 --- /dev/null +++ b/scratchpad/HWPF/Model/NoteType.cs @@ -0,0 +1,67 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +/** + * Word document notes types (and their FIB field indices) + * + * @author Sergey Vladimirov (vlsergey {at} gmail {doc} com) + */ +namespace NPOI.HWPF.Model +{ + + + +public class NoteType { + /** Ending note */ + public static NoteType ENDNOTE = new NoteType(FIBFieldHandler.PLCFENDREF, FIBFieldHandler.PLCFENDTXT); + + /** Footnote */ + public static NoteType FOOTNOTE= new NoteType(FIBFieldHandler.PLCFFNDREF, FIBFieldHandler.PLCFFNDTXT ); + + private int fibDescriptorsFieldIndex; + private int fibTextPositionsFieldIndex; + + private NoteType( int fibDescriptorsFieldIndex, + int fibTextPositionsFieldIndex ) + { + this.fibDescriptorsFieldIndex = fibDescriptorsFieldIndex; + this.fibTextPositionsFieldIndex = fibTextPositionsFieldIndex; + } + + public static NoteType[] Values + { + get + { + return new NoteType[] { NoteType.ENDNOTE, NoteType.FOOTNOTE }; + } + } + + public int GetFibDescriptorsFieldIndex() + { + return fibDescriptorsFieldIndex; + } + + public int GetFibTextPositionsFieldIndex() + { + return fibTextPositionsFieldIndex; + } +} + + +} + + diff --git a/scratchpad/HWPF/Model/NotesTables.cs b/scratchpad/HWPF/Model/NotesTables.cs new file mode 100644 index 0000000..88b884a --- /dev/null +++ b/scratchpad/HWPF/Model/NotesTables.cs @@ -0,0 +1,125 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +using System.IO; +using NPOI.HWPF.Model.IO; +namespace NPOI.HWPF.Model +{ + + + /** + * Holds information about document notes (footnotes or ending notes) + * + * @author Sergey Vladimirov (vlsergey {at} gmail {doc} com) + */ + + public class NotesTables + { + private PlexOfCps descriptors = new PlexOfCps( + FootnoteReferenceDescriptor.GetSize()); + + private NoteType noteType; + + private PlexOfCps textPositions = new PlexOfCps(0); + + public NotesTables(NoteType noteType) + { + this.noteType = noteType; + textPositions + .AddProperty(new GenericPropertyNode(0, 1, new byte[0])); + } + + public NotesTables(NoteType noteType, byte[] tableStream, + FileInformationBlock fib) + { + this.noteType = noteType; + Read(tableStream, fib); + } + + public GenericPropertyNode GetDescriptor(int index) + { + return descriptors.GetProperty(index); + } + + public int GetDescriptorsCount() + { + return descriptors.Length; + } + + public GenericPropertyNode GetTextPosition(int index) + { + return textPositions.GetProperty(index); + } + + private void Read(byte[] tableStream, FileInformationBlock fib) + { + int referencesStart = fib.GetNotesDescriptorsOffset(noteType); + int referencesLength = fib.GetNotesDescriptorsSize(noteType); + + if (referencesStart != 0 && referencesLength != 0) + this.descriptors = new PlexOfCps(tableStream, referencesStart, + referencesLength, FootnoteReferenceDescriptor.GetSize()); + + int textPositionsStart = fib.GetNotesTextPositionsOffset(noteType); + int textPositionsLength = fib.GetNotesTextPositionsSize(noteType); + + if (textPositionsStart != 0 && textPositionsLength != 0) + this.textPositions = new PlexOfCps(tableStream, + textPositionsStart, textPositionsLength, 0); + } + + public void WriteRef(FileInformationBlock fib, HWPFStream tableStream) + { + if (descriptors == null || descriptors.Length == 0) + { + fib.SetNotesDescriptorsOffset(noteType, tableStream.Offset); + fib.SetNotesDescriptorsSize(noteType, 0); + return; + } + + int start = tableStream.Offset; + byte[] data = descriptors.ToByteArray(); + tableStream.Write(data); + int end =tableStream.Offset; + + fib.SetNotesDescriptorsOffset(noteType, start); + fib.SetNotesDescriptorsSize(noteType, end - start); + } + + public void WriteTxt(FileInformationBlock fib, HWPFStream tableStream) + { + if (textPositions == null || textPositions.Length == 0) + { + fib.SetNotesTextPositionsOffset(noteType, tableStream.Offset); + fib.SetNotesTextPositionsSize(noteType, 0); + return; + } + + int start = tableStream.Offset; + byte[] data = textPositions.ToByteArray(); + tableStream.Write(data); + int end = tableStream.Offset; + + fib.SetNotesTextPositionsOffset(noteType, start); + fib.SetNotesTextPositionsSize(noteType, end - start); + } + } + + +} + + + diff --git a/scratchpad/HWPF/Model/OldCHPBinTable.cs b/scratchpad/HWPF/Model/OldCHPBinTable.cs new file mode 100644 index 0000000..d5cf983 --- /dev/null +++ b/scratchpad/HWPF/Model/OldCHPBinTable.cs @@ -0,0 +1,69 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + + using NPOI.Util; + using NPOI.POIFS.Common; + + /** + * This class holds all of the character formatting + * properties from Old (Word 6 / Word 95) documents. + * Unlike with Word 97+, it all Gets held in the + * same stream. + * In common with the rest of the old support, it + * is read only + */ + public class OldCHPBinTable : CHPBinTable + { + /** + * Constructor used to read an old-style binTable + * in from a Word document. + * + * @param documentStream + * @param offset + * @param size + * @param fcMin + */ + public OldCHPBinTable(byte[] documentStream, int OffSet, + int size, int fcMin, TextPieceTable tpt) + { + PlexOfCps binTable = new PlexOfCps(documentStream, OffSet, size, 2); + + int length = binTable.Length; + for (int x = 0; x < length; x++) + { + GenericPropertyNode node = binTable.GetProperty(x); + + int pageNum = LittleEndian.GetShort(node.Bytes); + int pageOffset = POIFSConstants.SMALLER_BIG_BLOCK_SIZE * pageNum; + + CHPFormattedDiskPage cfkp = new CHPFormattedDiskPage(documentStream, + pageOffset, fcMin, tpt); + + int fkpSize = cfkp.Size(); + + for (int y = 0; y < fkpSize; y++) + { + _textRuns.Add(cfkp.GetCHPX(y)); + } + } + } + } +} + diff --git a/scratchpad/HWPF/Model/OldPAPBinTable.cs b/scratchpad/HWPF/Model/OldPAPBinTable.cs new file mode 100644 index 0000000..fe5c537 --- /dev/null +++ b/scratchpad/HWPF/Model/OldPAPBinTable.cs @@ -0,0 +1,64 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +namespace NPOI.HWPF.Model +{ + using NPOI.Util; + using NPOI.POIFS.Common; + using System.Collections; + using System.Collections.Generic; + /** + * This class holds all of the paragraph formatting + * properties from Old (Word 6 / Word 95) documents. + * Unlike with Word 97+, it all Gets held in the + * same stream. + * In common with the rest of the old support, it + * is read only + */ + public class OldPAPBinTable : PAPBinTable + { + public OldPAPBinTable(byte[] documentStream, int OffSet, + int size, int fcMin, TextPieceTable tpt) + { + PlexOfCps binTable = new PlexOfCps(documentStream, OffSet, size, 2); + + int length = binTable.Length; + for (int x = 0; x < length; x++) + { + GenericPropertyNode node = binTable.GetProperty(x); + + int pageNum = LittleEndian.GetShort(node.Bytes); + int pageOffset = POIFSConstants.SMALLER_BIG_BLOCK_SIZE * pageNum; + + PAPFormattedDiskPage pfkp = new PAPFormattedDiskPage(documentStream, + documentStream, pageOffset, tpt); + + int fkpSize = pfkp.Size(); + + for (int y = 0; y < fkpSize; y++) + { + PAPX papx = pfkp.GetPAPX(y); + _paragraphs.Add(papx); + } + } + _paragraphs.Sort((IComparer)PropertyNode.PAPXComparator.instance); + } + } + +} + diff --git a/scratchpad/HWPF/Model/OldSectionTable.cs b/scratchpad/HWPF/Model/OldSectionTable.cs new file mode 100644 index 0000000..bc6a26b --- /dev/null +++ b/scratchpad/HWPF/Model/OldSectionTable.cs @@ -0,0 +1,83 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using NPOI.Util; +using System; +namespace NPOI.HWPF.Model +{ + + + /** + * This class holds all of the section formatting + * properties from Old (Word 6 / Word 95) documents. + * Unlike with Word 97+, it all Gets held in the + * same stream. + * In common with the rest of the old support, it + * is read only + */ + public class OldSectionTable : SectionTable + { + public OldSectionTable(byte[] documentStream, int offset, + int size, int fcMin, + TextPieceTable tpt):this(documentStream, offset, size) + { + + } + + public OldSectionTable(byte[] documentStream, int offset, int size) + { + PlexOfCps sedPlex = new PlexOfCps(documentStream, offset, size, 12); + + int length = sedPlex.Length; + + for (int x = 0; x < length; x++) + { + GenericPropertyNode node = sedPlex.GetProperty(x); + SectionDescriptor sed = new SectionDescriptor(node.Bytes, 0); + + int fileOffset = sed.GetFc(); + int startAt = node.Start; + int endAt = node.End; + + SEPX sepx; + // check for the optimization + if (fileOffset == unchecked((int)0xffffffff)) + { + sepx = new SEPX(sed, startAt, endAt, new byte[0]); + } + else + { + // The first short at the offset is the size of the grpprl. + int sepxSize = LittleEndian.GetShort(documentStream, fileOffset); + // Because we don't properly know about all the details of the old + // section properties, and we're trying to decode them as if they + // were the new ones, we sometimes "need" more data than we have. + // As a workaround, have a few extra 0 bytes on the end! + byte[] buf = new byte[sepxSize+2]; + fileOffset += LittleEndianConsts.SHORT_SIZE; + Array.Copy(documentStream, fileOffset, buf, 0, buf.Length>=documentStream.Length - fileOffset?documentStream.Length - fileOffset: buf.Length); + sepx = new SEPX(sed, startAt, endAt,buf); + } + _sections.Add(sepx); + } + + _sections.Sort(PropertyNode.SEPXComparator.instance); + } + + } +} + diff --git a/scratchpad/HWPF/Model/PAPBinTable.cs b/scratchpad/HWPF/Model/PAPBinTable.cs new file mode 100644 index 0000000..a286137 --- /dev/null +++ b/scratchpad/HWPF/Model/PAPBinTable.cs @@ -0,0 +1,435 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using System.Collections.Generic; +using NPOI.POIFS.Common; +using NPOI.Util; +using NPOI.HWPF.SPRM; +using NPOI.HWPF.Model.IO; +using System.IO; +using System; +using System.Text; +namespace NPOI.HWPF.Model +{ + + + /** + * This class represents the bin table of Word document but it also serves as a + * holder for all of the paragraphs of document that have been loaded into + * memory. + * + * @author Ryan Ackley + */ + public class PAPBinTable + { + protected List _paragraphs = new List(); + byte[] _dataStream; + + /** So we can know if things are unicode or not */ + private TextPieceTable tpt; + + public PAPBinTable() + { + } + + [Obsolete] + public PAPBinTable(byte[] documentStream, byte[] tableStream, + byte[] dataStream, int offset, int size, int fcMin, + TextPieceTable tpt) : + this(documentStream, tableStream, dataStream, offset, size, tpt) + { + + } + + public PAPBinTable(byte[] documentStream, byte[] tableStream, byte[] dataStream, int offset, + int size, CharIndexTranslator charIndexTranslator) + { + PlexOfCps binTable = new PlexOfCps(tableStream, offset, size, 4); + + int length = binTable.Length; + for (int x = 0; x < length; x++) + { + GenericPropertyNode node = binTable.GetProperty(x); + + int pageNum = LittleEndian.GetInt(node.Bytes); + int pageOffset = POIFSConstants.SMALLER_BIG_BLOCK_SIZE * pageNum; + + PAPFormattedDiskPage pfkp = new PAPFormattedDiskPage(documentStream, + dataStream, pageOffset, charIndexTranslator); + + int fkpSize = pfkp.Size(); + + for (int y = 0; y < fkpSize; y++) + { + PAPX papx = pfkp.GetPAPX(y); + _paragraphs.Add(papx); + } + } + _dataStream = dataStream; + } + + public void Insert(int listIndex, int cpStart, SprmBuffer buf) + { + + PAPX forInsert = new PAPX(0, 0, buf); + + // Ensure character OffSets are really characters + forInsert.Start = cpStart; + forInsert.End = cpStart; + + if (listIndex == _paragraphs.Count) + { + _paragraphs.Add(forInsert); + } + else + { + PAPX currentPap = _paragraphs[listIndex]; + if (currentPap != null && currentPap.Start < cpStart) + { + SprmBuffer ClonedBuf = null; + ClonedBuf = (SprmBuffer)currentPap.GetSprmBuf().Clone(); + + + // Copy the properties of the one before to afterwards + // Will go: + // Original, until insert at point + // New one + // Clone of original, on to the old end + PAPX clone = new PAPX(0, 0, ClonedBuf); + // Again ensure Contains character based OffSets no matter what + clone.Start = (cpStart); + clone.End = (currentPap.End); + + currentPap.End = cpStart; + + _paragraphs.Insert(listIndex + 1, forInsert); + _paragraphs.Insert(listIndex + 2, clone); + } + else + { + _paragraphs.Insert(listIndex, forInsert); + } + } + + } + internal class PAPXToFileComparer : IComparer + { + Dictionary list; + public PAPXToFileComparer(Dictionary list) + { + this.list = list; + } + #region IComparer Members + + public int Compare(PAPX o1, PAPX o2) + { + int i1 = list[o1]; + int i2 = list[o2]; + return i1.CompareTo(i2); + } + #endregion + } + public void Rebuild(StringBuilder docText, + ComplexFileTable complexFileTable) + { + long start = DateTime.Now.Ticks; + + if (complexFileTable != null) + { + SprmBuffer[] sprmBuffers = complexFileTable.GetGrpprls(); + + // adding PAPX from fast-saved SPRMs + foreach (TextPiece textPiece in complexFileTable.GetTextPieceTable() + .TextPieces) + { + PropertyModifier prm = textPiece.PieceDescriptor.Prm; + if (!prm.IsComplex()) + continue; + int igrpprl = prm.GetIgrpprl(); + + if (igrpprl < 0 || igrpprl >= sprmBuffers.Length) + { + logger.Log(POILogger.WARN, textPiece + + "'s PRM references to unknown grpprl"); + continue; + } + + bool hasPap = false; + SprmBuffer sprmBuffer = sprmBuffers[igrpprl]; + for (SprmIterator iterator = sprmBuffer.Iterator(); iterator + .HasNext(); ) + { + SprmOperation sprmOperation = iterator.Next(); + if (sprmOperation.Type == SprmOperation.TYPE_PAP) + { + hasPap = true; + break; + } + } + + if (hasPap) + { + SprmBuffer newSprmBuffer = new SprmBuffer(2); + newSprmBuffer.Append(sprmBuffer.ToByteArray()); + + PAPX papx = new PAPX(textPiece.Start, + textPiece.End, newSprmBuffer); + _paragraphs.Add(papx); + } + } + + logger.Log(POILogger.DEBUG, + "Merged (?) with PAPX from complex file table in ", + DateTime.Now.Ticks - start, + " ms (", _paragraphs.Count, + " elements in total)"); + start = DateTime.Now.Ticks; + } + + List oldPapxSortedByEndPos = new List(_paragraphs); + oldPapxSortedByEndPos.Sort( + (IComparer)PropertyNode.PAPXComparator.instance); + + logger.Log(POILogger.DEBUG, "PAPX sorted by end position in ", + DateTime.Now.Ticks - start, " ms"); + start = DateTime.Now.Ticks; + + Dictionary papxToFileOrder = new Dictionary(); + int counter = 0; + foreach (PAPX papx in _paragraphs) + { + papxToFileOrder[papx] = counter++; + } + + logger.Log(POILogger.DEBUG, "PAPX's order map created in ", + DateTime.Now.Ticks - start, " ms"); + start = DateTime.Now.Ticks; + + List newPapxs = new List(); + int lastParStart = 0; + int lastPapxIndex = 0; + for (int charIndex = 0; charIndex < docText.Length; charIndex++) + { + char c = docText[charIndex]; + if (c != 13 && c != 7 && c != 12) + continue; + + int startInclusive = lastParStart; + int endExclusive = charIndex + 1; + + bool broken = false; + List papxs = new List(); + for (int papxIndex = lastPapxIndex; papxIndex < oldPapxSortedByEndPos + .Count; papxIndex++) + { + broken = false; + PAPX papx = oldPapxSortedByEndPos[papxIndex]; + + + if (papx.End - 1 > charIndex) + { + lastPapxIndex = papxIndex; + broken = true; + break; + } + + papxs.Add(papx); + } + if (!broken) + { + lastPapxIndex = oldPapxSortedByEndPos.Count - 1; + } + + if (papxs.Count == 0) + { + logger.Log(POILogger.WARN, "Paragraph [", + startInclusive, "; ", + endExclusive, + ") has no PAPX. Creating new one."); + // create it manually + PAPX papx = new PAPX(startInclusive, endExclusive, + new SprmBuffer(2)); + newPapxs.Add(papx); + + lastParStart = endExclusive; + continue; + } + + if (papxs.Count == 1) + { + // can we reuse existing? + PAPX existing = papxs[0]; + if (existing.Start == startInclusive + && existing.End == endExclusive) + { + newPapxs.Add(existing); + lastParStart = endExclusive; + continue; + } + } + PAPXToFileComparer papxFileOrderComparator = new PAPXToFileComparer(papxToFileOrder); + // restore file order of PAPX + papxs.Sort(papxFileOrderComparator); + + SprmBuffer sprmBuffer = null; + foreach (PAPX papx in papxs) + { + if (sprmBuffer == null) + sprmBuffer = (SprmBuffer)papx.GetSprmBuf().Clone(); + + else + sprmBuffer.Append(papx.GetGrpprl(), 2); + } + PAPX newPapx = new PAPX(startInclusive, endExclusive, sprmBuffer); + newPapxs.Add(newPapx); + + lastParStart = endExclusive; + continue; + } + this._paragraphs = new List(newPapxs); + + logger.Log(POILogger.DEBUG, "PAPX rebuilded from document text in ", + DateTime.Now.Ticks - start, " ms (", + _paragraphs.Count, " elements)"); + start = DateTime.Now.Ticks; + } + + private static POILogger logger = POILogFactory + .GetLogger(typeof(PAPBinTable)); + + public void AdjustForDelete(int listIndex, int offset, int Length) + { + int size = _paragraphs.Count; + int endMark = offset + Length; + int endIndex = listIndex; + + PAPX papx = _paragraphs[endIndex]; + while (papx.End < endMark) + { + papx = _paragraphs[++endIndex]; + } + if (listIndex == endIndex) + { + papx = _paragraphs[endIndex]; + papx.End = ((papx.End - endMark) + offset); + } + else + { + papx = _paragraphs[listIndex]; + papx.End = (offset); + for (int x = listIndex + 1; x < endIndex; x++) + { + papx = _paragraphs[x]; + papx.Start = (offset); + papx.End = (offset); + } + papx = _paragraphs[endIndex]; + papx.End = ((papx.End - endMark) + offset); + } + + for (int x = endIndex + 1; x < size; x++) + { + papx = _paragraphs[x]; + papx.Start = (papx.Start - Length); + papx.End = (papx.End - Length); + } + } + + + public void AdjustForInsert(int listIndex, int Length) + { + int size = _paragraphs.Count; + PAPX papx = (PAPX)_paragraphs[listIndex]; + papx.End = (papx.End + Length); + + for (int x = listIndex + 1; x < size; x++) + { + papx = (PAPX)_paragraphs[x]; + papx.Start = (papx.Start + Length); + papx.End = (papx.End + Length); + } + } + + + public List GetParagraphs() + { + return _paragraphs; + } + + [Obsolete] + public void WriteTo(HWPFFileSystem sys, CharIndexTranslator translator) + { + HWPFStream wordDocumentStream = sys.GetStream("WordDocument"); + HWPFStream tableStream = sys.GetStream("1Table"); + + WriteTo(wordDocumentStream, tableStream, translator); + } + public void WriteTo(HWPFStream docStream, + HWPFStream tableStream, CharIndexTranslator translator ) + + { + PlexOfCps binTable = new PlexOfCps(4); + + // each FKP must start on a 512 byte page. + int docOffset = docStream.Offset; + int mod = docOffset % POIFSConstants.SMALLER_BIG_BLOCK_SIZE; + if (mod != 0) + { + byte[] pAdding = new byte[POIFSConstants.SMALLER_BIG_BLOCK_SIZE - mod]; + docStream.Write(pAdding); + } + + // get the page number for the first fkp + docOffset = docStream.Offset; + int pageNum = docOffset / POIFSConstants.SMALLER_BIG_BLOCK_SIZE; + + // get the ending fc + int endingFc = ((PropertyNode)_paragraphs[_paragraphs.Count - 1]).End; + + + List overflow = _paragraphs; + do + { + PropertyNode startingProp = (PropertyNode)overflow[0]; + int start = translator.GetByteIndex(startingProp.Start); + + PAPFormattedDiskPage pfkp = new PAPFormattedDiskPage(_dataStream); + pfkp.Fill(overflow); + + byte[] bufFkp = pfkp.ToByteArray(tableStream,translator); + docStream.Write(bufFkp); + overflow = pfkp.GetOverflow(); + + int end = endingFc; + if (overflow != null) + { + end = translator.GetByteIndex(overflow[0].Start); + } + + byte[] intHolder = new byte[4]; + LittleEndian.PutInt(intHolder, pageNum++); + binTable.AddProperty(new GenericPropertyNode(start, end, intHolder)); + + } + while (overflow != null); + byte[] bytes = binTable.ToByteArray(); + tableStream.Write(bytes, 0, bytes.Length); + } + + + } +} diff --git a/scratchpad/HWPF/Model/PAPFormattedDiskPage.cs b/scratchpad/HWPF/Model/PAPFormattedDiskPage.cs new file mode 100644 index 0000000..553b138 --- /dev/null +++ b/scratchpad/HWPF/Model/PAPFormattedDiskPage.cs @@ -0,0 +1,332 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +namespace NPOI.HWPF.Model +{ + + using System.Collections.Generic; + using NPOI.Util; + using System; + using NPOI.HWPF.Model.IO; + /** + * Represents a PAP FKP. The style properties for paragraph and character Runs + * are stored in fkps. There are PAP fkps for paragraph properties and CHP fkps + * for character run properties. The first part of the fkp for both CHP and PAP + * fkps consists of an array of 4 byte int offsets in the main stream for that + * Paragraph's or Character Run's text. The ending offset is the next + * value in the array. For example, if an fkp has X number of Paragraph's + * stored in it then there are (x + 1) 4 byte ints in the beginning array. The + * number X is determined by the last byte in a 512 byte fkp. + * + * CHP and PAP fkps also store the compressed styles(grpprl) that correspond to + * the offsets on the front of the fkp. The offset of the grpprls is determined + * differently for CHP fkps and PAP fkps. + * + * @author Ryan Ackley + */ + public class PAPFormattedDiskPage : FormattedDiskPage + { + + private static int BX_SIZE = 13; + private static int FC_SIZE = 4; + + private List _papxList = new List(); + private List _overFlow; + + + public PAPFormattedDiskPage(byte[] dataStream):this() + { + + } + + public PAPFormattedDiskPage() + { + } + /** + * Creates a PAPFormattedDiskPage from a 512 byte array + */ + [Obsolete] + public PAPFormattedDiskPage(byte[] documentStream, byte[] dataStream, int offset, int fcMin, TextPieceTable tpt) + : this(documentStream, dataStream, offset, tpt ) + { + } + /** + * Creates a PAPFormattedDiskPage from a 512 byte array + */ + public PAPFormattedDiskPage(byte[] documentStream, byte[] dataStream, + int offset, CharIndexTranslator translator) + :base(documentStream, offset) + { + for (int x = 0; x < _crun; x++) + { + int bytesStartAt = GetStart(x); + int bytesEndAt = GetEnd(x); + + int charStartAt = translator.GetCharIndex(bytesStartAt); + int charEndAt = translator.GetCharIndex(bytesEndAt, charStartAt); + + PAPX papx = new PAPX(charStartAt, charEndAt, GetGrpprl(x), GetParagraphHeight(x), dataStream); + _papxList.Add(papx); + } + _fkp = null; + } + + /** + * Fills the queue for writing. + * + * @param Filler a List of PAPXs + */ + public void Fill(List Filler) + { + _papxList.AddRange(Filler); + } + + /** + * Used when writing out a Word docunment. This method is part of a sequence + * that is necessary because there is no easy and efficient way to + * determine the number PAPX's that will fit into one FKP. THe sequence is + * as follows: + * + * Fill() + * ToArray() + * GetOverflow() + * + * @return The remaining PAPXs that didn't fit into this FKP. + */ + internal List GetOverflow() + { + return _overFlow; + } + + /** + * Gets the PAPX at index. + * @param index The index to get the PAPX for. + * @return The PAPX at index. + */ + public PAPX GetPAPX(int index) + { + return _papxList[index]; + } + + /** + * Gets the papx grpprl for the paragraph at index in this fkp. + * + * @param index The index of the papx to Get. + * @return a papx grpprl. + */ + protected override byte[] GetGrpprl(int index) + { + int papxOffset = 2 * LittleEndian.GetUByte(_fkp, _offset + (((_crun + 1) * FC_SIZE) + (index * BX_SIZE))); + int size = 2 * LittleEndian.GetUByte(_fkp, _offset + papxOffset); + if (size == 0) + { + size = 2 * LittleEndian.GetUByte(_fkp, _offset + ++papxOffset); + } + else + { + size--; + } + + byte[] papx = new byte[size]; + Array.Copy(_fkp, _offset + ++papxOffset, papx, 0, size); + return papx; + } + + /** + * Creates a byte array representation of this data structure. Suitable for + * writing to a Word document. + * + * @param fcMin The file offset in the main stream where text begins. + * @return A byte array representing this data structure. + */ + internal byte[] ToByteArray(HWPFStream dataStream, + CharIndexTranslator translator) + { + byte[] buf = new byte[512]; + int size = _papxList.Count; + int grpprlOffset = 0; + int bxOffset = 0; + int fcOffset = 0; + byte[] lastGrpprl = new byte[0]; + + // total size is currently the size of one FC + int totalSize = FC_SIZE; + + int index = 0; + for (; index < size; index++) + { + byte[] grpprl = ((PAPX)_papxList[index]).GetGrpprl(); + int grpprlLength = grpprl.Length; + + // is grpprl huge? + if (grpprlLength > 488) + { + grpprlLength = 8; // set equal to size of sprmPHugePapx grpprl + } + + // check to see if we have enough room for an FC, a BX, and the grpprl + // and the 1 byte size of the grpprl. + int addition = 0; + if (!Arrays.Equals(grpprl, lastGrpprl)) + { + addition = (FC_SIZE + BX_SIZE + grpprlLength + 1); + } + else + { + addition = (FC_SIZE + BX_SIZE); + } + + totalSize += addition; + + // if size is uneven we will have to add one so the first grpprl falls + // on a word boundary + if (totalSize > 511 + (index % 2)) + { + totalSize -= addition; + break; + } + + // grpprls must fall on word boundaries + if (grpprlLength % 2 > 0) + { + totalSize += 1; + } + else + { + totalSize += 2; + } + lastGrpprl = grpprl; + } + + // see if we couldn't fit some + if (index != size) + { + _overFlow = new List(); + _overFlow.AddRange(_papxList.GetRange(index, size-index)); + } + + // index should equal number of papxs that will be in this fkp now. + buf[511] = (byte)index; + + bxOffset = (FC_SIZE * index) + FC_SIZE; + grpprlOffset = 511; + + PAPX papx = null; + lastGrpprl = new byte[0]; + for (int x = 0; x < index; x++) + { + papx = _papxList[x]; + byte[] phe = papx.GetParagraphHeight().ToArray(); + byte[] grpprl = papx.GetGrpprl(); + + // is grpprl huge? + if (grpprl.Length > 488) + { + /* + // if so do we have storage at GetHugeGrpprloffset() + int hugeGrpprlOffset = papx.GetHugeGrpprlOffset(); + if (hugeGrpprlOffset == -1) // then we have no storage... + { + throw new InvalidOperationException( + "This Paragraph has no dataStream storage."); + } + // we have some storage... + + // get the size of the existing storage + int maxHugeGrpprlSize = LittleEndian.GetUShort(_dataStream, hugeGrpprlOffset); + + if (maxHugeGrpprlSize < grpprl.Length - 2) + { // grpprl.Length-2 because we don't store the istd + throw new InvalidOperationException( + "This Paragraph's dataStream storage is too small."); + } + + + // store grpprl at hugeGrpprlOffset + Array.Copy(grpprl, 2, _dataStream, hugeGrpprlOffset + 2, + grpprl.Length - 2); // grpprl.Length-2 because we don't store the istd + LittleEndian.PutUShort(_dataStream, hugeGrpprlOffset, grpprl.Length - 2); + */ + + byte[] hugePapx = new byte[grpprl.Length - 2]; + System.Array.Copy(grpprl, 2, hugePapx, 0, grpprl.Length - 2); + int dataStreamOffset = dataStream.Offset; + dataStream.Write(hugePapx); + + // grpprl = grpprl Containing only a sprmPHugePapx2 + int istd = LittleEndian.GetUShort(grpprl, 0); + grpprl = new byte[8]; + LittleEndian.PutUShort(grpprl, 0, istd); + LittleEndian.PutUShort(grpprl, 2, 0x6646); // sprmPHugePapx2 + LittleEndian.PutInt(grpprl, 4, dataStreamOffset); + } + + bool same = Arrays.Equals(lastGrpprl, grpprl); + if (!same) + { + grpprlOffset -= (grpprl.Length + (2 - grpprl.Length % 2)); + grpprlOffset -= (grpprlOffset % 2); + } + LittleEndian.PutInt(buf, fcOffset, translator.GetByteIndex(papx.Start)); + buf[bxOffset] = (byte)(grpprlOffset / 2); + Array.Copy(phe, 0, buf, bxOffset + 1, phe.Length); + + // refer to the section on PAPX in the spec. Places a size on the front + // of the PAPX. Has to do with how the grpprl stays on word + // boundaries. + if (!same) + { + int copyOffset = grpprlOffset; + if ((grpprl.Length % 2) > 0) + { + buf[copyOffset++] = (byte)((grpprl.Length + 1) / 2); + } + else + { + buf[++copyOffset] = (byte)((grpprl.Length) / 2); + copyOffset++; + } + Array.Copy(grpprl, 0, buf, copyOffset, grpprl.Length); + lastGrpprl = grpprl; + } + + bxOffset += BX_SIZE; + fcOffset += FC_SIZE; + + } + + LittleEndian.PutInt(buf, fcOffset, translator.GetByteIndex(papx.End)); + return buf; + } + + /** + * Used to get the ParagraphHeight of a PAPX at a particular index. + * @param index + * @return The ParagraphHeight + */ + private ParagraphHeight GetParagraphHeight(int index) + { + int pheOffset = _offset + 1 + (((_crun + 1) * 4) + (index * 13)); + + ParagraphHeight phe = new ParagraphHeight(_fkp, pheOffset); + + return phe; + } + } +} + diff --git a/scratchpad/HWPF/Model/PAPX.cs b/scratchpad/HWPF/Model/PAPX.cs new file mode 100644 index 0000000..97781a5 --- /dev/null +++ b/scratchpad/HWPF/Model/PAPX.cs @@ -0,0 +1,163 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +namespace NPOI.HWPF.Model +{ + using NPOI.HWPF.SPRM; + using NPOI.Util; + using System; + using NPOI.HWPF.UserModel; + + + /** + * DANGER - works in bytes! + * + * Make sure you call GetStart() / GetEnd() when you want characters + * (normal use), but GetStartByte() / GetEndByte() when you're + * Reading in / writing out! + * + * @author Ryan Ackley + */ + + public class PAPX : BytePropertyNode + { + + private ParagraphHeight _phe; + + public PAPX(int charStart, int charEnd, SprmBuffer buf): + base(charStart, charEnd, buf) + { + + _phe = new ParagraphHeight(); + } + + public PAPX(int fcStart, int fcEnd, CharIndexTranslator translator, byte[] papx, ParagraphHeight phe, byte[] dataStream) + : base(fcStart, fcEnd, translator, new SprmBuffer(papx,2)) + { + + _phe = phe; + SprmBuffer buf = FindHuge(new SprmBuffer(papx,2), dataStream); + if (buf != null) + _buf = buf; + } + public PAPX(int charStart, int charEnd, byte[] papx, ParagraphHeight phe, + byte[] dataStream): + base(charStart, charEnd, new SprmBuffer(papx, 2)) + { + _phe = phe; + SprmBuffer buf = FindHuge(new SprmBuffer(papx, 2), dataStream); + if (buf != null) + _buf = buf; + } + [Obsolete] + public PAPX(int fcStart, int fcEnd, CharIndexTranslator translator, SprmBuffer buf, byte[] dataStream) + : base(fcStart, fcEnd, translator, buf) + { + + _phe = new ParagraphHeight(); + buf = FindHuge(buf, dataStream); + if (buf != null) + _buf = buf; + } + + private SprmBuffer FindHuge(SprmBuffer buf, byte[] datastream) + { + byte[] grpprl = buf.ToByteArray(); + if (grpprl.Length == 8 && datastream != null) // then check for sprmPHugePapx + { + SprmOperation sprm = new SprmOperation(grpprl, 2); + if ((sprm.Operation == 0x45 || sprm.Operation == 0x46) + && sprm.SizeCode == 3) + { + int hugeGrpprlOffset = sprm.Operand; + if (hugeGrpprlOffset + 1 < datastream.Length) + { + int grpprlSize = LittleEndian.GetShort(datastream, hugeGrpprlOffset); + if (hugeGrpprlOffset + grpprlSize < datastream.Length) + { + byte[] hugeGrpprl = new byte[grpprlSize + 2]; + // copy original istd into huge Grpprl + hugeGrpprl[0] = grpprl[0]; + hugeGrpprl[1] = grpprl[1]; + // copy Grpprl from dataStream + Array.Copy(datastream, hugeGrpprlOffset + 2, hugeGrpprl, 2, + grpprlSize); + + return new SprmBuffer(hugeGrpprl,2); + } + } + } + } + return null; + } + + + public ParagraphHeight GetParagraphHeight() + { + return _phe; + } + + public byte[] GetGrpprl() + { + return ((SprmBuffer)_buf).ToByteArray(); + } + + public short GetIstd() + { + byte[] buf = GetGrpprl(); + if (buf.Length == 0) + { + return 0; + } + if (buf.Length == 1) + { + return (short)LittleEndian.GetUByte(buf, 0); + } + return LittleEndian.GetShort(buf); + } + + public SprmBuffer GetSprmBuf() + { + return (SprmBuffer)_buf; + } + + public ParagraphProperties GetParagraphProperties(StyleSheet ss) + { + if (ss == null) + { + // TODO Fix up for Word 6/95 + return new ParagraphProperties(); + } + + short istd = GetIstd(); + ParagraphProperties baseStyle = ss.GetParagraphStyle(istd); + ParagraphProperties props = ParagraphSprmUncompressor.UncompressPAP(baseStyle, GetGrpprl(), 2); + return props; + } + + public override bool Equals(Object o) + { + if (base.Equals(o)) + { + return _phe.Equals(((PAPX)o)._phe); + } + return false; + } + } +} + diff --git a/scratchpad/HWPF/Model/ParagraphHeight.cs b/scratchpad/HWPF/Model/ParagraphHeight.cs new file mode 100644 index 0000000..9782d35 --- /dev/null +++ b/scratchpad/HWPF/Model/ParagraphHeight.cs @@ -0,0 +1,81 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + using System; + using NPOI.Util; + using System.IO; + + public class ParagraphHeight + { + private short infoField; + private BitField fSpare = BitFieldFactory.GetInstance(0x0001); + private BitField fUnk = BitFieldFactory.GetInstance(0x0002); + private BitField fDiffLines = BitFieldFactory.GetInstance(0x0004); + private BitField clMac = BitFieldFactory.GetInstance(0xff00); + private short reserved; + private int dxaCol; + private int dymLineOrHeight; + + public ParagraphHeight(byte[] buf, int offset) + { + infoField = LittleEndian.GetShort(buf, offset); + offset += LittleEndianConsts.SHORT_SIZE; + reserved = LittleEndian.GetShort(buf, offset); + offset += LittleEndianConsts.SHORT_SIZE; + dxaCol = LittleEndian.GetInt(buf, offset); + offset += LittleEndianConsts.INT_SIZE; + dymLineOrHeight = LittleEndian.GetInt(buf, offset); + } + + public ParagraphHeight() + { + + } + + public void Write(Stream out1) + { + byte[] bytes=ToArray(); + out1.Write(bytes, (int)out1.Position, bytes.Length); + } + + internal byte[] ToArray() + { + byte[] buf = new byte[12]; + int offset = 0; + LittleEndian.PutShort(buf, offset, infoField); + offset += LittleEndianConsts.SHORT_SIZE; + LittleEndian.PutShort(buf, offset, reserved); + offset += LittleEndianConsts.SHORT_SIZE; + LittleEndian.PutInt(buf, offset, dxaCol); + offset += LittleEndianConsts.INT_SIZE; + LittleEndian.PutInt(buf, offset, dymLineOrHeight); + + return buf; + } + + public override bool Equals(Object o) + { + ParagraphHeight ph = (ParagraphHeight)o; + + return infoField == ph.infoField && reserved == ph.reserved && + dxaCol == ph.dxaCol && dymLineOrHeight == ph.dymLineOrHeight; + } + } +} + diff --git a/scratchpad/HWPF/Model/PictureDescriptor.cs b/scratchpad/HWPF/Model/PictureDescriptor.cs new file mode 100644 index 0000000..201e6f1 --- /dev/null +++ b/scratchpad/HWPF/Model/PictureDescriptor.cs @@ -0,0 +1,215 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using System; +using System.Collections.Generic; +using System.Text; +using NPOI.Util; + +namespace NPOI.HWPF.Model +{ + public class PictureDescriptor + { + private static int LCB_OFFSET = 0x00; + private static int CBHEADER_OFFSET = 0x04; + + private static int MFP_MM_OFFSET = 0x06; + private static int MFP_XEXT_OFFSET = 0x08; + private static int MFP_YEXT_OFFSET = 0x0A; + private static int MFP_HMF_OFFSET = 0x0C; + + private static int DXAGOAL_OFFSET = 0x1C; + private static int DYAGOAL_OFFSET = 0x1E; + + private static int MX_OFFSET = 0x20; + private static int MY_OFFSET = 0x22; + + private static int DXACROPLEFT_OFFSET = 0x24; + private static int DYACROPTOP_OFFSET = 0x26; + private static int DXACROPRIGHT_OFFSET = 0x28; + private static int DYACROPBOTTOM_OFFSET = 0x2A; + + /** + * Number of bytes in the PIC structure plus size of following picture data + * which may be a Window's metafile, a bitmap, or the filename of a TIFF + * file. In the case of a Macintosh PICT picture, this includes the size of + * the PIC, the standard "x" metafile, and the Macintosh PICT data. See + * Appendix B for more information. + */ + protected int lcb; + + /** + * Number of bytes in the PIC (to allow for future expansion). + */ + protected int cbHeader; + + /* + * Microsoft Office Word 97-2007 Binary File Format (.doc) Specification + * + * Page 181 of 210 + * + * If a Windows metafile is stored immediately following the PIC structure, + * the mfp is a Window's METAFILEPICT structure. See + * http://msdn2.microsoft.com/en-us/library/ms649017(VS.85).aspx for more + * information about the METAFILEPICT structure and + * http://download.microsoft.com/download/0/B/E/0BE8BDD7-E5E8-422A-ABFD- + * 4342ED7AD886/WindowsMetafileFormat(wmf)Specification.pdf for Windows + * Metafile Format specification. + * + * When the data immediately following the PIC is a TIFF filename, + * mfp.mm==98 If a bitmap is stored after the pic, mfp.mm==99. + * + * When the PIC describes a bitmap, mfp.xExt is the width of the bitmap in + * pixels and mfp.yExt is the height of the bitmap in pixels. + */ + + protected int mfp_mm; + protected int mfp_xExt; + protected int mfp_yExt; + protected int mfp_hMF; + + /** + *
  • Window's bitmap structure when PIC describes a BITMAP (14 bytes) + * + *
  • Rectangle for window origin and extents when metafile is stored -- + * ignored if 0 (8 bytes) + */ + protected byte[] offset14 = new byte[14]; + + /** + * Horizontal measurement in twips of the rectangle the picture should be + * imaged within + */ + protected short dxaGoal = 0; + + /** + * Vertical measurement in twips of the rectangle the picture should be + * imaged within + */ + protected short dyaGoal = 0; + + /** + * Horizontal scaling factor supplied by user expressed in .001% units + */ + protected short mx; + + /** + * Vertical scaling factor supplied by user expressed in .001% units + */ + protected short my; + + /** + * The amount the picture has been cropped on the left in twips + */ + protected short dxaCropLeft = 0; + + /** + * The amount the picture has been cropped on the top in twips + */ + protected short dyaCropTop = 0; + + /** + * The amount the picture has been cropped on the right in twips + */ + protected short dxaCropRight = 0; + + /** + * The amount the picture has been cropped on the bottom in twips + */ + protected short dyaCropBottom = 0; + + public PictureDescriptor() + { + } + + public PictureDescriptor(byte[] _dataStream, int startOffset) + { + this.lcb = LittleEndian.GetInt(_dataStream, startOffset + LCB_OFFSET); + this.cbHeader = LittleEndian.GetUShort(_dataStream, startOffset + + CBHEADER_OFFSET); + + this.mfp_mm = LittleEndian.GetUShort(_dataStream, startOffset + + MFP_MM_OFFSET); + this.mfp_xExt = LittleEndian.GetUShort(_dataStream, startOffset + + MFP_XEXT_OFFSET); + this.mfp_yExt = LittleEndian.GetUShort(_dataStream, startOffset + + MFP_YEXT_OFFSET); + this.mfp_hMF = LittleEndian.GetUShort(_dataStream, startOffset + + MFP_HMF_OFFSET); + + this.offset14 = LittleEndian.GetByteArray(_dataStream, + startOffset + 0x0E, 14); + + this.dxaGoal = LittleEndian.GetShort(_dataStream, startOffset + + DXAGOAL_OFFSET); + this.dyaGoal = LittleEndian.GetShort(_dataStream, startOffset + + DYAGOAL_OFFSET); + + this.mx = LittleEndian.GetShort(_dataStream, startOffset + MX_OFFSET); + this.my = LittleEndian.GetShort(_dataStream, startOffset + MY_OFFSET); + + this.dxaCropLeft = LittleEndian.GetShort(_dataStream, startOffset + + DXACROPLEFT_OFFSET); + this.dyaCropTop = LittleEndian.GetShort(_dataStream, startOffset + + DYACROPTOP_OFFSET); + this.dxaCropRight = LittleEndian.GetShort(_dataStream, startOffset + + DXACROPRIGHT_OFFSET); + this.dyaCropBottom = LittleEndian.GetShort(_dataStream, startOffset + + DYACROPBOTTOM_OFFSET); + } + + public override String ToString() + { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.Append("[PICF]\n"); + stringBuilder.Append(" lcb = ").Append(this.lcb) + .Append('\n'); + stringBuilder.Append(" cbHeader = ") + .Append(this.cbHeader).Append('\n'); + + stringBuilder.Append(" mfp.mm = ").Append(this.mfp_mm) + .Append('\n'); + stringBuilder.Append(" mfp.xExt = ") + .Append(this.mfp_xExt).Append('\n'); + stringBuilder.Append(" mfp.yExt = ") + .Append(this.mfp_yExt).Append('\n'); + stringBuilder.Append(" mfp.hMF = ") + .Append(this.mfp_hMF).Append('\n'); + + stringBuilder.Append(" offset14 = "); + foreach (byte b in this.offset14) + stringBuilder.Append(b); + stringBuilder.Append('\n'); + stringBuilder.Append(" dxaGoal = ") + .Append(this.dxaGoal).Append('\n'); + stringBuilder.Append(" dyaGoal = ") + .Append(this.dyaGoal).Append('\n'); + + stringBuilder.Append(" dxaCropLeft = ") + .Append(this.dxaCropLeft).Append('\n'); + stringBuilder.Append(" dyaCropTop = ") + .Append(this.dyaCropTop).Append('\n'); + stringBuilder.Append(" dxaCropRight = ") + .Append(this.dxaCropRight).Append('\n'); + stringBuilder.Append(" dyaCropBottom = ") + .Append(this.dyaCropBottom).Append('\n'); + + stringBuilder.Append("[/PICF]"); + return stringBuilder.ToString(); + } + } +} diff --git a/scratchpad/HWPF/Model/PicturesTable.cs b/scratchpad/HWPF/Model/PicturesTable.cs new file mode 100644 index 0000000..f5fb2fe --- /dev/null +++ b/scratchpad/HWPF/Model/PicturesTable.cs @@ -0,0 +1,246 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using NPOI.Util; +using NPOI.DDF; +using System.Collections.Generic; +using NPOI.HWPF.UserModel; +using System.Collections; +using System; +namespace NPOI.HWPF.Model +{ + + /** + * Holds information about all pictures embedded in Word Document either via "Insert -> Picture -> From File" or via + * clipboard. Responsible for images extraction and determining whether some document's piece Contains embedded image. + * Analyzes raw data bytestream 'Data' (where Word stores all embedded objects) provided by HWPFDocument. + * + * Word stores images as is within so called "Data stream" - the stream within a Word docfile Containing various data + * that hang off of characters in the main stream. For example, binary data describing in-line pictures and/or + * formfields an also embedded objects-native data. Word picture structures are concatenated one after the other in + * the data stream if the document Contains pictures. + * Data stream is easily reachable via HWPFDocument._dataStream property. + * A picture is represented in the document text stream as a special character, an Unicode \u0001 whose + * CharacterRun.IsSpecial() returns true. The file location of the picture in the Word binary file is accessed + * via CharacterRun.GetPicOffSet(). The CharacterRun.GetPicOffSet() is a byte offset into the data stream. + * Beginning at the position recorded in picOffSet, a header data structure, will be stored. + * + * @author Dmitry Romanov + */ + public class PicturesTable + { + private static POILogger logger = POILogFactory + .GetLogger( typeof(PicturesTable) ); + + static int TYPE_IMAGE = 0x08; + static int TYPE_IMAGE_WORD2000 = 0x00; + static int TYPE_IMAGE_PASTED_FROM_CLIPBOARD = 0xA; + static int TYPE_IMAGE_PASTED_FROM_CLIPBOARD_WORD2000 = 0x2; + static int TYPE_HORIZONTAL_LINE = 0xE; + static int BLOCK_TYPE_OFFSET = 0xE; + static int MM_MODE_TYPE_OFFSET = 0x6; + + private HWPFDocument _document; + private byte[] _dataStream; + private byte[] _mainStream; + private FSPATable _fspa; + private EscherRecordHolder _dgg; + + /** @link dependency + * @stereotype instantiate*/ + /*# Picture lnkPicture; */ + + /** + * + * @param _document + * @param _dataStream + */ + public PicturesTable(HWPFDocument _document, byte[] _dataStream, byte[] _mainStream, FSPATable fspa, EscherRecordHolder dgg) + { + this._document = _document; + this._dataStream = _dataStream; + this._mainStream = _mainStream; + this._fspa = fspa; + this._dgg = dgg; + } + + /** + * determines whether specified CharacterRun Contains reference to a picture + * @param run + */ + public bool HasPicture(CharacterRun run) + { + if (run.IsSpecialCharacter() && !run.IsObj() && !run.IsOle2() && !run.IsData()) + { + // Image should be in it's own run, or in a run with the end-of-special marker + if ("\u0001".Equals(run.Text) || "\u0001\u0015".Equals(run.Text)) + { + return IsBlockContainsImage(run.GetPicOffset()); + } + } + return false; + } + + public bool HasEscherPicture(CharacterRun run) + { + if (run.IsSpecialCharacter() && !run.IsObj() && !run.IsOle2() && !run.IsData() && run.Text.StartsWith("\u0008")) + { + return true; + } + return false; + } + + /** + * determines whether specified CharacterRun Contains reference to a picture + * @param run + */ + public bool HasHorizontalLine(CharacterRun run) + { + if (run.IsSpecialCharacter() && "\u0001".Equals(run.Text)) + { + return IsBlockContainsHorizontalLine(run.GetPicOffset()); + } + return false; + } + + private bool IsPictureRecognized(short blockType, short mappingModeOfMETAFILEPICT) + { + return (blockType == TYPE_IMAGE || blockType == TYPE_IMAGE_PASTED_FROM_CLIPBOARD || (blockType == TYPE_IMAGE_WORD2000 && mappingModeOfMETAFILEPICT == 0x64) || (blockType == TYPE_IMAGE_PASTED_FROM_CLIPBOARD_WORD2000 && mappingModeOfMETAFILEPICT == 0x64)); + } + + private static short GetBlockType(byte[] dataStream, int pictOffset) + { + return LittleEndian.GetShort(dataStream, pictOffset + BLOCK_TYPE_OFFSET); + } + + private static short GetMmMode(byte[] dataStream, int pictOffset) + { + return LittleEndian.GetShort(dataStream, pictOffset + MM_MODE_TYPE_OFFSET); + } + + /** + * Returns picture object tied to specified CharacterRun + * @param run + * @param FillBytes if true, Picture will be returned with Filled byte array that represent picture's contents. If you don't want + * to have that byte array in memory but only write picture's contents to stream, pass false and then use Picture.WriteImageContent + * @see Picture#WriteImageContent(java.io.OutputStream) + * @return a Picture object if picture exists for specified CharacterRun, null otherwise. PicturesTable.hasPicture is used to determine this. + * @see #hasPicture(NPOI.HWPF.usermodel.CharacterRun) + */ + public Picture ExtractPicture(CharacterRun run, bool FillBytes) + { + if (HasPicture(run)) + { + return new Picture(run.GetPicOffset(), _dataStream, FillBytes); + } + return null; + } + + /** + * Performs a recursive search for pictures in the given list of escher records. + * + * @param escherRecords the escher records. + * @param pictures the list to populate with the pictures. + */ + private void SearchForPictures(IList escherRecords, List pictures) + { + foreach (EscherRecord escherRecord in escherRecords) + { + if (escherRecord is EscherBSERecord) + { + EscherBSERecord bse = (EscherBSERecord)escherRecord; + EscherBlipRecord blip = bse.BlipRecord; + if (blip != null) + { + pictures.Add(new Picture(blip.PictureData)); + } + else if (bse.Offset > 0) + { + try + { + // Blip stored in delay stream, which in a word doc, is the main stream + IEscherRecordFactory recordFactory = new DefaultEscherRecordFactory(); + EscherRecord record = recordFactory.CreateRecord(_mainStream, bse.Offset); + + if (record is EscherBlipRecord) + { + record.FillFields(_mainStream, bse.Offset, recordFactory); + blip = (EscherBlipRecord)record; + pictures.Add(new Picture(blip.PictureData)); + } + + } + catch (Exception exc) + { + logger.Log( + POILogger.WARN, + "Unable to load picture from BLIB record at offset #", + bse.Offset, exc); + } + } + } + + // Recursive call. + SearchForPictures(escherRecord.ChildRecords, pictures); + } + } + + /** + * Not all documents have all the images concatenated in the data stream + * although MS claims so. The best approach is to scan all character Runs. + * + * @return a list of Picture objects found in current document + */ + public List GetAllPictures() + { + List pictures = new List(); + + Range range = _document.GetOverallRange(); + for (int i = 0; i < range.NumCharacterRuns; i++) + { + CharacterRun run = range.GetCharacterRun(i); + + if (run == null) + { + continue; + } + + Picture picture = ExtractPicture(run, false); + if (picture != null) + { + pictures.Add(picture); + } + } + + SearchForPictures(_dgg.EscherRecords, pictures); + + return pictures; + } + + private bool IsBlockContainsImage(int i) + { + return IsPictureRecognized(GetBlockType(_dataStream, i), GetMmMode(_dataStream, i)); + } + + private bool IsBlockContainsHorizontalLine(int i) + { + return GetBlockType(_dataStream, i) == TYPE_HORIZONTAL_LINE && GetMmMode(_dataStream, i) == 0x64; + } + + } +} + diff --git a/scratchpad/HWPF/Model/PieceDescriptor.cs b/scratchpad/HWPF/Model/PieceDescriptor.cs new file mode 100644 index 0000000..87c5773 --- /dev/null +++ b/scratchpad/HWPF/Model/PieceDescriptor.cs @@ -0,0 +1,126 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + + +namespace NPOI.HWPF.Model +{ + using System; + using NPOI.Util; + + public class PieceDescriptor + { + + short descriptor; + private static BitField fNoParaLast = BitFieldFactory.GetInstance(0x01); + private static BitField fPaphNil = BitFieldFactory.GetInstance(0x02); + private static BitField fCopied = BitFieldFactory.GetInstance(0x04); + int fc; + PropertyModifier prm; + bool unicode; + + + public PieceDescriptor(byte[] buf, int offset) + { + descriptor = LittleEndian.GetShort(buf, offset); + offset += LittleEndianConsts.SHORT_SIZE; + fc = LittleEndian.GetInt(buf, offset); + offset += LittleEndianConsts.INT_SIZE; + prm = new PropertyModifier(LittleEndian.GetShort(buf, offset)); + + // see if this piece uses unicode. + if ((fc & 0x40000000) == 0) + { + unicode = true; + } + else + { + unicode = false; + fc &= ~(0x40000000);//gives me FC in doc stream + fc /= 2; + } + + } + + public int FilePosition + { + get + { + return fc; + } + set + { + fc = value; + } + } + + public bool IsUnicode + { + get + { + return unicode; + } + } + + internal byte[] ToByteArray() + { + // Set up the fc + int tempFc = fc; + if (!unicode) + { + tempFc *= 2; + tempFc |= (0x40000000); + } + + int offset = 0; + byte[] buf = new byte[8]; + LittleEndian.PutShort(buf, offset, descriptor); + offset += LittleEndianConsts.SHORT_SIZE; + LittleEndian.PutInt(buf, offset, tempFc); + offset += LittleEndianConsts.INT_SIZE; + LittleEndian.PutShort(buf, offset, prm.GetValue()); + + return buf; + + } + + public PropertyModifier Prm + { + get + { + return prm; + } + } + + + public static int SizeInBytes + { + get + { + return 8; + } + } + + public override bool Equals(Object o) + { + PieceDescriptor pd = (PieceDescriptor)o; + + return descriptor == pd.descriptor && prm == pd.prm && unicode == pd.unicode; + } + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/PlexOfCps.cs b/scratchpad/HWPF/Model/PlexOfCps.cs new file mode 100644 index 0000000..73ac362 --- /dev/null +++ b/scratchpad/HWPF/Model/PlexOfCps.cs @@ -0,0 +1,158 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + using System; + using System.Collections; + using NPOI.Util; + + + /** + * common data structure in a Word file. Contains an array of 4 byte ints in + * the front that relate to an array of abitrary data structures in the back. + * + * + * @author Ryan Ackley + */ + public class PlexOfCps + { + private int _iMac; + private int _offset; + private int _sizeOfStruct; + private ArrayList _props; + + + public PlexOfCps(int sizeOfStruct) + { + _props = new ArrayList(); + _sizeOfStruct = sizeOfStruct; + } + + /** + * Constructor + * + * @param size The size in bytes of this PlexOfCps + * @param sizeOfStruct The size of the data structure type stored in + * this PlexOfCps. + */ + public PlexOfCps(byte[] buf, int start, int size, int sizeOfStruct) + { + // Figure out the number we hold + _iMac = (size - 4) / (4 + sizeOfStruct); + + _sizeOfStruct = sizeOfStruct; + _props = new ArrayList(_iMac); + + for (int x = 0; x < _iMac; x++) + { + _props.Add(GetProperty(x, buf, start)); + } + } + + public GenericPropertyNode GetProperty(int index) + { + return (GenericPropertyNode)_props[index]; + } + + public void AddProperty(GenericPropertyNode node) + { + _props.Add(node); + } + + public byte[] ToByteArray() + { + int size = _props.Count; + int cpBufSize = ((size + 1) * LittleEndianConsts.INT_SIZE); + int structBufSize = +(_sizeOfStruct * size); + int bufSize = cpBufSize + structBufSize; + + byte[] buf = new byte[bufSize]; + + GenericPropertyNode node = null; + for (int x = 0; x < size; x++) + { + node = (GenericPropertyNode)_props[x]; + + // put the starting offset of the property into the plcf. + LittleEndian.PutInt(buf, (LittleEndianConsts.INT_SIZE * x), node.Start); + + // put the struct into the plcf + System.Array.Copy(node.Bytes, 0, buf, cpBufSize + (x * _sizeOfStruct), + _sizeOfStruct); + } + // put the ending offset of the last property into the plcf. + LittleEndian.PutInt(buf, LittleEndianConsts.INT_SIZE * size, node.End); + + return buf; + + } + + private GenericPropertyNode GetProperty(int index, byte[] buf, int offset) + { + int start = LittleEndian.GetInt(buf, offset + GetIntOffset(index)); + int end = LittleEndian.GetInt(buf, offset + GetIntOffset(index + 1)); + + byte[] structure = new byte[_sizeOfStruct]; + System.Array.Copy(buf, offset + GetStructOffset(index), structure, 0, _sizeOfStruct); + + return new GenericPropertyNode(start, end, structure); + } + + private int GetIntOffset(int index) + { + return index * 4; + } + + /** + * returns the number of data structures in this PlexOfCps. + * + * @return The number of data structures in this PlexOfCps + */ + public int Length + { + get + { + return _iMac; + } + } + + + internal GenericPropertyNode[] ToPropertiesArray() + { + if (_props == null || _props.Count==0) + return new GenericPropertyNode[0]; + + return (GenericPropertyNode[])_props.ToArray(typeof(GenericPropertyNode)); + } + + /** + * Returns the offset, in bytes, from the beginning if this PlexOfCps to + * the data structure at index. + * + * @param index The index of the data structure. + * + * @return The offset, in bytes, from the beginning if this PlexOfCps to + * the data structure at index. + */ + private int GetStructOffset(int index) + { + return (4 * (_iMac + 1)) + (_sizeOfStruct * index); + } + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/PlexOfField.cs b/scratchpad/HWPF/Model/PlexOfField.cs new file mode 100644 index 0000000..c754856 --- /dev/null +++ b/scratchpad/HWPF/Model/PlexOfField.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Text; +using NPOI.Util; + +namespace NPOI.HWPF.Model +{ + public class PlexOfField + { + + private GenericPropertyNode propertyNode; + private FieldDescriptor fld; + + public PlexOfField(GenericPropertyNode propertyNode) + { + this.propertyNode = propertyNode; + fld = new FieldDescriptor(propertyNode.Bytes); + } + + public int FcStart + { + get + { + return propertyNode.Start; + } + } + + public int FcEnd + { + get + { + return propertyNode.End; + } + } + + public FieldDescriptor Fld + { + get + { + return fld; + } + } + + public override String ToString() + { + return string.Format("[{0}, {1}) - FLD - 0x{2}; 0x{3}", + FcStart, FcEnd, + StringUtil.ToHexString(0xff & fld.GetBoundaryType()), + StringUtil.ToHexString(0xff & fld.GetFlt())); + } + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/Prm0.cs b/scratchpad/HWPF/Model/Prm0.cs new file mode 100644 index 0000000..6d168fd --- /dev/null +++ b/scratchpad/HWPF/Model/Prm0.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Text; +using NPOI.Util; + +namespace NPOI.HWPF.Model +{ + public enum SprmType : short + { + sprmClbcCRJ = 0x00, + sprmPIncLvl = 0x04, + sprmPJc = 0x05, + sprmPFKeep = 0x07, + sprmPFKeepFollow = 0x08, + sprmPFPageBreakBefore = 0x09, + sprmPIlvl = 0x0C, + sprmPFMirrorIndents = 0x0D, + sprmPFNoLineNumb = 0x0E, + sprmPTtwo = 0x0F, + sprmPFInTable = 0x18, + sprmPFTtp = 0x19, + sprmPPc = 0x1D, + sprmPWr = 0x25, + sprmPFNoAutoHyph = 0x2C, + sprmPFLocked = 0x32, + sprmPFWidowControl = 0x33, + sprmPFKinsoku = 0x35, + sprmPFWordWrap = 0x36, + sprmPFOverflowPunct = 0x37, + sprmPFTopLinePunct = 0x38, + sprmPFAutoSpaceDE = 0x39, + sprmPFAutoSpaceDN = 0x3A, + sprmCFRMarkDel = 0x41, + sprmCFRMarkIns = 0x42, + sprmCFFldVanish = 0x43, + sprmCFData = 0x47, + sprmCFOle2 = 0x4B, + sprmCHighlight = 0x4D, + sprmCFEmboss = 0x4E, + sprmCSfxText = 0x4F, + sprmCFWebHidden = 0x50, + sprmCFSpecVanish = 0x51, + sprmCPlain = 0x53, + sprmCFBold = 0x55, + sprmCFItalic = 0x56, + sprmCFStrike = 0x57, + sprmCFOutline = 0x58, + sprmCFShadow = 0x59, + sprmCFSmallCaps = 0x5A, + sprmCFCaps = 0x5B, + sprmCFVanish = 0x5C, + sprmCKul = 0x5E, + } + + public class Prm0 + { + private byte field_1_fComplex = 0; + private static BitField field_2_isprm = BitFieldFactory.GetInstance(0x7F); + + } +} diff --git a/scratchpad/HWPF/Model/PropertyModifier.cs b/scratchpad/HWPF/Model/PropertyModifier.cs new file mode 100644 index 0000000..8a9bd50 --- /dev/null +++ b/scratchpad/HWPF/Model/PropertyModifier.cs @@ -0,0 +1,148 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +using NPOI.Util; +using System; +using System.Text; +namespace NPOI.HWPF.Model +{ + + + public class PropertyModifier + { + /** + *
  • "Set to 0 for variant 1"
  • "Set to 1 for variant 2" + */ + private static BitField _fComplex = new BitField(0x0001); + + /** + * "Index to a grpprl stored in CLX portion of file" + */ + private static BitField _figrpprl = new BitField(0xfffe); + + /** + * "Index to entry into rgsprmPrm" + */ + private static BitField _fisprm = new BitField(0x00fe); + + /** + * "sprm's operand" + */ + private static BitField _fval = new BitField(0xff00); + + private short value; + + public PropertyModifier(short value) + { + this.value = value; + } + + + protected PropertyModifier Clone() + { + return new PropertyModifier(value); + } + + + public override bool Equals(Object obj) + { + if (this == obj) + return true; + if (obj == null) + return false; + if (this.GetType() != obj.GetType()) + return false; + PropertyModifier other = (PropertyModifier)obj; + if (value != other.value) + return false; + return true; + } + + /** + * "Index to a grpprl stored in CLX portion of file" + */ + public short GetIgrpprl() + { + if (!IsComplex()) + throw new InvalidOperationException("Not complex"); + + return _figrpprl.GetShortValue(value); + } + + public short GetIsprm() + { + if (IsComplex()) + throw new InvalidOperationException("Not simple"); + + return _fisprm.GetShortValue(value); + } + + public short GetVal() + { + if (IsComplex()) + throw new InvalidOperationException("Not simple"); + + return _fval.GetShortValue(value); + } + + public short GetValue() + { + return value; + } + + + public override int GetHashCode() + { + int prime = 31; + int result = 1; + result = prime * result + value; + return result; + } + + public bool IsComplex() + { + return _fComplex.IsSet(value); + } + + + public override String ToString() + { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.Append("[PRM] (complex: "); + stringBuilder.Append(IsComplex()); + stringBuilder.Append("; "); + if (IsComplex()) + { + stringBuilder.Append("igrpprl: "); + stringBuilder.Append(GetIgrpprl()); + stringBuilder.Append("; "); + } + else + { + stringBuilder.Append("isprm: "); + stringBuilder.Append(GetIsprm()); + stringBuilder.Append("; "); + stringBuilder.Append("val: "); + stringBuilder.Append(GetVal()); + stringBuilder.Append("; "); + } + stringBuilder.Append(")"); + return stringBuilder.ToString(); + } + } + + +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/PropertyNode.cs b/scratchpad/HWPF/Model/PropertyNode.cs new file mode 100644 index 0000000..0c74117 --- /dev/null +++ b/scratchpad/HWPF/Model/PropertyNode.cs @@ -0,0 +1,239 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + using System; + using System.Collections; + using NPOI.Util; +using System.Collections.Generic; + + /** + * Represents a lightweight node in the Trees used to store content + * properties. + * This only ever works in characters. For the few odd cases when + * the start and end aren't in characters (eg PAPX and CHPX), use + * {@link BytePropertyNode} between you and this. + * + * @author Ryan Ackley + */ + public abstract class PropertyNode : IComparable + { + public class EndComparator:IComparer + { + public static EndComparator instance = new EndComparator(); + + public int Compare( PropertyNode o1, PropertyNode o2 ) + { + int thisVal = o1.End; + int anotherVal = o2.End; + return ( thisVal < anotherVal ? -1 : ( thisVal == anotherVal ? 0 + : 1 ) ); + } + } + + public class StartComparator:IComparer + { + public static StartComparator instance = new StartComparator(); + + public int Compare(PropertyNode o1, PropertyNode o2) + { + int thisVal = o1.Start; + int anotherVal = o2.Start; + return ( thisVal < anotherVal ? -1 : ( thisVal == anotherVal ? 0 + : 1 ) ); + } + } + + public class CHPXComparator : IComparer + { + public static CHPXComparator instance = new CHPXComparator(); + + public int Compare(CHPX o1, CHPX o2) + { + int thisVal = o1.Start; + int anotherVal = o2.Start; + return (thisVal < anotherVal ? -1 : (thisVal == anotherVal ? 0 + : 1)); + } + } + + public class PAPXComparator : IComparer + { + public static PAPXComparator instance = new PAPXComparator(); + + public int Compare(PAPX o1, PAPX o2) + { + int thisVal = o1.Start; + int anotherVal = o2.Start; + return (thisVal < anotherVal ? -1 : (thisVal == anotherVal ? 0 + : 1)); + } + } + + public class SEPXComparator : IComparer + { + public static SEPXComparator instance = new SEPXComparator(); + + public int Compare(SEPX o1, SEPX o2) + { + int thisVal = o1.Start; + int anotherVal = o2.Start; + return (thisVal < anotherVal ? -1 : (thisVal == anotherVal ? 0 + : 1)); + } + } + + protected Object _buf; + /** The start, in characters */ + private int _cpStart; + /** The end, in characters */ + private int _cpEnd; + + + /** + * @param fcStart The start of the text for this property, in characters. + * @param fcEnd The end of the text for this property, in characters. + * @param buf FIXME: Old documentation Is: "grpprl The property description in compressed form." + */ + protected PropertyNode(int fcStart, int fcEnd, Object buf) + { + _cpStart = fcStart; + _cpEnd = fcEnd; + _buf = buf; + + if (_cpStart < 0) + { + Console.WriteLine("A property claimed to start before zero, at " + _cpStart + "! Resetting it to zero, and hoping for the best"); + _cpStart = 0; + } + if (_cpEnd < _cpStart) + { + Console.WriteLine("A property claimed to end (" + _cpEnd + + ") before start! " + + "Resetting end to start, and hoping for the best"); + _cpEnd = _cpStart; + } + } + + /** + * @return The start offset of this property's text. + */ + public int Start + { + get + { + return _cpStart; + } + set + { + _cpStart = value; + } + } + + + /** + * @return The offset of the end of this property's text. + */ + public int End + { + get + { + return _cpEnd; + } + set + { + _cpEnd = value; + } + } + + /** + * Adjust for a deletion that can span multiple PropertyNodes. + * @param start + * @param length + */ + public virtual void AdjustForDelete(int start, int length) + { + int end = start + length; + + if (_cpEnd > start) + { + // The start of the change Is before we end + + if (_cpStart < end) + { + // The delete was somewhere in the middle of us + _cpEnd = end >= _cpEnd ? start : _cpEnd - length; + _cpStart = Math.Min(start, _cpStart); + } + else + { + // The delete was before us + _cpEnd -= length; + _cpStart -= length; + } + } + } + + protected bool LimitsAreEqual(Object o) + { + return ((PropertyNode)o).Start == _cpStart && + ((PropertyNode)o).End == _cpEnd; + + } + + public override bool Equals(Object o) + { + if (LimitsAreEqual(o)) + { + Object testBuf = ((PropertyNode)o)._buf; + if (testBuf is byte[] && _buf is byte[]) + { + return Arrays.Equals((byte[])testBuf, (byte[])_buf); + } + return _buf.Equals(testBuf); + } + return false; + } + + /** + * Used for sorting in collections. + */ + public int CompareTo(Object o) + { + int cpEnd = ((PropertyNode)o).End; + if (_cpEnd == cpEnd) + { + return 0; + } + else if (_cpEnd < cpEnd) + { + return -1; + } + else + { + return 1; + } + } + + public override int GetHashCode() + { + return this._cpStart * 31 + this._buf.GetHashCode(); + } + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/RevisionMarkAuthorTable.cs b/scratchpad/HWPF/Model/RevisionMarkAuthorTable.cs new file mode 100644 index 0000000..bde2211 --- /dev/null +++ b/scratchpad/HWPF/Model/RevisionMarkAuthorTable.cs @@ -0,0 +1,156 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +namespace NPOI.HWPF.Model +{ + using NPOI.Util; + using System; + using System.Collections.Generic; + using NPOI.HWPF.Model.IO; + + /** + * String table Containing the names of authors of revision marks, e-mails and + * comments in this document. + * + * @author Ryan Lauck + */ + public class RevisionMarkAuthorTable + { + /** + * must be 0xFFFF + */ + private short fExtend = unchecked((short)0xFFFF); + + /** + * the number of entries in the table + */ + private short cData = 0; + + /** + * must be 0 + */ + private short cbExtra = 0; + + /** + * Array of entries. + */ + private String[] entries; + + /** + * Constructor to read the table from the table stream. + * + * @param tableStream the table stream. + * @param offset the offset into the byte array. + * @param size the size of the table in the byte array. + */ + public RevisionMarkAuthorTable(byte[] tableStream, int offset, int size) + { + // Read fExtend - it isn't used + fExtend = LittleEndian.GetShort(tableStream, offset); + if (fExtend != unchecked((short)0xFFFF)) + { + //TODO: throw an exception here? + } + offset += 2; + + // Read the number of entries + cData = LittleEndian.GetShort(tableStream, offset); + offset += 2; + + // Read cbExtra - it isn't used + cbExtra = LittleEndian.GetShort(tableStream, offset); + if (cbExtra != 0) + { + //TODO: throw an exception here? + } + offset += 2; + + entries = new String[cData]; + for (int i = 0; i < cData; i++) + { + int len = LittleEndian.GetShort(tableStream, offset); + offset += 2; + + String name = StringUtil.GetFromUnicodeLE(tableStream, offset, len); + offset += len * 2; + + entries[i] = name; + } + } + + /** + * Gets the entries. The returned list cannot be modified. + * + * @return the list of entries. + */ + public List GetEntries() + { + return new List(entries); + } + + /** + * Get an author by its index. Returns null if it does not exist. + * + * @return the revision mark author + */ + public String GetAuthor(int index) + { + String auth = null; + if (index >= 0 && index < entries.Length) + { + auth = entries[index]; + } + return auth; + } + + /** + * Gets the number of entries. + * + * @return the number of entries. + */ + public int GetSize() + { + return cData; + } + + /** + * Writes this table to the table stream. + * + * @param tableStream the table stream to write to. + * @throws IOException if an error occurs while writing. + */ + public void WriteTo(HWPFStream tableStream) + { + byte[] header = new byte[6]; + LittleEndian.PutShort(header, 0, fExtend); + LittleEndian.PutShort(header, 2, cData); + LittleEndian.PutShort(header, 4, cbExtra); + tableStream.Write(header); + + foreach (String name in entries) + { + byte[] buf = new byte[name.Length * 2 + 2]; + LittleEndian.PutShort(buf, 0, (short)name.Length); + StringUtil.PutUnicodeLE(name, buf, 2); + tableStream.Write(buf); + } + } + + } +} + diff --git a/scratchpad/HWPF/Model/SEPX.cs b/scratchpad/HWPF/Model/SEPX.cs new file mode 100644 index 0000000..4f7e164 --- /dev/null +++ b/scratchpad/HWPF/Model/SEPX.cs @@ -0,0 +1,81 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + using System; + using NPOI.HWPF.SPRM; + using NPOI.HWPF.UserModel; + + /** + */ + public class SEPX : BytePropertyNode + { + + SectionProperties sectionProperties; + SectionDescriptor _sed; + + public SEPX(SectionDescriptor sed, int start, int end, byte[] grpprl) + : base(start, end, new SprmBuffer(grpprl, 0)) + { + + _sed = sed; + } + + public byte[] GetGrpprl() + { + if (sectionProperties != null) + { + byte[] grpprl = SectionSprmCompressor + .CompressSectionProperty(sectionProperties); + _buf = new SprmBuffer(grpprl, 0); + } + return ((SprmBuffer)_buf).ToByteArray(); + } + + public SectionDescriptor GetSectionDescriptor() + { + return _sed; + } + + public SectionProperties GetSectionProperties() + { + if (sectionProperties == null) + { + sectionProperties = SectionSprmUncompressor.UncompressSEP( + ((SprmBuffer)_buf).ToByteArray(), 0); + } + return sectionProperties; + } + + public override bool Equals(Object o) + { + SEPX sepx = (SEPX)o; + if (base.Equals(o)) + { + return sepx._sed.Equals(_sed); + } + return false; + } + + public override String ToString() + { + return "SEPX from " + Start + " to " + End; + } + } +} + diff --git a/scratchpad/HWPF/Model/SavedByEntry.cs b/scratchpad/HWPF/Model/SavedByEntry.cs new file mode 100644 index 0000000..a63bbb3 --- /dev/null +++ b/scratchpad/HWPF/Model/SavedByEntry.cs @@ -0,0 +1,89 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +namespace NPOI.HWPF.Model +{ + using System; + + + /** + * A single entry in the {@link SavedByTable}. + * + * @author Daniel Noll + */ + public class SavedByEntry + { + private String userName; + private String saveLocation; + + public SavedByEntry(String userName, String saveLocation) + { + this.userName = userName; + this.saveLocation = saveLocation; + } + + public String GetUserName() + { + return userName; + } + + public String GetSaveLocation() + { + return saveLocation; + } + + /** + * Compares this object with another, for equality. + * + * @param other the object to compare to this one. + * @return true iff the other object Is equal to this one. + */ + public override bool Equals(Object other) + { + if (other == this) return true; + if (!(other is SavedByEntry)) return false; + SavedByEntry that = (SavedByEntry)other; + return that.userName.Equals(userName) && + that.saveLocation.Equals(saveLocation); + } + + /** + * Generates a hash code for consistency with {@link #equals(Object)}. + * + * @return the hash code. + */ + public override int GetHashCode() + { + int hash = 29; + hash = hash * 13 + userName.GetHashCode(); + hash = hash * 13 + saveLocation.GetHashCode(); + return hash; + } + + /** + * Returns a string for display. + * + * @return the string. + */ + public override String ToString() + { + return "SavedByEntry[userName=" + GetUserName() + + ",saveLocation=" + GetSaveLocation() + "]"; + } + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/SavedByTable.cs b/scratchpad/HWPF/Model/SavedByTable.cs new file mode 100644 index 0000000..ba16bf4 --- /dev/null +++ b/scratchpad/HWPF/Model/SavedByTable.cs @@ -0,0 +1,114 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +namespace NPOI.HWPF.Model +{ + using System; + using System.Collections; + using NPOI.Util; + using NPOI.HWPF.Model.IO; + /** + * String table containing the history of the last few revisions ("saves") of the document. + * Read-only for the time being. + * + * @author Daniel Noll + */ + public class SavedByTable + { + /** + * A value that I don't know what it does, but Is maintained for accuracy. + */ + private short unknownValue = -1; + + /** + * Array of entries. + */ + private SavedByEntry[] entries; + + /** + * Constructor to read the table from the table stream. + * + * @param tableStream the table stream. + * @param offset the offset into the byte array. + * @param size the size of the table in the byte array. + */ + public SavedByTable(byte[] tableStream, int offset, int size) + { + // Read the value that I don't know what it does. :-) + unknownValue = LittleEndian.GetShort(tableStream, offset); + offset += 2; + + // The stored int Is the number of strings, and there are two strings per entry. + int numEntries = LittleEndian.GetInt(tableStream, offset) / 2; + offset += 4; + + entries = new SavedByEntry[numEntries]; + for (int i = 0; i < numEntries; i++) + { + int len = LittleEndian.GetShort(tableStream, offset); + offset += 2; + String userName = StringUtil.GetFromUnicodeLE(tableStream, offset, len); + offset += len * 2; + len = LittleEndian.GetShort(tableStream, offset); + offset += 2; + String saveLocation = StringUtil.GetFromUnicodeLE(tableStream, offset, len); + offset += len * 2; + + entries[i] = new SavedByEntry(userName, saveLocation); + } + } + + /** + * Gets the entries. The returned list cannot be modified. + * + * @return the list of entries. + */ + public IList GetEntries() + { + return Arrays.AsList(entries); + } + + /** + * Writes this table to the table stream. + * + * @param tableStream the table stream to write to. + * @throws IOException if an error occurs while writing. + */ + public void WriteTo(HWPFStream tableStream) + { + byte[] header = new byte[6]; + LittleEndian.PutShort(header, 0, unknownValue); + LittleEndian.PutInt(header, 2, entries.Length * 2); + tableStream.Write(header); + + for (int i = 0; i < entries.Length; i++) + { + WriteStringValue(tableStream, entries[i].GetUserName()); + WriteStringValue(tableStream, entries[i].GetSaveLocation()); + } + } + + private void WriteStringValue(HWPFStream tableStream, String value) + { + byte[] buf = new byte[value.Length * 2 + 2]; + LittleEndian.PutShort(buf, 0, (short)value.Length); + StringUtil.PutUnicodeLE(value, buf, 2); + tableStream.Write(buf); + } + } +} diff --git a/scratchpad/HWPF/Model/SectionDescriptor.cs b/scratchpad/HWPF/Model/SectionDescriptor.cs new file mode 100644 index 0000000..d4924f4 --- /dev/null +++ b/scratchpad/HWPF/Model/SectionDescriptor.cs @@ -0,0 +1,99 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + using System; + using NPOI.Util; + + public class SectionDescriptor + { + /// + /// Used internally by Word + /// + private short fn; + /// + /// File offset in main stream to beginning of SEPX stored for section. + /// If sed.fcSepx==0xFFFFFFFF, the section properties for the section are equal + /// to the standard SEP (see SEP definition). + /// + private int fcSepx; + /// + /// Used internally by Word + /// + private short fnMpr; + /// + /// Points to offset in FC space of main stream where the Macintosh Print + /// Record for a document created on a Macintosh will be stored + /// + private int fcMpr; + + public SectionDescriptor() + { + } + + public SectionDescriptor(byte[] buf, int offset) + { + fn = LittleEndian.GetShort(buf, offset); + offset += LittleEndianConsts.SHORT_SIZE; + fcSepx = LittleEndian.GetInt(buf, offset); + offset += LittleEndianConsts.INT_SIZE; + fnMpr = LittleEndian.GetShort(buf, offset); + offset += LittleEndianConsts.SHORT_SIZE; + fcMpr = LittleEndian.GetInt(buf, offset); + } + + public int GetFc() + { + return fcSepx; + } + + public void SetFc(int fc) + { + this.fcSepx = fc; + } + + public override bool Equals(Object o) + { + SectionDescriptor sed = (SectionDescriptor)o; + return sed.fn == fn && sed.fnMpr == fnMpr; + } + + public byte[] ToArray() + { + int offset = 0; + byte[] buf = new byte[12]; + + LittleEndian.PutShort(buf, offset, fn); + offset += LittleEndianConsts.SHORT_SIZE; + LittleEndian.PutInt(buf, offset, fcSepx); + offset += LittleEndianConsts.INT_SIZE; + LittleEndian.PutShort(buf, offset, fnMpr); + offset += LittleEndianConsts.SHORT_SIZE; + LittleEndian.PutInt(buf, offset, fcMpr); + + return buf; + } + public override string ToString() + { + + return "[SED] (fn: " + fn + "; fcSepx: " + fcSepx + "; fnMpr: " + fnMpr + + "; fcMpr: " + fcMpr + ")"; + } + } +} + diff --git a/scratchpad/HWPF/Model/SectionTable.cs b/scratchpad/HWPF/Model/SectionTable.cs new file mode 100644 index 0000000..9bf0cea --- /dev/null +++ b/scratchpad/HWPF/Model/SectionTable.cs @@ -0,0 +1,207 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using System.Collections.Generic; +using NPOI.Util; +using NPOI.HWPF.Model.IO; +using System; +namespace NPOI.HWPF.Model +{ + + + + /** + * @author Ryan Ackley + */ + public class SectionTable + { + private static int SED_SIZE = 12; + + protected List _sections = new List(); + protected List _text; + + /** So we can know if things are unicode or not */ + private TextPieceTable tpt; + + public SectionTable() + { + } + + + public SectionTable(byte[] documentStream, byte[] tableStream, int OffSet, + int size, int fcMin, + TextPieceTable tpt, int mainLength) + { + PlexOfCps sedPlex = new PlexOfCps(tableStream, OffSet, size, SED_SIZE); + this.tpt = tpt; + this._text = tpt.TextPieces; + + int length = sedPlex.Length; + + for (int x = 0; x < length; x++) + { + GenericPropertyNode node = sedPlex.GetProperty(x); + SectionDescriptor sed = new SectionDescriptor(node.Bytes, 0); + + int fileOffset = sed.GetFc(); + //int startAt = CPtoFC(node.Start); + //int endAt = CPtoFC(node.End); + int startAt = node.Start; + int endAt = node.End; + + // check for the optimization + if (fileOffset == unchecked((int)0xffffffff)) + { + _sections.Add(new SEPX(sed, startAt, endAt, new byte[0])); + } + else + { + // The first short at the offset is the size of the grpprl. + int sepxSize = LittleEndian.GetShort(documentStream, fileOffset); + byte[] buf = new byte[sepxSize]; + fileOffset += LittleEndianConsts.SHORT_SIZE; + Array.Copy(documentStream, fileOffset, buf, 0, buf.Length); + _sections.Add(new SEPX(sed, startAt, endAt, buf)); + } + } + + // Some files seem to lie about their unicode status, which + // is very very pesky. Try to work around these, but this + // is Getting on for black magic... + int mainEndsAt = mainLength; + bool matchAt = false; + bool matchHalf = false; + for (int i = 0; i < _sections.Count; i++) + { + SEPX s = _sections[i]; + if (s.End == mainEndsAt) + { + matchAt = true; + } + else if (s.End == mainEndsAt || s.End == mainEndsAt - 1) + { + matchHalf = true; + } + } + if (!matchAt && matchHalf) + { + //System.err.println("Your document seemed to be mostly unicode, but the section defInition was in bytes! Trying anyway, but things may well go wrong!"); + for (int i = 0; i < _sections.Count; i++) + { + SEPX s = _sections[i]; + GenericPropertyNode node = sedPlex.GetProperty(i); + + int startAt = node.Start; + int endAt = node.End; + s.Start = (startAt); + s.End = (endAt); + } + } + } + + public void AdjustForInsert(int listIndex, int Length) + { + int size = _sections.Count; + SEPX sepx = _sections[listIndex]; + sepx.End = (sepx.End + Length); + + for (int x = listIndex + 1; x < size; x++) + { + sepx = _sections[x]; + sepx.Start = (sepx.Start + Length); + sepx.End = (sepx.End + Length); + } + } + + // goss version of CPtoFC - this takes into account non-contiguous textpieces + // that we have come across in real world documents. Tests against the example + // code in HWPFDocument show no variation to Ryan's version of the code in + // normal use, but this version works with our non-contiguous test case. + // So far unable to get this test case to be written out as well due to + // other issues. - piers + private int CPtoFC(int CP) + { + TextPiece TP = null; + + for (int i = _text.Count - 1; i > -1; i--) + { + TP = _text[i]; + + if (CP >= TP.GetCP()) break; + } + int FC = TP.PieceDescriptor.FilePosition; + int offset = CP - TP.GetCP(); + if (TP.IsUnicode) + { + offset = offset * 2; + } + FC = FC + offset; + return FC; + } + + public List GetSections() + { + return _sections; + } + + public void WriteTo(HWPFFileSystem sys, int fcMin) + { + HWPFStream docStream = sys.GetStream("WordDocument"); + HWPFStream tableStream = sys.GetStream("1Table"); + + int offset = docStream.Offset; + int len = _sections.Count; + PlexOfCps plex = new PlexOfCps(SED_SIZE); + + for (int x = 0; x < len; x++) + { + SEPX sepx = _sections[x]; + byte[] grpprl = sepx.GetGrpprl(); + + // write the sepx to the document stream. starts with a 2 byte size + // followed by the grpprl + byte[] shortBuf = new byte[2]; + LittleEndian.PutShort(shortBuf, (short)grpprl.Length); + + docStream.Write(shortBuf); + docStream.Write(grpprl); + + // set the fc in the section descriptor + SectionDescriptor sed = sepx.GetSectionDescriptor(); + sed.SetFc(offset); + + // add the section descriptor bytes to the PlexOfCps. + + + // original line - + //GenericPropertyNode property = new GenericPropertyNode(sepx.Start, sepx.End, sed.ToArray()); + + // Line using Ryan's FCtoCP() conversion method - + // unable to observe any effect on our testcases when using this code - piers + GenericPropertyNode property = new GenericPropertyNode(tpt.GetCharIndex(sepx.StartBytes), tpt.GetCharIndex(sepx.EndBytes), sed.ToArray()); + + + plex.AddProperty(property); + + offset = docStream.Offset; + } + tableStream.Write(plex.ToByteArray()); + } + } + + +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/ShapesTable.cs b/scratchpad/HWPF/Model/ShapesTable.cs new file mode 100644 index 0000000..ed0619a --- /dev/null +++ b/scratchpad/HWPF/Model/ShapesTable.cs @@ -0,0 +1,61 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + + + using NPOI.HWPF.UserModel; + using System.Collections; + + public class ShapesTable + { + private ArrayList _shapes; + private ArrayList _shapesVisibili; //holds visible shapes + + public ShapesTable(byte[] tblStream, FileInformationBlock fib) + { + PlexOfCps binTable = new PlexOfCps(tblStream, + fib.GetFcPlcspaMom(), fib.GetLcbPlcspaMom(), 26); + + _shapes = new ArrayList(); + _shapesVisibili = new ArrayList(); + + + for (int i = 0; i < binTable.Length; i++) + { + GenericPropertyNode nodo = binTable.GetProperty(i); + + Shape sh = new Shape(nodo); + _shapes.Add(sh); + if (sh.IsWithinDocument) + _shapesVisibili.Add(sh); + } + } + + public ArrayList GetAllShapes() + { + return _shapes; + } + + public ArrayList GetVisibleShapes() + { + return _shapesVisibili; + } + } +} + diff --git a/scratchpad/HWPF/Model/SinglentonTextPiece.cs b/scratchpad/HWPF/Model/SinglentonTextPiece.cs new file mode 100644 index 0000000..8e969a7 --- /dev/null +++ b/scratchpad/HWPF/Model/SinglentonTextPiece.cs @@ -0,0 +1,71 @@ + + /* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + ==================================================================== */ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NPOI.HWPF.Model +{ + public class SinglentonTextPiece : TextPiece + { + + public SinglentonTextPiece(StringBuilder buffer) : + base(0, buffer.Length, Encoding.GetEncoding("UTF-16LE").GetBytes(buffer.ToString()), + new PieceDescriptor(new byte[8], 0)) + { + + } + + public override int BytesLength + { + get + { + return GetStringBuilder().Length * 2; + } + } + + public override int CharacterLength + { + get + { + return GetStringBuilder().Length; + } + } + + public override int GetCP() + { + return 0; + } + + public int GetEnd() + { + return CharacterLength; + } + + public int GetStart() + { + return 0; + } + + public override String ToString() + { + return "SinglentonTextPiece (" + CharacterLength + " chars)"; + } + } + +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/SttbfUtils.cs b/scratchpad/HWPF/Model/SttbfUtils.cs new file mode 100644 index 0000000..f70a8c7 --- /dev/null +++ b/scratchpad/HWPF/Model/SttbfUtils.cs @@ -0,0 +1,90 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +using NPOI.Util; +using System; +using NPOI.HWPF.Model.IO; +namespace NPOI.HWPF.Model +{ + /** + * Utils for storing and Reading "STring TaBle stored in File" + * + * @author Sergey Vladimirov (vlsergey {at} gmail {dot} com) + */ + + public class SttbfUtils + { + public static String[] Read(byte[] data, int startOffset) + { + short ffff = LittleEndian.GetShort(data, startOffset); + + if (ffff != unchecked((short)0xffff)) + { + // Non-extended character Pascal strings + throw new NotSupportedException( + "Non-extended character Pascal strings are not supported right now. " + + "Please, contact POI developers for update."); + } + + // strings are extended character strings + int offset = startOffset + 2; + int numEntries = LittleEndian.GetInt(data, offset); + offset += 4; + + String[] entries = new String[numEntries]; + for (int i = 0; i < numEntries; i++) + { + int len = LittleEndian.GetShort(data, offset); + offset += 2; + String value = StringUtil.GetFromUnicodeLE(data, offset, len); + offset += len * 2; + entries[i] = value; + } + return entries; + } + + public static int Write(HWPFStream tableStream, String[] entries) + { + byte[] header = new byte[6]; + LittleEndian.PutShort(header, 0, unchecked((short)0xffff)); + + if (entries == null || entries.Length == 0) + { + LittleEndian.PutInt(header, 2, 0); + tableStream.Write(header); + return 6; + } + + LittleEndian.PutInt(header, 2, entries.Length); + tableStream.Write(header); + int size = 6; + + foreach (String entry in entries) + { + byte[] buf = new byte[entry.Length * 2 + 2]; + LittleEndian.PutShort(buf, 0, (short)entry.Length); + StringUtil.PutUnicodeLE(entry, buf, 2); + tableStream.Write(buf); + size += buf.Length; + } + + return size; + } + + } +} + + diff --git a/scratchpad/HWPF/Model/StyleDescription.cs b/scratchpad/HWPF/Model/StyleDescription.cs new file mode 100644 index 0000000..c2d08c9 --- /dev/null +++ b/scratchpad/HWPF/Model/StyleDescription.cs @@ -0,0 +1,261 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + + + using NPOI.Util; + using System; + using System.Text; + using NPOI.HWPF.UserModel; + /** + * Comment me + * + * @author Ryan Ackley + */ + + public class StyleDescription + { + + private const int PARAGRAPH_STYLE = 1; + private const int CHARACTER_STYLE = 2; + + private int _istd; + private int _baseLength; + private short _infoshort; + private static BitField _sti = BitFieldFactory.GetInstance(0xfff); + private static BitField _fScratch = BitFieldFactory.GetInstance(0x1000); + private static BitField _fInvalHeight = BitFieldFactory.GetInstance(0x2000); + private static BitField _fHasUpe = BitFieldFactory.GetInstance(0x4000); + private static BitField _fMassCopy = BitFieldFactory.GetInstance(0x8000); + private short _infoshort2; + private static BitField _styleTypeCode = BitFieldFactory.GetInstance(0xf); + private static BitField _baseStyle = BitFieldFactory.GetInstance(0xfff0); + private short _infoshort3; + private static BitField _numUPX = BitFieldFactory.GetInstance(0xf); + private static BitField _nextStyle = BitFieldFactory.GetInstance(0xfff0); + private short _bchUpe; + private short _infoshort4; + private static BitField _fAutoRedef = BitFieldFactory.GetInstance(0x1); + private static BitField _fHidden = BitFieldFactory.GetInstance(0x2); + + UPX[] _upxs; + String _name; + ParagraphProperties _pap; + CharacterProperties _chp; + + public StyleDescription() + { + // _pap = new ParagraphProperties(); + // _chp = new CharacterProperties(); + } + public StyleDescription(byte[] std, int baseLength, int offset, bool word9) + { + _baseLength = baseLength; + int nameStart = offset + baseLength; + _infoshort = LittleEndian.GetShort(std, offset); + offset += LittleEndianConsts.SHORT_SIZE; + _infoshort2 = LittleEndian.GetShort(std, offset); + offset += LittleEndianConsts.SHORT_SIZE; + _infoshort3 = LittleEndian.GetShort(std, offset); + offset += LittleEndianConsts.SHORT_SIZE; + _bchUpe = LittleEndian.GetShort(std, offset); + offset += LittleEndianConsts.SHORT_SIZE; + _infoshort4 = LittleEndian.GetShort(std, offset); + offset += LittleEndianConsts.SHORT_SIZE; + + //first byte(s) of variable length section of std is the length of the + //style name and aliases string + int nameLength = 0; + int multiplier = 1; + if (word9) + { + nameLength = LittleEndian.GetShort(std, nameStart); + multiplier = 2; + nameStart += LittleEndianConsts.SHORT_SIZE; + } + else + { + nameLength = std[nameStart]; + } + + try + { + _name = Encoding.GetEncoding("UTF-16LE").GetString(std, nameStart, nameLength * multiplier); + } + catch (EncoderFallbackException) + { + // ignore + } + + //length then null terminator. + int grupxStart = ((nameLength + 1) * multiplier) + nameStart; + + // the spec only refers to two possible upxs but it mentions + // that more may be Added in the future + int varoffset = grupxStart; + int numUPX = _numUPX.GetValue(_infoshort3); + _upxs = new UPX[numUPX]; + for (int x = 0; x < numUPX; x++) + { + int upxSize = LittleEndian.GetShort(std, varoffset); + varoffset += LittleEndianConsts.SHORT_SIZE; + + byte[] upx = new byte[upxSize]; + Array.Copy(std, varoffset, upx, 0, upxSize); + _upxs[x] = new UPX(upx); + varoffset += upxSize; + + + // the upx will always start on a word boundary. + if (upxSize % 2 == 1) + { + ++varoffset; + } + + } + + + } + public int GetBaseStyle() + { + return _baseStyle.GetValue(_infoshort2); + } + public byte[] GetCHPX() + { + switch (_styleTypeCode.GetValue(_infoshort2)) + { + case PARAGRAPH_STYLE: + if (_upxs.Length > 1) + { + return _upxs[1].GetUPX(); + } + return null; + case CHARACTER_STYLE: + return _upxs[0].GetUPX(); + default: + return null; + } + + } + public byte[] GetPAPX() + { + switch (_styleTypeCode.GetValue(_infoshort2)) + { + case PARAGRAPH_STYLE: + return _upxs[0].GetUPX(); + default: + return null; + } + } + public ParagraphProperties GetPAP() + { + return _pap; + } + public CharacterProperties GetCHP() + { + return _chp; + } + internal void SetPAP(ParagraphProperties pap) + { + _pap = pap; + } + internal void SetCHP(CharacterProperties chp) + { + _chp = chp; + } + + public String GetName() + { + return _name; + } + + public byte[] ToArray() + { + // size Equals _baseLength bytes for known variables plus 2 bytes for name + // length plus name length * 2 plus 2 bytes for null plus upx's preceded by + // length + int size = _baseLength + 2 + ((_name.Length + 1) * 2); + + // determine the size needed for the upxs. They always fall on word + // boundaries. + size += _upxs[0].Size + 2; + for (int x = 1; x < _upxs.Length; x++) + { + size += _upxs[x - 1].Size % 2; + size += _upxs[x].Size + 2; + } + + + byte[] buf = new byte[size]; + + int offset = 0; + LittleEndian.PutShort(buf, offset, _infoshort); + offset += LittleEndianConsts.SHORT_SIZE; + LittleEndian.PutShort(buf, offset, _infoshort2); + offset += LittleEndianConsts.SHORT_SIZE; + LittleEndian.PutShort(buf, offset, _infoshort3); + offset += LittleEndianConsts.SHORT_SIZE; + LittleEndian.PutShort(buf, offset, _bchUpe); + offset += LittleEndianConsts.SHORT_SIZE; + LittleEndian.PutShort(buf, offset, _infoshort4); + offset = _baseLength; + + char[] letters = _name.ToCharArray(); + LittleEndian.PutShort(buf, _baseLength, (short)letters.Length); + offset += LittleEndianConsts.SHORT_SIZE; + for (int x = 0; x < letters.Length; x++) + { + LittleEndian.PutShort(buf, offset, (short)letters[x]); + offset += LittleEndianConsts.SHORT_SIZE; + } + // get past the null delimiter for the name. + offset += LittleEndianConsts.SHORT_SIZE; + + for (int x = 0; x < _upxs.Length; x++) + { + short upxSize = (short)_upxs[x].Size; + LittleEndian.PutShort(buf, offset, upxSize); + offset += LittleEndianConsts.SHORT_SIZE; + Array.Copy(_upxs[x].GetUPX(), 0, buf, offset, upxSize); + offset += upxSize + (upxSize % 2); + } + + return buf; + } + + public override bool Equals(Object o) + { + StyleDescription sd = (StyleDescription)o; + if (sd._infoshort == _infoshort && sd._infoshort2 == _infoshort2 && + sd._infoshort3 == _infoshort3 && sd._bchUpe == _bchUpe && + sd._infoshort4 == _infoshort4 && + _name.Equals(sd._name)) + { + + if (!Arrays.Equals(_upxs, sd._upxs)) + { + return false; + } + return true; + } + return false; + } + } + +} diff --git a/scratchpad/HWPF/Model/StyleSheet.cs b/scratchpad/HWPF/Model/StyleSheet.cs new file mode 100644 index 0000000..b4adc58 --- /dev/null +++ b/scratchpad/HWPF/Model/StyleSheet.cs @@ -0,0 +1,354 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +namespace NPOI.HWPF.Model +{ + using System; + using NPOI.Util; + using NPOI.HWPF.UserModel; + using NPOI.HWPF.SPRM; + using NPOI.HWPF.Model.IO; + + /** + * Represents a document's stylesheet. A word documents formatting is stored as + * compressed styles that are based on styles Contained in the stylesheet. This + * class also Contains static utility functions to uncompress different + * formatting properties. + * + * @author Ryan Ackley + */ + public class StyleSheet + { + + public const int NIL_STYLE = 4095; + private const int PAP_TYPE = 1; + private const int CHP_TYPE = 2; + private const int SEP_TYPE = 4; + private const int TAP_TYPE = 5; + + + private static ParagraphProperties NIL_PAP = new ParagraphProperties(); + private static CharacterProperties NIL_CHP = new CharacterProperties(); + + private int _stshiLength; + private int _baseLength; + private int _flags; + private int _maxIndex; + private int _maxFixedIndex; + private int _stylenameVersion; + private int[] _rgftc; + + StyleDescription[] _styleDescriptions; + + /** + * StyleSheet constructor. Loads a document's stylesheet information, + * + * @param tableStream A byte array Containing a document's raw stylesheet + * info. Found by using FileInformationBlock.GetFcStshf() and + * FileInformationBLock.GetLcbStshf() + */ + public StyleSheet(byte[] tableStream, int offset) + { + int startoffset = offset; + _stshiLength = LittleEndian.GetShort(tableStream, offset); + offset += LittleEndianConsts.SHORT_SIZE; + int stdCount = LittleEndian.GetShort(tableStream, offset); + offset += LittleEndianConsts.SHORT_SIZE; + _baseLength = LittleEndian.GetShort(tableStream, offset); + offset += LittleEndianConsts.SHORT_SIZE; + _flags = LittleEndian.GetShort(tableStream, offset); + offset += LittleEndianConsts.SHORT_SIZE; + _maxIndex = LittleEndian.GetShort(tableStream, offset); + offset += LittleEndianConsts.SHORT_SIZE; + _maxFixedIndex = LittleEndian.GetShort(tableStream, offset); + offset += LittleEndianConsts.SHORT_SIZE; + _stylenameVersion = LittleEndian.GetShort(tableStream, offset); + offset += LittleEndianConsts.SHORT_SIZE; + + _rgftc = new int[3]; + _rgftc[0] = LittleEndian.GetShort(tableStream, offset); + offset += LittleEndianConsts.SHORT_SIZE; + _rgftc[1] = LittleEndian.GetShort(tableStream, offset); + offset += LittleEndianConsts.SHORT_SIZE; + _rgftc[2] = LittleEndian.GetShort(tableStream, offset); + offset += LittleEndianConsts.SHORT_SIZE; + + offset = startoffset + LittleEndianConsts.SHORT_SIZE + _stshiLength; + _styleDescriptions = new StyleDescription[stdCount]; + for (int x = 0; x < stdCount; x++) + { + int stdSize = LittleEndian.GetShort(tableStream, offset); + //get past the size + offset += 2; + if (stdSize > 0) + { + //byte[] std = new byte[stdSize]; + + StyleDescription aStyle = new StyleDescription(tableStream, + _baseLength, offset, true); + + _styleDescriptions[x] = aStyle; + } + + offset += stdSize; + + } + for (int x = 0; x < _styleDescriptions.Length; x++) + { + if (_styleDescriptions[x] != null) + { + CreatePap(x); + CreateChp(x); + } + } + } + + public void WriteTo(HWPFStream out1) + { + int offset = 0; + // add two bytes so we can prepend the stylesheet w/ its size + byte[] buf = new byte[_stshiLength + 2]; + LittleEndian.PutShort(buf, offset, (short)_stshiLength); + offset += LittleEndianConsts.SHORT_SIZE; + LittleEndian.PutShort(buf, offset, (short)_styleDescriptions.Length); + offset += LittleEndianConsts.SHORT_SIZE; + LittleEndian.PutShort(buf, offset, (short)_baseLength); + offset += LittleEndianConsts.SHORT_SIZE; + LittleEndian.PutShort(buf, offset, (short)_flags); + offset += LittleEndianConsts.SHORT_SIZE; + LittleEndian.PutShort(buf, offset, (short)_maxIndex); + offset += LittleEndianConsts.SHORT_SIZE; + LittleEndian.PutShort(buf, offset, (short)_maxFixedIndex); + offset += LittleEndianConsts.SHORT_SIZE; + LittleEndian.PutShort(buf, offset, (short)_stylenameVersion); + offset += LittleEndianConsts.SHORT_SIZE; + + LittleEndian.PutShort(buf, offset, (short)_rgftc[0]); + offset += LittleEndianConsts.SHORT_SIZE; + LittleEndian.PutShort(buf, offset, (short)_rgftc[1]); + offset += LittleEndianConsts.SHORT_SIZE; + LittleEndian.PutShort(buf, offset, (short)_rgftc[2]); + + out1.Write(buf); + + byte[] sizeHolder = new byte[2]; + for (int x = 0; x < _styleDescriptions.Length; x++) + { + if (_styleDescriptions[x] != null) + { + byte[] std = _styleDescriptions[x].ToArray(); + + // adjust the size so it is always on a word boundary + LittleEndian.PutShort(sizeHolder, (short)((std.Length) + (std.Length % 2))); + out1.Write(sizeHolder); + out1.Write(std); + + // Must always start on a word boundary. + if (std.Length % 2 == 1) + { + out1.Write('\0'); + } + } + else + { + sizeHolder[0] = 0; + sizeHolder[1] = 0; + out1.Write(sizeHolder); + } + } + } + + + public override bool Equals(Object o) + { + StyleSheet ss = (StyleSheet)o; + + if (ss._baseLength == _baseLength && ss._flags == _flags && + ss._maxFixedIndex == _maxFixedIndex && ss._maxIndex == _maxIndex && + ss._rgftc[0] == _rgftc[0] && ss._rgftc[1] == _rgftc[1] && + ss._rgftc[2] == _rgftc[2] && ss._stshiLength == _stshiLength && + ss._stylenameVersion == _stylenameVersion) + { + if (ss._styleDescriptions.Length == _styleDescriptions.Length) + { + for (int x = 0; x < _styleDescriptions.Length; x++) + { + // check for null + if (ss._styleDescriptions[x] != _styleDescriptions[x]) + { + // check for Equality + if (!ss._styleDescriptions[x].Equals(_styleDescriptions[x])) + { + return false; + } + } + } + return true; + } + } + return false; + } + /** + * Creates a PartagraphProperties object from a papx stored in the + * StyleDescription at the index istd in the StyleDescription array. The PAP + * is placed in the StyleDescription at istd after its been Created. Not + * every StyleDescription will contain a papx. In these cases this function + * does nothing + * + * @param istd The index of the StyleDescription to create the + * ParagraphProperties from (and also place the finished PAP in) + */ + private void CreatePap(int istd) + { + StyleDescription sd = _styleDescriptions[istd]; + ParagraphProperties pap = sd.GetPAP(); + byte[] papx = sd.GetPAPX(); + int baseIndex = sd.GetBaseStyle(); + if (pap == null && papx != null) + { + ParagraphProperties parentPAP = new ParagraphProperties(); + if (baseIndex != NIL_STYLE) + { + + parentPAP = _styleDescriptions[baseIndex].GetPAP(); + if (parentPAP == null) + { + if (baseIndex == istd) + { + // Oh dear, style claims that it is its own parent + throw new InvalidOperationException("Pap style " + istd + " claimed to have itself as its parent, which isn't allowed"); + } + // Create the parent style + CreatePap(baseIndex); + parentPAP = _styleDescriptions[baseIndex].GetPAP(); + } + + } + + pap = ParagraphSprmUncompressor.UncompressPAP(parentPAP, papx, 2); + sd.SetPAP(pap); + } + } + /** + * Creates a CharacterProperties object from a chpx stored in the + * StyleDescription at the index istd in the StyleDescription array. The + * CharacterProperties object is placed in the StyleDescription at istd after + * its been Created. Not every StyleDescription will contain a chpx. In these + * cases this function does nothing. + * + * @param istd The index of the StyleDescription to create the + * CharacterProperties object from. + */ + private void CreateChp(int istd) + { + StyleDescription sd = _styleDescriptions[istd]; + CharacterProperties chp = sd.GetCHP(); + byte[] chpx = sd.GetCHPX(); + int baseIndex = sd.GetBaseStyle(); + + if (baseIndex == istd) + { + // Oh dear, this isn't allowed... + // The word file seems to be corrupted + // Switch to using the nil style so that + // there's a chance we can read it + baseIndex = NIL_STYLE; + } + + // Build and decompress the Chp if required + if (chp == null && chpx != null) + { + CharacterProperties parentCHP = new CharacterProperties(); + if (baseIndex != NIL_STYLE) + { + + parentCHP = _styleDescriptions[baseIndex].GetCHP(); + if (parentCHP == null) + { + CreateChp(baseIndex); + parentCHP = _styleDescriptions[baseIndex].GetCHP(); + } + + } + + chp = CharacterSprmUncompressor.UncompressCHP(parentCHP, chpx, 0); + sd.SetCHP(chp); + } + } + + /** + * Gets the number of styles in the style sheet. + * @return The number of styles in the style sheet. + */ + public int NumStyles() + { + return _styleDescriptions.Length; + } + + /** + * Gets the StyleDescription at index x. + * + * @param x the index of the desired StyleDescription. + */ + public StyleDescription GetStyleDescription(int x) + { + return _styleDescriptions[x]; + } + + public CharacterProperties GetCharacterStyle(int x) + { + if (x == NIL_STYLE) + { + return NIL_CHP; + } + if (x >= _styleDescriptions.Length) + { + return NIL_CHP; + } + return (_styleDescriptions[x] != null ? _styleDescriptions[x].GetCHP() : NIL_CHP); + } + + public ParagraphProperties GetParagraphStyle(int x) + { + if (x == NIL_STYLE) + { + return NIL_PAP; + } + + if (x >= _styleDescriptions.Length) + { + return NIL_PAP; + } + + if (_styleDescriptions[x] == null) + { + return NIL_PAP; + } + + if (_styleDescriptions[x].GetPAP() == null) + { + return NIL_PAP; + } + + return _styleDescriptions[x].GetPAP(); + } + + } + + +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/SubdocumentType.cs b/scratchpad/HWPF/Model/SubdocumentType.cs new file mode 100644 index 0000000..d5f371b --- /dev/null +++ b/scratchpad/HWPF/Model/SubdocumentType.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace NPOI.HWPF.Model +{ + public enum SubdocumentType:int + { + MAIN= FIBLongHandler.CCPTEXT , + + FOOTNOTE= FIBLongHandler.CCPFTN , + + HEADER= FIBLongHandler.CCPHDD , + + MACRO= FIBLongHandler.CCPMCR , + + ANNOTATION= FIBLongHandler.CCPATN , + + ENDNOTE= FIBLongHandler.CCPEDN , + + TEXTBOX= FIBLongHandler.CCPTXBX , + + HEADER_TEXTBOX= FIBLongHandler.CCPHDRTXBX + } + + +} diff --git a/scratchpad/HWPF/Model/TextPiece.cs b/scratchpad/HWPF/Model/TextPiece.cs new file mode 100644 index 0000000..afd32cc --- /dev/null +++ b/scratchpad/HWPF/Model/TextPiece.cs @@ -0,0 +1,229 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + using System; + using System.Text; + + /** + * Lightweight representation of a text piece. + * Works in the character domain, not the byte domain, so you + * need to have turned byte references into character + * references before Getting here. + * + * @author Ryan Ackley + */ + + public class TextPiece : PropertyNode + { + private bool _usesUnicode; + + private PieceDescriptor _pd; + + /** + * @param start Beginning offset in main document stream, in characters. + * @param end Ending offset in main document stream, in characters. + * @param text The raw bytes of our text + */ + public TextPiece(int start, int end, byte[] text, PieceDescriptor pd, int cpStart) + : this(start, end, text, pd) + { + + } + public TextPiece(int start, int end, byte[] text, PieceDescriptor pd) + : base(start, end, buildInitSB(text, pd)) + { + _usesUnicode = pd.IsUnicode; + _pd = pd; + + // Validate + int textLength = ((StringBuilder)_buf).Length; + if (end - start != textLength) + { + throw new InvalidOperationException("Told we're for characters " + start + " -> " + end + ", but actually covers " + textLength + " characters!"); + } + if (end < start) + { + throw new InvalidOperationException("Told we're of negative size! start=" + start + " end=" + end); + } + } + + /** + * Create the StringBuilder from the text and unicode flag + */ + private static StringBuilder buildInitSB(byte[] text, PieceDescriptor pd) + { + String str; + try + { + if (pd.IsUnicode) + { + str = Encoding.GetEncoding("UTF-16LE").GetString(text); + } + else + { + //str = Encoding.GetEncoding("CP1252").GetString(text); + str = Encoding.GetEncoding("Windows-1252").GetString(text); + } + } + catch (EncoderFallbackException) + { + throw new Exception("Your Java is broken! It doesn't know about basic, required character encodings!"); + } + return new StringBuilder(str); + } + + /** + * @return If this text piece is unicode + */ + public bool IsUnicode + { + get + { + return _usesUnicode; + } + } + + public PieceDescriptor PieceDescriptor + { + get + { + return _pd; + } + } + + public StringBuilder GetStringBuilder() + { + return (StringBuilder)_buf; + } + + public byte[] RawBytes + { + get + { + return Encoding.GetEncoding(_usesUnicode ? "UTF-16LE" : "Windows-1252").GetBytes(_buf.ToString()); + } + } + + /** + * Returns part of the string. + * Works only in characters, not in bytes! + * @param start Local start position, in characters + * @param end Local end position, in characters + */ + public String Substring(int start, int end) + { + StringBuilder buf = (StringBuilder)_buf; + + // Validate + if (start < 0) + { + throw new IndexOutOfRangeException("Can't request a substring before 0 - asked for " + start); + } + if (end > buf.Length) + { + throw new IndexOutOfRangeException("Index " + end + " out of range 0 -> " + buf.Length); + } + if (end < start) + { + throw new IndexOutOfRangeException("Asked for text from " + start + " to " + end + ", which has an end before the start!"); + } + return buf.ToString().Substring(start, end - start); + } + + /** + * Adjusts the internal string for deletinging + * some characters within this. + * @param start The start position for the delete, in characters + * @param length The number of characters to delete + */ + public override void AdjustForDelete(int start, int Length) + { + int numChars = Length; + + int myStart = Start; + int myEnd = End; + int end = start + numChars; + + /* do we have to delete from this text piece? */ + if (start <= myEnd && end >= myStart) + { + + /* find where the deleted area overlaps with this text piece */ + int overlapStart = Math.Max(myStart, start); + int overlapEnd = Math.Min(myEnd, end); + ((StringBuilder)_buf).Remove(overlapStart, overlapEnd - overlapStart); + } + + // We need to invoke this even if text from this piece is not being + // deleted because the adjustment must propagate to all subsequent + // text pieces i.e., if text from tp[n] is being deleted, then + // tp[n + 1], tp[n + 2], etc. will need to be adjusted. + // The superclass is expected to use a separate sentry for this. + base.AdjustForDelete(start, Length); + } + + /** + * Returns the Length, in characters + */ + public virtual int CharacterLength + { + get + { + return (End - Start); + } + } + /** + * Returns the Length, in bytes + */ + public virtual int BytesLength + { + get + { + return (End - Start) * (_usesUnicode ? 2 : 1); + } + } + + public override bool Equals(Object o) + { + if (LimitsAreEqual(o)) + { + TextPiece tp = (TextPiece)o; + return GetStringBuilder().ToString().Equals(tp.GetStringBuilder().ToString()) && + tp._usesUnicode == _usesUnicode && _pd.Equals(tp._pd); + } + return false; + } + + + /** + * Returns the character position we start at. + */ + public virtual int GetCP() + { + return Start; + } + + public override String ToString() + { + return "TextPiece from " + Start + " to " + End + " (" + + PieceDescriptor + ")"; + } + } + +} diff --git a/scratchpad/HWPF/Model/TextPieceTable.cs b/scratchpad/HWPF/Model/TextPieceTable.cs new file mode 100644 index 0000000..da30901 --- /dev/null +++ b/scratchpad/HWPF/Model/TextPieceTable.cs @@ -0,0 +1,414 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + using System; + using System.Collections; + using System.Collections.Generic; + using NPOI.POIFS.Common; + using NPOI.HWPF.Model.IO; + using System.Text; + + /** + * The piece table for matching up character positions to bits of text. This + * mostly works in bytes, but the TextPieces themselves work in characters. This + * does the icky Convertion. + * + * @author Ryan Ackley + */ + public class TextPieceTable : CharIndexTranslator + { + protected List _textPieces = new List(); + protected List _textPiecesFCOrder = new List(); + // int _multiple; + int _cpMin; + + public TextPieceTable() + { + } + + public TextPieceTable(byte[] documentStream, byte[] tableStream, int offset, int size, int fcMin) + { + // get our plex of PieceDescriptors + PlexOfCps pieceTable = new PlexOfCps(tableStream, offset, size, PieceDescriptor + .SizeInBytes); + + int length = pieceTable.Length; + PieceDescriptor[] pieces = new PieceDescriptor[length]; + + // iterate through piece descriptors raw bytes and create + // PieceDescriptor objects + for (int x = 0; x < length; x++) + { + GenericPropertyNode node = pieceTable.GetProperty(x); + pieces[x] = new PieceDescriptor(node.Bytes, 0); + } + + // Figure out the cp of the earliest text piece + // Note that text pieces don't have to be stored in order! + _cpMin = pieces[0].FilePosition - fcMin; + for (int x = 0; x < pieces.Length; x++) + { + int start = pieces[x].FilePosition - fcMin; + if (start < _cpMin) + { + _cpMin = start; + } + } + + // using the PieceDescriptors, build our list of TextPieces. + for (int x = 0; x < pieces.Length; x++) + { + int start = pieces[x].FilePosition; + PropertyNode node = pieceTable.GetProperty(x); + + // Grab the start and end, which are in characters + int nodeStartChars = node.Start; + int nodeEndChars = node.End; + + // What's the relationship between bytes and characters? + bool unicode = pieces[x].IsUnicode; + int multiple = 1; + if (unicode) + { + multiple = 2; + } + + // Figure out the Length, in bytes and chars + int textSizeChars = (nodeEndChars - nodeStartChars); + int textSizeBytes = textSizeChars * multiple; + + // Grab the data that Makes up the piece + byte[] buf = new byte[textSizeBytes]; + Array.Copy(documentStream, start, buf, 0, textSizeBytes); + + // And now build the piece + _textPieces.Add(new TextPiece(nodeStartChars, nodeEndChars, buf, pieces[x], node + .Start)); + } + + // In the interest of our sanity, now sort the text pieces + // into order, if they're not already + _textPieces.Sort(); + _textPiecesFCOrder = new List(_textPieces); + _textPiecesFCOrder.Sort(new FCComparator()); + } + + public int CpMin + { + get + { + return _cpMin; + } + } + + public List TextPieces + { + get + { + return _textPieces; + } + } + + public void Add(TextPiece piece) + { + _textPieces.Add(piece); + _textPiecesFCOrder.Add(piece); + _textPieces.Sort(); + _textPiecesFCOrder.Sort(new FCComparator()); + } + + public byte[] WriteTo(HWPFStream docStream) + { + + PlexOfCps textPlex = new PlexOfCps(PieceDescriptor.SizeInBytes); + // int fcMin = docStream.Getoffset(); + + int size = _textPieces.Count; + for (int x = 0; x < size; x++) + { + TextPiece next = _textPieces[x]; + PieceDescriptor pd = next.PieceDescriptor; + + int offset = docStream.Offset; + int mod = (offset % POIFSConstants.SMALLER_BIG_BLOCK_SIZE); + if (mod != 0) + { + mod = POIFSConstants.SMALLER_BIG_BLOCK_SIZE - mod; + byte[] buf = new byte[mod]; + docStream.Write(buf); + } + + // set the text piece position to the current docStream offset. + pd.FilePosition = (docStream.Offset); + + // write the text to the docstream and save the piece descriptor to + // the + // plex which will be written later to the tableStream. + docStream.Write(next.RawBytes); + + // The TextPiece is already in characters, which + // Makes our life much easier + int nodeStart = next.Start; + int nodeEnd = next.End; + textPlex.AddProperty(new GenericPropertyNode(nodeStart, nodeEnd, pd.ToByteArray())); + } + + return textPlex.ToByteArray(); + + } + + /** + * Adjust all the text piece after inserting some text into one of them + * + * @param listIndex + * The TextPiece that had characters inserted into + * @param length + * The number of characters inserted + */ + public int AdjustForInsert(int listIndex, int length) + { + int size = _textPieces.Count; + + TextPiece tp = _textPieces[listIndex]; + + // Update with the new end + tp.End = (tp.End + length); + + // Now change all subsequent ones + for (int x = listIndex + 1; x < size; x++) + { + tp = (TextPiece)_textPieces[x]; + tp.Start = (tp.Start + length); + tp.End = (tp.End + length); + } + + // All done + return length; + } + + public override bool Equals(Object o) + { + TextPieceTable tpt = (TextPieceTable)o; + + int size = tpt._textPieces.Count; + if (size == _textPieces.Count) + { + for (int x = 0; x < size; x++) + { + if (!tpt._textPieces[x].Equals(_textPieces[x])) + { + return false; + } + } + return true; + } + return false; + } + + public int GetByteIndex(int charPos) + { + int byteCount = 0; + foreach (TextPiece tp in _textPieces) + { + if (charPos >= tp.End) + { + byteCount = tp.PieceDescriptor.FilePosition + + (tp.End - tp.Start) + * (tp.IsUnicode ? 2 : 1); + + if (charPos == tp.End) + break; + + continue; + } + if (charPos < tp.End) + { + int left = charPos - tp.Start; + byteCount = tp.PieceDescriptor.FilePosition + left + * (tp.IsUnicode ? 2 : 1); + break; + } + } + return byteCount; + } + + public int GetCharIndex(int bytePos) + { + return GetCharIndex(bytePos, 0); + } + + public int GetCharIndex(int bytePos, int startCP) + { + int charCount = 0; + + bytePos = LookIndexForward(bytePos); + + foreach (TextPiece tp in _textPieces) + { + int pieceStart = tp.PieceDescriptor.FilePosition; + + int bytesLength = tp.BytesLength; + int pieceEnd = pieceStart + bytesLength; + + int toAdd; + + if (bytePos < pieceStart || bytePos > pieceEnd) + { + toAdd = bytesLength; + } + else if (bytePos > pieceStart && bytePos < pieceEnd) + { + toAdd = (bytePos - pieceStart); + } + else + { + toAdd = bytesLength - (pieceEnd - bytePos); + } + + if (tp.IsUnicode) + { + charCount += toAdd / 2; + } + else + { + charCount += toAdd; + } + + if (bytePos >= pieceStart && bytePos <= pieceEnd && charCount >= startCP) + { + break; + } + } + + return charCount; + } + + public int LookIndexForward(int bytePos) + { + foreach (TextPiece tp in _textPiecesFCOrder) + { + int pieceStart = tp.PieceDescriptor.FilePosition; + + if (bytePos > pieceStart + tp.BytesLength) + { + continue; + } + + if (pieceStart > bytePos) + { + bytePos = pieceStart; + } + + break; + } + return bytePos; + } + + public int LookIndexBackward(int bytePos) + { + int lastEnd = 0; + + foreach (TextPiece tp in _textPiecesFCOrder) + { + int pieceStart = tp.PieceDescriptor.FilePosition; + + if (bytePos > pieceStart + tp.BytesLength) + { + lastEnd = pieceStart + tp.BytesLength; + continue; + } + + if (pieceStart > bytePos) + { + bytePos = lastEnd; + } + + break; + } + + return bytePos; + } + + public virtual bool IsIndexInTable(int bytePos) + { + foreach (TextPiece tp in _textPiecesFCOrder) + { + int pieceStart = tp.PieceDescriptor.FilePosition; + + if (bytePos > pieceStart + tp.BytesLength) + { + continue; + } + + if (pieceStart > bytePos) + { + return false; + } + + return true; + } + + return false; + } + + public StringBuilder Text + { + get + { + long start = DateTime.Now.Ticks; + + // rebuild document paragraphs structure + StringBuilder docText = new StringBuilder(); + foreach (TextPiece textPiece in _textPieces) + { + String toAppend = textPiece.GetStringBuilder().ToString(); + int toAppendLength = toAppend.Length; + + //if ( toAppendLength != textPiece.getEnd() - textPiece.getStart() ) + //{ + //} + docText.Append(toAppend); + } + + return docText; + } + } + + private class FCComparator : IComparer + { + public int Compare(TextPiece textPiece, TextPiece textPiece1) + { + if (textPiece.PieceDescriptor.FilePosition > textPiece1.PieceDescriptor.FilePosition) + { + return 1; + } + else if (textPiece.PieceDescriptor.FilePosition < textPiece1.PieceDescriptor.FilePosition) + { + return -1; + } + else + { + return 0; + } + } + } + } +} + + diff --git a/scratchpad/HWPF/Model/Types/BKFAbstractType.cs b/scratchpad/HWPF/Model/Types/BKFAbstractType.cs new file mode 100644 index 0000000..a067867 --- /dev/null +++ b/scratchpad/HWPF/Model/Types/BKFAbstractType.cs @@ -0,0 +1,196 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model.Types +{ + + using NPOI.Util; + using System.Text; + using System; + + /** + * BooKmark First descriptor (BKF). + *

    + * Class and fields descriptions are quoted from Microsoft Office Word 97-2007 + * Binary File Format (.doc) Specification + * + * NOTE: This source is automatically generated please do not modify this file. + * Either subclass or remove the record in src/types/defInitions. + * + * @author Sergey Vladimirov; according to Microsoft Office Word 97-2007 Binary + * File Format (.doc) Specification + */ + + public abstract class BKFAbstractType : BaseObject + { + + protected short field_1_ibkl; + protected short field_2_bkf_flags; + private static BitField itcFirst = new BitField(0x007F); + private static BitField fPub = new BitField(0x0080); + private static BitField itcLim = new BitField(0x7F00); + private static BitField fCol = new BitField(0x8000); + + protected BKFAbstractType() + { + } + + protected void FillFields(byte[] data, int offset) + { + field_1_ibkl = LittleEndian.GetShort(data, 0x0 + offset); + field_2_bkf_flags = LittleEndian.GetShort(data, 0x2 + offset); + } + + public void Serialize(byte[] data, int offset) + { + LittleEndian.PutShort(data, 0x0 + offset, field_1_ibkl); + LittleEndian.PutShort(data, 0x2 + offset, field_2_bkf_flags); + } + + /** + * Size of record + */ + public static int GetSize() + { + return 0 + 2 + 2; + } + + public override String ToString() + { + StringBuilder builder = new StringBuilder(); + builder.Append("[BKF]\n"); + builder.Append(" .ibkl = "); + builder.Append(" (").Append(GetIbkl()).Append(" )\n"); + builder.Append(" .bkf_flags = "); + builder.Append(" (").Append(GetBkf_flags()).Append(" )\n"); + builder.Append(" .itcFirst = ").Append(GetItcFirst()).Append('\n'); + builder.Append(" .fPub = ").Append(IsFPub()).Append('\n'); + builder.Append(" .itcLim = ").Append(GetItcLim()).Append('\n'); + builder.Append(" .fCol = ").Append(IsFCol()).Append('\n'); + + builder.Append("[/BKF]\n"); + return builder.ToString(); + } + + /** + * Index to BKL entry in plcfbkl that describes the ending position of this bookmark in the CP stream. + */ + public short GetIbkl() + { + return field_1_ibkl; + } + + /** + * Index to BKL entry in plcfbkl that describes the ending position of this bookmark in the CP stream. + */ + public void SetIbkl(short field_1_ibkl) + { + this.field_1_ibkl = field_1_ibkl; + } + + /** + * Get the bkf_flags field for the BKF record. + */ + public short GetBkf_flags() + { + return field_2_bkf_flags; + } + + /** + * Set the bkf_flags field for the BKF record. + */ + public void SetBkf_flags(short field_2_bkf_flags) + { + this.field_2_bkf_flags = field_2_bkf_flags; + } + + /** + * Sets the itcFirst field value. + * When bkf.fCol==1, this is the index to the first column of a table column bookmark + */ + public void SetItcFirst(byte value) + { + field_2_bkf_flags = (short)itcFirst.SetValue(field_2_bkf_flags, value); + } + + /** + * When bkf.fCol==1, this is the index to the first column of a table column bookmark + * @return the itcFirst field value. + */ + public byte GetItcFirst() + { + return (byte)itcFirst.GetValue(field_2_bkf_flags); + } + + /** + * Sets the fPub field value. + * When 1, this indicates that this bookmark is marking the range of a Macintosh Publisher section + */ + public void SetFPub(bool value) + { + field_2_bkf_flags = (short)fPub.SetBoolean(field_2_bkf_flags, value); + } + + /** + * When 1, this indicates that this bookmark is marking the range of a Macintosh Publisher section + * @return the fPub field value. + */ + public bool IsFPub() + { + return fPub.IsSet(field_2_bkf_flags); + } + + /** + * Sets the itcLim field value. + * When bkf.fCol==1, this is the index to limit column of a table column bookmark + */ + public void SetItcLim(byte value) + { + field_2_bkf_flags = (short)itcLim.SetValue(field_2_bkf_flags, value); + } + + /** + * When bkf.fCol==1, this is the index to limit column of a table column bookmark + * @return the itcLim field value. + */ + public byte GetItcLim() + { + return (byte)itcLim.GetValue(field_2_bkf_flags); + } + + /** + * Sets the fCol field value. + * When 1, this bookmark marks a range of columns in a table specified by (bkf.itcFirst, bkf.itcLim) + */ + public void SetFCol(bool value) + { + field_2_bkf_flags = (short)fCol.SetBoolean(field_2_bkf_flags, value); + } + + /** + * When 1, this bookmark marks a range of columns in a table specified by (bkf.itcFirst, bkf.itcLim) + * @return the fCol field value. + */ + public bool IsFCol() + { + return fCol.IsSet(field_2_bkf_flags); + } + + } +} + + diff --git a/scratchpad/HWPF/Model/Types/CHPAbstractType.cs b/scratchpad/HWPF/Model/Types/CHPAbstractType.cs new file mode 100644 index 0000000..32d08c7 --- /dev/null +++ b/scratchpad/HWPF/Model/Types/CHPAbstractType.cs @@ -0,0 +1,1382 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + + +namespace NPOI.HWPF.Model.Types +{ + using System; + using NPOI.Util; + + using NPOI.HWPF.UserModel; + + /** + * Character Properties. + * NOTE: This source Is automatically generated please do not modify this file. Either subclass or + * remove the record in src/records/definitions. + + * @author S. Ryan Ackley + */ + public abstract class CHPAbstractType : BaseObject + { + + protected short field_1_chse; + protected int field_2_format_flags; + private static BitField fBold = BitFieldFactory.GetInstance(0x0001); + private static BitField fItalic = BitFieldFactory.GetInstance(0x0002); + private static BitField fRMarkDel = BitFieldFactory.GetInstance(0x0004); + private static BitField fOutline = BitFieldFactory.GetInstance(0x0008); + private static BitField fFldVanish = BitFieldFactory.GetInstance(0x0010); + private static BitField fSmallCaps = BitFieldFactory.GetInstance(0x0020); + private static BitField fCaps = BitFieldFactory.GetInstance(0x0040); + private static BitField fVanish = BitFieldFactory.GetInstance(0x0080); + private static BitField fRMark = BitFieldFactory.GetInstance(0x0100); + private static BitField fSpec = BitFieldFactory.GetInstance(0x0200); + private static BitField fStrike = BitFieldFactory.GetInstance(0x0400); + private static BitField fObj = BitFieldFactory.GetInstance(0x0800); + private static BitField fShadow = BitFieldFactory.GetInstance(0x1000); + private static BitField fLowerCase = BitFieldFactory.GetInstance(0x2000); + private static BitField fData = BitFieldFactory.GetInstance(0x4000); + private static BitField fOle2 = BitFieldFactory.GetInstance(0x8000); + protected int field_3_format_flags1; + private static BitField fEmboss = BitFieldFactory.GetInstance(0x0001); + private static BitField fImprint = BitFieldFactory.GetInstance(0x0002); + private static BitField fDStrike = BitFieldFactory.GetInstance(0x0004); + private static BitField fUsePgsuSettings = BitFieldFactory.GetInstance(0x0008); + protected int field_4_ftcAscii; + protected int field_5_ftcFE; + protected int field_6_ftcOther; + protected int field_7_hps; + protected int field_8_dxaSpace; + protected byte field_9_iss; + protected byte field_10_kul; + protected byte field_11_ico; + protected int field_12_hpsPos; + protected int field_13_lidDefault; + protected int field_14_lidFE; + protected byte field_15_idctHint; + protected int field_16_wCharScale; + protected int field_17_fcPic; + protected int field_18_fcObj; + protected int field_19_lTagObj; + protected int field_20_ibstRMark; + protected int field_21_ibstRMarkDel; + protected DateAndTime field_22_dttmRMark; + protected DateAndTime field_23_dttmRMarkDel; + protected int field_24_istd; + protected int field_25_baseIstd; + protected int field_26_ftcSym; + protected int field_27_xchSym; + protected int field_28_idslRMReason; + protected int field_29_idslReasonDel; + protected byte field_30_ysr; + protected byte field_31_chYsr; + protected int field_32_hpsKern; + protected short field_33_Highlight; + private static BitField icoHighlight = BitFieldFactory.GetInstance(0x001f); + private static BitField fHighlight = BitFieldFactory.GetInstance(0x0020); + private static BitField kcd = BitFieldFactory.GetInstance(0x01c0); + private static BitField fNavHighlight = BitFieldFactory.GetInstance(0x0200); + private static BitField fChsDiff = BitFieldFactory.GetInstance(0x0400); + private static BitField fMacChs = BitFieldFactory.GetInstance(0x0800); + private static BitField fFtcAsciSym = BitFieldFactory.GetInstance(0x1000); + protected short field_34_fPropMark; + protected int field_35_ibstPropRMark; + protected DateAndTime field_36_dttmPropRMark; + protected byte field_37_sfxtText; + protected byte field_38_fDispFldRMark; + protected int field_39_ibstDispFldRMark; + protected DateAndTime field_40_dttmDispFldRMark; + protected byte[] field_41_xstDispFldRMark; + protected ShadingDescriptor field_42_shd; + protected BorderCode field_43_brc; + + + public CHPAbstractType() + { + + } + + /** + * Size of record (exluding 4 byte header) + */ + public int GetSize() + { + return 4 + +2 + 2 + 2 + 2 + 2 + 2 + 2 + 4 + 1 + 1 + 1 + 2 + 2 + 2 + 1 + 2 + 4 + 4 + 4 + 2 + 2 + 4 + 4 + 2 + 2 + 2 + 2 + 2 + 2 + 1 + 1 + 2 + 2 + 2 + 2 + 4 + 1 + 1 + 2 + 4 + 32 + 2 + 4; + } + + + + /** + * Get the chse field for the CHP record. + */ + public short GetChse() + { + return field_1_chse; + } + + /** + * Set the chse field for the CHP record. + */ + public void SetChse(short field_1_chse) + { + this.field_1_chse = field_1_chse; + } + + /** + * Get the format_flags field for the CHP record. + */ + public int GetFormat_flags() + { + return field_2_format_flags; + } + + /** + * Set the format_flags field for the CHP record. + */ + public void SetFormat_flags(int field_2_format_flags) + { + this.field_2_format_flags = field_2_format_flags; + } + + /** + * Get the format_flags1 field for the CHP record. + */ + public int GetFormat_flags1() + { + return field_3_format_flags1; + } + + /** + * Set the format_flags1 field for the CHP record. + */ + public void SetFormat_flags1(int field_3_format_flags1) + { + this.field_3_format_flags1 = field_3_format_flags1; + } + + /** + * Get the ftcAscii field for the CHP record. + */ + public int GetFtcAscii() + { + return field_4_ftcAscii; + } + + /** + * Set the ftcAscii field for the CHP record. + */ + public void SetFtcAscii(int field_4_ftcAscii) + { + this.field_4_ftcAscii = field_4_ftcAscii; + } + + /** + * Get the ftcFE field for the CHP record. + */ + public int GetFtcFE() + { + return field_5_ftcFE; + } + + /** + * Set the ftcFE field for the CHP record. + */ + public void SetFtcFE(int field_5_ftcFE) + { + this.field_5_ftcFE = field_5_ftcFE; + } + + /** + * Get the ftcOther field for the CHP record. + */ + public int GetFtcOther() + { + return field_6_ftcOther; + } + + /** + * Set the ftcOther field for the CHP record. + */ + public void SetFtcOther(int field_6_ftcOther) + { + this.field_6_ftcOther = field_6_ftcOther; + } + + /** + * Get the hps field for the CHP record. + */ + public int GetHps() + { + return field_7_hps; + } + + /** + * Set the hps field for the CHP record. + */ + public void SetHps(int field_7_hps) + { + this.field_7_hps = field_7_hps; + } + + /** + * Get the dxaSpace field for the CHP record. + */ + public int GetDxaSpace() + { + return field_8_dxaSpace; + } + + /** + * Set the dxaSpace field for the CHP record. + */ + public void SetDxaSpace(int field_8_dxaSpace) + { + this.field_8_dxaSpace = field_8_dxaSpace; + } + + /** + * Get the Iss field for the CHP record. + */ + public byte GetIss() + { + return field_9_iss; + } + + /** + * Set the Iss field for the CHP record. + */ + public void SetIss(byte field_9_iss) + { + this.field_9_iss = field_9_iss; + } + + /** + * Get the kul field for the CHP record. + */ + public byte GetKul() + { + return field_10_kul; + } + + /** + * Set the kul field for the CHP record. + */ + public void SetKul(byte field_10_kul) + { + this.field_10_kul = field_10_kul; + } + + /** + * Get the ico field for the CHP record. + */ + public byte GetIco() + { + return field_11_ico; + } + + /** + * Set the ico field for the CHP record. + */ + public void SetIco(byte field_11_ico) + { + this.field_11_ico = field_11_ico; + } + + /** + * Get the hpsPos field for the CHP record. + */ + public int GetHpsPos() + { + return field_12_hpsPos; + } + + /** + * Set the hpsPos field for the CHP record. + */ + public void SetHpsPos(int field_12_hpsPos) + { + this.field_12_hpsPos = field_12_hpsPos; + } + + /** + * Get the lidDefault field for the CHP record. + */ + public int GetLidDefault() + { + return field_13_lidDefault; + } + + /** + * Set the lidDefault field for the CHP record. + */ + public void SetLidDefault(int field_13_lidDefault) + { + this.field_13_lidDefault = field_13_lidDefault; + } + + /** + * Get the lidFE field for the CHP record. + */ + public int GetLidFE() + { + return field_14_lidFE; + } + + /** + * Set the lidFE field for the CHP record. + */ + public void SetLidFE(int field_14_lidFE) + { + this.field_14_lidFE = field_14_lidFE; + } + + /** + * Get the idctHint field for the CHP record. + */ + public byte GetIdctHint() + { + return field_15_idctHint; + } + + /** + * Set the idctHint field for the CHP record. + */ + public void SetIdctHint(byte field_15_idctHint) + { + this.field_15_idctHint = field_15_idctHint; + } + + /** + * Get the wCharScale field for the CHP record. + */ + public int GetWCharScale() + { + return field_16_wCharScale; + } + + /** + * Set the wCharScale field for the CHP record. + */ + public void SetWCharScale(int field_16_wCharScale) + { + this.field_16_wCharScale = field_16_wCharScale; + } + + /** + * Get the fcPic field for the CHP record. + */ + public int GetFcPic() + { + return field_17_fcPic; + } + + /** + * Set the fcPic field for the CHP record. + */ + public void SetFcPic(int field_17_fcPic) + { + this.field_17_fcPic = field_17_fcPic; + } + + /** + * Get the fcObj field for the CHP record. + */ + public int GetFcObj() + { + return field_18_fcObj; + } + + /** + * Set the fcObj field for the CHP record. + */ + public void SetFcObj(int field_18_fcObj) + { + this.field_18_fcObj = field_18_fcObj; + } + + /** + * Get the lTagObj field for the CHP record. + */ + public int GetLTagObj() + { + return field_19_lTagObj; + } + + /** + * Set the lTagObj field for the CHP record. + */ + public void SetLTagObj(int field_19_lTagObj) + { + this.field_19_lTagObj = field_19_lTagObj; + } + + /** + * Get the ibstRMark field for the CHP record. + */ + public int GetIbstRMark() + { + return field_20_ibstRMark; + } + + /** + * Set the ibstRMark field for the CHP record. + */ + public void SetIbstRMark(int field_20_ibstRMark) + { + this.field_20_ibstRMark = field_20_ibstRMark; + } + + /** + * Get the ibstRMarkDel field for the CHP record. + */ + public int GetIbstRMarkDel() + { + return field_21_ibstRMarkDel; + } + + /** + * Set the ibstRMarkDel field for the CHP record. + */ + public void SetIbstRMarkDel(int field_21_ibstRMarkDel) + { + this.field_21_ibstRMarkDel = field_21_ibstRMarkDel; + } + + /** + * Get the dttmRMark field for the CHP record. + */ + public DateAndTime GetDttmRMark() + { + return field_22_dttmRMark; + } + + /** + * Set the dttmRMark field for the CHP record. + */ + public void SetDttmRMark(DateAndTime field_22_dttmRMark) + { + this.field_22_dttmRMark = field_22_dttmRMark; + } + + /** + * Get the dttmRMarkDel field for the CHP record. + */ + public DateAndTime GetDttmRMarkDel() + { + return field_23_dttmRMarkDel; + } + + /** + * Set the dttmRMarkDel field for the CHP record. + */ + public void SetDttmRMarkDel(DateAndTime field_23_dttmRMarkDel) + { + this.field_23_dttmRMarkDel = field_23_dttmRMarkDel; + } + + /** + * Get the Istd field for the CHP record. + */ + public int GetIstd() + { + return field_24_istd; + } + + /** + * Set the Istd field for the CHP record. + */ + public void SetIstd(int field_24_istd) + { + this.field_24_istd = field_24_istd; + } + + /** + * Get the baseIstd field for the CHP record. + */ + public int GetBaseIstd() + { + return field_25_baseIstd; + } + + /** + * Set the baseIstd field for the CHP record. + */ + public void SetBaseIstd(int field_25_baseIstd) + { + this.field_25_baseIstd = field_25_baseIstd; + } + + /** + * Get the ftcSym field for the CHP record. + */ + public int GetFtcSym() + { + return field_26_ftcSym; + } + + /** + * Set the ftcSym field for the CHP record. + */ + public void SetFtcSym(int field_26_ftcSym) + { + this.field_26_ftcSym = field_26_ftcSym; + } + + /** + * Get the xchSym field for the CHP record. + */ + public int GetXchSym() + { + return field_27_xchSym; + } + + /** + * Set the xchSym field for the CHP record. + */ + public void SetXchSym(int field_27_xchSym) + { + this.field_27_xchSym = field_27_xchSym; + } + + /** + * Get the idslRMReason field for the CHP record. + */ + public int GetIdslRMReason() + { + return field_28_idslRMReason; + } + + /** + * Set the idslRMReason field for the CHP record. + */ + public void SetIdslRMReason(int field_28_idslRMReason) + { + this.field_28_idslRMReason = field_28_idslRMReason; + } + + /** + * Get the idslReasonDel field for the CHP record. + */ + public int GetIdslReasonDel() + { + return field_29_idslReasonDel; + } + + /** + * Set the idslReasonDel field for the CHP record. + */ + public void SetIdslReasonDel(int field_29_idslReasonDel) + { + this.field_29_idslReasonDel = field_29_idslReasonDel; + } + + /** + * Get the ysr field for the CHP record. + */ + public byte GetYsr() + { + return field_30_ysr; + } + + /** + * Set the ysr field for the CHP record. + */ + public void SetYsr(byte field_30_ysr) + { + this.field_30_ysr = field_30_ysr; + } + + /** + * Get the chYsr field for the CHP record. + */ + public byte GetChYsr() + { + return field_31_chYsr; + } + + /** + * Set the chYsr field for the CHP record. + */ + public void SetChYsr(byte field_31_chYsr) + { + this.field_31_chYsr = field_31_chYsr; + } + + /** + * Get the hpsKern field for the CHP record. + */ + public int GetHpsKern() + { + return field_32_hpsKern; + } + + /** + * Set the hpsKern field for the CHP record. + */ + public void SetHpsKern(int field_32_hpsKern) + { + this.field_32_hpsKern = field_32_hpsKern; + } + + /** + * Get the Highlight field for the CHP record. + */ + public short GetHighlight() + { + return field_33_Highlight; + } + + /** + * Set the Highlight field for the CHP record. + */ + public void SetHighlight(short field_33_Highlight) + { + this.field_33_Highlight = field_33_Highlight; + } + + /** + * Get the fPropMark field for the CHP record. + */ + public short GetFPropMark() + { + return field_34_fPropMark; + } + + /** + * Set the fPropMark field for the CHP record. + */ + public void SetFPropMark(short field_34_fPropMark) + { + this.field_34_fPropMark = field_34_fPropMark; + } + + /** + * Get the ibstPropRMark field for the CHP record. + */ + public int GetIbstPropRMark() + { + return field_35_ibstPropRMark; + } + + /** + * Set the ibstPropRMark field for the CHP record. + */ + public void SetIbstPropRMark(int field_35_ibstPropRMark) + { + this.field_35_ibstPropRMark = field_35_ibstPropRMark; + } + + /** + * Get the dttmPropRMark field for the CHP record. + */ + public DateAndTime GetDttmPropRMark() + { + return field_36_dttmPropRMark; + } + + /** + * Set the dttmPropRMark field for the CHP record. + */ + public void SetDttmPropRMark(DateAndTime field_36_dttmPropRMark) + { + this.field_36_dttmPropRMark = field_36_dttmPropRMark; + } + + /** + * Get the sfxtText field for the CHP record. + */ + public byte GetSfxtText() + { + return field_37_sfxtText; + } + + /** + * Set the sfxtText field for the CHP record. + */ + public void SetSfxtText(byte field_37_sfxtText) + { + this.field_37_sfxtText = field_37_sfxtText; + } + + /** + * Get the fDispFldRMark field for the CHP record. + */ + public byte GetFDispFldRMark() + { + return field_38_fDispFldRMark; + } + + /** + * Set the fDispFldRMark field for the CHP record. + */ + public void SetFDispFldRMark(byte field_38_fDispFldRMark) + { + this.field_38_fDispFldRMark = field_38_fDispFldRMark; + } + + /** + * Get the ibstDispFldRMark field for the CHP record. + */ + public int GetIbstDispFldRMark() + { + return field_39_ibstDispFldRMark; + } + + /** + * Set the ibstDispFldRMark field for the CHP record. + */ + public void SetIbstDispFldRMark(int field_39_ibstDispFldRMark) + { + this.field_39_ibstDispFldRMark = field_39_ibstDispFldRMark; + } + + /** + * Get the dttmDispFldRMark field for the CHP record. + */ + public DateAndTime GetDttmDispFldRMark() + { + return field_40_dttmDispFldRMark; + } + + /** + * Set the dttmDispFldRMark field for the CHP record. + */ + public void SetDttmDispFldRMark(DateAndTime field_40_dttmDispFldRMark) + { + this.field_40_dttmDispFldRMark = field_40_dttmDispFldRMark; + } + + /** + * Get the xstDispFldRMark field for the CHP record. + */ + public byte[] GetXstDispFldRMark() + { + return field_41_xstDispFldRMark; + } + + /** + * Set the xstDispFldRMark field for the CHP record. + */ + public void SetXstDispFldRMark(byte[] field_41_xstDispFldRMark) + { + this.field_41_xstDispFldRMark = field_41_xstDispFldRMark; + } + + /** + * Get the shd field for the CHP record. + */ + public ShadingDescriptor GetShd() + { + return field_42_shd; + } + + /** + * Set the shd field for the CHP record. + */ + public void SetShd(ShadingDescriptor field_42_shd) + { + this.field_42_shd = field_42_shd; + } + + /** + * Get the brc field for the CHP record. + */ + public BorderCode GetBrc() + { + return field_43_brc; + } + + /** + * Set the brc field for the CHP record. + */ + public void SetBrc(BorderCode field_43_brc) + { + this.field_43_brc = field_43_brc; + } + + /** + * Sets the fBold field value. + * + */ + public void SetFBold(bool value) + { + field_2_format_flags = (int)fBold.SetBoolean(field_2_format_flags, value); + + + } + + /** + * + * @return the fBold field value. + */ + public bool IsFBold() + { + return fBold.IsSet(field_2_format_flags); + + } + + /** + * Sets the fItalic field value. + * + */ + public void SetFItalic(bool value) + { + field_2_format_flags = (int)fItalic.SetBoolean(field_2_format_flags, value); + + + } + + /** + * + * @return the fItalic field value. + */ + public bool IsFItalic() + { + return fItalic.IsSet(field_2_format_flags); + + } + + /** + * Sets the fRMarkDel field value. + * + */ + public void SetFRMarkDel(bool value) + { + field_2_format_flags = (int)fRMarkDel.SetBoolean(field_2_format_flags, value); + + + } + + /** + * + * @return the fRMarkDel field value. + */ + public bool IsFRMarkDel() + { + return fRMarkDel.IsSet(field_2_format_flags); + + } + + /** + * Sets the fOutline field value. + * + */ + public void SetFOutline(bool value) + { + field_2_format_flags = (int)fOutline.SetBoolean(field_2_format_flags, value); + + + } + + /** + * + * @return the fOutline field value. + */ + public bool IsFOutline() + { + return fOutline.IsSet(field_2_format_flags); + + } + + /** + * Sets the fFldVanish field value. + * + */ + public void SetFFldVanish(bool value) + { + field_2_format_flags = (int)fFldVanish.SetBoolean(field_2_format_flags, value); + + + } + + /** + * + * @return the fFldVanish field value. + */ + public bool IsFFldVanish() + { + return fFldVanish.IsSet(field_2_format_flags); + + } + + /** + * Sets the fSmallCaps field value. + * + */ + public void SetFSmallCaps(bool value) + { + field_2_format_flags = (int)fSmallCaps.SetBoolean(field_2_format_flags, value); + + + } + + /** + * + * @return the fSmallCaps field value. + */ + public bool IsFSmallCaps() + { + return fSmallCaps.IsSet(field_2_format_flags); + + } + + /** + * Sets the fCaps field value. + * + */ + public void SetFCaps(bool value) + { + field_2_format_flags = (int)fCaps.SetBoolean(field_2_format_flags, value); + + + } + + /** + * + * @return the fCaps field value. + */ + public bool IsFCaps() + { + return fCaps.IsSet(field_2_format_flags); + + } + + /** + * Sets the fVanish field value. + * + */ + public void SetFVanish(bool value) + { + field_2_format_flags = (int)fVanish.SetBoolean(field_2_format_flags, value); + + + } + + /** + * + * @return the fVanish field value. + */ + public bool IsFVanish() + { + return fVanish.IsSet(field_2_format_flags); + + } + + /** + * Sets the fRMark field value. + * + */ + public void SetFRMark(bool value) + { + field_2_format_flags = (int)fRMark.SetBoolean(field_2_format_flags, value); + + + } + + /** + * + * @return the fRMark field value. + */ + public bool IsFRMark() + { + return fRMark.IsSet(field_2_format_flags); + + } + + /** + * Sets the fSpec field value. + * + */ + public void SetFSpec(bool value) + { + field_2_format_flags = (int)fSpec.SetBoolean(field_2_format_flags, value); + + + } + + /** + * + * @return the fSpec field value. + */ + public bool IsFSpec() + { + return fSpec.IsSet(field_2_format_flags); + + } + + /** + * Sets the fStrike field value. + * + */ + public void SetFStrike(bool value) + { + field_2_format_flags = (int)fStrike.SetBoolean(field_2_format_flags, value); + + + } + + /** + * + * @return the fStrike field value. + */ + public bool IsFStrike() + { + return fStrike.IsSet(field_2_format_flags); + + } + + /** + * Sets the fObj field value. + * + */ + public void SetFObj(bool value) + { + field_2_format_flags = (int)fObj.SetBoolean(field_2_format_flags, value); + + + } + + /** + * + * @return the fObj field value. + */ + public bool IsFObj() + { + return fObj.IsSet(field_2_format_flags); + + } + + /** + * Sets the fShadow field value. + * + */ + public void SetFShadow(bool value) + { + field_2_format_flags = (int)fShadow.SetBoolean(field_2_format_flags, value); + + + } + + /** + * + * @return the fShadow field value. + */ + public bool IsFShadow() + { + return fShadow.IsSet(field_2_format_flags); + + } + + /** + * Sets the fLowerCase field value. + * + */ + public void SetFLowerCase(bool value) + { + field_2_format_flags = (int)fLowerCase.SetBoolean(field_2_format_flags, value); + + + } + + /** + * + * @return the fLowerCase field value. + */ + public bool IsFLowerCase() + { + return fLowerCase.IsSet(field_2_format_flags); + + } + + /** + * Sets the fData field value. + * + */ + public void SetFData(bool value) + { + field_2_format_flags = (int)fData.SetBoolean(field_2_format_flags, value); + + + } + + /** + * + * @return the fData field value. + */ + public bool IsFData() + { + return fData.IsSet(field_2_format_flags); + + } + + /** + * Sets the fOle2 field value. + * + */ + public void SetFOle2(bool value) + { + field_2_format_flags = (int)fOle2.SetBoolean(field_2_format_flags, value); + + + } + + /** + * + * @return the fOle2 field value. + */ + public bool IsFOle2() + { + return fOle2.IsSet(field_2_format_flags); + + } + + /** + * Sets the fEmboss field value. + * + */ + public void SetFEmboss(bool value) + { + field_3_format_flags1 = (int)fEmboss.SetBoolean(field_3_format_flags1, value); + + + } + + /** + * + * @return the fEmboss field value. + */ + public bool IsFEmboss() + { + return fEmboss.IsSet(field_3_format_flags1); + + } + + /** + * Sets the fImprint field value. + * + */ + public void SetFImprint(bool value) + { + field_3_format_flags1 = (int)fImprint.SetBoolean(field_3_format_flags1, value); + + + } + + /** + * + * @return the fImprint field value. + */ + public bool IsFImprint() + { + return fImprint.IsSet(field_3_format_flags1); + + } + + /** + * Sets the fDStrike field value. + * + */ + public void SetFDStrike(bool value) + { + field_3_format_flags1 = (int)fDStrike.SetBoolean(field_3_format_flags1, value); + + + } + + /** + * + * @return the fDStrike field value. + */ + public bool IsFDStrike() + { + return fDStrike.IsSet(field_3_format_flags1); + + } + + /** + * Sets the fUsePgsuSettings field value. + * + */ + public void SetFUsePgsuSettings(bool value) + { + field_3_format_flags1 = (int)fUsePgsuSettings.SetBoolean(field_3_format_flags1, value); + + + } + + /** + * + * @return the fUsePgsuSettings field value. + */ + public bool IsFUsePgsuSettings() + { + return fUsePgsuSettings.IsSet(field_3_format_flags1); + + } + + /** + * Sets the icoHighlight field value. + * + */ + public void SetIcoHighlight(byte value) + { + field_33_Highlight = (short)icoHighlight.SetValue(field_33_Highlight, value); + + + } + + /** + * + * @return the icoHighlight field value. + */ + public byte GetIcoHighlight() + { + return (byte)icoHighlight.GetValue(field_33_Highlight); + + } + + /** + * Sets the fHighlight field value. + * + */ + public void SetFHighlight(bool value) + { + field_33_Highlight = (short)fHighlight.SetBoolean(field_33_Highlight, value); + + + } + + /** + * + * @return the fHighlight field value. + */ + public bool IsFHighlight() + { + return fHighlight.IsSet(field_33_Highlight); + + } + + /** + * Sets the kcd field value. + * + */ + public void SetKcd(byte value) + { + field_33_Highlight = (short)kcd.SetValue(field_33_Highlight, value); + + + } + + /** + * + * @return the kcd field value. + */ + public byte GetKcd() + { + return (byte)kcd.GetValue(field_33_Highlight); + + } + + /** + * Sets the fNavHighlight field value. + * + */ + public void SetFNavHighlight(bool value) + { + field_33_Highlight = (short)fNavHighlight.SetBoolean(field_33_Highlight, value); + + + } + + /** + * + * @return the fNavHighlight field value. + */ + public bool IsFNavHighlight() + { + return fNavHighlight.IsSet(field_33_Highlight); + + } + + /** + * Sets the fChsDiff field value. + * + */ + public void SetFChsDiff(bool value) + { + field_33_Highlight = (short)fChsDiff.SetBoolean(field_33_Highlight, value); + + + } + + /** + * + * @return the fChsDiff field value. + */ + public bool IsFChsDiff() + { + return fChsDiff.IsSet(field_33_Highlight); + + } + + /** + * Sets the fMacChs field value. + * + */ + public void SetFMacChs(bool value) + { + field_33_Highlight = (short)fMacChs.SetBoolean(field_33_Highlight, value); + + + } + + /** + * + * @return the fMacChs field value. + */ + public bool IsFMacChs() + { + return fMacChs.IsSet(field_33_Highlight); + + } + + /** + * Sets the fFtcAsciSym field value. + * + */ + public void SetFFtcAsciSym(bool value) + { + field_33_Highlight = (short)fFtcAsciSym.SetBoolean(field_33_Highlight, value); + + + } + + /** + * + * @return the fFtcAsciSym field value. + */ + public bool IsFFtcAsciSym() + { + return fFtcAsciSym.IsSet(field_33_Highlight); + + } + + + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/Types/DOPAbstractType.cs b/scratchpad/HWPF/Model/Types/DOPAbstractType.cs new file mode 100644 index 0000000..d09d588 --- /dev/null +++ b/scratchpad/HWPF/Model/Types/DOPAbstractType.cs @@ -0,0 +1,3362 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + + +namespace NPOI.HWPF.Model.Types +{ + using System; + using NPOI.Util; + + using NPOI.HWPF.UserModel; + using System.Text; + + /** + * Document Properties. + * NOTE: This source Is automatically generated please do not modify this file. Either subclass or + * remove the record in src/records/definitions. + + * @author S. Ryan Ackley + */ + public abstract class DOPAbstractType : BaseObject + { + + protected byte field_1_formatFlags; + private static BitField fFacingPages = BitFieldFactory.GetInstance(0x01); + private static BitField fWidowControl = BitFieldFactory.GetInstance(0x02); + private static BitField fPMHMainDoc = BitFieldFactory.GetInstance(0x04); + private static BitField grfSupression = BitFieldFactory.GetInstance(0x18); + private static BitField fpc = BitFieldFactory.GetInstance(0x60); + private static BitField unused1 = BitFieldFactory.GetInstance(0x80); + protected byte field_2_unused2; + protected short field_3_footnoteInfo; + private static BitField rncFtn = BitFieldFactory.GetInstance(0x0003); + private static BitField nFtn = BitFieldFactory.GetInstance(0xfffc); + protected byte field_4_fOutlineDirtySave; + protected byte field_5_docinfo; + private static BitField fOnlyMacPics = BitFieldFactory.GetInstance(0x01); + private static BitField fOnlyWinPics = BitFieldFactory.GetInstance(0x02); + private static BitField fLabelDoc = BitFieldFactory.GetInstance(0x04); + private static BitField fHyphCapitals = BitFieldFactory.GetInstance(0x08); + private static BitField fAutoHyphen = BitFieldFactory.GetInstance(0x10); + private static BitField fFormNoFields = BitFieldFactory.GetInstance(0x20); + private static BitField fLinkStyles = BitFieldFactory.GetInstance(0x40); + private static BitField fRevMarking = BitFieldFactory.GetInstance(0x80); + protected byte field_6_docinfo1; + private static BitField fBackup = BitFieldFactory.GetInstance(0x01); + private static BitField fExactCWords = BitFieldFactory.GetInstance(0x02); + private static BitField fPagHidden = BitFieldFactory.GetInstance(0x04); + private static BitField fPagResults = BitFieldFactory.GetInstance(0x08); + private static BitField fLockAtn = BitFieldFactory.GetInstance(0x10); + private static BitField fMirrorMargins = BitFieldFactory.GetInstance(0x20); + private static BitField unused3 = BitFieldFactory.GetInstance(0x40); + private static BitField fDfltTrueType = BitFieldFactory.GetInstance(0x80); + protected byte field_7_docinfo2; + private static BitField fPagSupressTopSpacing = BitFieldFactory.GetInstance(0x01); + private static BitField fProtEnabled = BitFieldFactory.GetInstance(0x02); + private static BitField fDispFormFldSel = BitFieldFactory.GetInstance(0x04); + private static BitField fRMView = BitFieldFactory.GetInstance(0x08); + private static BitField fRMPrint = BitFieldFactory.GetInstance(0x10); + private static BitField unused4 = BitFieldFactory.GetInstance(0x20); + private static BitField fLockRev = BitFieldFactory.GetInstance(0x40); + private static BitField fEmbedFonts = BitFieldFactory.GetInstance(0x80); + protected short field_8_docinfo3; + private static BitField oldfNoTabForInd = BitFieldFactory.GetInstance(0x0001); + private static BitField oldfNoSpaceRaiseLower = BitFieldFactory.GetInstance(0x0002); + private static BitField oldfSuppressSpbfAfterPageBreak = BitFieldFactory.GetInstance(0x0004); + private static BitField oldfWrapTrailSpaces = BitFieldFactory.GetInstance(0x0008); + private static BitField oldfMapPrintTextColor = BitFieldFactory.GetInstance(0x0010); + private static BitField oldfNoColumnBalance = BitFieldFactory.GetInstance(0x0020); + private static BitField oldfConvMailMergeEsc = BitFieldFactory.GetInstance(0x0040); + private static BitField oldfSupressTopSpacing = BitFieldFactory.GetInstance(0x0080); + private static BitField oldfOrigWordTableRules = BitFieldFactory.GetInstance(0x0100); + private static BitField oldfTransparentMetafiles = BitFieldFactory.GetInstance(0x0200); + private static BitField oldfShowBreaksInFrames = BitFieldFactory.GetInstance(0x0400); + private static BitField oldfSwapBordersFacingPgs = BitFieldFactory.GetInstance(0x0800); + private static BitField unused5 = BitFieldFactory.GetInstance(0xf000); + protected int field_9_dxaTab; + protected int field_10_wSpare; + protected int field_11_dxaHotz; + protected int field_12_cConsexHypLim; + protected int field_13_wSpare2; + protected int field_14_dttmCreated; + protected int field_15_dttmRevised; + protected int field_16_dttmLastPrint; + protected int field_17_nRevision; + protected int field_18_tmEdited; + protected int field_19_cWords; + protected int field_20_cCh; + protected int field_21_cPg; + protected int field_22_cParas; + protected short field_23_Edn; + private static BitField rncEdn = BitFieldFactory.GetInstance(0x0003); + private static BitField nEdn = BitFieldFactory.GetInstance(0xfffc); + protected short field_24_Edn1; + private static BitField epc = BitFieldFactory.GetInstance(0x0003); + private static BitField nfcFtnRef1 = BitFieldFactory.GetInstance(0x003c); + private static BitField nfcEdnRef1 = BitFieldFactory.GetInstance(0x03c0); + private static BitField fPrintFormData = BitFieldFactory.GetInstance(0x0400); + private static BitField fSaveFormData = BitFieldFactory.GetInstance(0x0800); + private static BitField fShadeFormData = BitFieldFactory.GetInstance(0x1000); + private static BitField fWCFtnEdn = BitFieldFactory.GetInstance(0x8000); + protected int field_25_cLines; + protected int field_26_cWordsFtnEnd; + protected int field_27_cChFtnEdn; + protected short field_28_cPgFtnEdn; + protected int field_29_cParasFtnEdn; + protected int field_30_cLinesFtnEdn; + protected int field_31_lKeyProtDoc; + protected short field_32_view; + private static BitField wvkSaved = BitFieldFactory.GetInstance(0x0007); + private static BitField wScaleSaved = BitFieldFactory.GetInstance(0x0ff8); + private static BitField zkSaved = BitFieldFactory.GetInstance(0x3000); + private static BitField fRotateFontW6 = BitFieldFactory.GetInstance(0x4000); + private static BitField iGutterPos = BitFieldFactory.GetInstance(0x8000); + protected int field_33_docinfo4; + private static BitField fNoTabForInd = BitFieldFactory.GetInstance(0x00000001); + private static BitField fNoSpaceRaiseLower = BitFieldFactory.GetInstance(0x00000002); + private static BitField fSupressSpdfAfterPageBreak = BitFieldFactory.GetInstance(0x00000004); + private static BitField fWrapTrailSpaces = BitFieldFactory.GetInstance(0x00000008); + private static BitField fMapPrintTextColor = BitFieldFactory.GetInstance(0x00000010); + private static BitField fNoColumnBalance = BitFieldFactory.GetInstance(0x00000020); + private static BitField fConvMailMergeEsc = BitFieldFactory.GetInstance(0x00000040); + private static BitField fSupressTopSpacing = BitFieldFactory.GetInstance(0x00000080); + private static BitField fOrigWordTableRules = BitFieldFactory.GetInstance(0x00000100); + private static BitField fTransparentMetafiles = BitFieldFactory.GetInstance(0x00000200); + private static BitField fShowBreaksInFrames = BitFieldFactory.GetInstance(0x00000400); + private static BitField fSwapBordersFacingPgs = BitFieldFactory.GetInstance(0x00000800); + private static BitField fSuppressTopSPacingMac5 = BitFieldFactory.GetInstance(0x00010000); + private static BitField fTruncDxaExpand = BitFieldFactory.GetInstance(0x00020000); + private static BitField fPrintBodyBeforeHdr = BitFieldFactory.GetInstance(0x00040000); + private static BitField fNoLeading = BitFieldFactory.GetInstance(0x00080000); + private static BitField fMWSmallCaps = BitFieldFactory.GetInstance(0x00200000); + protected short field_34_adt; + protected byte[] field_35_doptypography; + protected byte[] field_36_dogrid; + protected short field_37_docinfo5; + private static BitField lvl = BitFieldFactory.GetInstance(0x001e); + private static BitField fGramAllDone = BitFieldFactory.GetInstance(0x0020); + private static BitField fGramAllClean = BitFieldFactory.GetInstance(0x0040); + private static BitField fSubsetFonts = BitFieldFactory.GetInstance(0x0080); + private static BitField fHideLastVersion = BitFieldFactory.GetInstance(0x0100); + private static BitField fHtmlDoc = BitFieldFactory.GetInstance(0x0200); + private static BitField fSnapBorder = BitFieldFactory.GetInstance(0x0800); + private static BitField fIncludeHeader = BitFieldFactory.GetInstance(0x1000); + private static BitField fIncludeFooter = BitFieldFactory.GetInstance(0x2000); + private static BitField fForcePageSizePag = BitFieldFactory.GetInstance(0x4000); + private static BitField fMinFontSizePag = BitFieldFactory.GetInstance(0x8000); + protected short field_38_docinfo6; + private static BitField fHaveVersions = BitFieldFactory.GetInstance(0x0001); + private static BitField fAutoVersions = BitFieldFactory.GetInstance(0x0002); + protected byte[] field_39_asumyi; + protected int field_40_cChWS; + protected int field_41_cChWSFtnEdn; + protected int field_42_grfDocEvents; + protected int field_43_virusinfo; + private static BitField fVirusPrompted = BitFieldFactory.GetInstance(0x0001); + private static BitField fVirusLoadSafe = BitFieldFactory.GetInstance(0x0002); + private static BitField KeyVirusSession30 = BitFieldFactory.GetInstance(unchecked((int)0xfffffffc)); + protected byte[] field_44_Spare; + protected int field_45_reserved1; + protected int field_46_reserved2; + protected int field_47_cDBC; + protected int field_48_cDBCFtnEdn; + protected int field_49_reserved; + protected short field_50_nfcFtnRef; + protected short field_51_nfcEdnRef; + protected short field_52_hpsZoonFontPag; + protected short field_53_dywDispPag; + + + public DOPAbstractType() + { + + } + + protected void FillFields(byte[] data, int offset) + { + field_1_formatFlags = data[0x0 + offset]; + field_2_unused2 = data[0x1 + offset]; + field_3_footnoteInfo = LittleEndian.GetShort(data, 0x2 + offset); + field_4_fOutlineDirtySave = data[0x4 + offset]; + field_5_docinfo = data[0x5 + offset]; + field_6_docinfo1 = data[0x6 + offset]; + field_7_docinfo2 = data[0x7 + offset]; + field_8_docinfo3 = LittleEndian.GetShort(data, 0x8 + offset); + field_9_dxaTab = LittleEndian.GetShort(data, 0xa + offset); + field_10_wSpare = LittleEndian.GetShort(data, 0xc + offset); + field_11_dxaHotz = LittleEndian.GetShort(data, 0xe + offset); + field_12_cConsexHypLim = LittleEndian.GetShort(data, 0x10 + offset); + field_13_wSpare2 = LittleEndian.GetShort(data, 0x12 + offset); + field_14_dttmCreated = LittleEndian.GetInt(data, 0x14 + offset); + field_15_dttmRevised = LittleEndian.GetInt(data, 0x18 + offset); + field_16_dttmLastPrint = LittleEndian.GetInt(data, 0x1c + offset); + field_17_nRevision = LittleEndian.GetShort(data, 0x20 + offset); + field_18_tmEdited = LittleEndian.GetInt(data, 0x22 + offset); + field_19_cWords = LittleEndian.GetInt(data, 0x26 + offset); + field_20_cCh = LittleEndian.GetInt(data, 0x2a + offset); + field_21_cPg = LittleEndian.GetShort(data, 0x2e + offset); + field_22_cParas = LittleEndian.GetInt(data, 0x30 + offset); + field_23_Edn = LittleEndian.GetShort(data, 0x34 + offset); + field_24_Edn1 = LittleEndian.GetShort(data, 0x36 + offset); + field_25_cLines = LittleEndian.GetInt(data, 0x38 + offset); + field_26_cWordsFtnEnd = LittleEndian.GetInt(data, 0x3c + offset); + field_27_cChFtnEdn = LittleEndian.GetInt(data, 0x40 + offset); + field_28_cPgFtnEdn = LittleEndian.GetShort(data, 0x44 + offset); + field_29_cParasFtnEdn = LittleEndian.GetInt(data, 0x46 + offset); + field_30_cLinesFtnEdn = LittleEndian.GetInt(data, 0x4a + offset); + field_31_lKeyProtDoc = LittleEndian.GetInt(data, 0x4e + offset); + field_32_view = LittleEndian.GetShort(data, 0x52 + offset); + field_33_docinfo4 = LittleEndian.GetInt(data, 0x54 + offset); + field_34_adt = LittleEndian.GetShort(data, 0x58 + offset); + field_35_doptypography = LittleEndian.GetByteArray(data, 0x5a + offset, 310); + field_36_dogrid = LittleEndian.GetByteArray(data, 0x190 + offset, 10); + field_37_docinfo5 = LittleEndian.GetShort(data, 0x19a + offset); + field_38_docinfo6 = LittleEndian.GetShort(data, 0x19c + offset); + field_39_asumyi = LittleEndian.GetByteArray(data, 0x19e + offset, 12); + field_40_cChWS = LittleEndian.GetInt(data, 0x1aa + offset); + field_41_cChWSFtnEdn = LittleEndian.GetInt(data, 0x1ae + offset); + field_42_grfDocEvents = LittleEndian.GetInt(data, 0x1b2 + offset); + field_43_virusinfo = LittleEndian.GetInt(data, 0x1b6 + offset); + field_44_Spare = LittleEndian.GetByteArray(data, 0x1ba + offset, 30); + field_45_reserved1 = LittleEndian.GetInt(data, 0x1d8 + offset); + field_46_reserved2 = LittleEndian.GetInt(data, 0x1dc + offset); + field_47_cDBC = LittleEndian.GetInt(data, 0x1e0 + offset); + field_48_cDBCFtnEdn = LittleEndian.GetInt(data, 0x1e4 + offset); + field_49_reserved = LittleEndian.GetInt(data, 0x1e8 + offset); + field_50_nfcFtnRef = LittleEndian.GetShort(data, 0x1ec + offset); + field_51_nfcEdnRef = LittleEndian.GetShort(data, 0x1ee + offset); + field_52_hpsZoonFontPag = LittleEndian.GetShort(data, 0x1f0 + offset); + field_53_dywDispPag = LittleEndian.GetShort(data, 0x1f2 + offset); + + } + + public void Serialize(byte[] data, int offset) + { + data[0x0 + offset] = field_1_formatFlags; ; + data[0x1 + offset] = field_2_unused2; ; + LittleEndian.PutShort(data, 0x2 + offset, (short)field_3_footnoteInfo); ; + data[0x4 + offset] = field_4_fOutlineDirtySave; ; + data[0x5 + offset] = field_5_docinfo; ; + data[0x6 + offset] = field_6_docinfo1; ; + data[0x7 + offset] = field_7_docinfo2; ; + LittleEndian.PutShort(data, 0x8 + offset, (short)field_8_docinfo3); ; + LittleEndian.PutShort(data, 0xa + offset, (short)field_9_dxaTab); ; + LittleEndian.PutShort(data, 0xc + offset, (short)field_10_wSpare); ; + LittleEndian.PutShort(data, 0xe + offset, (short)field_11_dxaHotz); ; + LittleEndian.PutShort(data, 0x10 + offset, (short)field_12_cConsexHypLim); ; + LittleEndian.PutShort(data, 0x12 + offset, (short)field_13_wSpare2); ; + LittleEndian.PutInt(data, 0x14 + offset, field_14_dttmCreated); ; + LittleEndian.PutInt(data, 0x18 + offset, field_15_dttmRevised); ; + LittleEndian.PutInt(data, 0x1c + offset, field_16_dttmLastPrint); ; + LittleEndian.PutShort(data, 0x20 + offset, (short)field_17_nRevision); ; + LittleEndian.PutInt(data, 0x22 + offset, field_18_tmEdited); ; + LittleEndian.PutInt(data, 0x26 + offset, field_19_cWords); ; + LittleEndian.PutInt(data, 0x2a + offset, field_20_cCh); ; + LittleEndian.PutShort(data, 0x2e + offset, (short)field_21_cPg); ; + LittleEndian.PutInt(data, 0x30 + offset, field_22_cParas); ; + LittleEndian.PutShort(data, 0x34 + offset, (short)field_23_Edn); ; + LittleEndian.PutShort(data, 0x36 + offset, (short)field_24_Edn1); ; + LittleEndian.PutInt(data, 0x38 + offset, field_25_cLines); ; + LittleEndian.PutInt(data, 0x3c + offset, field_26_cWordsFtnEnd); ; + LittleEndian.PutInt(data, 0x40 + offset, field_27_cChFtnEdn); ; + LittleEndian.PutShort(data, 0x44 + offset, (short)field_28_cPgFtnEdn); ; + LittleEndian.PutInt(data, 0x46 + offset, field_29_cParasFtnEdn); ; + LittleEndian.PutInt(data, 0x4a + offset, field_30_cLinesFtnEdn); ; + LittleEndian.PutInt(data, 0x4e + offset, field_31_lKeyProtDoc); ; + LittleEndian.PutShort(data, 0x52 + offset, (short)field_32_view); ; + LittleEndian.PutInt(data, 0x54 + offset, field_33_docinfo4); ; + LittleEndian.PutShort(data, 0x58 + offset, (short)field_34_adt); ; + Array.Copy(field_35_doptypography, 0, data, 0x5a + offset, field_35_doptypography.Length); ; + Array.Copy(field_36_dogrid, 0, data, 0x190 + offset, field_36_dogrid.Length); ; + LittleEndian.PutShort(data, 0x19a + offset, (short)field_37_docinfo5); ; + LittleEndian.PutShort(data, 0x19c + offset, (short)field_38_docinfo6); ; + Array.Copy(field_39_asumyi, 0, data, 0x19e + offset, field_39_asumyi.Length); ; + LittleEndian.PutInt(data, 0x1aa + offset, field_40_cChWS); ; + LittleEndian.PutInt(data, 0x1ae + offset, field_41_cChWSFtnEdn); ; + LittleEndian.PutInt(data, 0x1b2 + offset, field_42_grfDocEvents); ; + LittleEndian.PutInt(data, 0x1b6 + offset, field_43_virusinfo); ; + Array.Copy(field_44_Spare, 0, data, 0x1ba + offset, field_44_Spare.Length); ; + LittleEndian.PutInt(data, 0x1d8 + offset, field_45_reserved1); ; + LittleEndian.PutInt(data, 0x1dc + offset, field_46_reserved2); ; + LittleEndian.PutInt(data, 0x1e0 + offset, field_47_cDBC); ; + LittleEndian.PutInt(data, 0x1e4 + offset, field_48_cDBCFtnEdn); ; + LittleEndian.PutInt(data, 0x1e8 + offset, field_49_reserved); ; + LittleEndian.PutShort(data, 0x1ec + offset, (short)field_50_nfcFtnRef); ; + LittleEndian.PutShort(data, 0x1ee + offset, (short)field_51_nfcEdnRef); ; + LittleEndian.PutShort(data, 0x1f0 + offset, (short)field_52_hpsZoonFontPag); ; + LittleEndian.PutShort(data, 0x1f2 + offset, (short)field_53_dywDispPag); ; + + } + + public override String ToString() + { + StringBuilder buffer = new StringBuilder(); + + buffer.Append("[DOP]\n"); + + buffer.Append(" .formatFlags = "); + buffer.Append(" (").Append(GetFormatFlags()).Append(" )\n"); + buffer.Append(" .fFacingPages = ").Append(IsFFacingPages()).Append('\n'); + buffer.Append(" .fWidowControl = ").Append(IsFWidowControl()).Append('\n'); + buffer.Append(" .fPMHMainDoc = ").Append(IsFPMHMainDoc()).Append('\n'); + buffer.Append(" .grfSupression = ").Append(GetGrfSupression()).Append('\n'); + buffer.Append(" .fpc = ").Append(GetFpc()).Append('\n'); + buffer.Append(" .unused1 = ").Append(IsUnused1()).Append('\n'); + + buffer.Append(" .unused2 = "); + buffer.Append(" (").Append(GetUnused2()).Append(" )\n"); + + buffer.Append(" .footnoteInfo = "); + buffer.Append(" (").Append(GetFootnoteInfo()).Append(" )\n"); + buffer.Append(" .rncFtn = ").Append(GetRncFtn()).Append('\n'); + buffer.Append(" .nFtn = ").Append(GetNFtn()).Append('\n'); + + buffer.Append(" .fOutlineDirtySave = "); + buffer.Append(" (").Append(GetFOutlineDirtySave()).Append(" )\n"); + + buffer.Append(" .docinfo = "); + buffer.Append(" (").Append(GetDocinfo()).Append(" )\n"); + buffer.Append(" .fOnlyMacPics = ").Append(IsFOnlyMacPics()).Append('\n'); + buffer.Append(" .fOnlyWinPics = ").Append(IsFOnlyWinPics()).Append('\n'); + buffer.Append(" .fLabelDoc = ").Append(IsFLabelDoc()).Append('\n'); + buffer.Append(" .fHyphCapitals = ").Append(IsFHyphCapitals()).Append('\n'); + buffer.Append(" .fAutoHyphen = ").Append(IsFAutoHyphen()).Append('\n'); + buffer.Append(" .fFormNoFields = ").Append(IsFFormNoFields()).Append('\n'); + buffer.Append(" .fLinkStyles = ").Append(IsFLinkStyles()).Append('\n'); + buffer.Append(" .fRevMarking = ").Append(IsFRevMarking()).Append('\n'); + + buffer.Append(" .docinfo1 = "); + buffer.Append(" (").Append(GetDocinfo1()).Append(" )\n"); + buffer.Append(" .fBackup = ").Append(IsFBackup()).Append('\n'); + buffer.Append(" .fExactCWords = ").Append(IsFExactCWords()).Append('\n'); + buffer.Append(" .fPagHidden = ").Append(IsFPagHidden()).Append('\n'); + buffer.Append(" .fPagResults = ").Append(IsFPagResults()).Append('\n'); + buffer.Append(" .fLockAtn = ").Append(IsFLockAtn()).Append('\n'); + buffer.Append(" .fMirrorMargins = ").Append(IsFMirrorMargins()).Append('\n'); + buffer.Append(" .unused3 = ").Append(IsUnused3()).Append('\n'); + buffer.Append(" .fDfltTrueType = ").Append(IsFDfltTrueType()).Append('\n'); + + buffer.Append(" .docinfo2 = "); + buffer.Append(" (").Append(GetDocinfo2()).Append(" )\n"); + buffer.Append(" .fPagSupressTopSpacing = ").Append(IsFPagSupressTopSpacing()).Append('\n'); + buffer.Append(" .fProtEnabled = ").Append(IsFProtEnabled()).Append('\n'); + buffer.Append(" .fDispFormFldSel = ").Append(IsFDispFormFldSel()).Append('\n'); + buffer.Append(" .fRMView = ").Append(IsFRMView()).Append('\n'); + buffer.Append(" .fRMPrint = ").Append(IsFRMPrint()).Append('\n'); + buffer.Append(" .unused4 = ").Append(IsUnused4()).Append('\n'); + buffer.Append(" .fLockRev = ").Append(IsFLockRev()).Append('\n'); + buffer.Append(" .fEmbedFonts = ").Append(IsFEmbedFonts()).Append('\n'); + + buffer.Append(" .docinfo3 = "); + buffer.Append(" (").Append(GetDocinfo3()).Append(" )\n"); + buffer.Append(" .oldfNoTabForInd = ").Append(IsOldfNoTabForInd()).Append('\n'); + buffer.Append(" .oldfNoSpaceRaiseLower = ").Append(IsOldfNoSpaceRaiseLower()).Append('\n'); + buffer.Append(" .oldfSuppressSpbfAfterPageBreak = ").Append(IsOldfSuppressSpbfAfterPageBreak()).Append('\n'); + buffer.Append(" .oldfWrapTrailSpaces = ").Append(IsOldfWrapTrailSpaces()).Append('\n'); + buffer.Append(" .oldfMapPrintTextColor = ").Append(IsOldfMapPrintTextColor()).Append('\n'); + buffer.Append(" .oldfNoColumnBalance = ").Append(IsOldfNoColumnBalance()).Append('\n'); + buffer.Append(" .oldfConvMailMergeEsc = ").Append(IsOldfConvMailMergeEsc()).Append('\n'); + buffer.Append(" .oldfSupressTopSpacing = ").Append(IsOldfSupressTopSpacing()).Append('\n'); + buffer.Append(" .oldfOrigWordTableRules = ").Append(IsOldfOrigWordTableRules()).Append('\n'); + buffer.Append(" .oldfTransparentMetafiles = ").Append(IsOldfTransparentMetafiles()).Append('\n'); + buffer.Append(" .oldfShowBreaksInFrames = ").Append(IsOldfShowBreaksInFrames()).Append('\n'); + buffer.Append(" .oldfSwapBordersFacingPgs = ").Append(IsOldfSwapBordersFacingPgs()).Append('\n'); + buffer.Append(" .unused5 = ").Append(GetUnused5()).Append('\n'); + + buffer.Append(" .dxaTab = "); + buffer.Append(" (").Append(GetDxaTab()).Append(" )\n"); + + buffer.Append(" .wSpare = "); + buffer.Append(" (").Append(GetWSpare()).Append(" )\n"); + + buffer.Append(" .dxaHotz = "); + buffer.Append(" (").Append(GetDxaHotz()).Append(" )\n"); + + buffer.Append(" .cConsexHypLim = "); + buffer.Append(" (").Append(GetCConsexHypLim()).Append(" )\n"); + + buffer.Append(" .wSpare2 = "); + buffer.Append(" (").Append(GetWSpare2()).Append(" )\n"); + + buffer.Append(" .dttmCreated = "); + buffer.Append(" (").Append(GetDttmCreated()).Append(" )\n"); + + buffer.Append(" .dttmRevised = "); + buffer.Append(" (").Append(GetDttmRevised()).Append(" )\n"); + + buffer.Append(" .dttmLastPrint = "); + buffer.Append(" (").Append(GetDttmLastPrint()).Append(" )\n"); + + buffer.Append(" .nRevision = "); + buffer.Append(" (").Append(GetNRevision()).Append(" )\n"); + + buffer.Append(" .tmEdited = "); + buffer.Append(" (").Append(GetTmEdited()).Append(" )\n"); + + buffer.Append(" .cWords = "); + buffer.Append(" (").Append(GetCWords()).Append(" )\n"); + + buffer.Append(" .cCh = "); + buffer.Append(" (").Append(GetCCh()).Append(" )\n"); + + buffer.Append(" .cPg = "); + buffer.Append(" (").Append(GetCPg()).Append(" )\n"); + + buffer.Append(" .cParas = "); + buffer.Append(" (").Append(GetCParas()).Append(" )\n"); + + buffer.Append(" .Edn = "); + buffer.Append(" (").Append(GetEdn()).Append(" )\n"); + buffer.Append(" .rncEdn = ").Append(GetRncEdn()).Append('\n'); + buffer.Append(" .nEdn = ").Append(GetNEdn()).Append('\n'); + + buffer.Append(" .Edn1 = "); + buffer.Append(" (").Append(GetEdn1()).Append(" )\n"); + buffer.Append(" .epc = ").Append(GetEpc()).Append('\n'); + buffer.Append(" .nfcFtnRef1 = ").Append(GetNfcFtnRef1()).Append('\n'); + buffer.Append(" .nfcEdnRef1 = ").Append(GetNfcEdnRef1()).Append('\n'); + buffer.Append(" .fPrintFormData = ").Append(IsFPrintFormData()).Append('\n'); + buffer.Append(" .fSaveFormData = ").Append(IsFSaveFormData()).Append('\n'); + buffer.Append(" .fShadeFormData = ").Append(IsFShadeFormData()).Append('\n'); + buffer.Append(" .fWCFtnEdn = ").Append(IsFWCFtnEdn()).Append('\n'); + + buffer.Append(" .cLines = "); + buffer.Append(" (").Append(GetCLines()).Append(" )\n"); + + buffer.Append(" .cWordsFtnEnd = "); + buffer.Append(" (").Append(GetCWordsFtnEnd()).Append(" )\n"); + + buffer.Append(" .cChFtnEdn = "); + buffer.Append(" (").Append(GetCChFtnEdn()).Append(" )\n"); + + buffer.Append(" .cPgFtnEdn = "); + buffer.Append(" (").Append(GetCPgFtnEdn()).Append(" )\n"); + + buffer.Append(" .cParasFtnEdn = "); + buffer.Append(" (").Append(GetCParasFtnEdn()).Append(" )\n"); + + buffer.Append(" .cLinesFtnEdn = "); + buffer.Append(" (").Append(GetCLinesFtnEdn()).Append(" )\n"); + + buffer.Append(" .lKeyProtDoc = "); + buffer.Append(" (").Append(GetLKeyProtDoc()).Append(" )\n"); + + buffer.Append(" .view = "); + buffer.Append(" (").Append(GetView()).Append(" )\n"); + buffer.Append(" .wvkSaved = ").Append(GetWvkSaved()).Append('\n'); + buffer.Append(" .wScaleSaved = ").Append(GetWScaleSaved()).Append('\n'); + buffer.Append(" .zkSaved = ").Append(GetZkSaved()).Append('\n'); + buffer.Append(" .fRotateFontW6 = ").Append(IsFRotateFontW6()).Append('\n'); + buffer.Append(" .iGutterPos = ").Append(IsIGutterPos()).Append('\n'); + + buffer.Append(" .docinfo4 = "); + buffer.Append(" (").Append(GetDocinfo4()).Append(" )\n"); + buffer.Append(" .fNoTabForInd = ").Append(IsFNoTabForInd()).Append('\n'); + buffer.Append(" .fNoSpaceRaiseLower = ").Append(IsFNoSpaceRaiseLower()).Append('\n'); + buffer.Append(" .fSupressSpdfAfterPageBreak = ").Append(IsFSupressSpdfAfterPageBreak()).Append('\n'); + buffer.Append(" .fWrapTrailSpaces = ").Append(IsFWrapTrailSpaces()).Append('\n'); + buffer.Append(" .fMapPrintTextColor = ").Append(IsFMapPrintTextColor()).Append('\n'); + buffer.Append(" .fNoColumnBalance = ").Append(IsFNoColumnBalance()).Append('\n'); + buffer.Append(" .fConvMailMergeEsc = ").Append(IsFConvMailMergeEsc()).Append('\n'); + buffer.Append(" .fSupressTopSpacing = ").Append(IsFSupressTopSpacing()).Append('\n'); + buffer.Append(" .fOrigWordTableRules = ").Append(IsFOrigWordTableRules()).Append('\n'); + buffer.Append(" .fTransparentMetafiles = ").Append(IsFTransparentMetafiles()).Append('\n'); + buffer.Append(" .fShowBreaksInFrames = ").Append(IsFShowBreaksInFrames()).Append('\n'); + buffer.Append(" .fSwapBordersFacingPgs = ").Append(IsFSwapBordersFacingPgs()).Append('\n'); + buffer.Append(" .fSuppressTopSPacingMac5 = ").Append(IsFSuppressTopSPacingMac5()).Append('\n'); + buffer.Append(" .fTruncDxaExpand = ").Append(IsFTruncDxaExpand()).Append('\n'); + buffer.Append(" .fPrintBodyBeforeHdr = ").Append(IsFPrintBodyBeforeHdr()).Append('\n'); + buffer.Append(" .fNoLeading = ").Append(IsFNoLeading()).Append('\n'); + buffer.Append(" .fMWSmallCaps = ").Append(IsFMWSmallCaps()).Append('\n'); + + buffer.Append(" .adt = "); + buffer.Append(" (").Append(GetAdt()).Append(" )\n"); + + buffer.Append(" .doptypography = "); + buffer.Append(" (").Append(GetDoptypography()).Append(" )\n"); + + buffer.Append(" .dogrid = "); + buffer.Append(" (").Append(GetDogrid()).Append(" )\n"); + + buffer.Append(" .docinfo5 = "); + buffer.Append(" (").Append(GetDocinfo5()).Append(" )\n"); + buffer.Append(" .lvl = ").Append(GetLvl()).Append('\n'); + buffer.Append(" .fGramAllDone = ").Append(IsFGramAllDone()).Append('\n'); + buffer.Append(" .fGramAllClean = ").Append(IsFGramAllClean()).Append('\n'); + buffer.Append(" .fSubsetFonts = ").Append(IsFSubsetFonts()).Append('\n'); + buffer.Append(" .fHideLastVersion = ").Append(IsFHideLastVersion()).Append('\n'); + buffer.Append(" .fHtmlDoc = ").Append(IsFHtmlDoc()).Append('\n'); + buffer.Append(" .fSnapBorder = ").Append(IsFSnapBorder()).Append('\n'); + buffer.Append(" .fIncludeHeader = ").Append(IsFIncludeHeader()).Append('\n'); + buffer.Append(" .fIncludeFooter = ").Append(IsFIncludeFooter()).Append('\n'); + buffer.Append(" .fForcePageSizePag = ").Append(IsFForcePageSizePag()).Append('\n'); + buffer.Append(" .fMinFontSizePag = ").Append(IsFMinFontSizePag()).Append('\n'); + + buffer.Append(" .docinfo6 = "); + buffer.Append(" (").Append(GetDocinfo6()).Append(" )\n"); + buffer.Append(" .fHaveVersions = ").Append(IsFHaveVersions()).Append('\n'); + buffer.Append(" .fAutoVersions = ").Append(IsFAutoVersions()).Append('\n'); + + buffer.Append(" .asumyi = "); + buffer.Append(" (").Append(GetAsumyi()).Append(" )\n"); + + buffer.Append(" .cChWS = "); + buffer.Append(" (").Append(GetCChWS()).Append(" )\n"); + + buffer.Append(" .cChWSFtnEdn = "); + buffer.Append(" (").Append(GetCChWSFtnEdn()).Append(" )\n"); + + buffer.Append(" .grfDocEvents = "); + buffer.Append(" (").Append(GetGrfDocEvents()).Append(" )\n"); + + buffer.Append(" .virusinfo = "); + buffer.Append(" (").Append(GetVirusinfo()).Append(" )\n"); + buffer.Append(" .fVirusPrompted = ").Append(IsFVirusPrompted()).Append('\n'); + buffer.Append(" .fVirusLoadSafe = ").Append(IsFVirusLoadSafe()).Append('\n'); + buffer.Append(" .KeyVirusSession30 = ").Append(GetKeyVirusSession30()).Append('\n'); + + buffer.Append(" .Spare = "); + buffer.Append(" (").Append(GetSpare()).Append(" )\n"); + + buffer.Append(" .reserved1 = "); + buffer.Append(" (").Append(GetReserved1()).Append(" )\n"); + + buffer.Append(" .reserved2 = "); + buffer.Append(" (").Append(GetReserved2()).Append(" )\n"); + + buffer.Append(" .cDBC = "); + buffer.Append(" (").Append(GetCDBC()).Append(" )\n"); + + buffer.Append(" .cDBCFtnEdn = "); + buffer.Append(" (").Append(GetCDBCFtnEdn()).Append(" )\n"); + + buffer.Append(" .reserved = "); + buffer.Append(" (").Append(GetReserved()).Append(" )\n"); + + buffer.Append(" .nfcFtnRef = "); + buffer.Append(" (").Append(GetNfcFtnRef()).Append(" )\n"); + + buffer.Append(" .nfcEdnRef = "); + buffer.Append(" (").Append(GetNfcEdnRef()).Append(" )\n"); + + buffer.Append(" .hpsZoonFontPag = "); + buffer.Append(" (").Append(GetHpsZoonFontPag()).Append(" )\n"); + + buffer.Append(" .dywDispPag = "); + buffer.Append(" (").Append(GetDywDispPag()).Append(" )\n"); + + buffer.Append("[/DOP]\n"); + return buffer.ToString(); + } + + /** + * Size of record (exluding 4 byte header) + */ + public int GetSize() + { + return 4 + +1 + 1 + 2 + 1 + 1 + 1 + 1 + 2 + 2 + 2 + 2 + 2 + 2 + 4 + 4 + 4 + 2 + 4 + 4 + 4 + 2 + 4 + 2 + 2 + 4 + 4 + 4 + 2 + 4 + 4 + 4 + 2 + 4 + 2 + 310 + 10 + 2 + 2 + 12 + 4 + 4 + 4 + 4 + 30 + 4 + 4 + 4 + 4 + 4 + 2 + 2 + 2 + 2; + } + + + + /** + * Get the formatFlags field for the DOP record. + */ + public byte GetFormatFlags() + { + return field_1_formatFlags; + } + + /** + * Set the formatFlags field for the DOP record. + */ + public void SetFormatFlags(byte field_1_formatFlags) + { + this.field_1_formatFlags = field_1_formatFlags; + } + + /** + * Get the unused2 field for the DOP record. + */ + public byte GetUnused2() + { + return field_2_unused2; + } + + /** + * Set the unused2 field for the DOP record. + */ + public void SetUnused2(byte field_2_unused2) + { + this.field_2_unused2 = field_2_unused2; + } + + /** + * Get the footnoteInfo field for the DOP record. + */ + public short GetFootnoteInfo() + { + return field_3_footnoteInfo; + } + + /** + * Set the footnoteInfo field for the DOP record. + */ + public void SetFootnoteInfo(short field_3_footnoteInfo) + { + this.field_3_footnoteInfo = field_3_footnoteInfo; + } + + /** + * Get the fOutlineDirtySave field for the DOP record. + */ + public byte GetFOutlineDirtySave() + { + return field_4_fOutlineDirtySave; + } + + /** + * Set the fOutlineDirtySave field for the DOP record. + */ + public void SetFOutlineDirtySave(byte field_4_fOutlineDirtySave) + { + this.field_4_fOutlineDirtySave = field_4_fOutlineDirtySave; + } + + /** + * Get the docinfo field for the DOP record. + */ + public byte GetDocinfo() + { + return field_5_docinfo; + } + + /** + * Set the docinfo field for the DOP record. + */ + public void SetDocinfo(byte field_5_docinfo) + { + this.field_5_docinfo = field_5_docinfo; + } + + /** + * Get the docinfo1 field for the DOP record. + */ + public byte GetDocinfo1() + { + return field_6_docinfo1; + } + + /** + * Set the docinfo1 field for the DOP record. + */ + public void SetDocinfo1(byte field_6_docinfo1) + { + this.field_6_docinfo1 = field_6_docinfo1; + } + + /** + * Get the docinfo2 field for the DOP record. + */ + public byte GetDocinfo2() + { + return field_7_docinfo2; + } + + /** + * Set the docinfo2 field for the DOP record. + */ + public void SetDocinfo2(byte field_7_docinfo2) + { + this.field_7_docinfo2 = field_7_docinfo2; + } + + /** + * Get the docinfo3 field for the DOP record. + */ + public short GetDocinfo3() + { + return field_8_docinfo3; + } + + /** + * Set the docinfo3 field for the DOP record. + */ + public void SetDocinfo3(short field_8_docinfo3) + { + this.field_8_docinfo3 = field_8_docinfo3; + } + + /** + * Get the dxaTab field for the DOP record. + */ + public int GetDxaTab() + { + return field_9_dxaTab; + } + + /** + * Set the dxaTab field for the DOP record. + */ + public void SetDxaTab(int field_9_dxaTab) + { + this.field_9_dxaTab = field_9_dxaTab; + } + + /** + * Get the wSpare field for the DOP record. + */ + public int GetWSpare() + { + return field_10_wSpare; + } + + /** + * Set the wSpare field for the DOP record. + */ + public void SetWSpare(int field_10_wSpare) + { + this.field_10_wSpare = field_10_wSpare; + } + + /** + * Get the dxaHotz field for the DOP record. + */ + public int GetDxaHotz() + { + return field_11_dxaHotz; + } + + /** + * Set the dxaHotz field for the DOP record. + */ + public void SetDxaHotz(int field_11_dxaHotz) + { + this.field_11_dxaHotz = field_11_dxaHotz; + } + + /** + * Get the cConsexHypLim field for the DOP record. + */ + public int GetCConsexHypLim() + { + return field_12_cConsexHypLim; + } + + /** + * Set the cConsexHypLim field for the DOP record. + */ + public void SetCConsexHypLim(int field_12_cConsexHypLim) + { + this.field_12_cConsexHypLim = field_12_cConsexHypLim; + } + + /** + * Get the wSpare2 field for the DOP record. + */ + public int GetWSpare2() + { + return field_13_wSpare2; + } + + /** + * Set the wSpare2 field for the DOP record. + */ + public void SetWSpare2(int field_13_wSpare2) + { + this.field_13_wSpare2 = field_13_wSpare2; + } + + /** + * Get the dttmCreated field for the DOP record. + */ + public int GetDttmCreated() + { + return field_14_dttmCreated; + } + + /** + * Set the dttmCreated field for the DOP record. + */ + public void SetDttmCreated(int field_14_dttmCreated) + { + this.field_14_dttmCreated = field_14_dttmCreated; + } + + /** + * Get the dttmRevised field for the DOP record. + */ + public int GetDttmRevised() + { + return field_15_dttmRevised; + } + + /** + * Set the dttmRevised field for the DOP record. + */ + public void SetDttmRevised(int field_15_dttmRevised) + { + this.field_15_dttmRevised = field_15_dttmRevised; + } + + /** + * Get the dttmLastPrint field for the DOP record. + */ + public int GetDttmLastPrint() + { + return field_16_dttmLastPrint; + } + + /** + * Set the dttmLastPrint field for the DOP record. + */ + public void SetDttmLastPrint(int field_16_dttmLastPrint) + { + this.field_16_dttmLastPrint = field_16_dttmLastPrint; + } + + /** + * Get the nRevision field for the DOP record. + */ + public int GetNRevision() + { + return field_17_nRevision; + } + + /** + * Set the nRevision field for the DOP record. + */ + public void SetNRevision(int field_17_nRevision) + { + this.field_17_nRevision = field_17_nRevision; + } + + /** + * Get the tmEdited field for the DOP record. + */ + public int GetTmEdited() + { + return field_18_tmEdited; + } + + /** + * Set the tmEdited field for the DOP record. + */ + public void SetTmEdited(int field_18_tmEdited) + { + this.field_18_tmEdited = field_18_tmEdited; + } + + /** + * Get the cWords field for the DOP record. + */ + public int GetCWords() + { + return field_19_cWords; + } + + /** + * Set the cWords field for the DOP record. + */ + public void SetCWords(int field_19_cWords) + { + this.field_19_cWords = field_19_cWords; + } + + /** + * Get the cCh field for the DOP record. + */ + public int GetCCh() + { + return field_20_cCh; + } + + /** + * Set the cCh field for the DOP record. + */ + public void SetCCh(int field_20_cCh) + { + this.field_20_cCh = field_20_cCh; + } + + /** + * Get the cPg field for the DOP record. + */ + public int GetCPg() + { + return field_21_cPg; + } + + /** + * Set the cPg field for the DOP record. + */ + public void SetCPg(int field_21_cPg) + { + this.field_21_cPg = field_21_cPg; + } + + /** + * Get the cParas field for the DOP record. + */ + public int GetCParas() + { + return field_22_cParas; + } + + /** + * Set the cParas field for the DOP record. + */ + public void SetCParas(int field_22_cParas) + { + this.field_22_cParas = field_22_cParas; + } + + /** + * Get the Edn field for the DOP record. + */ + public short GetEdn() + { + return field_23_Edn; + } + + /** + * Set the Edn field for the DOP record. + */ + public void SetEdn(short field_23_Edn) + { + this.field_23_Edn = field_23_Edn; + } + + /** + * Get the Edn1 field for the DOP record. + */ + public short GetEdn1() + { + return field_24_Edn1; + } + + /** + * Set the Edn1 field for the DOP record. + */ + public void SetEdn1(short field_24_Edn1) + { + this.field_24_Edn1 = field_24_Edn1; + } + + /** + * Get the cLines field for the DOP record. + */ + public int GetCLines() + { + return field_25_cLines; + } + + /** + * Set the cLines field for the DOP record. + */ + public void SetCLines(int field_25_cLines) + { + this.field_25_cLines = field_25_cLines; + } + + /** + * Get the cWordsFtnEnd field for the DOP record. + */ + public int GetCWordsFtnEnd() + { + return field_26_cWordsFtnEnd; + } + + /** + * Set the cWordsFtnEnd field for the DOP record. + */ + public void SetCWordsFtnEnd(int field_26_cWordsFtnEnd) + { + this.field_26_cWordsFtnEnd = field_26_cWordsFtnEnd; + } + + /** + * Get the cChFtnEdn field for the DOP record. + */ + public int GetCChFtnEdn() + { + return field_27_cChFtnEdn; + } + + /** + * Set the cChFtnEdn field for the DOP record. + */ + public void SetCChFtnEdn(int field_27_cChFtnEdn) + { + this.field_27_cChFtnEdn = field_27_cChFtnEdn; + } + + /** + * Get the cPgFtnEdn field for the DOP record. + */ + public short GetCPgFtnEdn() + { + return field_28_cPgFtnEdn; + } + + /** + * Set the cPgFtnEdn field for the DOP record. + */ + public void SetCPgFtnEdn(short field_28_cPgFtnEdn) + { + this.field_28_cPgFtnEdn = field_28_cPgFtnEdn; + } + + /** + * Get the cParasFtnEdn field for the DOP record. + */ + public int GetCParasFtnEdn() + { + return field_29_cParasFtnEdn; + } + + /** + * Set the cParasFtnEdn field for the DOP record. + */ + public void SetCParasFtnEdn(int field_29_cParasFtnEdn) + { + this.field_29_cParasFtnEdn = field_29_cParasFtnEdn; + } + + /** + * Get the cLinesFtnEdn field for the DOP record. + */ + public int GetCLinesFtnEdn() + { + return field_30_cLinesFtnEdn; + } + + /** + * Set the cLinesFtnEdn field for the DOP record. + */ + public void SetCLinesFtnEdn(int field_30_cLinesFtnEdn) + { + this.field_30_cLinesFtnEdn = field_30_cLinesFtnEdn; + } + + /** + * Get the lKeyProtDoc field for the DOP record. + */ + public int GetLKeyProtDoc() + { + return field_31_lKeyProtDoc; + } + + /** + * Set the lKeyProtDoc field for the DOP record. + */ + public void SetLKeyProtDoc(int field_31_lKeyProtDoc) + { + this.field_31_lKeyProtDoc = field_31_lKeyProtDoc; + } + + /** + * Get the view field for the DOP record. + */ + public short GetView() + { + return field_32_view; + } + + /** + * Set the view field for the DOP record. + */ + public void SetView(short field_32_view) + { + this.field_32_view = field_32_view; + } + + /** + * Get the docinfo4 field for the DOP record. + */ + public int GetDocinfo4() + { + return field_33_docinfo4; + } + + /** + * Set the docinfo4 field for the DOP record. + */ + public void SetDocinfo4(int field_33_docinfo4) + { + this.field_33_docinfo4 = field_33_docinfo4; + } + + /** + * Get the adt field for the DOP record. + */ + public short GetAdt() + { + return field_34_adt; + } + + /** + * Set the adt field for the DOP record. + */ + public void SetAdt(short field_34_adt) + { + this.field_34_adt = field_34_adt; + } + + /** + * Get the doptypography field for the DOP record. + */ + public byte[] GetDoptypography() + { + return field_35_doptypography; + } + + /** + * Set the doptypography field for the DOP record. + */ + public void SetDoptypography(byte[] field_35_doptypography) + { + this.field_35_doptypography = field_35_doptypography; + } + + /** + * Get the dogrid field for the DOP record. + */ + public byte[] GetDogrid() + { + return field_36_dogrid; + } + + /** + * Set the dogrid field for the DOP record. + */ + public void SetDogrid(byte[] field_36_dogrid) + { + this.field_36_dogrid = field_36_dogrid; + } + + /** + * Get the docinfo5 field for the DOP record. + */ + public short GetDocinfo5() + { + return field_37_docinfo5; + } + + /** + * Set the docinfo5 field for the DOP record. + */ + public void SetDocinfo5(short field_37_docinfo5) + { + this.field_37_docinfo5 = field_37_docinfo5; + } + + /** + * Get the docinfo6 field for the DOP record. + */ + public short GetDocinfo6() + { + return field_38_docinfo6; + } + + /** + * Set the docinfo6 field for the DOP record. + */ + public void SetDocinfo6(short field_38_docinfo6) + { + this.field_38_docinfo6 = field_38_docinfo6; + } + + /** + * Get the asumyi field for the DOP record. + */ + public byte[] GetAsumyi() + { + return field_39_asumyi; + } + + /** + * Set the asumyi field for the DOP record. + */ + public void SetAsumyi(byte[] field_39_asumyi) + { + this.field_39_asumyi = field_39_asumyi; + } + + /** + * Get the cChWS field for the DOP record. + */ + public int GetCChWS() + { + return field_40_cChWS; + } + + /** + * Set the cChWS field for the DOP record. + */ + public void SetCChWS(int field_40_cChWS) + { + this.field_40_cChWS = field_40_cChWS; + } + + /** + * Get the cChWSFtnEdn field for the DOP record. + */ + public int GetCChWSFtnEdn() + { + return field_41_cChWSFtnEdn; + } + + /** + * Set the cChWSFtnEdn field for the DOP record. + */ + public void SetCChWSFtnEdn(int field_41_cChWSFtnEdn) + { + this.field_41_cChWSFtnEdn = field_41_cChWSFtnEdn; + } + + /** + * Get the grfDocEvents field for the DOP record. + */ + public int GetGrfDocEvents() + { + return field_42_grfDocEvents; + } + + /** + * Set the grfDocEvents field for the DOP record. + */ + public void SetGrfDocEvents(int field_42_grfDocEvents) + { + this.field_42_grfDocEvents = field_42_grfDocEvents; + } + + /** + * Get the virusinfo field for the DOP record. + */ + public int GetVirusinfo() + { + return field_43_virusinfo; + } + + /** + * Set the virusinfo field for the DOP record. + */ + public void SetVirusinfo(int field_43_virusinfo) + { + this.field_43_virusinfo = field_43_virusinfo; + } + + /** + * Get the Spare field for the DOP record. + */ + public byte[] GetSpare() + { + return field_44_Spare; + } + + /** + * Set the Spare field for the DOP record. + */ + public void SetSpare(byte[] field_44_Spare) + { + this.field_44_Spare = field_44_Spare; + } + + /** + * Get the reserved1 field for the DOP record. + */ + public int GetReserved1() + { + return field_45_reserved1; + } + + /** + * Set the reserved1 field for the DOP record. + */ + public void SetReserved1(int field_45_reserved1) + { + this.field_45_reserved1 = field_45_reserved1; + } + + /** + * Get the reserved2 field for the DOP record. + */ + public int GetReserved2() + { + return field_46_reserved2; + } + + /** + * Set the reserved2 field for the DOP record. + */ + public void SetReserved2(int field_46_reserved2) + { + this.field_46_reserved2 = field_46_reserved2; + } + + /** + * Get the cDBC field for the DOP record. + */ + public int GetCDBC() + { + return field_47_cDBC; + } + + /** + * Set the cDBC field for the DOP record. + */ + public void SetCDBC(int field_47_cDBC) + { + this.field_47_cDBC = field_47_cDBC; + } + + /** + * Get the cDBCFtnEdn field for the DOP record. + */ + public int GetCDBCFtnEdn() + { + return field_48_cDBCFtnEdn; + } + + /** + * Set the cDBCFtnEdn field for the DOP record. + */ + public void SetCDBCFtnEdn(int field_48_cDBCFtnEdn) + { + this.field_48_cDBCFtnEdn = field_48_cDBCFtnEdn; + } + + /** + * Get the reserved field for the DOP record. + */ + public int GetReserved() + { + return field_49_reserved; + } + + /** + * Set the reserved field for the DOP record. + */ + public void SetReserved(int field_49_reserved) + { + this.field_49_reserved = field_49_reserved; + } + + /** + * Get the nfcFtnRef field for the DOP record. + */ + public short GetNfcFtnRef() + { + return field_50_nfcFtnRef; + } + + /** + * Set the nfcFtnRef field for the DOP record. + */ + public void SetNfcFtnRef(short field_50_nfcFtnRef) + { + this.field_50_nfcFtnRef = field_50_nfcFtnRef; + } + + /** + * Get the nfcEdnRef field for the DOP record. + */ + public short GetNfcEdnRef() + { + return field_51_nfcEdnRef; + } + + /** + * Set the nfcEdnRef field for the DOP record. + */ + public void SetNfcEdnRef(short field_51_nfcEdnRef) + { + this.field_51_nfcEdnRef = field_51_nfcEdnRef; + } + + /** + * Get the hpsZoonFontPag field for the DOP record. + */ + public short GetHpsZoonFontPag() + { + return field_52_hpsZoonFontPag; + } + + /** + * Set the hpsZoonFontPag field for the DOP record. + */ + public void SetHpsZoonFontPag(short field_52_hpsZoonFontPag) + { + this.field_52_hpsZoonFontPag = field_52_hpsZoonFontPag; + } + + /** + * Get the dywDispPag field for the DOP record. + */ + public short GetDywDispPag() + { + return field_53_dywDispPag; + } + + /** + * Set the dywDispPag field for the DOP record. + */ + public void SetDywDispPag(short field_53_dywDispPag) + { + this.field_53_dywDispPag = field_53_dywDispPag; + } + + /** + * Sets the fFacingPages field value. + * + */ + public void SetFFacingPages(bool value) + { + field_1_formatFlags = (byte)fFacingPages.SetBoolean(field_1_formatFlags, value); + + + } + + /** + * + * @return the fFacingPages field value. + */ + public bool IsFFacingPages() + { + return fFacingPages.IsSet(field_1_formatFlags); + + } + + /** + * Sets the fWidowControl field value. + * + */ + public void SetFWidowControl(bool value) + { + field_1_formatFlags = (byte)fWidowControl.SetBoolean(field_1_formatFlags, value); + + + } + + /** + * + * @return the fWidowControl field value. + */ + public bool IsFWidowControl() + { + return fWidowControl.IsSet(field_1_formatFlags); + + } + + /** + * Sets the fPMHMainDoc field value. + * + */ + public void SetFPMHMainDoc(bool value) + { + field_1_formatFlags = (byte)fPMHMainDoc.SetBoolean(field_1_formatFlags, value); + + + } + + /** + * + * @return the fPMHMainDoc field value. + */ + public bool IsFPMHMainDoc() + { + return fPMHMainDoc.IsSet(field_1_formatFlags); + + } + + /** + * Sets the grfSupression field value. + * + */ + public void SetGrfSupression(byte value) + { + field_1_formatFlags = (byte)grfSupression.SetValue(field_1_formatFlags, value); + + + } + + /** + * + * @return the grfSupression field value. + */ + public byte GetGrfSupression() + { + return (byte)grfSupression.GetValue(field_1_formatFlags); + + } + + /** + * Sets the fpc field value. + * + */ + public void SetFpc(byte value) + { + field_1_formatFlags = (byte)fpc.SetValue(field_1_formatFlags, value); + + + } + + /** + * + * @return the fpc field value. + */ + public byte GetFpc() + { + return (byte)fpc.GetValue(field_1_formatFlags); + + } + + /** + * Sets the unused1 field value. + * + */ + public void SetUnused1(bool value) + { + field_1_formatFlags = (byte)unused1.SetBoolean(field_1_formatFlags, value); + + + } + + /** + * + * @return the unused1 field value. + */ + public bool IsUnused1() + { + return unused1.IsSet(field_1_formatFlags); + + } + + /** + * Sets the rncFtn field value. + * + */ + public void SetRncFtn(byte value) + { + field_3_footnoteInfo = (short)rncFtn.SetValue(field_3_footnoteInfo, value); + + + } + + /** + * + * @return the rncFtn field value. + */ + public byte GetRncFtn() + { + return (byte)rncFtn.GetValue(field_3_footnoteInfo); + + } + + /** + * Sets the nFtn field value. + * + */ + public void SetNFtn(short value) + { + field_3_footnoteInfo = (short)nFtn.SetValue(field_3_footnoteInfo, value); + + + } + + /** + * + * @return the nFtn field value. + */ + public short GetNFtn() + { + return (short)nFtn.GetValue(field_3_footnoteInfo); + + } + + /** + * Sets the fOnlyMacPics field value. + * + */ + public void SetFOnlyMacPics(bool value) + { + field_5_docinfo = (byte)fOnlyMacPics.SetBoolean(field_5_docinfo, value); + + + } + + /** + * + * @return the fOnlyMacPics field value. + */ + public bool IsFOnlyMacPics() + { + return fOnlyMacPics.IsSet(field_5_docinfo); + + } + + /** + * Sets the fOnlyWinPics field value. + * + */ + public void SetFOnlyWinPics(bool value) + { + field_5_docinfo = (byte)fOnlyWinPics.SetBoolean(field_5_docinfo, value); + + + } + + /** + * + * @return the fOnlyWinPics field value. + */ + public bool IsFOnlyWinPics() + { + return fOnlyWinPics.IsSet(field_5_docinfo); + + } + + /** + * Sets the fLabelDoc field value. + * + */ + public void SetFLabelDoc(bool value) + { + field_5_docinfo = (byte)fLabelDoc.SetBoolean(field_5_docinfo, value); + + + } + + /** + * + * @return the fLabelDoc field value. + */ + public bool IsFLabelDoc() + { + return fLabelDoc.IsSet(field_5_docinfo); + + } + + /** + * Sets the fHyphCapitals field value. + * + */ + public void SetFHyphCapitals(bool value) + { + field_5_docinfo = (byte)fHyphCapitals.SetBoolean(field_5_docinfo, value); + + + } + + /** + * + * @return the fHyphCapitals field value. + */ + public bool IsFHyphCapitals() + { + return fHyphCapitals.IsSet(field_5_docinfo); + + } + + /** + * Sets the fAutoHyphen field value. + * + */ + public void SetFAutoHyphen(bool value) + { + field_5_docinfo = (byte)fAutoHyphen.SetBoolean(field_5_docinfo, value); + + + } + + /** + * + * @return the fAutoHyphen field value. + */ + public bool IsFAutoHyphen() + { + return fAutoHyphen.IsSet(field_5_docinfo); + + } + + /** + * Sets the fFormNoFields field value. + * + */ + public void SetFFormNoFields(bool value) + { + field_5_docinfo = (byte)fFormNoFields.SetBoolean(field_5_docinfo, value); + + + } + + /** + * + * @return the fFormNoFields field value. + */ + public bool IsFFormNoFields() + { + return fFormNoFields.IsSet(field_5_docinfo); + + } + + /** + * Sets the fLinkStyles field value. + * + */ + public void SetFLinkStyles(bool value) + { + field_5_docinfo = (byte)fLinkStyles.SetBoolean(field_5_docinfo, value); + + + } + + /** + * + * @return the fLinkStyles field value. + */ + public bool IsFLinkStyles() + { + return fLinkStyles.IsSet(field_5_docinfo); + + } + + /** + * Sets the fRevMarking field value. + * + */ + public void SetFRevMarking(bool value) + { + field_5_docinfo = (byte)fRevMarking.SetBoolean(field_5_docinfo, value); + + + } + + /** + * + * @return the fRevMarking field value. + */ + public bool IsFRevMarking() + { + return fRevMarking.IsSet(field_5_docinfo); + + } + + /** + * Sets the fBackup field value. + * + */ + public void SetFBackup(bool value) + { + field_6_docinfo1 = (byte)fBackup.SetBoolean(field_6_docinfo1, value); + + + } + + /** + * + * @return the fBackup field value. + */ + public bool IsFBackup() + { + return fBackup.IsSet(field_6_docinfo1); + + } + + /** + * Sets the fExactCWords field value. + * + */ + public void SetFExactCWords(bool value) + { + field_6_docinfo1 = (byte)fExactCWords.SetBoolean(field_6_docinfo1, value); + + + } + + /** + * + * @return the fExactCWords field value. + */ + public bool IsFExactCWords() + { + return fExactCWords.IsSet(field_6_docinfo1); + + } + + /** + * Sets the fPagHidden field value. + * + */ + public void SetFPagHidden(bool value) + { + field_6_docinfo1 = (byte)fPagHidden.SetBoolean(field_6_docinfo1, value); + + + } + + /** + * + * @return the fPagHidden field value. + */ + public bool IsFPagHidden() + { + return fPagHidden.IsSet(field_6_docinfo1); + + } + + /** + * Sets the fPagResults field value. + * + */ + public void SetFPagResults(bool value) + { + field_6_docinfo1 = (byte)fPagResults.SetBoolean(field_6_docinfo1, value); + + + } + + /** + * + * @return the fPagResults field value. + */ + public bool IsFPagResults() + { + return fPagResults.IsSet(field_6_docinfo1); + + } + + /** + * Sets the fLockAtn field value. + * + */ + public void SetFLockAtn(bool value) + { + field_6_docinfo1 = (byte)fLockAtn.SetBoolean(field_6_docinfo1, value); + + + } + + /** + * + * @return the fLockAtn field value. + */ + public bool IsFLockAtn() + { + return fLockAtn.IsSet(field_6_docinfo1); + + } + + /** + * Sets the fMirrorMargins field value. + * + */ + public void SetFMirrorMargins(bool value) + { + field_6_docinfo1 = (byte)fMirrorMargins.SetBoolean(field_6_docinfo1, value); + + + } + + /** + * + * @return the fMirrorMargins field value. + */ + public bool IsFMirrorMargins() + { + return fMirrorMargins.IsSet(field_6_docinfo1); + + } + + /** + * Sets the unused3 field value. + * + */ + public void SetUnused3(bool value) + { + field_6_docinfo1 = (byte)unused3.SetBoolean(field_6_docinfo1, value); + + + } + + /** + * + * @return the unused3 field value. + */ + public bool IsUnused3() + { + return unused3.IsSet(field_6_docinfo1); + + } + + /** + * Sets the fDfltTrueType field value. + * + */ + public void SetFDfltTrueType(bool value) + { + field_6_docinfo1 = (byte)fDfltTrueType.SetBoolean(field_6_docinfo1, value); + + + } + + /** + * + * @return the fDfltTrueType field value. + */ + public bool IsFDfltTrueType() + { + return fDfltTrueType.IsSet(field_6_docinfo1); + + } + + /** + * Sets the fPagSupressTopSpacing field value. + * + */ + public void SetFPagSupressTopSpacing(bool value) + { + field_7_docinfo2 = (byte)fPagSupressTopSpacing.SetBoolean(field_7_docinfo2, value); + + + } + + /** + * + * @return the fPagSupressTopSpacing field value. + */ + public bool IsFPagSupressTopSpacing() + { + return fPagSupressTopSpacing.IsSet(field_7_docinfo2); + + } + + /** + * Sets the fProtEnabled field value. + * + */ + public void SetFProtEnabled(bool value) + { + field_7_docinfo2 = (byte)fProtEnabled.SetBoolean(field_7_docinfo2, value); + + + } + + /** + * + * @return the fProtEnabled field value. + */ + public bool IsFProtEnabled() + { + return fProtEnabled.IsSet(field_7_docinfo2); + + } + + /** + * Sets the fDispFormFldSel field value. + * + */ + public void SetFDispFormFldSel(bool value) + { + field_7_docinfo2 = (byte)fDispFormFldSel.SetBoolean(field_7_docinfo2, value); + + + } + + /** + * + * @return the fDispFormFldSel field value. + */ + public bool IsFDispFormFldSel() + { + return fDispFormFldSel.IsSet(field_7_docinfo2); + + } + + /** + * Sets the fRMView field value. + * + */ + public void SetFRMView(bool value) + { + field_7_docinfo2 = (byte)fRMView.SetBoolean(field_7_docinfo2, value); + + + } + + /** + * + * @return the fRMView field value. + */ + public bool IsFRMView() + { + return fRMView.IsSet(field_7_docinfo2); + + } + + /** + * Sets the fRMPrint field value. + * + */ + public void SetFRMPrint(bool value) + { + field_7_docinfo2 = (byte)fRMPrint.SetBoolean(field_7_docinfo2, value); + + + } + + /** + * + * @return the fRMPrint field value. + */ + public bool IsFRMPrint() + { + return fRMPrint.IsSet(field_7_docinfo2); + + } + + /** + * Sets the unused4 field value. + * + */ + public void SetUnused4(bool value) + { + field_7_docinfo2 = (byte)unused4.SetBoolean(field_7_docinfo2, value); + + + } + + /** + * + * @return the unused4 field value. + */ + public bool IsUnused4() + { + return unused4.IsSet(field_7_docinfo2); + + } + + /** + * Sets the fLockRev field value. + * + */ + public void SetFLockRev(bool value) + { + field_7_docinfo2 = (byte)fLockRev.SetBoolean(field_7_docinfo2, value); + + + } + + /** + * + * @return the fLockRev field value. + */ + public bool IsFLockRev() + { + return fLockRev.IsSet(field_7_docinfo2); + + } + + /** + * Sets the fEmbedFonts field value. + * + */ + public void SetFEmbedFonts(bool value) + { + field_7_docinfo2 = (byte)fEmbedFonts.SetBoolean(field_7_docinfo2, value); + + + } + + /** + * + * @return the fEmbedFonts field value. + */ + public bool IsFEmbedFonts() + { + return fEmbedFonts.IsSet(field_7_docinfo2); + + } + + /** + * Sets the oldfNoTabForInd field value. + * + */ + public void SetOldfNoTabForInd(bool value) + { + field_8_docinfo3 = (short)oldfNoTabForInd.SetBoolean(field_8_docinfo3, value); + + + } + + /** + * + * @return the oldfNoTabForInd field value. + */ + public bool IsOldfNoTabForInd() + { + return oldfNoTabForInd.IsSet(field_8_docinfo3); + + } + + /** + * Sets the oldfNoSpaceRaiseLower field value. + * + */ + public void SetOldfNoSpaceRaiseLower(bool value) + { + field_8_docinfo3 = (short)oldfNoSpaceRaiseLower.SetBoolean(field_8_docinfo3, value); + + + } + + /** + * + * @return the oldfNoSpaceRaiseLower field value. + */ + public bool IsOldfNoSpaceRaiseLower() + { + return oldfNoSpaceRaiseLower.IsSet(field_8_docinfo3); + + } + + /** + * Sets the oldfSuppressSpbfAfterPageBreak field value. + * + */ + public void SetOldfSuppressSpbfAfterPageBreak(bool value) + { + field_8_docinfo3 = (short)oldfSuppressSpbfAfterPageBreak.SetBoolean(field_8_docinfo3, value); + + + } + + /** + * + * @return the oldfSuppressSpbfAfterPageBreak field value. + */ + public bool IsOldfSuppressSpbfAfterPageBreak() + { + return oldfSuppressSpbfAfterPageBreak.IsSet(field_8_docinfo3); + + } + + /** + * Sets the oldfWrapTrailSpaces field value. + * + */ + public void SetOldfWrapTrailSpaces(bool value) + { + field_8_docinfo3 = (short)oldfWrapTrailSpaces.SetBoolean(field_8_docinfo3, value); + + + } + + /** + * + * @return the oldfWrapTrailSpaces field value. + */ + public bool IsOldfWrapTrailSpaces() + { + return oldfWrapTrailSpaces.IsSet(field_8_docinfo3); + + } + + /** + * Sets the oldfMapPrintTextColor field value. + * + */ + public void SetOldfMapPrintTextColor(bool value) + { + field_8_docinfo3 = (short)oldfMapPrintTextColor.SetBoolean(field_8_docinfo3, value); + + + } + + /** + * + * @return the oldfMapPrintTextColor field value. + */ + public bool IsOldfMapPrintTextColor() + { + return oldfMapPrintTextColor.IsSet(field_8_docinfo3); + + } + + /** + * Sets the oldfNoColumnBalance field value. + * + */ + public void SetOldfNoColumnBalance(bool value) + { + field_8_docinfo3 = (short)oldfNoColumnBalance.SetBoolean(field_8_docinfo3, value); + + + } + + /** + * + * @return the oldfNoColumnBalance field value. + */ + public bool IsOldfNoColumnBalance() + { + return oldfNoColumnBalance.IsSet(field_8_docinfo3); + + } + + /** + * Sets the oldfConvMailMergeEsc field value. + * + */ + public void SetOldfConvMailMergeEsc(bool value) + { + field_8_docinfo3 = (short)oldfConvMailMergeEsc.SetBoolean(field_8_docinfo3, value); + + + } + + /** + * + * @return the oldfConvMailMergeEsc field value. + */ + public bool IsOldfConvMailMergeEsc() + { + return oldfConvMailMergeEsc.IsSet(field_8_docinfo3); + + } + + /** + * Sets the oldfSupressTopSpacing field value. + * + */ + public void SetOldfSupressTopSpacing(bool value) + { + field_8_docinfo3 = (short)oldfSupressTopSpacing.SetBoolean(field_8_docinfo3, value); + + + } + + /** + * + * @return the oldfSupressTopSpacing field value. + */ + public bool IsOldfSupressTopSpacing() + { + return oldfSupressTopSpacing.IsSet(field_8_docinfo3); + + } + + /** + * Sets the oldfOrigWordTableRules field value. + * + */ + public void SetOldfOrigWordTableRules(bool value) + { + field_8_docinfo3 = (short)oldfOrigWordTableRules.SetBoolean(field_8_docinfo3, value); + + + } + + /** + * + * @return the oldfOrigWordTableRules field value. + */ + public bool IsOldfOrigWordTableRules() + { + return oldfOrigWordTableRules.IsSet(field_8_docinfo3); + + } + + /** + * Sets the oldfTransparentMetafiles field value. + * + */ + public void SetOldfTransparentMetafiles(bool value) + { + field_8_docinfo3 = (short)oldfTransparentMetafiles.SetBoolean(field_8_docinfo3, value); + + + } + + /** + * + * @return the oldfTransparentMetafiles field value. + */ + public bool IsOldfTransparentMetafiles() + { + return oldfTransparentMetafiles.IsSet(field_8_docinfo3); + + } + + /** + * Sets the oldfShowBreaksInFrames field value. + * + */ + public void SetOldfShowBreaksInFrames(bool value) + { + field_8_docinfo3 = (short)oldfShowBreaksInFrames.SetBoolean(field_8_docinfo3, value); + + + } + + /** + * + * @return the oldfShowBreaksInFrames field value. + */ + public bool IsOldfShowBreaksInFrames() + { + return oldfShowBreaksInFrames.IsSet(field_8_docinfo3); + + } + + /** + * Sets the oldfSwapBordersFacingPgs field value. + * + */ + public void SetOldfSwapBordersFacingPgs(bool value) + { + field_8_docinfo3 = (short)oldfSwapBordersFacingPgs.SetBoolean(field_8_docinfo3, value); + + + } + + /** + * + * @return the oldfSwapBordersFacingPgs field value. + */ + public bool IsOldfSwapBordersFacingPgs() + { + return oldfSwapBordersFacingPgs.IsSet(field_8_docinfo3); + + } + + /** + * Sets the unused5 field value. + * + */ + public void SetUnused5(byte value) + { + field_8_docinfo3 = (short)unused5.SetValue(field_8_docinfo3, value); + + + } + + /** + * + * @return the unused5 field value. + */ + public byte GetUnused5() + { + return (byte)unused5.GetValue(field_8_docinfo3); + + } + + /** + * Sets the rncEdn field value. + * + */ + public void SetRncEdn(byte value) + { + field_23_Edn = (short)rncEdn.SetValue(field_23_Edn, value); + + + } + + /** + * + * @return the rncEdn field value. + */ + public byte GetRncEdn() + { + return (byte)rncEdn.GetValue(field_23_Edn); + + } + + /** + * Sets the nEdn field value. + * + */ + public void SetNEdn(short value) + { + field_23_Edn = (short)nEdn.SetValue(field_23_Edn, value); + + + } + + /** + * + * @return the nEdn field value. + */ + public short GetNEdn() + { + return (short)nEdn.GetValue(field_23_Edn); + + } + + /** + * Sets the epc field value. + * + */ + public void SetEpc(byte value) + { + field_24_Edn1 = (short)epc.SetValue(field_24_Edn1, value); + + + } + + /** + * + * @return the epc field value. + */ + public byte GetEpc() + { + return (byte)epc.GetValue(field_24_Edn1); + + } + + /** + * Sets the nfcFtnRef1 field value. + * + */ + public void SetNfcFtnRef1(byte value) + { + field_24_Edn1 = (short)nfcFtnRef1.SetValue(field_24_Edn1, value); + + + } + + /** + * + * @return the nfcFtnRef1 field value. + */ + public byte GetNfcFtnRef1() + { + return (byte)nfcFtnRef1.GetValue(field_24_Edn1); + + } + + /** + * Sets the nfcEdnRef1 field value. + * + */ + public void SetNfcEdnRef1(byte value) + { + field_24_Edn1 = (short)nfcEdnRef1.SetValue(field_24_Edn1, value); + + + } + + /** + * + * @return the nfcEdnRef1 field value. + */ + public byte GetNfcEdnRef1() + { + return (byte)nfcEdnRef1.GetValue(field_24_Edn1); + + } + + /** + * Sets the fPrintFormData field value. + * + */ + public void SetFPrintFormData(bool value) + { + field_24_Edn1 = (short)fPrintFormData.SetBoolean(field_24_Edn1, value); + + + } + + /** + * + * @return the fPrintFormData field value. + */ + public bool IsFPrintFormData() + { + return fPrintFormData.IsSet(field_24_Edn1); + + } + + /** + * Sets the fSaveFormData field value. + * + */ + public void SetFSaveFormData(bool value) + { + field_24_Edn1 = (short)fSaveFormData.SetBoolean(field_24_Edn1, value); + + + } + + /** + * + * @return the fSaveFormData field value. + */ + public bool IsFSaveFormData() + { + return fSaveFormData.IsSet(field_24_Edn1); + + } + + /** + * Sets the fShadeFormData field value. + * + */ + public void SetFShadeFormData(bool value) + { + field_24_Edn1 = (short)fShadeFormData.SetBoolean(field_24_Edn1, value); + + + } + + /** + * + * @return the fShadeFormData field value. + */ + public bool IsFShadeFormData() + { + return fShadeFormData.IsSet(field_24_Edn1); + + } + + /** + * Sets the fWCFtnEdn field value. + * + */ + public void SetFWCFtnEdn(bool value) + { + field_24_Edn1 = (short)fWCFtnEdn.SetBoolean(field_24_Edn1, value); + + + } + + /** + * + * @return the fWCFtnEdn field value. + */ + public bool IsFWCFtnEdn() + { + return fWCFtnEdn.IsSet(field_24_Edn1); + + } + + /** + * Sets the wvkSaved field value. + * + */ + public void SetWvkSaved(byte value) + { + field_32_view = (short)wvkSaved.SetValue(field_32_view, value); + + + } + + /** + * + * @return the wvkSaved field value. + */ + public byte GetWvkSaved() + { + return (byte)wvkSaved.GetValue(field_32_view); + + } + + /** + * Sets the wScaleSaved field value. + * + */ + public void SetWScaleSaved(short value) + { + field_32_view = (short)wScaleSaved.SetValue(field_32_view, value); + + + } + + /** + * + * @return the wScaleSaved field value. + */ + public short GetWScaleSaved() + { + return (short)wScaleSaved.GetValue(field_32_view); + + } + + /** + * Sets the zkSaved field value. + * + */ + public void SetZkSaved(byte value) + { + field_32_view = (short)zkSaved.SetValue(field_32_view, value); + + + } + + /** + * + * @return the zkSaved field value. + */ + public byte GetZkSaved() + { + return (byte)zkSaved.GetValue(field_32_view); + + } + + /** + * Sets the fRotateFontW6 field value. + * + */ + public void SetFRotateFontW6(bool value) + { + field_32_view = (short)fRotateFontW6.SetBoolean(field_32_view, value); + + + } + + /** + * + * @return the fRotateFontW6 field value. + */ + public bool IsFRotateFontW6() + { + return fRotateFontW6.IsSet(field_32_view); + + } + + /** + * Sets the iGutterPos field value. + * + */ + public void SetIGutterPos(bool value) + { + field_32_view = (short)iGutterPos.SetBoolean(field_32_view, value); + + + } + + /** + * + * @return the iGutterPos field value. + */ + public bool IsIGutterPos() + { + return iGutterPos.IsSet(field_32_view); + + } + + /** + * Sets the fNoTabForInd field value. + * + */ + public void SetFNoTabForInd(bool value) + { + field_33_docinfo4 = (int)fNoTabForInd.SetBoolean(field_33_docinfo4, value); + + + } + + /** + * + * @return the fNoTabForInd field value. + */ + public bool IsFNoTabForInd() + { + return fNoTabForInd.IsSet(field_33_docinfo4); + + } + + /** + * Sets the fNoSpaceRaiseLower field value. + * + */ + public void SetFNoSpaceRaiseLower(bool value) + { + field_33_docinfo4 = (int)fNoSpaceRaiseLower.SetBoolean(field_33_docinfo4, value); + + + } + + /** + * + * @return the fNoSpaceRaiseLower field value. + */ + public bool IsFNoSpaceRaiseLower() + { + return fNoSpaceRaiseLower.IsSet(field_33_docinfo4); + + } + + /** + * Sets the fSupressSpdfAfterPageBreak field value. + * + */ + public void SetFSupressSpdfAfterPageBreak(bool value) + { + field_33_docinfo4 = (int)fSupressSpdfAfterPageBreak.SetBoolean(field_33_docinfo4, value); + + + } + + /** + * + * @return the fSupressSpdfAfterPageBreak field value. + */ + public bool IsFSupressSpdfAfterPageBreak() + { + return fSupressSpdfAfterPageBreak.IsSet(field_33_docinfo4); + + } + + /** + * Sets the fWrapTrailSpaces field value. + * + */ + public void SetFWrapTrailSpaces(bool value) + { + field_33_docinfo4 = (int)fWrapTrailSpaces.SetBoolean(field_33_docinfo4, value); + + + } + + /** + * + * @return the fWrapTrailSpaces field value. + */ + public bool IsFWrapTrailSpaces() + { + return fWrapTrailSpaces.IsSet(field_33_docinfo4); + + } + + /** + * Sets the fMapPrintTextColor field value. + * + */ + public void SetFMapPrintTextColor(bool value) + { + field_33_docinfo4 = (int)fMapPrintTextColor.SetBoolean(field_33_docinfo4, value); + + + } + + /** + * + * @return the fMapPrintTextColor field value. + */ + public bool IsFMapPrintTextColor() + { + return fMapPrintTextColor.IsSet(field_33_docinfo4); + + } + + /** + * Sets the fNoColumnBalance field value. + * + */ + public void SetFNoColumnBalance(bool value) + { + field_33_docinfo4 = (int)fNoColumnBalance.SetBoolean(field_33_docinfo4, value); + + + } + + /** + * + * @return the fNoColumnBalance field value. + */ + public bool IsFNoColumnBalance() + { + return fNoColumnBalance.IsSet(field_33_docinfo4); + + } + + /** + * Sets the fConvMailMergeEsc field value. + * + */ + public void SetFConvMailMergeEsc(bool value) + { + field_33_docinfo4 = (int)fConvMailMergeEsc.SetBoolean(field_33_docinfo4, value); + + + } + + /** + * + * @return the fConvMailMergeEsc field value. + */ + public bool IsFConvMailMergeEsc() + { + return fConvMailMergeEsc.IsSet(field_33_docinfo4); + + } + + /** + * Sets the fSupressTopSpacing field value. + * + */ + public void SetFSupressTopSpacing(bool value) + { + field_33_docinfo4 = (int)fSupressTopSpacing.SetBoolean(field_33_docinfo4, value); + + + } + + /** + * + * @return the fSupressTopSpacing field value. + */ + public bool IsFSupressTopSpacing() + { + return fSupressTopSpacing.IsSet(field_33_docinfo4); + + } + + /** + * Sets the fOrigWordTableRules field value. + * + */ + public void SetFOrigWordTableRules(bool value) + { + field_33_docinfo4 = (int)fOrigWordTableRules.SetBoolean(field_33_docinfo4, value); + + + } + + /** + * + * @return the fOrigWordTableRules field value. + */ + public bool IsFOrigWordTableRules() + { + return fOrigWordTableRules.IsSet(field_33_docinfo4); + + } + + /** + * Sets the fTransparentMetafiles field value. + * + */ + public void SetFTransparentMetafiles(bool value) + { + field_33_docinfo4 = (int)fTransparentMetafiles.SetBoolean(field_33_docinfo4, value); + + + } + + /** + * + * @return the fTransparentMetafiles field value. + */ + public bool IsFTransparentMetafiles() + { + return fTransparentMetafiles.IsSet(field_33_docinfo4); + + } + + /** + * Sets the fShowBreaksInFrames field value. + * + */ + public void SetFShowBreaksInFrames(bool value) + { + field_33_docinfo4 = (int)fShowBreaksInFrames.SetBoolean(field_33_docinfo4, value); + + + } + + /** + * + * @return the fShowBreaksInFrames field value. + */ + public bool IsFShowBreaksInFrames() + { + return fShowBreaksInFrames.IsSet(field_33_docinfo4); + + } + + /** + * Sets the fSwapBordersFacingPgs field value. + * + */ + public void SetFSwapBordersFacingPgs(bool value) + { + field_33_docinfo4 = (int)fSwapBordersFacingPgs.SetBoolean(field_33_docinfo4, value); + + + } + + /** + * + * @return the fSwapBordersFacingPgs field value. + */ + public bool IsFSwapBordersFacingPgs() + { + return fSwapBordersFacingPgs.IsSet(field_33_docinfo4); + + } + + /** + * Sets the fSuppressTopSPacingMac5 field value. + * + */ + public void SetFSuppressTopSPacingMac5(bool value) + { + field_33_docinfo4 = (int)fSuppressTopSPacingMac5.SetBoolean(field_33_docinfo4, value); + + + } + + /** + * + * @return the fSuppressTopSPacingMac5 field value. + */ + public bool IsFSuppressTopSPacingMac5() + { + return fSuppressTopSPacingMac5.IsSet(field_33_docinfo4); + + } + + /** + * Sets the fTruncDxaExpand field value. + * + */ + public void SetFTruncDxaExpand(bool value) + { + field_33_docinfo4 = (int)fTruncDxaExpand.SetBoolean(field_33_docinfo4, value); + + + } + + /** + * + * @return the fTruncDxaExpand field value. + */ + public bool IsFTruncDxaExpand() + { + return fTruncDxaExpand.IsSet(field_33_docinfo4); + + } + + /** + * Sets the fPrintBodyBeforeHdr field value. + * + */ + public void SetFPrintBodyBeforeHdr(bool value) + { + field_33_docinfo4 = (int)fPrintBodyBeforeHdr.SetBoolean(field_33_docinfo4, value); + + + } + + /** + * + * @return the fPrintBodyBeforeHdr field value. + */ + public bool IsFPrintBodyBeforeHdr() + { + return fPrintBodyBeforeHdr.IsSet(field_33_docinfo4); + + } + + /** + * Sets the fNoLeading field value. + * + */ + public void SetFNoLeading(bool value) + { + field_33_docinfo4 = (int)fNoLeading.SetBoolean(field_33_docinfo4, value); + + + } + + /** + * + * @return the fNoLeading field value. + */ + public bool IsFNoLeading() + { + return fNoLeading.IsSet(field_33_docinfo4); + + } + + /** + * Sets the fMWSmallCaps field value. + * + */ + public void SetFMWSmallCaps(bool value) + { + field_33_docinfo4 = (int)fMWSmallCaps.SetBoolean(field_33_docinfo4, value); + + + } + + /** + * + * @return the fMWSmallCaps field value. + */ + public bool IsFMWSmallCaps() + { + return fMWSmallCaps.IsSet(field_33_docinfo4); + + } + + /** + * Sets the lvl field value. + * + */ + public void SetLvl(byte value) + { + field_37_docinfo5 = (short)lvl.SetValue(field_37_docinfo5, value); + + + } + + /** + * + * @return the lvl field value. + */ + public byte GetLvl() + { + return (byte)lvl.GetValue(field_37_docinfo5); + + } + + /** + * Sets the fGramAllDone field value. + * + */ + public void SetFGramAllDone(bool value) + { + field_37_docinfo5 = (short)fGramAllDone.SetBoolean(field_37_docinfo5, value); + + + } + + /** + * + * @return the fGramAllDone field value. + */ + public bool IsFGramAllDone() + { + return fGramAllDone.IsSet(field_37_docinfo5); + + } + + /** + * Sets the fGramAllClean field value. + * + */ + public void SetFGramAllClean(bool value) + { + field_37_docinfo5 = (short)fGramAllClean.SetBoolean(field_37_docinfo5, value); + + + } + + /** + * + * @return the fGramAllClean field value. + */ + public bool IsFGramAllClean() + { + return fGramAllClean.IsSet(field_37_docinfo5); + + } + + /** + * Sets the fSubsetFonts field value. + * + */ + public void SetFSubsetFonts(bool value) + { + field_37_docinfo5 = (short)fSubsetFonts.SetBoolean(field_37_docinfo5, value); + + + } + + /** + * + * @return the fSubsetFonts field value. + */ + public bool IsFSubsetFonts() + { + return fSubsetFonts.IsSet(field_37_docinfo5); + + } + + /** + * Sets the fHideLastVersion field value. + * + */ + public void SetFHideLastVersion(bool value) + { + field_37_docinfo5 = (short)fHideLastVersion.SetBoolean(field_37_docinfo5, value); + + + } + + /** + * + * @return the fHideLastVersion field value. + */ + public bool IsFHideLastVersion() + { + return fHideLastVersion.IsSet(field_37_docinfo5); + + } + + /** + * Sets the fHtmlDoc field value. + * + */ + public void SetFHtmlDoc(bool value) + { + field_37_docinfo5 = (short)fHtmlDoc.SetBoolean(field_37_docinfo5, value); + + + } + + /** + * + * @return the fHtmlDoc field value. + */ + public bool IsFHtmlDoc() + { + return fHtmlDoc.IsSet(field_37_docinfo5); + + } + + /** + * Sets the fSnapBorder field value. + * + */ + public void SetFSnapBorder(bool value) + { + field_37_docinfo5 = (short)fSnapBorder.SetBoolean(field_37_docinfo5, value); + + + } + + /** + * + * @return the fSnapBorder field value. + */ + public bool IsFSnapBorder() + { + return fSnapBorder.IsSet(field_37_docinfo5); + + } + + /** + * Sets the fIncludeHeader field value. + * + */ + public void SetFIncludeHeader(bool value) + { + field_37_docinfo5 = (short)fIncludeHeader.SetBoolean(field_37_docinfo5, value); + + + } + + /** + * + * @return the fIncludeHeader field value. + */ + public bool IsFIncludeHeader() + { + return fIncludeHeader.IsSet(field_37_docinfo5); + + } + + /** + * Sets the fIncludeFooter field value. + * + */ + public void SetFIncludeFooter(bool value) + { + field_37_docinfo5 = (short)fIncludeFooter.SetBoolean(field_37_docinfo5, value); + + + } + + /** + * + * @return the fIncludeFooter field value. + */ + public bool IsFIncludeFooter() + { + return fIncludeFooter.IsSet(field_37_docinfo5); + + } + + /** + * Sets the fForcePageSizePag field value. + * + */ + public void SetFForcePageSizePag(bool value) + { + field_37_docinfo5 = (short)fForcePageSizePag.SetBoolean(field_37_docinfo5, value); + + + } + + /** + * + * @return the fForcePageSizePag field value. + */ + public bool IsFForcePageSizePag() + { + return fForcePageSizePag.IsSet(field_37_docinfo5); + + } + + /** + * Sets the fMinFontSizePag field value. + * + */ + public void SetFMinFontSizePag(bool value) + { + field_37_docinfo5 = (short)fMinFontSizePag.SetBoolean(field_37_docinfo5, value); + + + } + + /** + * + * @return the fMinFontSizePag field value. + */ + public bool IsFMinFontSizePag() + { + return fMinFontSizePag.IsSet(field_37_docinfo5); + + } + + /** + * Sets the fHaveVersions field value. + * + */ + public void SetFHaveVersions(bool value) + { + field_38_docinfo6 = (short)fHaveVersions.SetBoolean(field_38_docinfo6, value); + + + } + + /** + * + * @return the fHaveVersions field value. + */ + public bool IsFHaveVersions() + { + return fHaveVersions.IsSet(field_38_docinfo6); + + } + + /** + * Sets the fAutoVersions field value. + * + */ + public void SetFAutoVersions(bool value) + { + field_38_docinfo6 = (short)fAutoVersions.SetBoolean(field_38_docinfo6, value); + + + } + + /** + * + * @return the fAutoVersions field value. + */ + public bool IsFAutoVersions() + { + return fAutoVersions.IsSet(field_38_docinfo6); + + } + + /** + * Sets the fVirusPrompted field value. + * + */ + public void SetFVirusPrompted(bool value) + { + field_43_virusinfo = (int)fVirusPrompted.SetBoolean(field_43_virusinfo, value); + + + } + + /** + * + * @return the fVirusPrompted field value. + */ + public bool IsFVirusPrompted() + { + return fVirusPrompted.IsSet(field_43_virusinfo); + + } + + /** + * Sets the fVirusLoadSafe field value. + * + */ + public void SetFVirusLoadSafe(bool value) + { + field_43_virusinfo = (int)fVirusLoadSafe.SetBoolean(field_43_virusinfo, value); + + + } + + /** + * + * @return the fVirusLoadSafe field value. + */ + public bool IsFVirusLoadSafe() + { + return fVirusLoadSafe.IsSet(field_43_virusinfo); + + } + + /** + * Sets the KeyVirusSession30 field value. + * + */ + public void SetKeyVirusSession30(int value) + { + field_43_virusinfo = (int)KeyVirusSession30.SetValue(field_43_virusinfo, value); + + + } + + /** + * + * @return the KeyVirusSession30 field value. + */ + public int GetKeyVirusSession30() + { + return (int)KeyVirusSession30.GetValue(field_43_virusinfo); + + } + + + } +} + + diff --git a/scratchpad/HWPF/Model/Types/FIBAbstractType.cs b/scratchpad/HWPF/Model/Types/FIBAbstractType.cs new file mode 100644 index 0000000..7070f42 --- /dev/null +++ b/scratchpad/HWPF/Model/Types/FIBAbstractType.cs @@ -0,0 +1,823 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + + +namespace NPOI.HWPF.Model.Types +{ + + using System; + using NPOI.Util; + + using NPOI.HWPF.UserModel; + using System.Text; + /** + * Base part of the File information Block (FibBase). Holds the core part of the FIB, from the first 32 bytes. + * NOTE: This source Is automatically generated please do not modify this file. Either subclass or + * remove the record in src/records/definitions. + + * @author Andrew C. Oliver + */ + public abstract class FIBAbstractType : BaseObject + { + + protected int field_1_wIdent; + protected int field_2_nFib; + protected int field_3_nProduct; + protected int field_4_lid; + protected int field_5_pnNext; + protected short field_6_options; + private static BitField fDot = BitFieldFactory.GetInstance(0x0001); + private static BitField fGlsy = BitFieldFactory.GetInstance(0x0002); + private static BitField fComplex = BitFieldFactory.GetInstance(0x0004); + private static BitField fHasPic = BitFieldFactory.GetInstance(0x0008); + private static BitField cQuickSaves = BitFieldFactory.GetInstance(0x00F0); + private static BitField fEncrypted = BitFieldFactory.GetInstance(0x0100); + private static BitField fWhichTblStm = BitFieldFactory.GetInstance(0x0200); + private static BitField fReadOnlyRecommended = BitFieldFactory.GetInstance(0x0400); + private static BitField fWriteReservation = BitFieldFactory.GetInstance(0x0800); + private static BitField fExtChar = BitFieldFactory.GetInstance(0x1000); + private static BitField fLoadOverride = BitFieldFactory.GetInstance(0x2000); + private static BitField fFarEast = BitFieldFactory.GetInstance(0x4000); + private static BitField fCrypto = BitFieldFactory.GetInstance(0x8000); + protected int field_7_nFibBack; + protected int field_8_lKey; + protected int field_9_envr; + protected short field_10_history; + private static BitField fMac = BitFieldFactory.GetInstance(0x0001); + private static BitField fEmptySpecial = BitFieldFactory.GetInstance(0x0002); + private static BitField fLoadOverridePage = BitFieldFactory.GetInstance(0x0004); + private static BitField fFutureSavedUndo = BitFieldFactory.GetInstance(0x0008); + private static BitField fWord97Saved = BitFieldFactory.GetInstance(0x0010); + private static BitField fSpare0 = BitFieldFactory.GetInstance(0x00FE); + protected int field_11_chs; /** Latest docs say this Is Reserved3! */ + protected int field_12_chsTables; /** Latest docs say this Is Reserved4! */ + protected int field_13_fcMin; /** Latest docs say this Is Reserved5! */ + protected int field_14_fcMac; /** Latest docs say this Is Reserved6! */ + + + public FIBAbstractType() + { + + } + + protected void FillFields(byte[] data, int offset) + { + field_1_wIdent = LittleEndian.GetShort(data, 0x0 + offset); + field_2_nFib = LittleEndian.GetShort(data, 0x2 + offset); + field_3_nProduct = LittleEndian.GetShort(data, 0x4 + offset); + field_4_lid = LittleEndian.GetShort(data, 0x6 + offset); + field_5_pnNext = LittleEndian.GetShort(data, 0x8 + offset); + field_6_options = LittleEndian.GetShort(data, 0xa + offset); + field_7_nFibBack = LittleEndian.GetShort(data, 0xc + offset); + field_8_lKey = LittleEndian.GetShort(data, 0xe + offset); + field_9_envr = LittleEndian.GetShort(data, 0x10 + offset); + field_10_history = LittleEndian.GetShort(data, 0x12 + offset); + field_11_chs = LittleEndian.GetShort(data, 0x14 + offset); + field_12_chsTables = LittleEndian.GetShort(data, 0x16 + offset); + field_13_fcMin = LittleEndian.GetInt(data, 0x18 + offset); + field_14_fcMac = LittleEndian.GetInt(data, 0x1c + offset); + + } + + public void Serialize(byte[] data, int offset) + { + LittleEndian.PutShort(data, 0x0 + offset, (short)field_1_wIdent); ; + LittleEndian.PutShort(data, 0x2 + offset, (short)field_2_nFib); ; + LittleEndian.PutShort(data, 0x4 + offset, (short)field_3_nProduct); ; + LittleEndian.PutShort(data, 0x6 + offset, (short)field_4_lid); ; + LittleEndian.PutShort(data, 0x8 + offset, (short)field_5_pnNext); ; + LittleEndian.PutShort(data, 0xa + offset, (short)field_6_options); ; + LittleEndian.PutShort(data, 0xc + offset, (short)field_7_nFibBack); ; + LittleEndian.PutShort(data, 0xe + offset, (short)field_8_lKey); ; + LittleEndian.PutShort(data, 0x10 + offset, (short)field_9_envr); ; + LittleEndian.PutShort(data, 0x12 + offset, (short)field_10_history); ; + LittleEndian.PutShort(data, 0x14 + offset, (short)field_11_chs); ; + LittleEndian.PutShort(data, 0x16 + offset, (short)field_12_chsTables); ; + LittleEndian.PutInt(data, 0x18 + offset, field_13_fcMin); ; + LittleEndian.PutInt(data, 0x1c + offset, field_14_fcMac); ; + + } + + public override String ToString() + { + StringBuilder buffer = new StringBuilder(); + + buffer.Append("[FIB]\n"); + + buffer.Append(" .wIdent = "); + buffer.Append(" (").Append(GetWIdent()).Append(" )\n"); + + buffer.Append(" .nFib = "); + buffer.Append(" (").Append(GetNFib()).Append(" )\n"); + + buffer.Append(" .nProduct = "); + buffer.Append(" (").Append(GetNProduct()).Append(" )\n"); + + buffer.Append(" .lid = "); + buffer.Append(" (").Append(GetLid()).Append(" )\n"); + + buffer.Append(" .pnNext = "); + buffer.Append(" (").Append(GetPnNext()).Append(" )\n"); + + buffer.Append(" .options = "); + buffer.Append(" (").Append(GetOptions()).Append(" )\n"); + buffer.Append(" .fDot = ").Append(IsFDot()).Append('\n'); + buffer.Append(" .fGlsy = ").Append(IsFGlsy()).Append('\n'); + buffer.Append(" .fComplex = ").Append(IsFComplex()).Append('\n'); + buffer.Append(" .fHasPic = ").Append(IsFHasPic()).Append('\n'); + buffer.Append(" .cQuickSaves = ").Append(GetCQuickSaves()).Append('\n'); + buffer.Append(" .fEncrypted = ").Append(IsFEncrypted()).Append('\n'); + buffer.Append(" .fWhichTblStm = ").Append(IsFWhichTblStm()).Append('\n'); + buffer.Append(" .fReadOnlyRecommended = ").Append(IsFReadOnlyRecommended()).Append('\n'); + buffer.Append(" .fWriteReservation = ").Append(IsFWriteReservation()).Append('\n'); + buffer.Append(" .fExtChar = ").Append(IsFExtChar()).Append('\n'); + buffer.Append(" .fLoadOverride = ").Append(IsFLoadOverride()).Append('\n'); + buffer.Append(" .fFarEast = ").Append(IsFFarEast()).Append('\n'); + buffer.Append(" .fCrypto = ").Append(IsFCrypto()).Append('\n'); + + buffer.Append(" .nFibBack = "); + buffer.Append(" (").Append(GetNFibBack()).Append(" )\n"); + + buffer.Append(" .lKey = "); + buffer.Append(" (").Append(GetLKey()).Append(" )\n"); + + buffer.Append(" .envr = "); + buffer.Append(" (").Append(GetEnvr()).Append(" )\n"); + + buffer.Append(" .history = "); + buffer.Append(" (").Append(GetHistory()).Append(" )\n"); + buffer.Append(" .fMac = ").Append(IsFMac()).Append('\n'); + buffer.Append(" .fEmptySpecial = ").Append(IsFEmptySpecial()).Append('\n'); + buffer.Append(" .fLoadOverridePage = ").Append(IsFLoadOverridePage()).Append('\n'); + buffer.Append(" .fFutureSavedUndo = ").Append(IsFFutureSavedUndo()).Append('\n'); + buffer.Append(" .fWord97Saved = ").Append(IsFWord97Saved()).Append('\n'); + buffer.Append(" .fSpare0 = ").Append(GetFSpare0()).Append('\n'); + + buffer.Append(" .chs = "); + buffer.Append(" (").Append(GetChs()).Append(" )\n"); + + buffer.Append(" .chsTables = "); + buffer.Append(" (").Append(GetChsTables()).Append(" )\n"); + + buffer.Append(" .fcMin = "); + buffer.Append(" (").Append(GetFcMin()).Append(" )\n"); + + buffer.Append(" .fcMac = "); + buffer.Append(" (").Append(GetFcMac()).Append(" )\n"); + + buffer.Append("[/FIB]\n"); + return buffer.ToString(); + } + + /** + * Size of record (exluding 4 byte header) + */ + public virtual int GetSize() + { + return 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 4 + 4; + } + + + + /** + * Get the wIdent field for the FIB record. + */ + public int GetWIdent() + { + return field_1_wIdent; + } + + /** + * Set the wIdent field for the FIB record. + */ + public void SetWIdent(int field_1_wIdent) + { + this.field_1_wIdent = field_1_wIdent; + } + + /** + * Get the nFib field for the FIB record. + */ + public int GetNFib() + { + return field_2_nFib; + } + + /** + * Set the nFib field for the FIB record. + */ + public void SetNFib(int field_2_nFib) + { + this.field_2_nFib = field_2_nFib; + } + + /** + * Get the nProduct field for the FIB record. + */ + public int GetNProduct() + { + return field_3_nProduct; + } + + /** + * Set the nProduct field for the FIB record. + */ + public void SetNProduct(int field_3_nProduct) + { + this.field_3_nProduct = field_3_nProduct; + } + + /** + * Get the lid field for the FIB record. + */ + public int GetLid() + { + return field_4_lid; + } + + /** + * Set the lid field for the FIB record. + */ + public void SetLid(int field_4_lid) + { + this.field_4_lid = field_4_lid; + } + + /** + * Get the pnNext field for the FIB record. + */ + public int GetPnNext() + { + return field_5_pnNext; + } + + /** + * Set the pnNext field for the FIB record. + */ + public void SetPnNext(int field_5_pnNext) + { + this.field_5_pnNext = field_5_pnNext; + } + + /** + * Get the options field for the FIB record. + */ + public short GetOptions() + { + return field_6_options; + } + + /** + * Set the options field for the FIB record. + */ + public void SetOptions(short field_6_options) + { + this.field_6_options = field_6_options; + } + + /** + * Get the nFibBack field for the FIB record. + */ + public int GetNFibBack() + { + return field_7_nFibBack; + } + + /** + * Set the nFibBack field for the FIB record. + */ + public void SetNFibBack(int field_7_nFibBack) + { + this.field_7_nFibBack = field_7_nFibBack; + } + + /** + * Get the lKey field for the FIB record. + */ + public int GetLKey() + { + return field_8_lKey; + } + + /** + * Set the lKey field for the FIB record. + */ + public void SetLKey(int field_8_lKey) + { + this.field_8_lKey = field_8_lKey; + } + + /** + * Get the envr field for the FIB record. + */ + public int GetEnvr() + { + return field_9_envr; + } + + /** + * Set the envr field for the FIB record. + */ + public void SetEnvr(int field_9_envr) + { + this.field_9_envr = field_9_envr; + } + + /** + * Get the history field for the FIB record. + */ + public short GetHistory() + { + return field_10_history; + } + + /** + * Set the history field for the FIB record. + */ + public void SetHistory(short field_10_history) + { + this.field_10_history = field_10_history; + } + + /** + * Get the chs field for the FIB record. + */ + public int GetChs() + { + return field_11_chs; + } + + /** + * Set the chs field for the FIB record. + */ + public void SetChs(int field_11_chs) + { + this.field_11_chs = field_11_chs; + } + + /** + * Get the chsTables field for the FIB record. + */ + public int GetChsTables() + { + return field_12_chsTables; + } + + /** + * Set the chsTables field for the FIB record. + */ + public void SetChsTables(int field_12_chsTables) + { + this.field_12_chsTables = field_12_chsTables; + } + + /** + * Get the fcMin field for the FIB record. + */ + public int GetFcMin() + { + return field_13_fcMin; + } + + /** + * Set the fcMin field for the FIB record. + */ + public void SetFcMin(int field_13_fcMin) + { + this.field_13_fcMin = field_13_fcMin; + } + + /** + * Get the fcMac field for the FIB record. + */ + public int GetFcMac() + { + return field_14_fcMac; + } + + /** + * Set the fcMac field for the FIB record. + */ + public void SetFcMac(int field_14_fcMac) + { + this.field_14_fcMac = field_14_fcMac; + } + + /** + * Sets the fDot field value. + * + */ + public void SetFDot(bool value) + { + field_6_options = (short)fDot.SetBoolean(field_6_options, value); + + + } + + /** + * + * @return the fDot field value. + */ + public bool IsFDot() + { + return fDot.IsSet(field_6_options); + + } + + /** + * Sets the fGlsy field value. + * + */ + public void SetFGlsy(bool value) + { + field_6_options = (short)fGlsy.SetBoolean(field_6_options, value); + + + } + + /** + * + * @return the fGlsy field value. + */ + public bool IsFGlsy() + { + return fGlsy.IsSet(field_6_options); + + } + + /** + * Sets the fComplex field value. + * + */ + public void SetFComplex(bool value) + { + field_6_options = (short)fComplex.SetBoolean(field_6_options, value); + + + } + + /** + * + * @return the fComplex field value. + */ + public bool IsFComplex() + { + return fComplex.IsSet(field_6_options); + + } + + /** + * Sets the fHasPic field value. + * + */ + public void SetFHasPic(bool value) + { + field_6_options = (short)fHasPic.SetBoolean(field_6_options, value); + + + } + + /** + * + * @return the fHasPic field value. + */ + public bool IsFHasPic() + { + return fHasPic.IsSet(field_6_options); + + } + + /** + * Sets the cQuickSaves field value. + * + */ + public void SetCQuickSaves(byte value) + { + field_6_options = (short)cQuickSaves.SetValue(field_6_options, value); + + + } + + /** + * + * @return the cQuickSaves field value. + */ + public byte GetCQuickSaves() + { + return (byte)cQuickSaves.GetValue(field_6_options); + + } + + /** + * Sets the fEncrypted field value. + * + */ + public void SetFEncrypted(bool value) + { + field_6_options = (short)fEncrypted.SetBoolean(field_6_options, value); + + + } + + /** + * + * @return the fEncrypted field value. + */ + public bool IsFEncrypted() + { + return fEncrypted.IsSet(field_6_options); + + } + + /** + * Sets the fWhichTblStm field value. + * + */ + public void SetFWhichTblStm(bool value) + { + field_6_options = (short)fWhichTblStm.SetBoolean(field_6_options, value); + + + } + + /** + * + * @return the fWhichTblStm field value. + */ + public bool IsFWhichTblStm() + { + return fWhichTblStm.IsSet(field_6_options); + + } + + /** + * Sets the fReadOnlyRecommended field value. + * + */ + public void SetFReadOnlyRecommended(bool value) + { + field_6_options = (short)fReadOnlyRecommended.SetBoolean(field_6_options, value); + + + } + + /** + * + * @return the fReadOnlyRecommended field value. + */ + public bool IsFReadOnlyRecommended() + { + return fReadOnlyRecommended.IsSet(field_6_options); + + } + + /** + * Sets the fWriteReservation field value. + * + */ + public void SetFWriteReservation(bool value) + { + field_6_options = (short)fWriteReservation.SetBoolean(field_6_options, value); + + + } + + /** + * + * @return the fWriteReservation field value. + */ + public bool IsFWriteReservation() + { + return fWriteReservation.IsSet(field_6_options); + + } + + /** + * Sets the fExtChar field value. + * + */ + public void SetFExtChar(bool value) + { + field_6_options = (short)fExtChar.SetBoolean(field_6_options, value); + + + } + + /** + * + * @return the fExtChar field value. + */ + public bool IsFExtChar() + { + return fExtChar.IsSet(field_6_options); + + } + + /** + * Sets the fLoadOverride field value. + * + */ + public void SetFLoadOverride(bool value) + { + field_6_options = (short)fLoadOverride.SetBoolean(field_6_options, value); + + + } + + /** + * + * @return the fLoadOverride field value. + */ + public bool IsFLoadOverride() + { + return fLoadOverride.IsSet(field_6_options); + + } + + /** + * Sets the fFarEast field value. + * + */ + public void SetFFarEast(bool value) + { + field_6_options = (short)fFarEast.SetBoolean(field_6_options, value); + + + } + + /** + * + * @return the fFarEast field value. + */ + public bool IsFFarEast() + { + return fFarEast.IsSet(field_6_options); + + } + + /** + * Sets the fCrypto field value. + * + */ + public void SetFCrypto(bool value) + { + field_6_options = (short)fCrypto.SetBoolean(field_6_options, value); + + + } + + /** + * + * @return the fCrypto field value. + */ + public bool IsFCrypto() + { + return fCrypto.IsSet(field_6_options); + + } + + /** + * Sets the fMac field value. + * + */ + public void SetFMac(bool value) + { + field_10_history = (short)fMac.SetBoolean(field_10_history, value); + + + } + + /** + * + * @return the fMac field value. + */ + public bool IsFMac() + { + return fMac.IsSet(field_10_history); + + } + + /** + * Sets the fEmptySpecial field value. + * + */ + public void SetFEmptySpecial(bool value) + { + field_10_history = (short)fEmptySpecial.SetBoolean(field_10_history, value); + + + } + + /** + * + * @return the fEmptySpecial field value. + */ + public bool IsFEmptySpecial() + { + return fEmptySpecial.IsSet(field_10_history); + + } + + /** + * Sets the fLoadOverridePage field value. + * + */ + public void SetFLoadOverridePage(bool value) + { + field_10_history = (short)fLoadOverridePage.SetBoolean(field_10_history, value); + + + } + + /** + * + * @return the fLoadOverridePage field value. + */ + public bool IsFLoadOverridePage() + { + return fLoadOverridePage.IsSet(field_10_history); + + } + + /** + * Sets the fFutureSavedUndo field value. + * + */ + public void SetFFutureSavedUndo(bool value) + { + field_10_history = (short)fFutureSavedUndo.SetBoolean(field_10_history, value); + + + } + + /** + * + * @return the fFutureSavedUndo field value. + */ + public bool IsFFutureSavedUndo() + { + return fFutureSavedUndo.IsSet(field_10_history); + + } + + /** + * Sets the fWord97Saved field value. + * + */ + public void SetFWord97Saved(bool value) + { + field_10_history = (short)fWord97Saved.SetBoolean(field_10_history, value); + + + } + + /** + * + * @return the fWord97Saved field value. + */ + public bool IsFWord97Saved() + { + return fWord97Saved.IsSet(field_10_history); + + } + + /** + * Sets the fSpare0 field value. + * + */ + public void SetFSpare0(byte value) + { + field_10_history = (short)fSpare0.SetValue(field_10_history, value); + + + } + + /** + * + * @return the fSpare0 field value. + */ + public byte GetFSpare0() + { + return (byte)fSpare0.GetValue(field_10_history); + + } + + + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/Types/FLDAbstractType.cs b/scratchpad/HWPF/Model/Types/FLDAbstractType.cs new file mode 100644 index 0000000..94093a0 --- /dev/null +++ b/scratchpad/HWPF/Model/Types/FLDAbstractType.cs @@ -0,0 +1,354 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using NPOI.Util; +using System.Text; +using System; +namespace NPOI.HWPF.Model.Types +{ + + /** + * Field Descriptor (FLD). + *

    + * Class and fields descriptions are quoted from Microsoft Office Word 97-2007 + * Binary File Format + * + * NOTE: This source is automatically generated please do not modify this file. + * Either subclass or remove the record in src/records/defInitions. + * + * @author Sergey Vladimirov; according to Microsoft Office Word 97-2007 Binary + * File Format Specification [*.doc] + */ + public abstract class FLDAbstractType : BaseObject + { + + protected byte field_1_chHolder; + private static BitField ch = new BitField(0x1f); + private static BitField reserved = new BitField(0xe0); + protected byte field_2_flt; + private static BitField fDiffer = new BitField(0x01); + private static BitField fZombieEmbed = new BitField(0x02); + private static BitField fResultDirty = new BitField(0x04); + private static BitField fResultEdited = new BitField(0x08); + private static BitField fLocked = new BitField(0x10); + private static BitField fPrivateResult = new BitField(0x20); + private static BitField fNested = new BitField(0x40); + private static BitField fHasSep = new BitField(0x40); + + public FLDAbstractType() + { + + } + + protected void FillFields(byte[] data, int offset) + { + field_1_chHolder = data[0x0 + offset]; + field_2_flt = data[0x1 + offset]; + } + + public void Serialize(byte[] data, int offset) + { + data[0x0 + offset] = field_1_chHolder; + data[0x1 + offset] = field_2_flt; + } + + public override String ToString() + { + StringBuilder buffer = new StringBuilder(); + + buffer.Append("[FLD]\n"); + + buffer.Append(" .chHolder = "); + buffer.Append(" (").Append(GetChHolder()).Append(" )\n"); + buffer.Append(" .ch = ") + .Append(GetCh()).Append('\n'); + buffer.Append(" .reserved = ") + .Append(GetReserved()).Append('\n'); + + buffer.Append(" .flt = "); + buffer.Append(" (").Append(GetFlt()).Append(" )\n"); + buffer.Append(" .fDiffer = ") + .Append(IsFDiffer()).Append('\n'); + buffer.Append(" .fZombieEmbed = ") + .Append(IsFZombieEmbed()).Append('\n'); + buffer.Append(" .fResultDirty = ") + .Append(IsFResultDirty()).Append('\n'); + buffer.Append(" .fResultEdited = ") + .Append(IsFResultEdited()).Append('\n'); + buffer.Append(" .fLocked = ") + .Append(IsFLocked()).Append('\n'); + buffer.Append(" .fPrivateResult = ") + .Append(IsFPrivateResult()).Append('\n'); + buffer.Append(" .fNested = ") + .Append(IsFNested()).Append('\n'); + buffer.Append(" .fHasSep = ") + .Append(IsFHasSep()).Append('\n'); + + buffer.Append("[/FLD]\n"); + return buffer.ToString(); + } + + /** + * Size of record (exluding 4 byte header) + */ + public static int GetSize() + { + return 4 + +1 + 1; + } + + /** + * ch field holder (along with reserved bits). + */ + public byte GetChHolder() + { + return field_1_chHolder; + } + + /** + * ch field holder (along with reserved bits). + */ + public void SetChHolder(byte field_1_chHolder) + { + this.field_1_chHolder = field_1_chHolder; + } + + /** + * Field type when ch == 19 OR field flags when ch == 21 . + */ + public byte GetFlt() + { + return field_2_flt; + } + + /** + * Field type when ch == 19 OR field flags when ch == 21 . + */ + public void SetFlt(byte field_2_flt) + { + this.field_2_flt = field_2_flt; + } + + /** + * Sets the ch field value. Type of field boundary the FLD describes: 19 -- + * field begin mark, 20 -- field separation mark; 21 -- field end mark + */ + public void SetCh(byte value) + { + field_1_chHolder = (byte)ch.SetValue(field_1_chHolder, value); + + } + + /** + * Type of field boundary the FLD describes: 19 -- field begin mark, 20 -- + * field separation mark; 21 -- field end mark + * + * @return the ch field value. + */ + public byte GetCh() + { + return (byte)ch.GetValue(field_1_chHolder); + + } + + /** + * Sets the reserved field value. Reserved + */ + public void SetReserved(byte value) + { + field_1_chHolder = (byte)reserved.SetValue(field_1_chHolder, value); + + } + + /** + * Reserved + * + * @return the reserved field value. + */ + public byte GetReserved() + { + return (byte)reserved.GetValue(field_1_chHolder); + + } + + /** + * Sets the fDiffer field value. Ignored for saved file + */ + public void SetFDiffer(bool value) + { + field_2_flt = (byte)fDiffer.SetBoolean(field_2_flt, value); + + } + + /** + * Ignored for saved file + * + * @return the fDiffer field value. + */ + public bool IsFDiffer() + { + return fDiffer.IsSet(field_2_flt); + + } + + /** + * Sets the fZombieEmbed field value. ==1 when result still believes this + * field is an EMBED or LINK field + */ + public void SetFZombieEmbed(bool value) + { + field_2_flt = (byte)fZombieEmbed.SetBoolean(field_2_flt, value); + + } + + /** + * ==1 when result still believes this field is an EMBED or LINK field + * + * @return the fZombieEmbed field value. + */ + public bool IsFZombieEmbed() + { + return fZombieEmbed.IsSet(field_2_flt); + + } + + /** + * Sets the fResultDirty field value. ==1 when user has edited or formatted + * the result. == 0 otherwise + */ + public void SetFResultDirty(bool value) + { + field_2_flt = (byte)fResultDirty.SetBoolean(field_2_flt, value); + + } + + /** + * ==1 when user has edited or formatted the result. == 0 otherwise + * + * @return the fResultDirty field value. + */ + public bool IsFResultDirty() + { + return fResultDirty.IsSet(field_2_flt); + + } + + /** + * Sets the fResultEdited field value. ==1 when user has inserted text into + * or deleted text from the result + */ + public void SetFResultEdited(bool value) + { + field_2_flt = (byte)fResultEdited.SetBoolean(field_2_flt, value); + + } + + /** + * ==1 when user has inserted text into or deleted text from the result + * + * @return the fResultEdited field value. + */ + public bool IsFResultEdited() + { + return fResultEdited.IsSet(field_2_flt); + + } + + /** + * Sets the fLocked field value. ==1 when field is locked from recalculation + */ + public void SetFLocked(bool value) + { + field_2_flt = (byte)fLocked.SetBoolean(field_2_flt, value); + + } + + /** + * ==1 when field is locked from recalculation + * + * @return the fLocked field value. + */ + public bool IsFLocked() + { + return fLocked.IsSet(field_2_flt); + + } + + /** + * Sets the fPrivateResult field value. ==1 whenever the result of the field + * is never to be Shown + */ + public void SetFPrivateResult(bool value) + { + field_2_flt = (byte)fPrivateResult.SetBoolean(field_2_flt, value); + + } + + /** + * ==1 whenever the result of the field is never to be Shown + * + * @return the fPrivateResult field value. + */ + public bool IsFPrivateResult() + { + return fPrivateResult.IsSet(field_2_flt); + + } + + /** + * Sets the fNested field value. ==1 when field is nested within another + * field + */ + public void SetFNested(bool value) + { + field_2_flt = (byte)fNested.SetBoolean(field_2_flt, value); + + } + + /** + * ==1 when field is nested within another field + * + * @return the fNested field value. + */ + public bool IsFNested() + { + return fNested.IsSet(field_2_flt); + + } + + /** + * Sets the fHasSep field value. ==1 when field has a field separator + */ + public void SetFHasSep(bool value) + { + field_2_flt = (byte)fHasSep.SetBoolean(field_2_flt, value); + + } + + /** + * ==1 when field has a field separator + * + * @return the fHasSep field value. + */ + public bool IsFHasSep() + { + return fHasSep.IsSet(field_2_flt); + + } + } + +} + diff --git a/scratchpad/HWPF/Model/Types/FRDAbstractType.cs b/scratchpad/HWPF/Model/Types/FRDAbstractType.cs new file mode 100644 index 0000000..4b1ac59 --- /dev/null +++ b/scratchpad/HWPF/Model/Types/FRDAbstractType.cs @@ -0,0 +1,95 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +using NPOI.Util; +using System.Text; +using System; +namespace NPOI.HWPF.Model.Types +{ + + /** + * Footnote Reference Descriptor (FRD). + *

    + * Class and fields descriptions are quoted from Microsoft Office Word 97-2007 + * Binary File Format (.doc) Specification + * + * NOTE: This source is automatically generated please do not modify this file. + * Either subclass or remove the record in src/types/defInitions. + * + * @author Sergey Vladimirov; according to Microsoft Office Word 97-2007 Binary + * File Format (.doc) Specification + */ + + public abstract class FRDAbstractType:BaseObject + { + + protected short field_1_nAuto; + + protected FRDAbstractType() + { + } + + protected void FillFields(byte[] data, int offset) + { + field_1_nAuto = LittleEndian.GetShort(data, 0x0 + offset); + } + + public void Serialize(byte[] data, int offset) + { + LittleEndian.PutShort(data, 0x0 + offset, field_1_nAuto); + } + + /** + * Size of record + */ + public static int GetSize() + { + return 0 + 2; + } + + public override String ToString() + { + StringBuilder builder = new StringBuilder(); + builder.Append("[FRD]\n"); + builder.Append(" .nAuto = "); + builder.Append(" (").Append(GetNAuto()).Append(" )\n"); + + builder.Append("[/FRD]\n"); + return builder.ToString(); + } + + /** + * If > 0, the note is an automatically numbered note, otherwise it has a + * custom mark. + */ + public short GetNAuto() + { + return field_1_nAuto; + } + + /** + * If > 0, the note is an automatically numbered note, otherwise it has a + * custom mark. + */ + public void SetNAuto(short field_1_nAuto) + { + this.field_1_nAuto = field_1_nAuto; + } + + } +} + + diff --git a/scratchpad/HWPF/Model/Types/FSPAAbstractType.cs b/scratchpad/HWPF/Model/Types/FSPAAbstractType.cs new file mode 100644 index 0000000..390eb41 --- /dev/null +++ b/scratchpad/HWPF/Model/Types/FSPAAbstractType.cs @@ -0,0 +1,412 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +using NPOI.Util; +using System.Text; +using System; +namespace NPOI.HWPF.Model.Types +{ + + /** + * File Shape Address (FSPA). + *

    + * Class and fields descriptions are quoted from Microsoft Office Word 97-2007 + * Binary File Format + * + *

    + * NOTE: This source is automatically generated please do not modify this file. + * Either subclass or remove the record in src/types/defInitions. + *

    + * This class is internal. It content or properties may change without notice + * due to Changes in our knowledge of internal Microsoft Word binary structures. + * + * @author Sergey Vladimirov; according to Microsoft Office Word 97-2007 Binary + * File Format Specification [*.doc] + */ + + public abstract class FSPAAbstractType : BaseObject + { + + protected int field_1_spid; + protected int field_2_xaLeft; + protected int field_3_yaTop; + protected int field_4_xaRight; + protected int field_5_yaBottom; + protected short field_6_flags; + private static BitField fHdr = new BitField(0x0001); + private static BitField bx = new BitField(0x0006); + private static BitField by = new BitField(0x0018); + private static BitField wr = new BitField(0x01E0); + private static BitField wrk = new BitField(0x1E00); + private static BitField fRcaSimple = new BitField(0x2000); + private static BitField fBelowText = new BitField(0x4000); + private static BitField fAnchorLock = new BitField(0x8000); + protected int field_7_cTxbx; + + protected FSPAAbstractType() + { + } + + protected void FillFields(byte[] data, int offset) + { + field_1_spid = LittleEndian.GetInt(data, 0x0 + offset); + field_2_xaLeft = LittleEndian.GetInt(data, 0x4 + offset); + field_3_yaTop = LittleEndian.GetInt(data, 0x8 + offset); + field_4_xaRight = LittleEndian.GetInt(data, 0xc + offset); + field_5_yaBottom = LittleEndian.GetInt(data, 0x10 + offset); + field_6_flags = LittleEndian.GetShort(data, 0x14 + offset); + field_7_cTxbx = LittleEndian.GetInt(data, 0x16 + offset); + } + + public void Serialize(byte[] data, int offset) + { + LittleEndian.PutInt(data, 0x0 + offset, field_1_spid); + LittleEndian.PutInt(data, 0x4 + offset, field_2_xaLeft); + LittleEndian.PutInt(data, 0x8 + offset, field_3_yaTop); + LittleEndian.PutInt(data, 0xc + offset, field_4_xaRight); + LittleEndian.PutInt(data, 0x10 + offset, field_5_yaBottom); + LittleEndian.PutShort(data, 0x14 + offset, (short)field_6_flags); + LittleEndian.PutInt(data, 0x16 + offset, field_7_cTxbx); + } + + /** + * Size of record + */ + public static int GetSize() + { + return 0 + 4 + 4 + 4 + 4 + 4 + 2 + 4; + } + + public override String ToString() + { + StringBuilder builder = new StringBuilder(); + builder.Append("[FSPA]\n"); + builder.Append(" .spid = "); + builder.Append(" (").Append(GetSpid()).Append(" )\n"); + builder.Append(" .xaLeft = "); + builder.Append(" (").Append(GetXaLeft()).Append(" )\n"); + builder.Append(" .yaTop = "); + builder.Append(" (").Append(GetYaTop()).Append(" )\n"); + builder.Append(" .xaRight = "); + builder.Append(" (").Append(GetXaRight()).Append(" )\n"); + builder.Append(" .yaBottom = "); + builder.Append(" (").Append(GetYaBottom()).Append(" )\n"); + builder.Append(" .flags = "); + builder.Append(" (").Append(GetFlags()).Append(" )\n"); + builder.Append(" .fHdr = ").Append(IsFHdr()).Append('\n'); + builder.Append(" .bx = ").Append(GetBx()).Append('\n'); + builder.Append(" .by = ").Append(GetBy()).Append('\n'); + builder.Append(" .wr = ").Append(GetWr()).Append('\n'); + builder.Append(" .wrk = ").Append(GetWrk()).Append('\n'); + builder.Append(" .fRcaSimple = ").Append(IsFRcaSimple()).Append('\n'); + builder.Append(" .fBelowText = ").Append(IsFBelowText()).Append('\n'); + builder.Append(" .fAnchorLock = ").Append(IsFAnchorLock()).Append('\n'); + builder.Append(" .cTxbx = "); + builder.Append(" (").Append(GetCTxbx()).Append(" )\n"); + + builder.Append("[/FSPA]\n"); + return builder.ToString(); + } + + /** + * Shape Identifier. Used in conjunction with the office art data (found via fcDggInfo in the FIB) to find the actual data for this shape. + */ + + public int GetSpid() + { + return field_1_spid; + } + + /** + * Shape Identifier. Used in conjunction with the office art data (found via fcDggInfo in the FIB) to find the actual data for this shape. + */ + + public void SetSpid(int field_1_spid) + { + this.field_1_spid = field_1_spid; + } + + /** + * Left of rectangle enclosing shape relative to the origin of the shape. + */ + + public int GetXaLeft() + { + return field_2_xaLeft; + } + + /** + * Left of rectangle enclosing shape relative to the origin of the shape. + */ + + public void SetXaLeft(int field_2_xaLeft) + { + this.field_2_xaLeft = field_2_xaLeft; + } + + /** + * Top of rectangle enclosing shape relative to the origin of the shape. + */ + + public int GetYaTop() + { + return field_3_yaTop; + } + + /** + * Top of rectangle enclosing shape relative to the origin of the shape. + */ + + public void SetYaTop(int field_3_yaTop) + { + this.field_3_yaTop = field_3_yaTop; + } + + /** + * Right of rectangle enclosing shape relative to the origin of the shape. + */ + + public int GetXaRight() + { + return field_4_xaRight; + } + + /** + * Right of rectangle enclosing shape relative to the origin of the shape. + */ + + public void SetXaRight(int field_4_xaRight) + { + this.field_4_xaRight = field_4_xaRight; + } + + /** + * Bottom of the rectangle enclosing shape relative to the origin of the shape. + */ + + public int GetYaBottom() + { + return field_5_yaBottom; + } + + /** + * Bottom of the rectangle enclosing shape relative to the origin of the shape. + */ + + public void SetYaBottom(int field_5_yaBottom) + { + this.field_5_yaBottom = field_5_yaBottom; + } + + /** + * Get the flags field for the FSPA record. + */ + + public short GetFlags() + { + return field_6_flags; + } + + /** + * Set the flags field for the FSPA record. + */ + + public void SetFlags(short field_6_flags) + { + this.field_6_flags = field_6_flags; + } + + /** + * Count of textboxes in shape (undo doc only). + */ + + public int GetCTxbx() + { + return field_7_cTxbx; + } + + /** + * Count of textboxes in shape (undo doc only). + */ + + public void SetCTxbx(int field_7_cTxbx) + { + this.field_7_cTxbx = field_7_cTxbx; + } + + /** + * Sets the fHdr field value. + * 1 in the undo doc when shape is from the header doc, 0 otherwise (undefined when not in the undo doc) + */ + + public void SetFHdr(bool value) + { + field_6_flags = (short)fHdr.SetBoolean(field_6_flags, value); + } + + /** + * 1 in the undo doc when shape is from the header doc, 0 otherwise (undefined when not in the undo doc) + * @return the fHdr field value. + */ + + public bool IsFHdr() + { + return fHdr.IsSet(field_6_flags); + } + + /** + * Sets the bx field value. + * X position of shape relative to anchor CP + */ + + public void SetBx(byte value) + { + field_6_flags = (short)bx.SetValue(field_6_flags, value); + } + + /** + * X position of shape relative to anchor CP + * @return the bx field value. + */ + + public byte GetBx() + { + return (byte)bx.GetValue(field_6_flags); + } + + /** + * Sets the by field value. + * Y position of shape relative to anchor CP + */ + + public void SetBy(byte value) + { + field_6_flags = (short)by.SetValue(field_6_flags, value); + } + + /** + * Y position of shape relative to anchor CP + * @return the by field value. + */ + + public byte GetBy() + { + return (byte)by.GetValue(field_6_flags); + } + + /** + * Sets the wr field value. + * Text wrapping mode + */ + + public void SetWr(byte value) + { + field_6_flags = (short)wr.SetValue(field_6_flags, value); + } + + /** + * Text wrapping mode + * @return the wr field value. + */ + + public byte GetWr() + { + return (byte)wr.GetValue(field_6_flags); + } + + /** + * Sets the wrk field value. + * Text wrapping mode type (valid only for wrapping modes 2 and 4 + */ + + public void SetWrk(byte value) + { + field_6_flags = (short)wrk.SetValue(field_6_flags, value); + } + + /** + * Text wrapping mode type (valid only for wrapping modes 2 and 4 + * @return the wrk field value. + */ + + public byte GetWrk() + { + return (byte)wrk.GetValue(field_6_flags); + } + + /** + * Sets the fRcaSimple field value. + * When Set, temporarily overrides bx, by, forcing the xaLeft, xaRight, yaTop, and yaBottom fields to all be page relative. + */ + + public void SetFRcaSimple(bool value) + { + field_6_flags = (short)fRcaSimple.SetBoolean(field_6_flags, value); + } + + /** + * When Set, temporarily overrides bx, by, forcing the xaLeft, xaRight, yaTop, and yaBottom fields to all be page relative. + * @return the fRcaSimple field value. + */ + + public bool IsFRcaSimple() + { + return fRcaSimple.IsSet(field_6_flags); + } + + /** + * Sets the fBelowText field value. + * + */ + + public void SetFBelowText(bool value) + { + field_6_flags = (short)fBelowText.SetBoolean(field_6_flags, value); + } + + /** + * + * @return the fBelowText field value. + */ + + public bool IsFBelowText() + { + return fBelowText.IsSet(field_6_flags); + } + + /** + * Sets the fAnchorLock field value. + * + */ + + public void SetFAnchorLock(bool value) + { + field_6_flags = (short)fAnchorLock.SetBoolean(field_6_flags, value); + } + + /** + * + * @return the fAnchorLock field value. + */ + + public bool IsFAnchorLock() + { + return fAnchorLock.IsSet(field_6_flags); + } + + } +} + diff --git a/scratchpad/HWPF/Model/Types/HRESIAbstractType.cs b/scratchpad/HWPF/Model/Types/HRESIAbstractType.cs new file mode 100644 index 0000000..e1331f2 --- /dev/null +++ b/scratchpad/HWPF/Model/Types/HRESIAbstractType.cs @@ -0,0 +1,138 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using System.Text; +using System; +namespace NPOI.HWPF.Model.Types +{ + + /** + * Hyphenation (HRESI). + *

    + * Class and fields descriptions are quoted from Microsoft Office Word 97-2007 + * Binary File Format (.doc) Specification + * + * NOTE: This source is automatically generated please do not modify this file. + * Either subclass or remove the record in src/types/defInitions. + * + * @author Sergey Vladimirov; according to Microsoft Office Word 97-2007 Binary + * File Format (.doc) Specification + */ + + public abstract class HRESIAbstractType:BaseObject + { + + protected byte field_1_hres; + public static byte HRES_NO = 0; + public static byte HRES_NORMAL = 1; + public static byte HRES_ADD_LETTER_BEFORE = 2; + public static byte HRES_CHANGE_LETTER_BEFORE = 3; + public static byte HRES_DELETE_LETTER_BEFORE = 4; + public static byte HRES_CHANGE_LETTER_AFTER = 5; + public static byte HRES_DELETE_BEFORE_CHANGE_BEFORE = 6; + protected byte field_2_chHres; + + protected HRESIAbstractType() + { + } + + protected void FillFields(byte[] data, int offset) + { + field_1_hres = data[0x0 + offset]; + field_2_chHres = data[0x1 + offset]; + } + + public void Serialize(byte[] data, int offset) + { + data[0x0 + offset] = field_1_hres; + data[0x1 + offset] = field_2_chHres; + } + + /** + * Size of record (exluding 4 byte header) + */ + public static int GetSize() + { + return 4 + +1 + 1; + } + + public override String ToString() + { + StringBuilder builder = new StringBuilder(); + builder.Append("[HRESI]\n"); + builder.Append(" .hres = "); + builder.Append(" (").Append(GetHres()).Append(" )\n"); + builder.Append(" .chHres = "); + builder.Append(" (").Append(GetChHres()).Append(" )\n"); + + builder.Append("[/HRESI]\n"); + return builder.ToString(); + } + + /** + * Hyphenation rule. + * + * @return One of + *

  • {@link #HRES_NO} + *
  • {@link #HRES_NORMAL} + *
  • {@link #HRES_ADD_LETTER_BEFORE} + *
  • {@link #HRES_CHANGE_LETTER_BEFORE} + *
  • {@link #HRES_DELETE_LETTER_BEFORE} + *
  • {@link #HRES_CHANGE_LETTER_AFTER} + *
  • {@link #HRES_DELETE_BEFORE_CHANGE_BEFORE} + */ + public byte GetHres() + { + return field_1_hres; + } + + /** + * Hyphenation rule. + * + * @param field_1_hres + * One of + *
  • {@link #HRES_NO} + *
  • {@link #HRES_NORMAL} + *
  • {@link #HRES_ADD_LETTER_BEFORE} + *
  • {@link #HRES_CHANGE_LETTER_BEFORE} + *
  • {@link #HRES_DELETE_LETTER_BEFORE} + *
  • {@link #HRES_CHANGE_LETTER_AFTER} + *
  • {@link #HRES_DELETE_BEFORE_CHANGE_BEFORE} + */ + public void SetHres(byte field_1_hres) + { + this.field_1_hres = field_1_hres; + } + + /** + * The character that will be used to add or change a letter when hres is 2, 3, 5 or 6. + */ + public byte GetChHres() + { + return field_2_chHres; + } + + /** + * The character that will be used to add or change a letter when hres is 2, 3, 5 or 6. + */ + public void SetChHres(byte field_2_chHres) + { + this.field_2_chHres = field_2_chHres; + } + + } +} diff --git a/scratchpad/HWPF/Model/Types/LFOAbstractType.cs b/scratchpad/HWPF/Model/Types/LFOAbstractType.cs new file mode 100644 index 0000000..fb21590 --- /dev/null +++ b/scratchpad/HWPF/Model/Types/LFOAbstractType.cs @@ -0,0 +1,399 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +using NPOI.Util; +using System.Text; +using System; +namespace NPOI.HWPF.Model.Types +{ + /** + * List Format Override (LFO). + *

    + * Class and fields descriptions are quoted from Microsoft Office Word 97-2007 + * Binary File Format + * + * NOTE: This source is automatically generated please do not modify this file. + * Either subclass or remove the record in src/types/defInitions. + * + * @author Sergey Vladimirov; according to Microsoft Office Word 97-2007 Binary + * File Format Specification [*.doc] + */ + + public abstract class LFOAbstractType : BaseObject + { + + protected int field_1_lsid; + protected int field_2_reserved1; + protected int field_3_reserved2; + protected byte field_4_clfolvl; + protected byte field_5_ibstFltAutoNum; + protected byte field_6_grfhic; + private static BitField fHtmlChecked = new BitField(0x01); + private static BitField fHtmlUnsupported = new BitField(0x02); + private static BitField fHtmlListTextNotSharpDot = new BitField(0x04); + private static BitField fHtmlNotPeriod = new BitField(0x08); + private static BitField fHtmlFirstLineMismatch = new BitField(0x10); + private static BitField fHtmlTabLeftIndentMismatch = new BitField( + 0x20); + private static BitField fHtmlHangingIndentBeneathNumber = new BitField( + 0x40); + private static BitField fHtmlBuiltInBullet = new BitField(0x80); + protected byte field_7_reserved3; + + protected LFOAbstractType() + { + } + + protected void FillFields(byte[] data, int offset) + { + field_1_lsid = LittleEndian.GetInt(data, 0x0 + offset); + field_2_reserved1 = LittleEndian.GetInt(data, 0x4 + offset); + field_3_reserved2 = LittleEndian.GetInt(data, 0x8 + offset); + field_4_clfolvl = data[0xc + offset]; + field_5_ibstFltAutoNum = data[0xd + offset]; + field_6_grfhic = data[0xe + offset]; + field_7_reserved3 = data[0xf + offset]; + } + + public void Serialize(byte[] data, int offset) + { + LittleEndian.PutInt(data, 0x0 + offset, field_1_lsid); + LittleEndian.PutInt(data, 0x4 + offset, field_2_reserved1); + LittleEndian.PutInt(data, 0x8 + offset, field_3_reserved2); + data[0xc + offset] = field_4_clfolvl; + data[0xd + offset] = field_5_ibstFltAutoNum; + data[0xe + offset] = field_6_grfhic; + data[0xf + offset] = field_7_reserved3; + } + + /** + * Size of record + */ + public static int GetSize() + { + return 0 + 4 + 4 + 4 + 1 + 1 + 1 + 1; + } + + public override String ToString() + { + StringBuilder builder = new StringBuilder(); + builder.Append("[LFO]\n"); + builder.Append(" .lsid = "); + builder.Append(" (").Append(GetLsid()).Append(" )\n"); + builder.Append(" .reserved1 = "); + builder.Append(" (").Append(GetReserved1()).Append(" )\n"); + builder.Append(" .reserved2 = "); + builder.Append(" (").Append(GetReserved2()).Append(" )\n"); + builder.Append(" .clfolvl = "); + builder.Append(" (").Append(GetClfolvl()).Append(" )\n"); + builder.Append(" .ibstFltAutoNum = "); + builder.Append(" (").Append(GetIbstFltAutoNum()).Append(" )\n"); + builder.Append(" .grfhic = "); + builder.Append(" (").Append(GetGrfhic()).Append(" )\n"); + builder.Append(" .fHtmlChecked = ") + .Append(IsFHtmlChecked()).Append('\n'); + builder.Append(" .fHtmlUnsupported = ") + .Append(IsFHtmlUnsupported()).Append('\n'); + builder.Append(" .fHtmlListTextNotSharpDot = ") + .Append(IsFHtmlListTextNotSharpDot()).Append('\n'); + builder.Append(" .fHtmlNotPeriod = ") + .Append(IsFHtmlNotPeriod()).Append('\n'); + builder.Append(" .fHtmlFirstLineMismatch = ") + .Append(IsFHtmlFirstLineMismatch()).Append('\n'); + builder.Append(" .fHtmlTabLeftIndentMismatch = ") + .Append(IsFHtmlTabLeftIndentMismatch()).Append('\n'); + builder.Append(" .fHtmlHangingIndentBeneathNumber = ") + .Append(IsFHtmlHangingIndentBeneathNumber()).Append('\n'); + builder.Append(" .fHtmlBuiltInBullet = ") + .Append(IsFHtmlBuiltInBullet()).Append('\n'); + builder.Append(" .reserved3 = "); + builder.Append(" (").Append(GetReserved3()).Append(" )\n"); + + builder.Append("[/LFO]\n"); + return builder.ToString(); + } + + /** + * List ID of corresponding LSTF (see LSTF). + */ + public int GetLsid() + { + return field_1_lsid; + } + + /** + * List ID of corresponding LSTF (see LSTF). + */ + public void SetLsid(int field_1_lsid) + { + this.field_1_lsid = field_1_lsid; + } + + /** + * Reserved. + */ + public int GetReserved1() + { + return field_2_reserved1; + } + + /** + * Reserved. + */ + public void SetReserved1(int field_2_reserved1) + { + this.field_2_reserved1 = field_2_reserved1; + } + + /** + * Reserved. + */ + public int GetReserved2() + { + return field_3_reserved2; + } + + /** + * Reserved. + */ + public void SetReserved2(int field_3_reserved2) + { + this.field_3_reserved2 = field_3_reserved2; + } + + /** + * Count of levels whose format is overridden (see LFOLVL). + */ + public byte GetClfolvl() + { + return field_4_clfolvl; + } + + /** + * Count of levels whose format is overridden (see LFOLVL). + */ + public void SetClfolvl(byte field_4_clfolvl) + { + this.field_4_clfolvl = field_4_clfolvl; + } + + /** + * Used for AUTONUM field emulation. + */ + public byte GetIbstFltAutoNum() + { + return field_5_ibstFltAutoNum; + } + + /** + * Used for AUTONUM field emulation. + */ + public void SetIbstFltAutoNum(byte field_5_ibstFltAutoNum) + { + this.field_5_ibstFltAutoNum = field_5_ibstFltAutoNum; + } + + /** + * HTML compatibility flags. + */ + public byte GetGrfhic() + { + return field_6_grfhic; + } + + /** + * HTML compatibility flags. + */ + public void SetGrfhic(byte field_6_grfhic) + { + this.field_6_grfhic = field_6_grfhic; + } + + /** + * Reserved. + */ + public byte GetReserved3() + { + return field_7_reserved3; + } + + /** + * Reserved. + */ + public void SetReserved3(byte field_7_reserved3) + { + this.field_7_reserved3 = field_7_reserved3; + } + + /** + * Sets the fHtmlChecked field value. Checked + */ + public void SetFHtmlChecked(bool value) + { + field_6_grfhic = (byte)fHtmlChecked.SetBoolean(field_6_grfhic, value); + } + + /** + * Checked + * + * @return the fHtmlChecked field value. + */ + public bool IsFHtmlChecked() + { + return fHtmlChecked.IsSet(field_6_grfhic); + } + + /** + * Sets the fHtmlUnsupported field value. The numbering sequence or format + * is unsupported (includes tab & size) + */ + public void SetFHtmlUnsupported(bool value) + { + field_6_grfhic = (byte)fHtmlUnsupported.SetBoolean(field_6_grfhic, + value); + } + + /** + * The numbering sequence or format is unsupported (includes tab & size) + * + * @return the fHtmlUnsupported field value. + */ + public bool IsFHtmlUnsupported() + { + return fHtmlUnsupported.IsSet(field_6_grfhic); + } + + /** + * Sets the fHtmlListTextNotSharpDot field value. The list text is not "#." + */ + public void SetFHtmlListTextNotSharpDot(bool value) + { + field_6_grfhic = (byte)fHtmlListTextNotSharpDot.SetBoolean( + field_6_grfhic, value); + } + + /** + * The list text is not "#." + * + * @return the fHtmlListTextNotSharpDot field value. + */ + public bool IsFHtmlListTextNotSharpDot() + { + return fHtmlListTextNotSharpDot.IsSet(field_6_grfhic); + } + + /** + * Sets the fHtmlNotPeriod field value. Something other than a period is + * used + */ + public void SetFHtmlNotPeriod(bool value) + { + field_6_grfhic = (byte)fHtmlNotPeriod.SetBoolean(field_6_grfhic, + value); + } + + /** + * Something other than a period is used + * + * @return the fHtmlNotPeriod field value. + */ + public bool IsFHtmlNotPeriod() + { + return fHtmlNotPeriod.IsSet(field_6_grfhic); + } + + /** + * Sets the fHtmlFirstLineMismatch field value. First line indent mismatch + */ + public void SetFHtmlFirstLineMismatch(bool value) + { + field_6_grfhic = (byte)fHtmlFirstLineMismatch.SetBoolean( + field_6_grfhic, value); + } + + /** + * First line indent mismatch + * + * @return the fHtmlFirstLineMismatch field value. + */ + public bool IsFHtmlFirstLineMismatch() + { + return fHtmlFirstLineMismatch.IsSet(field_6_grfhic); + } + + /** + * Sets the fHtmlTabLeftIndentMismatch field value. The list tab and the + * dxaLeft don't match (need table?) + */ + public void SetFHtmlTabLeftIndentMismatch(bool value) + { + field_6_grfhic = (byte)fHtmlTabLeftIndentMismatch.SetBoolean( + field_6_grfhic, value); + } + + /** + * The list tab and the dxaLeft don't match (need table?) + * + * @return the fHtmlTabLeftIndentMismatch field value. + */ + public bool IsFHtmlTabLeftIndentMismatch() + { + return fHtmlTabLeftIndentMismatch.IsSet(field_6_grfhic); + } + + /** + * Sets the fHtmlHangingIndentBeneathNumber field value. The hanging indent + * falls beneath the number (need plain text) + */ + public void SetFHtmlHangingIndentBeneathNumber(bool value) + { + field_6_grfhic = (byte)fHtmlHangingIndentBeneathNumber.SetBoolean( + field_6_grfhic, value); + } + + /** + * The hanging indent falls beneath the number (need plain text) + * + * @return the fHtmlHangingIndentBeneathNumber field value. + */ + public bool IsFHtmlHangingIndentBeneathNumber() + { + return fHtmlHangingIndentBeneathNumber.IsSet(field_6_grfhic); + } + + /** + * Sets the fHtmlBuiltInBullet field value. A built-in HTML bullet + */ + public void SetFHtmlBuiltInBullet(bool value) + { + field_6_grfhic = (byte)fHtmlBuiltInBullet.SetBoolean(field_6_grfhic, + value); + } + + /** + * A built-in HTML bullet + * + * @return the fHtmlBuiltInBullet field value. + */ + public bool IsFHtmlBuiltInBullet() + { + return fHtmlBuiltInBullet.IsSet(field_6_grfhic); + } + + } +} + + diff --git a/scratchpad/HWPF/Model/Types/PAPAbstractType.cs b/scratchpad/HWPF/Model/Types/PAPAbstractType.cs new file mode 100644 index 0000000..1f8f7bd --- /dev/null +++ b/scratchpad/HWPF/Model/Types/PAPAbstractType.cs @@ -0,0 +1,1689 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model.Types +{ + + using NPOI.HWPF.UserModel; + using NPOI.Util; + using System; + using System.Text; + + /** + * Paragraph Properties. + * NOTE: This source is automatically generated please do not modify this file. Either subclass or + * remove the record in src/records/defInitions. + + * @author S. Ryan Ackley + */ + public abstract class PAPAbstractType:BaseObject + { + + protected int field_1_istd; + protected bool field_2_fSideBySide; + protected bool field_3_fKeep; + protected bool field_4_fKeepFollow; + protected bool field_5_fPageBreakBefore; + protected byte field_6_brcl; + /**/ + public static byte BRCL_SINGLE = 0; + /**/ + public static byte BRCL_THICK = 1; + /**/ + public static byte BRCL_DOUBLE = 2; + /**/ + public static byte BRCL_SHADOW = 3; + protected byte field_7_brcp; + /**/ + public static byte BRCP_NONE = 0; + /**/ + public static byte BRCP_BORDER_ABOVE = 1; + /**/ + public static byte BRCP_BORDER_BELOW = 2; + /**/ + public static byte BRCP_BOX_AROUND = 15; + /**/ + public static byte BRCP_BAR_TO_LEFT_OF_PARAGRAPH = 16; + protected byte field_8_ilvl; + protected int field_9_ilfo; + protected bool field_10_fNoLnn; + protected LineSpacingDescriptor field_11_lspd; + protected int field_12_dyaBefore; + protected int field_13_dyaAfter; + protected bool field_14_fInTable; + protected bool field_15_finTableW97; + protected bool field_16_fTtp; + protected int field_17_dxaAbs; + protected int field_18_dyaAbs; + protected int field_19_dxaWidth; + protected bool field_20_fBrLnAbove; + protected bool field_21_fBrLnBelow; + protected byte field_22_pcVert; + protected byte field_23_pcHorz; + protected byte field_24_wr; + protected bool field_25_fNoAutoHyph; + protected int field_26_dyaHeight; + protected bool field_27_fMinHeight; + /**/ + public static bool FMINHEIGHT_EXACT = false; + /**/ + public static bool FMINHEIGHT_AT_LEAST = true; + protected DropCapSpecifier field_28_dcs; + protected int field_29_dyaFromText; + protected int field_30_dxaFromText; + protected bool field_31_fLocked; + protected bool field_32_fWidowControl; + protected bool field_33_fKinsoku; + protected bool field_34_fWordWrap; + protected bool field_35_fOverflowPunct; + protected bool field_36_fTopLinePunct; + protected bool field_37_fAutoSpaceDE; + protected bool field_38_fAutoSpaceDN; + protected int field_39_wAlignFont; + /**/ + public static byte WALIGNFONT_HANGING = 0; + /**/ + public static byte WALIGNFONT_CENTERED = 1; + /**/ + public static byte WALIGNFONT_ROMAN = 2; + /**/ + public static byte WALIGNFONT_VARIABLE = 3; + /**/ + public static byte WALIGNFONT_AUTO = 4; + protected short field_40_fontAlign; + private static BitField fVertical = new BitField(0x0001); + private static BitField fBackward = new BitField(0x0002); + private static BitField fRotateFont = new BitField(0x0004); + protected byte field_41_lvl; + protected bool field_42_fBiDi; + protected bool field_43_fNumRMIns; + protected bool field_44_fCrLf; + protected bool field_45_fUsePgsuSettings; + protected bool field_46_fAdjustRight; + protected int field_47_itap; + protected bool field_48_fInnerTableCell; + protected bool field_49_fOpenTch; + protected bool field_50_fTtpEmbedded; + protected short field_51_dxcRight; + protected short field_52_dxcLeft; + protected short field_53_dxcLeft1; + protected bool field_54_fDyaBeforeAuto; + protected bool field_55_fDyaAfterAuto; + protected int field_56_dxaRight; + protected int field_57_dxaLeft; + protected int field_58_dxaLeft1; + protected byte field_59_jc; + protected bool field_60_fNoAllowOverlap; + protected BorderCode field_61_brcTop; + protected BorderCode field_62_brcLeft; + protected BorderCode field_63_brcBottom; + protected BorderCode field_64_brcRight; + protected BorderCode field_65_brcBetween; + protected BorderCode field_66_brcBar; + protected ShadingDescriptor field_67_shd; + protected byte[] field_68_anld; + protected byte[] field_69_phe; + protected bool field_70_fPropRMark; + protected int field_71_ibstPropRMark; + protected DateAndTime field_72_dttmPropRMark; + protected int field_73_itbdMac; + protected int[] field_74_rgdxaTab; + protected byte[] field_75_rgtbd; + protected byte[] field_76_numrm; + protected byte[] field_77_ptap; + + protected PAPAbstractType() + { + this.field_11_lspd = new LineSpacingDescriptor(); + this.field_11_lspd = new LineSpacingDescriptor(); + this.field_28_dcs = new DropCapSpecifier(); + this.field_32_fWidowControl = true; + this.field_41_lvl = 9; + this.field_61_brcTop = new BorderCode(); + this.field_62_brcLeft = new BorderCode(); + this.field_63_brcBottom = new BorderCode(); + this.field_64_brcRight = new BorderCode(); + this.field_65_brcBetween = new BorderCode(); + this.field_66_brcBar = new BorderCode(); + this.field_67_shd = new ShadingDescriptor(); + this.field_68_anld = new byte[0]; + this.field_69_phe = new byte[0]; + this.field_72_dttmPropRMark = new DateAndTime(); + this.field_74_rgdxaTab = new int[0]; + this.field_75_rgtbd = new byte[0]; + this.field_76_numrm = new byte[0]; + this.field_77_ptap = new byte[0]; + } + + + public override String ToString() + { + StringBuilder builder = new StringBuilder(); + builder.Append("[PAP]\n"); + builder.Append(" .Istd = "); + builder.Append(" (").Append(GetIstd()).Append(" )\n"); + builder.Append(" .fSideBySide = "); + builder.Append(" (").Append(GetFSideBySide()).Append(" )\n"); + builder.Append(" .fKeep = "); + builder.Append(" (").Append(GetFKeep()).Append(" )\n"); + builder.Append(" .fKeepFollow = "); + builder.Append(" (").Append(GetFKeepFollow()).Append(" )\n"); + builder.Append(" .fPageBreakBefore = "); + builder.Append(" (").Append(GetFPageBreakBefore()).Append(" )\n"); + builder.Append(" .brcl = "); + builder.Append(" (").Append(GetBrcl()).Append(" )\n"); + builder.Append(" .brcp = "); + builder.Append(" (").Append(GetBrcp()).Append(" )\n"); + builder.Append(" .ilvl = "); + builder.Append(" (").Append(GetIlvl()).Append(" )\n"); + builder.Append(" .ilfo = "); + builder.Append(" (").Append(GetIlfo()).Append(" )\n"); + builder.Append(" .fNoLnn = "); + builder.Append(" (").Append(GetFNoLnn()).Append(" )\n"); + builder.Append(" .lspd = "); + builder.Append(" (").Append(GetLspd()).Append(" )\n"); + builder.Append(" .dyaBefore = "); + builder.Append(" (").Append(GetDyaBefore()).Append(" )\n"); + builder.Append(" .dyaAfter = "); + builder.Append(" (").Append(GetDyaAfter()).Append(" )\n"); + builder.Append(" .fInTable = "); + builder.Append(" (").Append(GetFInTable()).Append(" )\n"); + builder.Append(" .finTableW97 = "); + builder.Append(" (").Append(GetFinTableW97()).Append(" )\n"); + builder.Append(" .fTtp = "); + builder.Append(" (").Append(GetFTtp()).Append(" )\n"); + builder.Append(" .dxaAbs = "); + builder.Append(" (").Append(GetDxaAbs()).Append(" )\n"); + builder.Append(" .dyaAbs = "); + builder.Append(" (").Append(GetDyaAbs()).Append(" )\n"); + builder.Append(" .dxaWidth = "); + builder.Append(" (").Append(GetDxaWidth()).Append(" )\n"); + builder.Append(" .fBrLnAbove = "); + builder.Append(" (").Append(GetFBrLnAbove()).Append(" )\n"); + builder.Append(" .fBrLnBelow = "); + builder.Append(" (").Append(GetFBrLnBelow()).Append(" )\n"); + builder.Append(" .pcVert = "); + builder.Append(" (").Append(GetPcVert()).Append(" )\n"); + builder.Append(" .pcHorz = "); + builder.Append(" (").Append(GetPcHorz()).Append(" )\n"); + builder.Append(" .wr = "); + builder.Append(" (").Append(GetWr()).Append(" )\n"); + builder.Append(" .fNoAutoHyph = "); + builder.Append(" (").Append(GetFNoAutoHyph()).Append(" )\n"); + builder.Append(" .dyaHeight = "); + builder.Append(" (").Append(GetDyaHeight()).Append(" )\n"); + builder.Append(" .fMinHeight = "); + builder.Append(" (").Append(GetFMinHeight()).Append(" )\n"); + builder.Append(" .dcs = "); + builder.Append(" (").Append(GetDcs()).Append(" )\n"); + builder.Append(" .dyaFromText = "); + builder.Append(" (").Append(GetDyaFromText()).Append(" )\n"); + builder.Append(" .dxaFromText = "); + builder.Append(" (").Append(GetDxaFromText()).Append(" )\n"); + builder.Append(" .fLocked = "); + builder.Append(" (").Append(GetFLocked()).Append(" )\n"); + builder.Append(" .fWidowControl = "); + builder.Append(" (").Append(GetFWidowControl()).Append(" )\n"); + builder.Append(" .fKinsoku = "); + builder.Append(" (").Append(GetFKinsoku()).Append(" )\n"); + builder.Append(" .fWordWrap = "); + builder.Append(" (").Append(GetFWordWrap()).Append(" )\n"); + builder.Append(" .fOverflowPunct = "); + builder.Append(" (").Append(GetFOverflowPunct()).Append(" )\n"); + builder.Append(" .fTopLinePunct = "); + builder.Append(" (").Append(GetFTopLinePunct()).Append(" )\n"); + builder.Append(" .fAutoSpaceDE = "); + builder.Append(" (").Append(GetFAutoSpaceDE()).Append(" )\n"); + builder.Append(" .fAutoSpaceDN = "); + builder.Append(" (").Append(GetFAutoSpaceDN()).Append(" )\n"); + builder.Append(" .wAlignFont = "); + builder.Append(" (").Append(GetWAlignFont()).Append(" )\n"); + builder.Append(" .fontAlign = "); + builder.Append(" (").Append(GetFontAlign()).Append(" )\n"); + builder.Append(" .fVertical = ").Append(IsFVertical()).Append('\n'); + builder.Append(" .fBackward = ").Append(IsFBackward()).Append('\n'); + builder.Append(" .fRotateFont = ").Append(IsFRotateFont()).Append('\n'); + builder.Append(" .lvl = "); + builder.Append(" (").Append(GetLvl()).Append(" )\n"); + builder.Append(" .fBiDi = "); + builder.Append(" (").Append(GetFBiDi()).Append(" )\n"); + builder.Append(" .fNumRMIns = "); + builder.Append(" (").Append(GetFNumRMIns()).Append(" )\n"); + builder.Append(" .fCrLf = "); + builder.Append(" (").Append(GetFCrLf()).Append(" )\n"); + builder.Append(" .fUsePgsuSettings = "); + builder.Append(" (").Append(GetFUsePgsuSettings()).Append(" )\n"); + builder.Append(" .fAdjustRight = "); + builder.Append(" (").Append(GetFAdjustRight()).Append(" )\n"); + builder.Append(" .itap = "); + builder.Append(" (").Append(GetItap()).Append(" )\n"); + builder.Append(" .fInnerTableCell = "); + builder.Append(" (").Append(GetFInnerTableCell()).Append(" )\n"); + builder.Append(" .fOpenTch = "); + builder.Append(" (").Append(GetFOpenTch()).Append(" )\n"); + builder.Append(" .fTtpEmbedded = "); + builder.Append(" (").Append(GetFTtpEmbedded()).Append(" )\n"); + builder.Append(" .dxcRight = "); + builder.Append(" (").Append(GetDxcRight()).Append(" )\n"); + builder.Append(" .dxcLeft = "); + builder.Append(" (").Append(GetDxcLeft()).Append(" )\n"); + builder.Append(" .dxcLeft1 = "); + builder.Append(" (").Append(GetDxcLeft1()).Append(" )\n"); + builder.Append(" .fDyaBeforeAuto = "); + builder.Append(" (").Append(GetFDyaBeforeAuto()).Append(" )\n"); + builder.Append(" .fDyaAfterAuto = "); + builder.Append(" (").Append(GetFDyaAfterAuto()).Append(" )\n"); + builder.Append(" .dxaRight = "); + builder.Append(" (").Append(GetDxaRight()).Append(" )\n"); + builder.Append(" .dxaLeft = "); + builder.Append(" (").Append(GetDxaLeft()).Append(" )\n"); + builder.Append(" .dxaLeft1 = "); + builder.Append(" (").Append(GetDxaLeft1()).Append(" )\n"); + builder.Append(" .jc = "); + builder.Append(" (").Append(GetJc()).Append(" )\n"); + builder.Append(" .fNoAllowOverlap = "); + builder.Append(" (").Append(GetFNoAllowOverlap()).Append(" )\n"); + builder.Append(" .brcTop = "); + builder.Append(" (").Append(GetBrcTop()).Append(" )\n"); + builder.Append(" .brcLeft = "); + builder.Append(" (").Append(GetBrcLeft()).Append(" )\n"); + builder.Append(" .brcBottom = "); + builder.Append(" (").Append(GetBrcBottom()).Append(" )\n"); + builder.Append(" .brcRight = "); + builder.Append(" (").Append(GetBrcRight()).Append(" )\n"); + builder.Append(" .brcBetween = "); + builder.Append(" (").Append(GetBrcBetween()).Append(" )\n"); + builder.Append(" .brcBar = "); + builder.Append(" (").Append(GetBrcBar()).Append(" )\n"); + builder.Append(" .shd = "); + builder.Append(" (").Append(GetShd()).Append(" )\n"); + builder.Append(" .anld = "); + builder.Append(" (").Append(GetAnld()).Append(" )\n"); + builder.Append(" .phe = "); + builder.Append(" (").Append(GetPhe()).Append(" )\n"); + builder.Append(" .fPropRMark = "); + builder.Append(" (").Append(GetFPropRMark()).Append(" )\n"); + builder.Append(" .ibstPropRMark = "); + builder.Append(" (").Append(GetIbstPropRMark()).Append(" )\n"); + builder.Append(" .dttmPropRMark = "); + builder.Append(" (").Append(GetDttmPropRMark()).Append(" )\n"); + builder.Append(" .itbdMac = "); + builder.Append(" (").Append(GetItbdMac()).Append(" )\n"); + builder.Append(" .rgdxaTab = "); + builder.Append(" (").Append(GetRgdxaTab()).Append(" )\n"); + builder.Append(" .rgtbd = "); + builder.Append(" (").Append(GetRgtbd()).Append(" )\n"); + builder.Append(" .numrm = "); + builder.Append(" (").Append(GetNumrm()).Append(" )\n"); + builder.Append(" .ptap = "); + builder.Append(" (").Append(GetPtap()).Append(" )\n"); + + builder.Append("[/PAP]\n"); + return builder.ToString(); + } + + /** + * Index to style descriptor. + */ + public int GetIstd() + { + return field_1_istd; + } + + /** + * Index to style descriptor. + */ + public void SetIstd(int field_1_istd) + { + this.field_1_istd = field_1_istd; + } + + /** + * Get the fSideBySide field for the PAP record. + */ + public bool GetFSideBySide() + { + return field_2_fSideBySide; + } + + /** + * Set the fSideBySide field for the PAP record. + */ + public void SetFSideBySide(bool field_2_fSideBySide) + { + this.field_2_fSideBySide = field_2_fSideBySide; + } + + /** + * Get the fKeep field for the PAP record. + */ + public bool GetFKeep() + { + return field_3_fKeep; + } + + /** + * Set the fKeep field for the PAP record. + */ + public void SetFKeep(bool field_3_fKeep) + { + this.field_3_fKeep = field_3_fKeep; + } + + /** + * Get the fKeepFollow field for the PAP record. + */ + public bool GetFKeepFollow() + { + return field_4_fKeepFollow; + } + + /** + * Set the fKeepFollow field for the PAP record. + */ + public void SetFKeepFollow(bool field_4_fKeepFollow) + { + this.field_4_fKeepFollow = field_4_fKeepFollow; + } + + /** + * Get the fPageBreakBefore field for the PAP record. + */ + public bool GetFPageBreakBefore() + { + return field_5_fPageBreakBefore; + } + + /** + * Set the fPageBreakBefore field for the PAP record. + */ + public void SetFPageBreakBefore(bool field_5_fPageBreakBefore) + { + this.field_5_fPageBreakBefore = field_5_fPageBreakBefore; + } + + /** + * Border line style. + * + * @return One of + *

  • {@link #BRCL_SINGLE} + *
  • {@link #BRCL_THICK} + *
  • {@link #BRCL_DOUBLE} + *
  • {@link #BRCL_SHADOW} + */ + public byte GetBrcl() + { + return field_6_brcl; + } + + /** + * Border line style. + * + * @param field_6_brcl + * One of + *
  • {@link #BRCL_SINGLE} + *
  • {@link #BRCL_THICK} + *
  • {@link #BRCL_DOUBLE} + *
  • {@link #BRCL_SHADOW} + */ + public void SetBrcl(byte field_6_brcl) + { + this.field_6_brcl = field_6_brcl; + } + + /** + * Rectangle border codes. + * + * @return One of + *
  • {@link #BRCP_NONE} + *
  • {@link #BRCP_BORDER_ABOVE} + *
  • {@link #BRCP_BORDER_BELOW} + *
  • {@link #BRCP_BOX_AROUND} + *
  • {@link #BRCP_BAR_TO_LEFT_OF_PARAGRAPH} + */ + public byte GetBrcp() + { + return field_7_brcp; + } + + /** + * Rectangle border codes. + * + * @param field_7_brcp + * One of + *
  • {@link #BRCP_NONE} + *
  • {@link #BRCP_BORDER_ABOVE} + *
  • {@link #BRCP_BORDER_BELOW} + *
  • {@link #BRCP_BOX_AROUND} + *
  • {@link #BRCP_BAR_TO_LEFT_OF_PARAGRAPH} + */ + public void SetBrcp(byte field_7_brcp) + { + this.field_7_brcp = field_7_brcp; + } + + /** + * List level if non-zero. + */ + public byte GetIlvl() + { + return field_8_ilvl; + } + + /** + * List level if non-zero. + */ + public void SetIlvl(byte field_8_ilvl) + { + this.field_8_ilvl = field_8_ilvl; + } + + /** + * 1-based index into the pllfo (lists structure), if non-zero. + */ + public int GetIlfo() + { + return field_9_ilfo; + } + + /** + * 1-based index into the pllfo (lists structure), if non-zero. + */ + public void SetIlfo(int field_9_ilfo) + { + this.field_9_ilfo = field_9_ilfo; + } + + /** + * No line numbering. + */ + public bool GetFNoLnn() + { + return field_10_fNoLnn; + } + + /** + * No line numbering. + */ + public void SetFNoLnn(bool field_10_fNoLnn) + { + this.field_10_fNoLnn = field_10_fNoLnn; + } + + /** + * Line spacing descriptor. + */ + public LineSpacingDescriptor GetLspd() + { + return field_11_lspd; + } + + /** + * Line spacing descriptor. + */ + public void SetLspd(LineSpacingDescriptor field_11_lspd) + { + this.field_11_lspd = field_11_lspd; + } + + /** + * Space before paragraph. + */ + public int GetDyaBefore() + { + return field_12_dyaBefore; + } + + /** + * Space before paragraph. + */ + public void SetDyaBefore(int field_12_dyaBefore) + { + this.field_12_dyaBefore = field_12_dyaBefore; + } + + /** + * Space after paragraph. + */ + public int GetDyaAfter() + { + return field_13_dyaAfter; + } + + /** + * Space after paragraph. + */ + public void SetDyaAfter(int field_13_dyaAfter) + { + this.field_13_dyaAfter = field_13_dyaAfter; + } + + /** + * Paragraph is in table flag. + */ + public bool GetFInTable() + { + return field_14_fInTable; + } + + /** + * Paragraph is in table flag. + */ + public void SetFInTable(bool field_14_fInTable) + { + this.field_14_fInTable = field_14_fInTable; + } + + /** + * Archaic paragraph is in table flag. + */ + public bool GetFinTableW97() + { + return field_15_finTableW97; + } + + /** + * Archaic paragraph is in table flag. + */ + public void SetFinTableW97(bool field_15_finTableW97) + { + this.field_15_finTableW97 = field_15_finTableW97; + } + + /** + * Table trailer paragraph (last in table row). + */ + public bool GetFTtp() + { + return field_16_fTtp; + } + + /** + * Table trailer paragraph (last in table row). + */ + public void SetFTtp(bool field_16_fTtp) + { + this.field_16_fTtp = field_16_fTtp; + } + + /** + * Get the dxaAbs field for the PAP record. + */ + public int GetDxaAbs() + { + return field_17_dxaAbs; + } + + /** + * Set the dxaAbs field for the PAP record. + */ + public void SetDxaAbs(int field_17_dxaAbs) + { + this.field_17_dxaAbs = field_17_dxaAbs; + } + + /** + * Get the dyaAbs field for the PAP record. + */ + public int GetDyaAbs() + { + return field_18_dyaAbs; + } + + /** + * Set the dyaAbs field for the PAP record. + */ + public void SetDyaAbs(int field_18_dyaAbs) + { + this.field_18_dyaAbs = field_18_dyaAbs; + } + + /** + * Get the dxaWidth field for the PAP record. + */ + public int GetDxaWidth() + { + return field_19_dxaWidth; + } + + /** + * Set the dxaWidth field for the PAP record. + */ + public void SetDxaWidth(int field_19_dxaWidth) + { + this.field_19_dxaWidth = field_19_dxaWidth; + } + + /** + * Get the fBrLnAbove field for the PAP record. + */ + public bool GetFBrLnAbove() + { + return field_20_fBrLnAbove; + } + + /** + * Set the fBrLnAbove field for the PAP record. + */ + public void SetFBrLnAbove(bool field_20_fBrLnAbove) + { + this.field_20_fBrLnAbove = field_20_fBrLnAbove; + } + + /** + * Get the fBrLnBelow field for the PAP record. + */ + public bool GetFBrLnBelow() + { + return field_21_fBrLnBelow; + } + + /** + * Set the fBrLnBelow field for the PAP record. + */ + public void SetFBrLnBelow(bool field_21_fBrLnBelow) + { + this.field_21_fBrLnBelow = field_21_fBrLnBelow; + } + + /** + * Get the pcVert field for the PAP record. + */ + public byte GetPcVert() + { + return field_22_pcVert; + } + + /** + * Set the pcVert field for the PAP record. + */ + public void SetPcVert(byte field_22_pcVert) + { + this.field_22_pcVert = field_22_pcVert; + } + + /** + * Get the pcHorz field for the PAP record. + */ + public byte GetPcHorz() + { + return field_23_pcHorz; + } + + /** + * Set the pcHorz field for the PAP record. + */ + public void SetPcHorz(byte field_23_pcHorz) + { + this.field_23_pcHorz = field_23_pcHorz; + } + + /** + * Get the wr field for the PAP record. + */ + public byte GetWr() + { + return field_24_wr; + } + + /** + * Set the wr field for the PAP record. + */ + public void SetWr(byte field_24_wr) + { + this.field_24_wr = field_24_wr; + } + + /** + * Get the fNoAutoHyph field for the PAP record. + */ + public bool GetFNoAutoHyph() + { + return field_25_fNoAutoHyph; + } + + /** + * Set the fNoAutoHyph field for the PAP record. + */ + public void SetFNoAutoHyph(bool field_25_fNoAutoHyph) + { + this.field_25_fNoAutoHyph = field_25_fNoAutoHyph; + } + + /** + * Get the dyaHeight field for the PAP record. + */ + public int GetDyaHeight() + { + return field_26_dyaHeight; + } + + /** + * Set the dyaHeight field for the PAP record. + */ + public void SetDyaHeight(int field_26_dyaHeight) + { + this.field_26_dyaHeight = field_26_dyaHeight; + } + + /** + * Minimum height is exact or auto. + * + * @return One of + *
  • {@link #FMINHEIGHT_EXACT} + *
  • {@link #FMINHEIGHT_AT_LEAST} + */ + public bool GetFMinHeight() + { + return field_27_fMinHeight; + } + + /** + * Minimum height is exact or auto. + * + * @param field_27_fMinHeight + * One of + *
  • {@link #FMINHEIGHT_EXACT} + *
  • {@link #FMINHEIGHT_AT_LEAST} + */ + public void SetFMinHeight(bool field_27_fMinHeight) + { + this.field_27_fMinHeight = field_27_fMinHeight; + } + + /** + * Get the dcs field for the PAP record. + */ + public DropCapSpecifier GetDcs() + { + return field_28_dcs; + } + + /** + * Set the dcs field for the PAP record. + */ + public void SetDcs(DropCapSpecifier field_28_dcs) + { + this.field_28_dcs = field_28_dcs; + } + + /** + * Vertical distance between text and absolutely positioned object. + */ + public int GetDyaFromText() + { + return field_29_dyaFromText; + } + + /** + * Vertical distance between text and absolutely positioned object. + */ + public void SetDyaFromText(int field_29_dyaFromText) + { + this.field_29_dyaFromText = field_29_dyaFromText; + } + + /** + * Horizontal distance between text and absolutely positioned object. + */ + public int GetDxaFromText() + { + return field_30_dxaFromText; + } + + /** + * Horizontal distance between text and absolutely positioned object. + */ + public void SetDxaFromText(int field_30_dxaFromText) + { + this.field_30_dxaFromText = field_30_dxaFromText; + } + + /** + * Anchor of an absolutely positioned frame is locked. + */ + public bool GetFLocked() + { + return field_31_fLocked; + } + + /** + * Anchor of an absolutely positioned frame is locked. + */ + public void SetFLocked(bool field_31_fLocked) + { + this.field_31_fLocked = field_31_fLocked; + } + + /** + * 1, Word will prevent widowed lines in this paragraph from being placed at the beginning of a page. + */ + public bool GetFWidowControl() + { + return field_32_fWidowControl; + } + + /** + * 1, Word will prevent widowed lines in this paragraph from being placed at the beginning of a page. + */ + public void SetFWidowControl(bool field_32_fWidowControl) + { + this.field_32_fWidowControl = field_32_fWidowControl; + } + + /** + * apply Kinsoku rules when performing line wrapping. + */ + public bool GetFKinsoku() + { + return field_33_fKinsoku; + } + + /** + * apply Kinsoku rules when performing line wrapping. + */ + public void SetFKinsoku(bool field_33_fKinsoku) + { + this.field_33_fKinsoku = field_33_fKinsoku; + } + + /** + * perform word wrap. + */ + public bool GetFWordWrap() + { + return field_34_fWordWrap; + } + + /** + * perform word wrap. + */ + public void SetFWordWrap(bool field_34_fWordWrap) + { + this.field_34_fWordWrap = field_34_fWordWrap; + } + + /** + * apply overflow punctuation rules when performing line wrapping. + */ + public bool GetFOverflowPunct() + { + return field_35_fOverflowPunct; + } + + /** + * apply overflow punctuation rules when performing line wrapping. + */ + public void SetFOverflowPunct(bool field_35_fOverflowPunct) + { + this.field_35_fOverflowPunct = field_35_fOverflowPunct; + } + + /** + * perform top line punctuation Processing. + */ + public bool GetFTopLinePunct() + { + return field_36_fTopLinePunct; + } + + /** + * perform top line punctuation Processing. + */ + public void SetFTopLinePunct(bool field_36_fTopLinePunct) + { + this.field_36_fTopLinePunct = field_36_fTopLinePunct; + } + + /** + * auto space East Asian and alphabetic characters. + */ + public bool GetFAutoSpaceDE() + { + return field_37_fAutoSpaceDE; + } + + /** + * auto space East Asian and alphabetic characters. + */ + public void SetFAutoSpaceDE(bool field_37_fAutoSpaceDE) + { + this.field_37_fAutoSpaceDE = field_37_fAutoSpaceDE; + } + + /** + * auto space East Asian and numeric characters. + */ + public bool GetFAutoSpaceDN() + { + return field_38_fAutoSpaceDN; + } + + /** + * auto space East Asian and numeric characters. + */ + public void SetFAutoSpaceDN(bool field_38_fAutoSpaceDN) + { + this.field_38_fAutoSpaceDN = field_38_fAutoSpaceDN; + } + + /** + * Get the wAlignFont field for the PAP record. + * + * @return One of + *
  • {@link #WALIGNFONT_HANGING} + *
  • {@link #WALIGNFONT_CENTERED} + *
  • {@link #WALIGNFONT_ROMAN} + *
  • {@link #WALIGNFONT_VARIABLE} + *
  • {@link #WALIGNFONT_AUTO} + */ + public int GetWAlignFont() + { + return field_39_wAlignFont; + } + + /** + * Set the wAlignFont field for the PAP record. + * + * @param field_39_wAlignFont + * One of + *
  • {@link #WALIGNFONT_HANGING} + *
  • {@link #WALIGNFONT_CENTERED} + *
  • {@link #WALIGNFONT_ROMAN} + *
  • {@link #WALIGNFONT_VARIABLE} + *
  • {@link #WALIGNFONT_AUTO} + */ + public void SetWAlignFont(int field_39_wAlignFont) + { + this.field_39_wAlignFont = field_39_wAlignFont; + } + + /** + * Used internally by Word. + */ + public short GetFontAlign() + { + return field_40_fontAlign; + } + + /** + * Used internally by Word. + */ + public void SetFontAlign(short field_40_fontAlign) + { + this.field_40_fontAlign = field_40_fontAlign; + } + + /** + * Outline level. + */ + public byte GetLvl() + { + return field_41_lvl; + } + + /** + * Outline level. + */ + public void SetLvl(byte field_41_lvl) + { + this.field_41_lvl = field_41_lvl; + } + + /** + * Get the fBiDi field for the PAP record. + */ + public bool GetFBiDi() + { + return field_42_fBiDi; + } + + /** + * Set the fBiDi field for the PAP record. + */ + public void SetFBiDi(bool field_42_fBiDi) + { + this.field_42_fBiDi = field_42_fBiDi; + } + + /** + * Get the fNumRMIns field for the PAP record. + */ + public bool GetFNumRMIns() + { + return field_43_fNumRMIns; + } + + /** + * Set the fNumRMIns field for the PAP record. + */ + public void SetFNumRMIns(bool field_43_fNumRMIns) + { + this.field_43_fNumRMIns = field_43_fNumRMIns; + } + + /** + * Get the fCrLf field for the PAP record. + */ + public bool GetFCrLf() + { + return field_44_fCrLf; + } + + /** + * Set the fCrLf field for the PAP record. + */ + public void SetFCrLf(bool field_44_fCrLf) + { + this.field_44_fCrLf = field_44_fCrLf; + } + + /** + * Get the fUsePgsuSettings field for the PAP record. + */ + public bool GetFUsePgsuSettings() + { + return field_45_fUsePgsuSettings; + } + + /** + * Set the fUsePgsuSettings field for the PAP record. + */ + public void SetFUsePgsuSettings(bool field_45_fUsePgsuSettings) + { + this.field_45_fUsePgsuSettings = field_45_fUsePgsuSettings; + } + + /** + * Get the fAdjustRight field for the PAP record. + */ + public bool GetFAdjustRight() + { + return field_46_fAdjustRight; + } + + /** + * Set the fAdjustRight field for the PAP record. + */ + public void SetFAdjustRight(bool field_46_fAdjustRight) + { + this.field_46_fAdjustRight = field_46_fAdjustRight; + } + + /** + * Table nesting level. + */ + public int GetItap() + { + return field_47_itap; + } + + /** + * Table nesting level. + */ + public void SetItap(int field_47_itap) + { + this.field_47_itap = field_47_itap; + } + + /** + * When 1, the end of paragraph mark is really an end of cell mark for a nested table cell. + */ + public bool GetFInnerTableCell() + { + return field_48_fInnerTableCell; + } + + /** + * When 1, the end of paragraph mark is really an end of cell mark for a nested table cell. + */ + public void SetFInnerTableCell(bool field_48_fInnerTableCell) + { + this.field_48_fInnerTableCell = field_48_fInnerTableCell; + } + + /** + * Ensure the Table Cell char doesn't show up as zero height. + */ + public bool GetFOpenTch() + { + return field_49_fOpenTch; + } + + /** + * Ensure the Table Cell char doesn't show up as zero height. + */ + public void SetFOpenTch(bool field_49_fOpenTch) + { + this.field_49_fOpenTch = field_49_fOpenTch; + } + + /** + * Word 97 compatibility indicates this end of paragraph mark is really an end of row marker for a nested table. + */ + public bool GetFTtpEmbedded() + { + return field_50_fTtpEmbedded; + } + + /** + * Word 97 compatibility indicates this end of paragraph mark is really an end of row marker for a nested table. + */ + public void SetFTtpEmbedded(bool field_50_fTtpEmbedded) + { + this.field_50_fTtpEmbedded = field_50_fTtpEmbedded; + } + + /** + * Right indent in character units. + */ + public short GetDxcRight() + { + return field_51_dxcRight; + } + + /** + * Right indent in character units. + */ + public void SetDxcRight(short field_51_dxcRight) + { + this.field_51_dxcRight = field_51_dxcRight; + } + + /** + * Left indent in character units. + */ + public short GetDxcLeft() + { + return field_52_dxcLeft; + } + + /** + * Left indent in character units. + */ + public void SetDxcLeft(short field_52_dxcLeft) + { + this.field_52_dxcLeft = field_52_dxcLeft; + } + + /** + * First line indent in character units. + */ + public short GetDxcLeft1() + { + return field_53_dxcLeft1; + } + + /** + * First line indent in character units. + */ + public void SetDxcLeft1(short field_53_dxcLeft1) + { + this.field_53_dxcLeft1 = field_53_dxcLeft1; + } + + /** + * Vertical spacing before is automatic. + */ + public bool GetFDyaBeforeAuto() + { + return field_54_fDyaBeforeAuto; + } + + /** + * Vertical spacing before is automatic. + */ + public void SetFDyaBeforeAuto(bool field_54_fDyaBeforeAuto) + { + this.field_54_fDyaBeforeAuto = field_54_fDyaBeforeAuto; + } + + /** + * Vertical spacing after is automatic. + */ + public bool GetFDyaAfterAuto() + { + return field_55_fDyaAfterAuto; + } + + /** + * Vertical spacing after is automatic. + */ + public void SetFDyaAfterAuto(bool field_55_fDyaAfterAuto) + { + this.field_55_fDyaAfterAuto = field_55_fDyaAfterAuto; + } + + /** + * Get the dxaRight field for the PAP record. + */ + public int GetDxaRight() + { + return field_56_dxaRight; + } + + /** + * Set the dxaRight field for the PAP record. + */ + public void SetDxaRight(int field_56_dxaRight) + { + this.field_56_dxaRight = field_56_dxaRight; + } + + /** + * Get the dxaLeft field for the PAP record. + */ + public int GetDxaLeft() + { + return field_57_dxaLeft; + } + + /** + * Set the dxaLeft field for the PAP record. + */ + public void SetDxaLeft(int field_57_dxaLeft) + { + this.field_57_dxaLeft = field_57_dxaLeft; + } + + /** + * Get the dxaLeft1 field for the PAP record. + */ + public int GetDxaLeft1() + { + return field_58_dxaLeft1; + } + + /** + * Set the dxaLeft1 field for the PAP record. + */ + public void SetDxaLeft1(int field_58_dxaLeft1) + { + this.field_58_dxaLeft1 = field_58_dxaLeft1; + } + + /** + * Get the jc field for the PAP record. + */ + public byte GetJc() + { + return field_59_jc; + } + + /** + * Set the jc field for the PAP record. + */ + public void SetJc(byte field_59_jc) + { + this.field_59_jc = field_59_jc; + } + + /** + * Get the fNoAllowOverlap field for the PAP record. + */ + public bool GetFNoAllowOverlap() + { + return field_60_fNoAllowOverlap; + } + + /** + * Set the fNoAllowOverlap field for the PAP record. + */ + public void SetFNoAllowOverlap(bool field_60_fNoAllowOverlap) + { + this.field_60_fNoAllowOverlap = field_60_fNoAllowOverlap; + } + + /** + * Get the brcTop field for the PAP record. + */ + public BorderCode GetBrcTop() + { + return field_61_brcTop; + } + + /** + * Set the brcTop field for the PAP record. + */ + public void SetBrcTop(BorderCode field_61_brcTop) + { + this.field_61_brcTop = field_61_brcTop; + } + + /** + * Get the brcLeft field for the PAP record. + */ + public BorderCode GetBrcLeft() + { + return field_62_brcLeft; + } + + /** + * Set the brcLeft field for the PAP record. + */ + public void SetBrcLeft(BorderCode field_62_brcLeft) + { + this.field_62_brcLeft = field_62_brcLeft; + } + + /** + * Get the brcBottom field for the PAP record. + */ + public BorderCode GetBrcBottom() + { + return field_63_brcBottom; + } + + /** + * Set the brcBottom field for the PAP record. + */ + public void SetBrcBottom(BorderCode field_63_brcBottom) + { + this.field_63_brcBottom = field_63_brcBottom; + } + + /** + * Get the brcRight field for the PAP record. + */ + public BorderCode GetBrcRight() + { + return field_64_brcRight; + } + + /** + * Set the brcRight field for the PAP record. + */ + public void SetBrcRight(BorderCode field_64_brcRight) + { + this.field_64_brcRight = field_64_brcRight; + } + + /** + * Get the brcBetween field for the PAP record. + */ + public BorderCode GetBrcBetween() + { + return field_65_brcBetween; + } + + /** + * Set the brcBetween field for the PAP record. + */ + public void SetBrcBetween(BorderCode field_65_brcBetween) + { + this.field_65_brcBetween = field_65_brcBetween; + } + + /** + * Get the brcBar field for the PAP record. + */ + public BorderCode GetBrcBar() + { + return field_66_brcBar; + } + + /** + * Set the brcBar field for the PAP record. + */ + public void SetBrcBar(BorderCode field_66_brcBar) + { + this.field_66_brcBar = field_66_brcBar; + } + + /** + * Get the shd field for the PAP record. + */ + public ShadingDescriptor GetShd() + { + return field_67_shd; + } + + /** + * Set the shd field for the PAP record. + */ + public void SetShd(ShadingDescriptor field_67_shd) + { + this.field_67_shd = field_67_shd; + } + + /** + * Get the anld field for the PAP record. + */ + public byte[] GetAnld() + { + return field_68_anld; + } + + /** + * Set the anld field for the PAP record. + */ + public void SetAnld(byte[] field_68_anld) + { + this.field_68_anld = field_68_anld; + } + + /** + * Get the phe field for the PAP record. + */ + public byte[] GetPhe() + { + return field_69_phe; + } + + /** + * Set the phe field for the PAP record. + */ + public void SetPhe(byte[] field_69_phe) + { + this.field_69_phe = field_69_phe; + } + + /** + * Get the fPropRMark field for the PAP record. + */ + public bool GetFPropRMark() + { + return field_70_fPropRMark; + } + + /** + * Set the fPropRMark field for the PAP record. + */ + public void SetFPropRMark(bool field_70_fPropRMark) + { + this.field_70_fPropRMark = field_70_fPropRMark; + } + + /** + * Get the ibstPropRMark field for the PAP record. + */ + public int GetIbstPropRMark() + { + return field_71_ibstPropRMark; + } + + /** + * Set the ibstPropRMark field for the PAP record. + */ + public void SetIbstPropRMark(int field_71_ibstPropRMark) + { + this.field_71_ibstPropRMark = field_71_ibstPropRMark; + } + + /** + * Get the dttmPropRMark field for the PAP record. + */ + public DateAndTime GetDttmPropRMark() + { + return field_72_dttmPropRMark; + } + + /** + * Set the dttmPropRMark field for the PAP record. + */ + public void SetDttmPropRMark(DateAndTime field_72_dttmPropRMark) + { + this.field_72_dttmPropRMark = field_72_dttmPropRMark; + } + + /** + * Get the itbdMac field for the PAP record. + */ + public int GetItbdMac() + { + return field_73_itbdMac; + } + + /** + * Set the itbdMac field for the PAP record. + */ + public void SetItbdMac(int field_73_itbdMac) + { + this.field_73_itbdMac = field_73_itbdMac; + } + + /** + * Get the rgdxaTab field for the PAP record. + */ + public int[] GetRgdxaTab() + { + return field_74_rgdxaTab; + } + + /** + * Set the rgdxaTab field for the PAP record. + */ + public void SetRgdxaTab(int[] field_74_rgdxaTab) + { + this.field_74_rgdxaTab = field_74_rgdxaTab; + } + + /** + * Get the rgtbd field for the PAP record. + */ + public byte[] GetRgtbd() + { + return field_75_rgtbd; + } + + /** + * Set the rgtbd field for the PAP record. + */ + public void SetRgtbd(byte[] field_75_rgtbd) + { + this.field_75_rgtbd = field_75_rgtbd; + } + + /** + * Get the numrm field for the PAP record. + */ + public byte[] GetNumrm() + { + return field_76_numrm; + } + + /** + * Set the numrm field for the PAP record. + */ + public void SetNumrm(byte[] field_76_numrm) + { + this.field_76_numrm = field_76_numrm; + } + + /** + * Get the ptap field for the PAP record. + */ + public byte[] GetPtap() + { + return field_77_ptap; + } + + /** + * Set the ptap field for the PAP record. + */ + public void SetPtap(byte[] field_77_ptap) + { + this.field_77_ptap = field_77_ptap; + } + + /** + * Sets the fVertical field value. + * + */ + public void SetFVertical(bool value) + { + field_40_fontAlign = (short)fVertical.SetBoolean(field_40_fontAlign, value); + + + } + + /** + * + * @return the fVertical field value. + */ + public bool IsFVertical() + { + return fVertical.IsSet(field_40_fontAlign); + + } + + /** + * Sets the fBackward field value. + * + */ + public void SetFBackward(bool value) + { + field_40_fontAlign = (short)fBackward.SetBoolean(field_40_fontAlign, value); + + + } + + /** + * + * @return the fBackward field value. + */ + public bool IsFBackward() + { + return fBackward.IsSet(field_40_fontAlign); + + } + + /** + * Sets the fRotateFont field value. + * + */ + public void SetFRotateFont(bool value) + { + field_40_fontAlign = (short)fRotateFont.SetBoolean(field_40_fontAlign, value); + + + } + + /** + * + * @return the fRotateFont field value. + */ + public bool IsFRotateFont() + { + return fRotateFont.IsSet(field_40_fontAlign); + + } + + } +} + + diff --git a/scratchpad/HWPF/Model/Types/SEPAbstractType.cs b/scratchpad/HWPF/Model/Types/SEPAbstractType.cs new file mode 100644 index 0000000..15734ae --- /dev/null +++ b/scratchpad/HWPF/Model/Types/SEPAbstractType.cs @@ -0,0 +1,1085 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + + +namespace NPOI.HWPF.Model.Types +{ + + using System; + using NPOI.Util; + + using NPOI.HWPF.UserModel; + using System.Text; + + /** + * Section Properties. + * NOTE: This source Is automatically generated please do not modify this file. Either subclass or + * remove the record in src/records/definitions. + + * @author S. Ryan Ackley + */ + public abstract class SEPAbstractType : BaseObject + { + + protected byte field_1_bkc; + protected bool field_2_fTitlePage; + protected bool field_3_fAutoPgn; + protected byte field_4_nfcPgn; + + /** Arabic */ + /**/public const byte NFCPGN_ARABIC = 0; + /** Roman (upper case) */ + /**/public const byte NFCPGN_ROMAN_UPPER_CASE = 1; + /** Roman (lower case) */ + /**/public const byte NFCPGN_ROMAN_LOWER_CASE = 2; + /** Letter (upper case) */ + /**/public const byte NFCPGN_LETTER_UPPER_CASE = 3; + /** Letter (lower case) */ + /**/public const byte NFCPGN_LETTER_LOWER_CASE = 4; + + protected bool field_5_fUnlocked; + protected byte field_6_cnsPgn; + protected bool field_7_fPgnRestart; + protected bool field_8_fEndNote; + protected byte field_9_lnc; + protected byte field_10_grpfIhdt; + protected int field_11_nLnnMod; + protected int field_12_dxaLnn; + protected int field_13_dxaPgn; + protected int field_14_dyaPgn; + protected bool field_15_fLBetween; + protected byte field_16_vjc; + protected int field_17_dmBinFirst; + protected int field_18_dmBinOther; + protected int field_19_dmPaperReq; + protected BorderCode field_20_brcTop; + protected BorderCode field_21_brcLeft; + protected BorderCode field_22_brcBottom; + protected BorderCode field_23_brcRight; + protected bool field_24_fPropMark; + protected int field_25_ibstPropRMark; + protected DateAndTime field_26_dttmPropRMark; + protected int field_27_dxtCharSpace; + protected int field_28_dyaLinePitch; + protected int field_29_clm; + protected int field_30_unused2; + protected bool field_31_dmOrientPage; + public const bool DMORIENTPAGE_LANDSCAPE = false; + public const bool DMORIENTPAGE_PORTRAIT = true; + + protected byte field_32_iHeadingPgn; + protected int field_33_pgnStart; + protected int field_34_lnnMin; + protected int field_35_wTextFlow; + protected short field_36_unused3; + protected int field_37_pgbProp; + protected short field_38_unused4; + protected int field_39_xaPage; + protected int field_40_yaPage; + protected int field_41_xaPageNUp; + protected int field_42_yaPageNUp; + protected int field_43_dxaLeft; + protected int field_44_dxaRight; + protected int field_45_dyaTop; + protected int field_46_dyaBottom; + protected int field_47_dzaGutter; + protected int field_48_dyaHdrTop; + protected int field_49_dyaHdrBottom; + protected int field_50_ccolM1; + protected bool field_51_fEvenlySpaced; + protected byte field_52_unused5; + protected int field_53_dxaColumns; + protected int[] field_54_rgdxaColumn; + protected int field_55_dxaColumnWidth; + protected byte field_56_dmOrientFirst; + protected byte field_57_fLayout; + protected short field_58_unused6; + protected byte[] field_59_olstAnm; + + + public SEPAbstractType() + { + this.field_1_bkc = 2; + this.field_8_fEndNote = true; + this.field_13_dxaPgn = 720; + this.field_14_dyaPgn = 720; + this.field_31_dmOrientPage = true; + this.field_33_pgnStart = 1; + this.field_39_xaPage = 12240; + this.field_40_yaPage = 15840; + this.field_41_xaPageNUp = 12240; + this.field_42_yaPageNUp = 15840; + this.field_43_dxaLeft = 1800; + this.field_44_dxaRight = 1800; + this.field_45_dyaTop = 1440; + this.field_46_dyaBottom = 1440; + this.field_48_dyaHdrTop = 720; + this.field_49_dyaHdrBottom = 720; + this.field_51_fEvenlySpaced = true; + this.field_53_dxaColumns = 720; + } + + + /** + * Get the bkc field for the SEP record. + */ + public byte GetBkc() + { + return field_1_bkc; + } + + /** + * Set the bkc field for the SEP record. + */ + public void SetBkc(byte field_1_bkc) + { + this.field_1_bkc = field_1_bkc; + } + + /** + * Get the fTitlePage field for the SEP record. + */ + public bool GetFTitlePage() + { + return field_2_fTitlePage; + } + + /** + * Set the fTitlePage field for the SEP record. + */ + public void SetFTitlePage(bool field_2_fTitlePage) + { + this.field_2_fTitlePage = field_2_fTitlePage; + } + + /** + * Get the fAutoPgn field for the SEP record. + */ + public bool GetFAutoPgn() + { + return field_3_fAutoPgn; + } + + /** + * Set the fAutoPgn field for the SEP record. + */ + public void SetFAutoPgn(bool field_3_fAutoPgn) + { + this.field_3_fAutoPgn = field_3_fAutoPgn; + } + + /** + * Get the nfcPgn field for the SEP record. + */ + public byte GetNfcPgn() + { + return field_4_nfcPgn; + } + + /** + * Set the nfcPgn field for the SEP record. + */ + public void SetNfcPgn(byte field_4_nfcPgn) + { + this.field_4_nfcPgn = field_4_nfcPgn; + } + + /** + * Get the fUnlocked field for the SEP record. + */ + public bool GetFUnlocked() + { + return field_5_fUnlocked; + } + + /** + * Set the fUnlocked field for the SEP record. + */ + public void SetFUnlocked(bool field_5_fUnlocked) + { + this.field_5_fUnlocked = field_5_fUnlocked; + } + + /** + * Get the cnsPgn field for the SEP record. + */ + public byte GetCnsPgn() + { + return field_6_cnsPgn; + } + + /** + * Set the cnsPgn field for the SEP record. + */ + public void SetCnsPgn(byte field_6_cnsPgn) + { + this.field_6_cnsPgn = field_6_cnsPgn; + } + + /** + * Get the fPgnRestart field for the SEP record. + */ + public bool GetFPgnRestart() + { + return field_7_fPgnRestart; + } + + /** + * Set the fPgnRestart field for the SEP record. + */ + public void SetFPgnRestart(bool field_7_fPgnRestart) + { + this.field_7_fPgnRestart = field_7_fPgnRestart; + } + + /** + * Get the fEndNote field for the SEP record. + */ + public bool GetFEndNote() + { + return field_8_fEndNote; + } + + /** + * Set the fEndNote field for the SEP record. + */ + public void SetFEndNote(bool field_8_fEndNote) + { + this.field_8_fEndNote = field_8_fEndNote; + } + + /** + * Get the lnc field for the SEP record. + */ + public byte GetLnc() + { + return field_9_lnc; + } + + /** + * Set the lnc field for the SEP record. + */ + public void SetLnc(byte field_9_lnc) + { + this.field_9_lnc = field_9_lnc; + } + + /** + * Get the grpfIhdt field for the SEP record. + */ + public byte GetGrpfIhdt() + { + return field_10_grpfIhdt; + } + + /** + * Set the grpfIhdt field for the SEP record. + */ + public void SetGrpfIhdt(byte field_10_grpfIhdt) + { + this.field_10_grpfIhdt = field_10_grpfIhdt; + } + + /** + * Get the nLnnMod field for the SEP record. + */ + public int GetNLnnMod() + { + return field_11_nLnnMod; + } + + /** + * Set the nLnnMod field for the SEP record. + */ + public void SetNLnnMod(int field_11_nLnnMod) + { + this.field_11_nLnnMod = field_11_nLnnMod; + } + + /** + * Get the dxaLnn field for the SEP record. + */ + public int GetDxaLnn() + { + return field_12_dxaLnn; + } + + /** + * Set the dxaLnn field for the SEP record. + */ + public void SetDxaLnn(int field_12_dxaLnn) + { + this.field_12_dxaLnn = field_12_dxaLnn; + } + + /** + * Get the dxaPgn field for the SEP record. + */ + public int GetDxaPgn() + { + return field_13_dxaPgn; + } + + /** + * Set the dxaPgn field for the SEP record. + */ + public void SetDxaPgn(int field_13_dxaPgn) + { + this.field_13_dxaPgn = field_13_dxaPgn; + } + + /** + * Get the dyaPgn field for the SEP record. + */ + public int GetDyaPgn() + { + return field_14_dyaPgn; + } + + /** + * Set the dyaPgn field for the SEP record. + */ + public void SetDyaPgn(int field_14_dyaPgn) + { + this.field_14_dyaPgn = field_14_dyaPgn; + } + + /** + * Get the fLBetween field for the SEP record. + */ + public bool GetFLBetween() + { + return field_15_fLBetween; + } + + /** + * Set the fLBetween field for the SEP record. + */ + public void SetFLBetween(bool field_15_fLBetween) + { + this.field_15_fLBetween = field_15_fLBetween; + } + + /** + * Get the vjc field for the SEP record. + */ + public byte GetVjc() + { + return field_16_vjc; + } + + /** + * Set the vjc field for the SEP record. + */ + public void SetVjc(byte field_16_vjc) + { + this.field_16_vjc = field_16_vjc; + } + + /** + * Get the dmBinFirst field for the SEP record. + */ + public int GetDmBinFirst() + { + return field_17_dmBinFirst; + } + + /** + * Set the dmBinFirst field for the SEP record. + */ + public void SetDmBinFirst(int field_17_dmBinFirst) + { + this.field_17_dmBinFirst = field_17_dmBinFirst; + } + + /** + * Get the dmBinOther field for the SEP record. + */ + public int GetDmBinOther() + { + return field_18_dmBinOther; + } + + /** + * Set the dmBinOther field for the SEP record. + */ + public void SetDmBinOther(int field_18_dmBinOther) + { + this.field_18_dmBinOther = field_18_dmBinOther; + } + + /** + * Get the dmPaperReq field for the SEP record. + */ + public int GetDmPaperReq() + { + return field_19_dmPaperReq; + } + + /** + * Set the dmPaperReq field for the SEP record. + */ + public void SetDmPaperReq(int field_19_dmPaperReq) + { + this.field_19_dmPaperReq = field_19_dmPaperReq; + } + + /** + * Get the brcTop field for the SEP record. + */ + public BorderCode GetBrcTop() + { + return field_20_brcTop; + } + + /** + * Set the brcTop field for the SEP record. + */ + public void SetBrcTop(BorderCode field_20_brcTop) + { + this.field_20_brcTop = field_20_brcTop; + } + + /** + * Get the brcLeft field for the SEP record. + */ + public BorderCode GetBrcLeft() + { + return field_21_brcLeft; + } + + /** + * Set the brcLeft field for the SEP record. + */ + public void SetBrcLeft(BorderCode field_21_brcLeft) + { + this.field_21_brcLeft = field_21_brcLeft; + } + + /** + * Get the brcBottom field for the SEP record. + */ + public BorderCode GetBrcBottom() + { + return field_22_brcBottom; + } + + /** + * Set the brcBottom field for the SEP record. + */ + public void SetBrcBottom(BorderCode field_22_brcBottom) + { + this.field_22_brcBottom = field_22_brcBottom; + } + + /** + * Get the brcRight field for the SEP record. + */ + public BorderCode GetBrcRight() + { + return field_23_brcRight; + } + + /** + * Set the brcRight field for the SEP record. + */ + public void SetBrcRight(BorderCode field_23_brcRight) + { + this.field_23_brcRight = field_23_brcRight; + } + + /** + * Get the fPropMark field for the SEP record. + */ + public bool GetFPropMark() + { + return field_24_fPropMark; + } + + /** + * Set the fPropMark field for the SEP record. + */ + public void SetFPropMark(bool field_24_fPropMark) + { + this.field_24_fPropMark = field_24_fPropMark; + } + + /** + * Get the ibstPropRMark field for the SEP record. + */ + public int GetIbstPropRMark() + { + return field_25_ibstPropRMark; + } + + /** + * Set the ibstPropRMark field for the SEP record. + */ + public void SetIbstPropRMark(int field_25_ibstPropRMark) + { + this.field_25_ibstPropRMark = field_25_ibstPropRMark; + } + + /** + * Get the dttmPropRMark field for the SEP record. + */ + public DateAndTime GetDttmPropRMark() + { + return field_26_dttmPropRMark; + } + + /** + * Set the dttmPropRMark field for the SEP record. + */ + public void SetDttmPropRMark(DateAndTime field_26_dttmPropRMark) + { + this.field_26_dttmPropRMark = field_26_dttmPropRMark; + } + + /** + * Get the dxtCharSpace field for the SEP record. + */ + public int GetDxtCharSpace() + { + return field_27_dxtCharSpace; + } + + /** + * Set the dxtCharSpace field for the SEP record. + */ + public void SetDxtCharSpace(int field_27_dxtCharSpace) + { + this.field_27_dxtCharSpace = field_27_dxtCharSpace; + } + + /** + * Get the dyaLinePitch field for the SEP record. + */ + public int GetDyaLinePitch() + { + return field_28_dyaLinePitch; + } + + /** + * Set the dyaLinePitch field for the SEP record. + */ + public void SetDyaLinePitch(int field_28_dyaLinePitch) + { + this.field_28_dyaLinePitch = field_28_dyaLinePitch; + } + + /** + * Get the clm field for the SEP record. + */ + public int GetClm() + { + return field_29_clm; + } + + /** + * Set the clm field for the SEP record. + */ + public void SetClm(int field_29_clm) + { + this.field_29_clm = field_29_clm; + } + + /** + * Get the unused2 field for the SEP record. + */ + public int GetUnused2() + { + return field_30_unused2; + } + + /** + * Set the unused2 field for the SEP record. + */ + public void SetUnused2(int field_30_unused2) + { + this.field_30_unused2 = field_30_unused2; + } + + /** + * Get the dmOrientPage field for the SEP record. + */ + public bool GetDmOrientPage() + { + return field_31_dmOrientPage; + } + + /** + * Set the dmOrientPage field for the SEP record. + */ + public void SetDmOrientPage(bool field_31_dmOrientPage) + { + this.field_31_dmOrientPage = field_31_dmOrientPage; + } + + /** + * Get the iHeadingPgn field for the SEP record. + */ + public byte GetIHeadingPgn() + { + return field_32_iHeadingPgn; + } + + /** + * Set the iHeadingPgn field for the SEP record. + */ + public void SetIHeadingPgn(byte field_32_iHeadingPgn) + { + this.field_32_iHeadingPgn = field_32_iHeadingPgn; + } + + /** + * Get the pgnStart field for the SEP record. + */ + public int GetPgnStart() + { + return field_33_pgnStart; + } + + /** + * Set the pgnStart field for the SEP record. + */ + public void SetPgnStart(int field_33_pgnStart) + { + this.field_33_pgnStart = field_33_pgnStart; + } + + /** + * Get the lnnMin field for the SEP record. + */ + public int GetLnnMin() + { + return field_34_lnnMin; + } + + /** + * Set the lnnMin field for the SEP record. + */ + public void SetLnnMin(int field_34_lnnMin) + { + this.field_34_lnnMin = field_34_lnnMin; + } + + /** + * Get the wTextFlow field for the SEP record. + */ + public int GetWTextFlow() + { + return field_35_wTextFlow; + } + + /** + * Set the wTextFlow field for the SEP record. + */ + public void SetWTextFlow(int field_35_wTextFlow) + { + this.field_35_wTextFlow = field_35_wTextFlow; + } + + /** + * Get the unused3 field for the SEP record. + */ + public short GetUnused3() + { + return field_36_unused3; + } + + /** + * Set the unused3 field for the SEP record. + */ + public void SetUnused3(short field_36_unused3) + { + this.field_36_unused3 = field_36_unused3; + } + + /** + * Get the pgbProp field for the SEP record. + */ + public int GetPgbProp() + { + return field_37_pgbProp; + } + + /** + * Set the pgbProp field for the SEP record. + */ + public void SetPgbProp(int field_37_pgbProp) + { + this.field_37_pgbProp = field_37_pgbProp; + } + + /** + * Get the unused4 field for the SEP record. + */ + public short GetUnused4() + { + return field_38_unused4; + } + + /** + * Set the unused4 field for the SEP record. + */ + public void SetUnused4(short field_38_unused4) + { + this.field_38_unused4 = field_38_unused4; + } + + /** + * Get the xaPage field for the SEP record. + */ + public int GetXaPage() + { + return field_39_xaPage; + } + + /** + * Set the xaPage field for the SEP record. + */ + public void SetXaPage(int field_39_xaPage) + { + this.field_39_xaPage = field_39_xaPage; + } + + /** + * Get the yaPage field for the SEP record. + */ + public int GetYaPage() + { + return field_40_yaPage; + } + + /** + * Set the yaPage field for the SEP record. + */ + public void SetYaPage(int field_40_yaPage) + { + this.field_40_yaPage = field_40_yaPage; + } + + /** + * Get the xaPageNUp field for the SEP record. + */ + public int GetXaPageNUp() + { + return field_41_xaPageNUp; + } + + /** + * Set the xaPageNUp field for the SEP record. + */ + public void SetXaPageNUp(int field_41_xaPageNUp) + { + this.field_41_xaPageNUp = field_41_xaPageNUp; + } + + /** + * Get the yaPageNUp field for the SEP record. + */ + public int GetYaPageNUp() + { + return field_42_yaPageNUp; + } + + /** + * Set the yaPageNUp field for the SEP record. + */ + public void SetYaPageNUp(int field_42_yaPageNUp) + { + this.field_42_yaPageNUp = field_42_yaPageNUp; + } + + /** + * Get the dxaLeft field for the SEP record. + */ + public int GetDxaLeft() + { + return field_43_dxaLeft; + } + + /** + * Set the dxaLeft field for the SEP record. + */ + public void SetDxaLeft(int field_43_dxaLeft) + { + this.field_43_dxaLeft = field_43_dxaLeft; + } + + /** + * Get the dxaRight field for the SEP record. + */ + public int GetDxaRight() + { + return field_44_dxaRight; + } + + /** + * Set the dxaRight field for the SEP record. + */ + public void SetDxaRight(int field_44_dxaRight) + { + this.field_44_dxaRight = field_44_dxaRight; + } + + /** + * Get the dyaTop field for the SEP record. + */ + public int GetDyaTop() + { + return field_45_dyaTop; + } + + /** + * Set the dyaTop field for the SEP record. + */ + public void SetDyaTop(int field_45_dyaTop) + { + this.field_45_dyaTop = field_45_dyaTop; + } + + /** + * Get the dyaBottom field for the SEP record. + */ + public int GetDyaBottom() + { + return field_46_dyaBottom; + } + + /** + * Set the dyaBottom field for the SEP record. + */ + public void SetDyaBottom(int field_46_dyaBottom) + { + this.field_46_dyaBottom = field_46_dyaBottom; + } + + /** + * Get the dzaGutter field for the SEP record. + */ + public int GetDzaGutter() + { + return field_47_dzaGutter; + } + + /** + * Set the dzaGutter field for the SEP record. + */ + public void SetDzaGutter(int field_47_dzaGutter) + { + this.field_47_dzaGutter = field_47_dzaGutter; + } + + /** + * Get the dyaHdrTop field for the SEP record. + */ + public int GetDyaHdrTop() + { + return field_48_dyaHdrTop; + } + + /** + * Set the dyaHdrTop field for the SEP record. + */ + public void SetDyaHdrTop(int field_48_dyaHdrTop) + { + this.field_48_dyaHdrTop = field_48_dyaHdrTop; + } + + /** + * Get the dyaHdrBottom field for the SEP record. + */ + public int GetDyaHdrBottom() + { + return field_49_dyaHdrBottom; + } + + /** + * Set the dyaHdrBottom field for the SEP record. + */ + public void SetDyaHdrBottom(int field_49_dyaHdrBottom) + { + this.field_49_dyaHdrBottom = field_49_dyaHdrBottom; + } + + /** + * Get the ccolM1 field for the SEP record. + */ + public int GetCcolM1() + { + return field_50_ccolM1; + } + + /** + * Set the ccolM1 field for the SEP record. + */ + public void SetCcolM1(int field_50_ccolM1) + { + this.field_50_ccolM1 = field_50_ccolM1; + } + + /** + * Get the fEvenlySpaced field for the SEP record. + */ + public bool GetFEvenlySpaced() + { + return field_51_fEvenlySpaced; + } + + /** + * Set the fEvenlySpaced field for the SEP record. + */ + public void SetFEvenlySpaced(bool field_51_fEvenlySpaced) + { + this.field_51_fEvenlySpaced = field_51_fEvenlySpaced; + } + + /** + * Get the unused5 field for the SEP record. + */ + public byte GetUnused5() + { + return field_52_unused5; + } + + /** + * Set the unused5 field for the SEP record. + */ + public void SetUnused5(byte field_52_unused5) + { + this.field_52_unused5 = field_52_unused5; + } + + /** + * Get the dxaColumns field for the SEP record. + */ + public int GetDxaColumns() + { + return field_53_dxaColumns; + } + + /** + * Set the dxaColumns field for the SEP record. + */ + public void SetDxaColumns(int field_53_dxaColumns) + { + this.field_53_dxaColumns = field_53_dxaColumns; + } + + /** + * Get the rgdxaColumn field for the SEP record. + */ + public int[] GetRgdxaColumn() + { + return field_54_rgdxaColumn; + } + + /** + * Set the rgdxaColumn field for the SEP record. + */ + public void SetRgdxaColumn(int[] field_54_rgdxaColumn) + { + this.field_54_rgdxaColumn = field_54_rgdxaColumn; + } + + /** + * Get the dxaColumnWidth field for the SEP record. + */ + public int GetDxaColumnWidth() + { + return field_55_dxaColumnWidth; + } + + /** + * Set the dxaColumnWidth field for the SEP record. + */ + public void SetDxaColumnWidth(int field_55_dxaColumnWidth) + { + this.field_55_dxaColumnWidth = field_55_dxaColumnWidth; + } + + /** + * Get the dmOrientFirst field for the SEP record. + */ + public byte GetDmOrientFirst() + { + return field_56_dmOrientFirst; + } + + /** + * Set the dmOrientFirst field for the SEP record. + */ + public void SetDmOrientFirst(byte field_56_dmOrientFirst) + { + this.field_56_dmOrientFirst = field_56_dmOrientFirst; + } + + /** + * Get the fLayout field for the SEP record. + */ + public byte GetFLayout() + { + return field_57_fLayout; + } + + /** + * Set the fLayout field for the SEP record. + */ + public void SetFLayout(byte field_57_fLayout) + { + this.field_57_fLayout = field_57_fLayout; + } + + /** + * Get the unused6 field for the SEP record. + */ + public short GetUnused6() + { + return field_58_unused6; + } + + /** + * Set the unused6 field for the SEP record. + */ + public void SetUnused6(short field_58_unused6) + { + this.field_58_unused6 = field_58_unused6; + } + + /** + * Get the olstAnm field for the SEP record. + */ + public byte[] GetOlstAnm() + { + return field_59_olstAnm; + } + + /** + * Set the olstAnm field for the SEP record. + */ + public void SetOlstAnm(byte[] field_59_olstAnm) + { + this.field_59_olstAnm = field_59_olstAnm; + } + + + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/Types/TAPAbstractType.cs b/scratchpad/HWPF/Model/Types/TAPAbstractType.cs new file mode 100644 index 0000000..058d1c9 --- /dev/null +++ b/scratchpad/HWPF/Model/Types/TAPAbstractType.cs @@ -0,0 +1,331 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + + +namespace NPOI.HWPF.Model.Types +{ + + using System; + using NPOI.Util; + + using NPOI.HWPF.UserModel; + using System.Text; + + /** + * Table Properties. + * NOTE: This source Is automatically generated please do not modify this file. Either subclass or + * remove the record in src/records/definitions. + + * @author S. Ryan Ackley + */ + public abstract class TAPAbstractType:BaseObject + { + + protected int field_1_jc; + protected int field_2_dxaGapHalf; + protected int field_3_dyaRowHeight; + protected bool field_4_fCantSplit; + protected bool field_5_fTableHeader; + protected int field_6_tlp; + protected short field_7_itcMac; + protected short[] field_8_rgdxaCenter; + protected TableCellDescriptor[] field_9_rgtc; + protected ShadingDescriptor[] field_10_rgshd; + protected BorderCode field_11_brcBottom; + protected BorderCode field_12_brcTop; + protected BorderCode field_13_brcLeft; + protected BorderCode field_14_brcRight; + protected BorderCode field_15_brcVertical; + protected BorderCode field_16_brcHorizontal; + + + public TAPAbstractType() + { + + } + + /** + * Size of record (exluding 4 byte header) + */ + public int GetSize() + { + return 4 + +2 + 4 + 4 + 0 + 0 + 4 + 2 + 130 + 0 + 0 + 4 + 4 + 4 + 4 + 4 + 4; + } + + + + /** + * Get the jc field for the TAP record. + */ + public int GetJc() + { + return field_1_jc; + } + + /** + * Set the jc field for the TAP record. + */ + public void SetJc(int field_1_jc) + { + this.field_1_jc = field_1_jc; + } + + /** + * Get the dxaGapHalf field for the TAP record. + */ + public int GetDxaGapHalf() + { + return field_2_dxaGapHalf; + } + + /** + * Set the dxaGapHalf field for the TAP record. + */ + public void SetDxaGapHalf(int field_2_dxaGapHalf) + { + this.field_2_dxaGapHalf = field_2_dxaGapHalf; + } + + /** + * Get the dyaRowHeight field for the TAP record. + */ + public int GetDyaRowHeight() + { + return field_3_dyaRowHeight; + } + + /** + * Set the dyaRowHeight field for the TAP record. + */ + public void SetDyaRowHeight(int field_3_dyaRowHeight) + { + this.field_3_dyaRowHeight = field_3_dyaRowHeight; + } + + /** + * Get the fCantSplit field for the TAP record. + */ + public bool GetFCantSplit() + { + return field_4_fCantSplit; + } + + /** + * Set the fCantSplit field for the TAP record. + */ + public void SetFCantSplit(bool field_4_fCantSplit) + { + this.field_4_fCantSplit = field_4_fCantSplit; + } + + /** + * Get the fTableHeader field for the TAP record. + */ + public bool GetFTableHeader() + { + return field_5_fTableHeader; + } + + /** + * Set the fTableHeader field for the TAP record. + */ + public void SetFTableHeader(bool field_5_fTableHeader) + { + this.field_5_fTableHeader = field_5_fTableHeader; + } + + /** + * Get the tlp field for the TAP record. + */ + public int GetTlp() + { + return field_6_tlp; + } + + /** + * Set the tlp field for the TAP record. + */ + public void SetTlp(int field_6_tlp) + { + this.field_6_tlp = field_6_tlp; + } + + /** + * Get the itcMac field for the TAP record. + */ + public short GetItcMac() + { + return field_7_itcMac; + } + + /** + * Set the itcMac field for the TAP record. + */ + public void SetItcMac(short field_7_itcMac) + { + this.field_7_itcMac = field_7_itcMac; + } + + /** + * Get the rgdxaCenter field for the TAP record. + */ + public short[] GetRgdxaCenter() + { + return field_8_rgdxaCenter; + } + + /** + * Set the rgdxaCenter field for the TAP record. + */ + public void SetRgdxaCenter(short[] field_8_rgdxaCenter) + { + this.field_8_rgdxaCenter = field_8_rgdxaCenter; + } + + /** + * Get the rgtc field for the TAP record. + */ + public TableCellDescriptor[] GetRgtc() + { + return field_9_rgtc; + } + + /** + * Set the rgtc field for the TAP record. + */ + public void SetRgtc(TableCellDescriptor[] field_9_rgtc) + { + this.field_9_rgtc = field_9_rgtc; + } + + /** + * Get the rgshd field for the TAP record. + */ + public ShadingDescriptor[] GetRgshd() + { + return field_10_rgshd; + } + + /** + * Set the rgshd field for the TAP record. + */ + public void SetRgshd(ShadingDescriptor[] field_10_rgshd) + { + this.field_10_rgshd = field_10_rgshd; + } + + /** + * Get the brcBottom field for the TAP record. + */ + public BorderCode GetBrcBottom() + { + return field_11_brcBottom; + } + + /** + * Set the brcBottom field for the TAP record. + */ + public void SetBrcBottom(BorderCode field_11_brcBottom) + { + this.field_11_brcBottom = field_11_brcBottom; + } + + /** + * Get the brcTop field for the TAP record. + */ + public BorderCode GetBrcTop() + { + return field_12_brcTop; + } + + /** + * Set the brcTop field for the TAP record. + */ + public void SetBrcTop(BorderCode field_12_brcTop) + { + this.field_12_brcTop = field_12_brcTop; + } + + /** + * Get the brcLeft field for the TAP record. + */ + public BorderCode GetBrcLeft() + { + return field_13_brcLeft; + } + + /** + * Set the brcLeft field for the TAP record. + */ + public void SetBrcLeft(BorderCode field_13_brcLeft) + { + this.field_13_brcLeft = field_13_brcLeft; + } + + /** + * Get the brcRight field for the TAP record. + */ + public BorderCode GetBrcRight() + { + return field_14_brcRight; + } + + /** + * Set the brcRight field for the TAP record. + */ + public void SetBrcRight(BorderCode field_14_brcRight) + { + this.field_14_brcRight = field_14_brcRight; + } + + /** + * Get the brcVertical field for the TAP record. + */ + public BorderCode GetBrcVertical() + { + return field_15_brcVertical; + } + + /** + * Set the brcVertical field for the TAP record. + */ + public void SetBrcVertical(BorderCode field_15_brcVertical) + { + this.field_15_brcVertical = field_15_brcVertical; + } + + /** + * Get the brcHorizontal field for the TAP record. + */ + public BorderCode GetBrcHorizontal() + { + return field_16_brcHorizontal; + } + + /** + * Set the brcHorizontal field for the TAP record. + */ + public void SetBrcHorizontal(BorderCode field_16_brcHorizontal) + { + this.field_16_brcHorizontal = field_16_brcHorizontal; + } + + + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/Types/TCAbstractType.cs b/scratchpad/HWPF/Model/Types/TCAbstractType.cs new file mode 100644 index 0000000..febe1c7 --- /dev/null +++ b/scratchpad/HWPF/Model/Types/TCAbstractType.cs @@ -0,0 +1,789 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + + +namespace NPOI.HWPF.Model.Types +{ + + using System; + using NPOI.Util; + + using NPOI.HWPF.UserModel; + using System.Text; + + /** + * Table Cell Descriptor. + * NOTE: This source Is automatically generated please do not modify this file. Either subclass or + * remove the record in src/records/definitions. + + * @author S. Ryan Ackley + */ + public abstract class TCAbstractType : BaseObject + { + + protected short field_1_rgf; + private static BitField fFirstMerged = BitFieldFactory.GetInstance(0x0001); + private static BitField fMerged = BitFieldFactory.GetInstance(0x0002); + private static BitField fVertical = BitFieldFactory.GetInstance(0x0004); + private static BitField fBackward = BitFieldFactory.GetInstance(0x0008); + private static BitField fRotateFont = BitFieldFactory.GetInstance(0x0010); + private static BitField fVertMerge = BitFieldFactory.GetInstance(0x0020); + private static BitField fVertRestart = BitFieldFactory.GetInstance(0x0040); + private static BitField vertAlign = BitFieldFactory.GetInstance(0x0180); + private static BitField ftsWidth = new BitField(0x0E00); + private static BitField fFitText = new BitField(0x1000); + private static BitField fNoWrap = new BitField(0x2000); + private static BitField fUnused = new BitField(0xC000); + protected short field_2_wWidth; + protected short field_3_wCellPaddingLeft; + protected short field_4_wCellPaddingTop; + protected short field_5_wCellPaddingBottom; + protected short field_6_wCellPaddingRight; + protected byte field_7_ftsCellPaddingLeft; + protected byte field_8_ftsCellPaddingTop; + protected byte field_9_ftsCellPaddingBottom; + protected byte field_10_ftsCellPaddingRight; + protected short field_11_wCellSpacingLeft; + protected short field_12_wCellSpacingTop; + protected short field_13_wCellSpacingBottom; + protected short field_14_wCellSpacingRight; + protected byte field_15_ftsCellSpacingLeft; + protected byte field_16_ftsCellSpacingTop; + protected byte field_17_ftsCellSpacingBottom; + protected byte field_18_ftsCellSpacingRight; + protected BorderCode field_19_brcTop; + protected BorderCode field_20_brcLeft; + protected BorderCode field_21_brcBottom; + protected BorderCode field_22_brcRight; + + + public TCAbstractType() + { + + } + + + public override String ToString() + { + StringBuilder buffer = new StringBuilder(); + + buffer.Append("[TC]\n"); + + buffer.Append(" .rgf = "); + buffer.Append(" (").Append(GetRgf()).Append(" )\n"); + buffer.Append(" .fFirstMerged = ").Append(IsFFirstMerged()).Append('\n'); + buffer.Append(" .fMerged = ").Append(IsFMerged()).Append('\n'); + buffer.Append(" .fVertical = ").Append(IsFVertical()).Append('\n'); + buffer.Append(" .fBackward = ").Append(IsFBackward()).Append('\n'); + buffer.Append(" .fRotateFont = ").Append(IsFRotateFont()).Append('\n'); + buffer.Append(" .fVertMerge = ").Append(IsFVertMerge()).Append('\n'); + buffer.Append(" .fVertRestart = ").Append(IsFVertRestart()).Append('\n'); + buffer.Append(" .vertAlign = ").Append(GetVertAlign()).Append('\n'); + buffer.Append(" .ftsWidth = ").Append(GetFtsWidth()).Append('\n'); + buffer.Append(" .fFitText = ").Append(IsFFitText()).Append('\n'); + buffer.Append(" .fNoWrap = ").Append(IsFNoWrap()).Append('\n'); + buffer.Append(" .fUnused = ").Append(GetFUnused()).Append('\n'); + + buffer.Append(" .wWidth = "); + buffer.Append(" (").Append(GetWWidth()).Append(" )\n"); + + buffer.Append(" .wCellPaddingLeft = "); + buffer.Append(" (").Append(GetWCellPaddingLeft()).Append(" )\n"); + + buffer.Append(" .wCellPaddingTop = "); + buffer.Append(" (").Append(GetWCellPaddingTop()).Append(" )\n"); + + buffer.Append(" .wCellPaddingBottom = "); + buffer.Append(" (").Append(GetWCellPaddingBottom()).Append(" )\n"); + + buffer.Append(" .wCellPaddingRight = "); + buffer.Append(" (").Append(GetWCellPaddingRight()).Append(" )\n"); + + buffer.Append(" .ftsCellPaddingLeft = "); + buffer.Append(" (").Append(GetFtsCellPaddingLeft()).Append(" )\n"); + + buffer.Append(" .ftsCellPaddingTop = "); + buffer.Append(" (").Append(GetFtsCellPaddingTop()).Append(" )\n"); + + buffer.Append(" .ftsCellPaddingBottom = "); + buffer.Append(" (").Append(GetFtsCellPaddingBottom()).Append(" )\n"); + + buffer.Append(" .ftsCellPaddingRight = "); + buffer.Append(" (").Append(GetFtsCellPaddingRight()).Append(" )\n"); + + buffer.Append(" .wCellSpacingLeft = "); + buffer.Append(" (").Append(GetWCellSpacingLeft()).Append(" )\n"); + + buffer.Append(" .wCellSpacingTop = "); + buffer.Append(" (").Append(GetWCellSpacingTop()).Append(" )\n"); + + buffer.Append(" .wCellSpacingBottom = "); + buffer.Append(" (").Append(GetWCellSpacingBottom()).Append(" )\n"); + + buffer.Append(" .wCellSpacingRight = "); + buffer.Append(" (").Append(GetWCellSpacingRight()).Append(" )\n"); + + buffer.Append(" .ftsCellSpacingLeft = "); + buffer.Append(" (").Append(GetFtsCellSpacingLeft()).Append(" )\n"); + + buffer.Append(" .ftsCellSpacingTop = "); + buffer.Append(" (").Append(GetFtsCellSpacingTop()).Append(" )\n"); + + buffer.Append(" .ftsCellSpacingBottom = "); + buffer.Append(" (").Append(GetFtsCellSpacingBottom()).Append(" )\n"); + + buffer.Append(" .ftsCellSpacingRight = "); + buffer.Append(" (").Append(GetFtsCellSpacingRight()).Append(" )\n"); + + buffer.Append(" .brcTop = "); + buffer.Append(" (").Append(GetBrcTop()).Append(" )\n"); + + buffer.Append(" .brcLeft = "); + buffer.Append(" (").Append(GetBrcLeft()).Append(" )\n"); + + buffer.Append(" .brcBottom = "); + buffer.Append(" (").Append(GetBrcBottom()).Append(" )\n"); + + buffer.Append(" .brcRight = "); + buffer.Append(" (").Append(GetBrcRight()).Append(" )\n"); + + buffer.Append("[/TC]\n"); + return buffer.ToString(); + } + + /** + * Size of record (exluding 4 byte header) + */ + public int GetSize() + { + return 4 + +2 + 2 + 2 + 2 + 2 + 2 + 1 + 1 + 1 + 1 + 2 + 2 + 2 + 2 + 1 + 1 + 1 + 1 + 4 + 4 + 4 + 4; + } + + + + /** + * Get the rgf field for the TC record. + */ + public short GetRgf() + { + return field_1_rgf; + } + + /** + * Set the rgf field for the TC record. + */ + public void SetRgf(short field_1_rgf) + { + this.field_1_rgf = field_1_rgf; + } + + /** + * Get the wWidth field for the TC record. + */ + public short GetWWidth() + { + return field_2_wWidth; + } + + /** + * Set the wWidth field for the TC record. + */ + public void SetWWidth(short field_2_wWidth) + { + this.field_2_wWidth = field_2_wWidth; + } + + /** + * Get the wCellPaddingLeft field for the TC record. + */ + public short GetWCellPaddingLeft() + { + return field_3_wCellPaddingLeft; + } + + /** + * Set the wCellPaddingLeft field for the TC record. + */ + public void SetWCellPaddingLeft(short field_3_wCellPaddingLeft) + { + this.field_3_wCellPaddingLeft = field_3_wCellPaddingLeft; + } + + /** + * Get the wCellPaddingTop field for the TC record. + */ + public short GetWCellPaddingTop() + { + return field_4_wCellPaddingTop; + } + + /** + * Set the wCellPaddingTop field for the TC record. + */ + public void SetWCellPaddingTop(short field_4_wCellPaddingTop) + { + this.field_4_wCellPaddingTop = field_4_wCellPaddingTop; + } + + /** + * Get the wCellPaddingBottom field for the TC record. + */ + public short GetWCellPaddingBottom() + { + return field_5_wCellPaddingBottom; + } + + /** + * Set the wCellPaddingBottom field for the TC record. + */ + public void SetWCellPaddingBottom(short field_5_wCellPaddingBottom) + { + this.field_5_wCellPaddingBottom = field_5_wCellPaddingBottom; + } + + /** + * Get the wCellPaddingRight field for the TC record. + */ + public short GetWCellPaddingRight() + { + return field_6_wCellPaddingRight; + } + + /** + * Set the wCellPaddingRight field for the TC record. + */ + public void SetWCellPaddingRight(short field_6_wCellPaddingRight) + { + this.field_6_wCellPaddingRight = field_6_wCellPaddingRight; + } + + /** + * Get the ftsCellPaddingLeft field for the TC record. + */ + public byte GetFtsCellPaddingLeft() + { + return field_7_ftsCellPaddingLeft; + } + + /** + * Set the ftsCellPaddingLeft field for the TC record. + */ + public void SetFtsCellPaddingLeft(byte field_7_ftsCellPaddingLeft) + { + this.field_7_ftsCellPaddingLeft = field_7_ftsCellPaddingLeft; + } + + /** + * Get the ftsCellPaddingTop field for the TC record. + */ + public byte GetFtsCellPaddingTop() + { + return field_8_ftsCellPaddingTop; + } + + /** + * Set the ftsCellPaddingTop field for the TC record. + */ + public void SetFtsCellPaddingTop(byte field_8_ftsCellPaddingTop) + { + this.field_8_ftsCellPaddingTop = field_8_ftsCellPaddingTop; + } + + /** + * Get the ftsCellPaddingBottom field for the TC record. + */ + public byte GetFtsCellPaddingBottom() + { + return field_9_ftsCellPaddingBottom; + } + + /** + * Set the ftsCellPaddingBottom field for the TC record. + */ + public void SetFtsCellPaddingBottom(byte field_9_ftsCellPaddingBottom) + { + this.field_9_ftsCellPaddingBottom = field_9_ftsCellPaddingBottom; + } + + /** + * Get the ftsCellPaddingRight field for the TC record. + */ + public byte GetFtsCellPaddingRight() + { + return field_10_ftsCellPaddingRight; + } + + /** + * Set the ftsCellPaddingRight field for the TC record. + */ + public void SetFtsCellPaddingRight(byte field_10_ftsCellPaddingRight) + { + this.field_10_ftsCellPaddingRight = field_10_ftsCellPaddingRight; + } + + /** + * Get the wCellSpacingLeft field for the TC record. + */ + public short GetWCellSpacingLeft() + { + return field_11_wCellSpacingLeft; + } + + /** + * Set the wCellSpacingLeft field for the TC record. + */ + public void SetWCellSpacingLeft(short field_11_wCellSpacingLeft) + { + this.field_11_wCellSpacingLeft = field_11_wCellSpacingLeft; + } + + /** + * Get the wCellSpacingTop field for the TC record. + */ + public short GetWCellSpacingTop() + { + return field_12_wCellSpacingTop; + } + + /** + * Set the wCellSpacingTop field for the TC record. + */ + public void SetWCellSpacingTop(short field_12_wCellSpacingTop) + { + this.field_12_wCellSpacingTop = field_12_wCellSpacingTop; + } + + /** + * Get the wCellSpacingBottom field for the TC record. + */ + public short GetWCellSpacingBottom() + { + return field_13_wCellSpacingBottom; + } + + /** + * Set the wCellSpacingBottom field for the TC record. + */ + public void SetWCellSpacingBottom(short field_13_wCellSpacingBottom) + { + this.field_13_wCellSpacingBottom = field_13_wCellSpacingBottom; + } + + /** + * Get the wCellSpacingRight field for the TC record. + */ + public short GetWCellSpacingRight() + { + return field_14_wCellSpacingRight; + } + + /** + * Set the wCellSpacingRight field for the TC record. + */ + public void SetWCellSpacingRight(short field_14_wCellSpacingRight) + { + this.field_14_wCellSpacingRight = field_14_wCellSpacingRight; + } + + /** + * Get the ftsCellSpacingLeft field for the TC record. + */ + public byte GetFtsCellSpacingLeft() + { + return field_15_ftsCellSpacingLeft; + } + + /** + * Set the ftsCellSpacingLeft field for the TC record. + */ + public void SetFtsCellSpacingLeft(byte field_15_ftsCellSpacingLeft) + { + this.field_15_ftsCellSpacingLeft = field_15_ftsCellSpacingLeft; + } + + /** + * Get the ftsCellSpacingTop field for the TC record. + */ + public byte GetFtsCellSpacingTop() + { + return field_16_ftsCellSpacingTop; + } + + /** + * Set the ftsCellSpacingTop field for the TC record. + */ + public void SetFtsCellSpacingTop(byte field_16_ftsCellSpacingTop) + { + this.field_16_ftsCellSpacingTop = field_16_ftsCellSpacingTop; + } + + /** + * Get the ftsCellSpacingBottom field for the TC record. + */ + public byte GetFtsCellSpacingBottom() + { + return field_17_ftsCellSpacingBottom; + } + + /** + * Set the ftsCellSpacingBottom field for the TC record. + */ + public void SetFtsCellSpacingBottom(byte field_17_ftsCellSpacingBottom) + { + this.field_17_ftsCellSpacingBottom = field_17_ftsCellSpacingBottom; + } + + /** + * Get the ftsCellSpacingRight field for the TC record. + */ + public byte GetFtsCellSpacingRight() + { + return field_18_ftsCellSpacingRight; + } + + /** + * Set the ftsCellSpacingRight field for the TC record. + */ + public void SetFtsCellSpacingRight(byte field_18_ftsCellSpacingRight) + { + this.field_18_ftsCellSpacingRight = field_18_ftsCellSpacingRight; + } + + /** + * Get the brcTop field for the TC record. + */ + public BorderCode GetBrcTop() + { + return field_19_brcTop; + } + + /** + * Set the brcTop field for the TC record. + */ + public void SetBrcTop(BorderCode field_19_brcTop) + { + this.field_19_brcTop = field_19_brcTop; + } + + /** + * Get the brcLeft field for the TC record. + */ + public BorderCode GetBrcLeft() + { + return field_20_brcLeft; + } + + /** + * Set the brcLeft field for the TC record. + */ + public void SetBrcLeft(BorderCode field_20_brcLeft) + { + this.field_20_brcLeft = field_20_brcLeft; + } + + /** + * Get the brcBottom field for the TC record. + */ + public BorderCode GetBrcBottom() + { + return field_21_brcBottom; + } + + /** + * Set the brcBottom field for the TC record. + */ + public void SetBrcBottom(BorderCode field_21_brcBottom) + { + this.field_21_brcBottom = field_21_brcBottom; + } + + /** + * Get the brcRight field for the TC record. + */ + public BorderCode GetBrcRight() + { + return field_22_brcRight; + } + + /** + * Set the brcRight field for the TC record. + */ + public void SetBrcRight(BorderCode field_22_brcRight) + { + this.field_22_brcRight = field_22_brcRight; + } + + /** + * Sets the fFirstMerged field value. + * + */ + public void SetFFirstMerged(bool value) + { + field_1_rgf = (short)fFirstMerged.SetBoolean(field_1_rgf, value); + + + } + + /** + * + * @return the fFirstMerged field value. + */ + public bool IsFFirstMerged() + { + return fFirstMerged.IsSet(field_1_rgf); + + } + + /** + * Sets the fMerged field value. + * + */ + public void SetFMerged(bool value) + { + field_1_rgf = (short)fMerged.SetBoolean(field_1_rgf, value); + + + } + + /** + * + * @return the fMerged field value. + */ + public bool IsFMerged() + { + return fMerged.IsSet(field_1_rgf); + + } + + /** + * Sets the fVertical field value. + * + */ + public void SetFVertical(bool value) + { + field_1_rgf = (short)fVertical.SetBoolean(field_1_rgf, value); + + + } + + /** + * + * @return the fVertical field value. + */ + public bool IsFVertical() + { + return fVertical.IsSet(field_1_rgf); + + } + + /** + * Sets the fBackward field value. + * + */ + public void SetFBackward(bool value) + { + field_1_rgf = (short)fBackward.SetBoolean(field_1_rgf, value); + + + } + + /** + * + * @return the fBackward field value. + */ + public bool IsFBackward() + { + return fBackward.IsSet(field_1_rgf); + + } + + /** + * Sets the fRotateFont field value. + * + */ + public void SetFRotateFont(bool value) + { + field_1_rgf = (short)fRotateFont.SetBoolean(field_1_rgf, value); + + + } + + /** + * + * @return the fRotateFont field value. + */ + public bool IsFRotateFont() + { + return fRotateFont.IsSet(field_1_rgf); + + } + + /** + * Sets the fVertMerge field value. + * + */ + public void SetFVertMerge(bool value) + { + field_1_rgf = (short)fVertMerge.SetBoolean(field_1_rgf, value); + + + } + + /** + * + * @return the fVertMerge field value. + */ + public bool IsFVertMerge() + { + return fVertMerge.IsSet(field_1_rgf); + + } + + /** + * Sets the fVertRestart field value. + * + */ + public void SetFVertRestart(bool value) + { + field_1_rgf = (short)fVertRestart.SetBoolean(field_1_rgf, value); + + + } + + /** + * + * @return the fVertRestart field value. + */ + public bool IsFVertRestart() + { + return fVertRestart.IsSet(field_1_rgf); + + } + + /** + * Sets the vertAlign field value. + * + */ + public void SetVertAlign(byte value) + { + field_1_rgf = (short)vertAlign.SetValue(field_1_rgf, value); + + + } + + /** + * + * @return the vertAlign field value. + */ + public byte GetVertAlign() + { + return (byte)vertAlign.GetValue(field_1_rgf); + + } + + /** + * Sets the ftsWidth field value. + * + */ + public void SetFtsWidth(byte value) + { + field_1_rgf = (short)ftsWidth.SetValue(field_1_rgf, value); + + + } + + /** + * + * @return the ftsWidth field value. + */ + public byte GetFtsWidth() + { + return (byte)ftsWidth.GetValue(field_1_rgf); + + } + + /** + * Sets the fFitText field value. + * + */ + public void SetFFitText(bool value) + { + field_1_rgf = (short)fFitText.SetBoolean(field_1_rgf, value); + + + } + + /** + * + * @return the fFitText field value. + */ + public bool IsFFitText() + { + return fFitText.IsSet(field_1_rgf); + + } + + /** + * Sets the fNoWrap field value. + * + */ + public void SetFNoWrap(bool value) + { + field_1_rgf = (short)fNoWrap.SetBoolean(field_1_rgf, value); + + + } + + /** + * + * @return the fNoWrap field value. + */ + public bool IsFNoWrap() + { + return fNoWrap.IsSet(field_1_rgf); + + } + + /** + * Sets the fUnused field value. + * + */ + public void SetFUnused(byte value) + { + field_1_rgf = (short)fUnused.SetValue(field_1_rgf, value); + + + } + + /** + * + * @return the fUnused field value. + */ + public byte GetFUnused() + { + return (byte)fUnused.GetValue(field_1_rgf); + + } + + + } +} + + + diff --git a/scratchpad/HWPF/Model/Types/TLPAbstractType.cs b/scratchpad/HWPF/Model/Types/TLPAbstractType.cs new file mode 100644 index 0000000..8560241 --- /dev/null +++ b/scratchpad/HWPF/Model/Types/TLPAbstractType.cs @@ -0,0 +1,293 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using NPOI.Util; +using System.Text; +using System; +namespace NPOI.HWPF.Model.Types +{ + + /** + * Table Autoformat Look sPecifier (TLP). + *

    + * Class and fields descriptions are quoted from Microsoft Office Word 97-2007 + * Binary File Format + * + * NOTE: This source is automatically generated please do not modify this file. + * Either subclass or remove the record in src/records/defInitions. + * + * @author Sergey Vladimirov; according to Microsoft Office Word 97-2007 Binary + * File Format Specification [*.doc] + */ + + public abstract class TLPAbstractType : BaseObject + { + + protected short field_1_itl; + protected byte field_2_tlp_flags; + private static BitField fBorders = new BitField(0x0001); + private static BitField fShading = new BitField(0x0002); + private static BitField fFont = new BitField(0x0004); + private static BitField fColor = new BitField(0x0008); + private static BitField fBestFit = new BitField(0x0010); + private static BitField fHdrRows = new BitField(0x0020); + private static BitField fLastRow = new BitField(0x0040); + + public TLPAbstractType() + { + + } + + protected void FillFields(byte[] data, int offset) + { + field_1_itl = LittleEndian.GetShort(data, 0x0 + offset); + field_2_tlp_flags = data[0x2 + offset]; + } + + public void Serialize(byte[] data, int offset) + { + LittleEndian.PutShort(data, 0x0 + offset, field_1_itl); + data[0x2 + offset] = field_2_tlp_flags; + } + + public override String ToString() + { + StringBuilder buffer = new StringBuilder(); + + buffer.Append("[TLP]\n"); + + buffer.Append(" .itl = "); + buffer.Append(" (").Append(GetItl()).Append(" )\n"); + + buffer.Append(" .tlp_flags = "); + buffer.Append(" (").Append(GetTlp_flags()).Append(" )\n"); + buffer.Append(" .fBorders = ") + .Append(IsFBorders()).Append('\n'); + buffer.Append(" .fShading = ") + .Append(IsFShading()).Append('\n'); + buffer.Append(" .fFont = ") + .Append(IsFFont()).Append('\n'); + buffer.Append(" .fColor = ") + .Append(IsFColor()).Append('\n'); + buffer.Append(" .fBestFit = ") + .Append(IsFBestFit()).Append('\n'); + buffer.Append(" .fHdrRows = ") + .Append(IsFHdrRows()).Append('\n'); + buffer.Append(" .fLastRow = ") + .Append(IsFLastRow()).Append('\n'); + + buffer.Append("[/TLP]\n"); + return buffer.ToString(); + } + + /** + * Size of record (exluding 4 byte header) + */ + public int GetSize() + { + return 4 + +2 + 1; + } + + /** + * Get the itl field for the TLP record. + */ + public short GetItl() + { + return field_1_itl; + } + + /** + * Set the itl field for the TLP record. + */ + public void SetItl(short field_1_itl) + { + this.field_1_itl = field_1_itl; + } + + /** + * Get the tlp_flags field for the TLP record. + */ + public byte GetTlp_flags() + { + return field_2_tlp_flags; + } + + /** + * Set the tlp_flags field for the TLP record. + */ + public void SetTlp_flags(byte field_2_tlp_flags) + { + this.field_2_tlp_flags = field_2_tlp_flags; + } + + /** + * Sets the fBorders field value. When == 1, use the border properties from + * the selected table look + */ + public void SetFBorders(bool value) + { + field_2_tlp_flags = (byte)fBorders.SetBoolean(field_2_tlp_flags, + value); + + } + + /** + * When == 1, use the border properties from the selected table look + * + * @return the fBorders field value. + */ + public bool IsFBorders() + { + return fBorders.IsSet(field_2_tlp_flags); + + } + + /** + * Sets the fShading field value. When == 1, use the shading properties from + * the selected table look + */ + public void SetFShading(bool value) + { + field_2_tlp_flags = (byte)fShading.SetBoolean(field_2_tlp_flags, + value); + + } + + /** + * When == 1, use the shading properties from the selected table look + * + * @return the fShading field value. + */ + public bool IsFShading() + { + return fShading.IsSet(field_2_tlp_flags); + + } + + /** + * Sets the fFont field value. When == 1, use the font from the selected + * table look + */ + public void SetFFont(bool value) + { + field_2_tlp_flags = (byte)fFont.SetBoolean(field_2_tlp_flags, value); + + } + + /** + * When == 1, use the font from the selected table look + * + * @return the fFont field value. + */ + public bool IsFFont() + { + return fFont.IsSet(field_2_tlp_flags); + + } + + /** + * Sets the fColor field value. When == 1, use the color from the selected + * table look + */ + public void SetFColor(bool value) + { + field_2_tlp_flags = (byte)fColor.SetBoolean(field_2_tlp_flags, value); + + } + + /** + * When == 1, use the color from the selected table look + * + * @return the fColor field value. + */ + public bool IsFColor() + { + return fColor.IsSet(field_2_tlp_flags); + + } + + /** + * Sets the fBestFit field value. When == 1, do best fit from the selected + * table look + */ + public void SetFBestFit(bool value) + { + field_2_tlp_flags = (byte)fBestFit.SetBoolean(field_2_tlp_flags, + value); + + } + + /** + * When == 1, do best fit from the selected table look + * + * @return the fBestFit field value. + */ + public bool IsFBestFit() + { + return fBestFit.IsSet(field_2_tlp_flags); + + } + + /** + * Sets the fHdrRows field value. When == 1, apply properties from the + * selected table look to the header rows in the table + */ + public void SetFHdrRows(bool value) + { + field_2_tlp_flags = (byte)fHdrRows.SetBoolean(field_2_tlp_flags, + value); + + } + + /** + * When == 1, apply properties from the selected table look to the header + * rows in the table + * + * @return the fHdrRows field value. + */ + public bool IsFHdrRows() + { + return fHdrRows.IsSet(field_2_tlp_flags); + + } + + /** + * Sets the fLastRow field value. When == 1, apply properties from the + * selected table look to the last row in the table + */ + public void SetFLastRow(bool value) + { + field_2_tlp_flags = (byte)fLastRow.SetBoolean(field_2_tlp_flags, + value); + + } + + /** + * When == 1, apply properties from the selected table look to the last row + * in the table + * + * @return the fLastRow field value. + */ + public bool IsFLastRow() + { + return fLastRow.IsSet(field_2_tlp_flags); + + } + + } +} + diff --git a/scratchpad/HWPF/Model/UPX.cs b/scratchpad/HWPF/Model/UPX.cs new file mode 100644 index 0000000..1e0be61 --- /dev/null +++ b/scratchpad/HWPF/Model/UPX.cs @@ -0,0 +1,52 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + using System; + using System.Collections; + using NPOI.Util; + + public class UPX + { + private byte[] _upx; + + public UPX(byte[] upx) + { + _upx = upx; + } + + public byte[] GetUPX() + { + return _upx; + } + public int Size + { + get + { + return _upx.Length; + } + } + + public override bool Equals(Object o) + { + UPX upx = (UPX)o; + return Arrays.Equals(_upx, upx._upx); + } + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/Model/UnhandledDataStructure.cs b/scratchpad/HWPF/Model/UnhandledDataStructure.cs new file mode 100644 index 0000000..017f69d --- /dev/null +++ b/scratchpad/HWPF/Model/UnhandledDataStructure.cs @@ -0,0 +1,44 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.Model +{ + using System; + public class UnhandledDataStructure + { + byte[] _buf; + + public UnhandledDataStructure(byte[] buf, int offset, int length) + { + // Console.WriteLine("Yes, using my code"); + _buf = new byte[length]; + if (offset + length > buf.Length) + { + throw new IndexOutOfRangeException("buffer length is " + buf.Length + + "but code is trying to read " + length + " from offset " + offset); + } + Array.Copy(buf, offset, _buf, 0, length); + } + + internal byte[] GetBuf() + { + return _buf; + } + } +} + + diff --git a/scratchpad/HWPF/OldWordFileFormatException.cs b/scratchpad/HWPF/OldWordFileFormatException.cs new file mode 100644 index 0000000..7e68ff5 --- /dev/null +++ b/scratchpad/HWPF/OldWordFileFormatException.cs @@ -0,0 +1,28 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +using System; +namespace NPOI.HWPF +{ + + public class OldWordFileFormatException : OldFileFormatException + { + public OldWordFileFormatException(String s):base(s) + { + + } + } +} diff --git a/scratchpad/HWPF/Properties/AssemblyInfo.cs b/scratchpad/HWPF/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..78e6afa --- /dev/null +++ b/scratchpad/HWPF/Properties/AssemblyInfo.cs @@ -0,0 +1,39 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security; + +// General Information about an assembly Is controlled through the following +// Set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("HWPF")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("HWPF")] +[assembly: AssemblyCopyright("Copyright © 2009")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, Set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID Is for the ID of the typelib if this project Is exposed to COM +[assembly: Guid("4d6b2d82-e18c-4f26-ba83-6961d90b2706")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.3.0.0")] +[assembly: AssemblyFileVersion("1.3.0.0")] +[assembly: AllowPartiallyTrustedCallers] +//[assembly: InternalsVisibleTo("TestCases")] diff --git a/scratchpad/HWPF/SPRM/CharacterSprmCompressor.cs b/scratchpad/HWPF/SPRM/CharacterSprmCompressor.cs new file mode 100644 index 0000000..258aad8 --- /dev/null +++ b/scratchpad/HWPF/SPRM/CharacterSprmCompressor.cs @@ -0,0 +1,290 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.SPRM +{ + using System; + using System.Collections; + using NPOI.HWPF.UserModel; + using NPOI.Util; + + public class CharacterSprmCompressor + { + public CharacterSprmCompressor() + { + } + public static byte[] CompressCharacterProperty(CharacterProperties newCHP, CharacterProperties oldCHP) + { + ArrayList sprmList = new ArrayList(); + int size = 0; + + if (newCHP.IsFRMarkDel() != oldCHP.IsFRMarkDel()) + { + int value = 0; + if (newCHP.IsFRMarkDel()) + { + value = 0x01; + } + size += SprmUtils.AddSprm((short)0x0800, value, null, sprmList); + } + if (newCHP.IsFRMark() != oldCHP.IsFRMark()) + { + int value = 0; + if (newCHP.IsFRMark()) + { + value = 0x01; + } + size += SprmUtils.AddSprm((short)0x0801, value, null, sprmList); + } + if (newCHP.IsFFldVanish() != oldCHP.IsFFldVanish()) + { + int value = 0; + if (newCHP.IsFFldVanish()) + { + value = 0x01; + } + size += SprmUtils.AddSprm((short)0x0802, value, null, sprmList); + } + if (newCHP.IsFSpec() != oldCHP.IsFSpec() || newCHP.GetFcPic() != oldCHP.GetFcPic()) + { + size += SprmUtils.AddSprm((short)0x6a03, newCHP.GetFcPic(), null, sprmList); + } + if (newCHP.GetIbstRMark() != oldCHP.GetIbstRMark()) + { + size += SprmUtils.AddSprm((short)0x4804, newCHP.GetIbstRMark(), null, sprmList); + } + if (!newCHP.GetDttmRMark().Equals(oldCHP.GetDttmRMark())) + { + byte[] buf = new byte[4]; + newCHP.GetDttmRMark().Serialize(buf, 0); + + size += SprmUtils.AddSprm((short)0x6805, LittleEndian.GetInt(buf), null, sprmList); + } + if (newCHP.IsFData() != oldCHP.IsFData()) + { + int value = 0; + if (newCHP.IsFData()) + { + value = 0x01; + } + size += SprmUtils.AddSprm((short)0x0806, value, null, sprmList); + } + if (newCHP.IsFSpec() && newCHP.GetFtcSym() != 0) + { + byte[] varParam = new byte[4]; + LittleEndian.PutShort(varParam, 0, (short)newCHP.GetFtcSym()); + LittleEndian.PutShort(varParam, 2, (short)newCHP.GetXchSym()); + + size += SprmUtils.AddSprm((short)0x6a09, 0, varParam, sprmList); + } + if (newCHP.IsFOle2() != newCHP.IsFOle2()) + { + int value = 0; + if (newCHP.IsFOle2()) + { + value = 0x01; + } + size += SprmUtils.AddSprm((short)0x080a, value, null, sprmList); + } + if (newCHP.GetIcoHighlight() != oldCHP.GetIcoHighlight()) + { + size += SprmUtils.AddSprm((short)0x2a0c, newCHP.GetIcoHighlight(), null, sprmList); + } + if (newCHP.GetFcObj() != oldCHP.GetFcObj()) + { + size += SprmUtils.AddSprm((short)0x680e, newCHP.GetFcObj(), null, sprmList); + } + if (newCHP.GetIstd() != oldCHP.GetIstd()) + { + size += SprmUtils.AddSprm((short)0x4a30, newCHP.GetIstd(), null, sprmList); + } + if (newCHP.IsFBold() != oldCHP.IsFBold()) + { + int value = 0; + if (newCHP.IsFBold()) + { + value = 0x01; + } + size += SprmUtils.AddSprm((short)0x0835, value, null, sprmList); + } + if (newCHP.IsFItalic() != oldCHP.IsFItalic()) + { + int value = 0; + if (newCHP.IsFItalic()) + { + value = 0x01; + } + size += SprmUtils.AddSprm((short)0x0836, value, null, sprmList); + } + if (newCHP.IsFStrike() != oldCHP.IsFStrike()) + { + int value = 0; + if (newCHP.IsFStrike()) + { + value = 0x01; + } + size += SprmUtils.AddSprm((short)0x0837, value, null, sprmList); + } + if (newCHP.IsFOutline() != oldCHP.IsFOutline()) + { + int value = 0; + if (newCHP.IsFOutline()) + { + value = 0x01; + } + size += SprmUtils.AddSprm((short)0x0838, value, null, sprmList); + } + if (newCHP.IsFShadow() != oldCHP.IsFShadow()) + { + int value = 0; + if (newCHP.IsFShadow()) + { + value = 0x01; + } + size += SprmUtils.AddSprm((short)0x0839, value, null, sprmList); + } + if (newCHP.IsFSmallCaps() != oldCHP.IsFSmallCaps()) + { + int value = 0; + if (newCHP.IsFSmallCaps()) + { + value = 0x01; + } + size += SprmUtils.AddSprm((short)0x083a, value, null, sprmList); + } + if (newCHP.IsFCaps() != oldCHP.IsFCaps()) + { + int value = 0; + if (newCHP.IsFCaps()) + { + value = 0x01; + } + size += SprmUtils.AddSprm((short)0x083b, value, null, sprmList); + } + if (newCHP.IsFVanish() != oldCHP.IsFVanish()) + { + int value = 0; + if (newCHP.IsFVanish()) + { + value = 0x01; + } + size += SprmUtils.AddSprm((short)0x083c, value, null, sprmList); + } + if (newCHP.GetKul() != oldCHP.GetKul()) + { + size += SprmUtils.AddSprm((short)0x2a3e, newCHP.GetKul(), null, sprmList); + } + if (newCHP.GetDxaSpace() != oldCHP.GetDxaSpace()) + { + size += SprmUtils.AddSprm(unchecked((short)0x8840), newCHP.GetDxaSpace(), null, sprmList); + } + if (newCHP.GetIco() != oldCHP.GetIco()) + { + size += SprmUtils.AddSprm((short)0x2a42, newCHP.GetIco(), null, sprmList); + } + if (newCHP.GetHps() != oldCHP.GetHps()) + { + size += SprmUtils.AddSprm((short)0x4a43, newCHP.GetHps(), null, sprmList); + } + if (newCHP.GetHpsPos() != oldCHP.GetHpsPos()) + { + size += SprmUtils.AddSprm((short)0x4845, newCHP.GetHpsPos(), null, sprmList); + } + if (newCHP.GetHpsKern() != oldCHP.GetHpsKern()) + { + size += SprmUtils.AddSprm((short)0x484b, newCHP.GetHpsKern(), null, sprmList); + } + if (newCHP.GetYsr() != oldCHP.GetYsr()) + { + size += SprmUtils.AddSprm((short)0x484e, newCHP.GetYsr(), null, sprmList); + } + if (newCHP.GetFtcAscii() != oldCHP.GetFtcAscii()) + { + size += SprmUtils.AddSprm((short)0x4a4f, newCHP.GetFtcAscii(), null, sprmList); + } + if (newCHP.GetFtcFE() != oldCHP.GetFtcFE()) + { + size += SprmUtils.AddSprm((short)0x4a50, newCHP.GetFtcFE(), null, sprmList); + } + if (newCHP.GetFtcOther() != oldCHP.GetFtcOther()) + { + size += SprmUtils.AddSprm((short)0x4a51, newCHP.GetFtcOther(), null, sprmList); + } + + if (newCHP.IsFDStrike() != oldCHP.IsFDStrike()) + { + int value = 0; + if (newCHP.IsFDStrike()) + { + value = 0x01; + } + size += SprmUtils.AddSprm((short)0x2a53, value, null, sprmList); + } + if (newCHP.IsFImprint() != oldCHP.IsFImprint()) + { + int value = 0; + if (newCHP.IsFImprint()) + { + value = 0x01; + } + size += SprmUtils.AddSprm((short)0x0854, value, null, sprmList); + } + if (newCHP.IsFSpec() != oldCHP.IsFSpec()) + { + int value = 0; + if (newCHP.IsFSpec()) + { + value = 0x01; + } + size += SprmUtils.AddSprm((short)0x0855, value, null, sprmList); + } + if (newCHP.IsFObj() != oldCHP.IsFObj()) + { + int value = 0; + if (newCHP.IsFObj()) + { + value = 0x01; + } + size += SprmUtils.AddSprm((short)0x0856, value, null, sprmList); + } + if (newCHP.IsFEmboss() != oldCHP.IsFEmboss()) + { + int value = 0; + if (newCHP.IsFEmboss()) + { + value = 0x01; + } + size += SprmUtils.AddSprm((short)0x0858, value, null, sprmList); + } + if (newCHP.GetSfxtText() != oldCHP.GetSfxtText()) + { + size += SprmUtils.AddSprm((short)0x2859, newCHP.GetSfxtText(), null, sprmList); + } + if (newCHP.GetIco24() != oldCHP.GetIco24()) + { + if (newCHP.GetIco24() != -1) // don't Add a sprm if we're looking at an ico = Auto + size += SprmUtils.AddSprm((short)0x6870, newCHP.GetIco24(), null, sprmList); + } + + return SprmUtils.GetGrpprl(sprmList, size); + } + + + + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/SPRM/CharacterSprmUncompressor.cs b/scratchpad/HWPF/SPRM/CharacterSprmUncompressor.cs new file mode 100644 index 0000000..4f36149 --- /dev/null +++ b/scratchpad/HWPF/SPRM/CharacterSprmUncompressor.cs @@ -0,0 +1,604 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.SPRM +{ + + using NPOI.HWPF.UserModel; + using NPOI.Util; + using System; + + public class CharacterSprmUncompressor + { + public CharacterSprmUncompressor() + { + } + + public static CharacterProperties UncompressCHP(CharacterProperties parent, + byte[] grpprl, + int Offset) + { + CharacterProperties newProperties = null; + newProperties = (CharacterProperties)parent.Clone(); + + SprmIterator sprmIt = new SprmIterator(grpprl, Offset); + + while (sprmIt.HasNext()) + { + SprmOperation sprm = sprmIt.Next(); + UncompressCHPOperation(parent, newProperties, sprm); + } + + return newProperties; + } + + /** + * Used in decompression of a chpx. This performs an operation defined by + * a single sprm. + * + * @param oldCHP The base CharacterProperties. + * @param newCHP The current CharacterProperties. + * @param operand The operand defined by the sprm (See Word file format spec) + * @param param The parameter defined by the sprm (See Word file format spec) + * @param varParam The variable length parameter defined by the sprm. (See + * Word file format spec) + * @param grpprl The entire chpx that this operation is a part of. + * @param offset The offset in the grpprl of the next sprm + * @param styleSheet The StyleSheet for this document. + */ + static void UncompressCHPOperation(CharacterProperties oldCHP, + CharacterProperties newCHP, + SprmOperation sprm) + { + + switch (sprm.Operation) + { + case 0: + newCHP.SetFRMarkDel(GetFlag(sprm.Operand)); + break; + case 0x1: + newCHP.SetFRMark(GetFlag(sprm.Operand)); + break; + case 0x2: + newCHP.SetFFldVanish(GetFlag(sprm.Operand)); + break; + case 0x3: + newCHP.SetFcPic(sprm.Operand); + newCHP.SetFSpec(true); + break; + case 0x4: + newCHP.SetIbstRMark((short)sprm.Operand); + break; + case 0x5: + newCHP.SetDttmRMark(new DateAndTime(sprm.Grpprl, sprm.GrpprlOffset)); + break; + case 0x6: + newCHP.SetFData(GetFlag(sprm.Operand)); + break; + case 0x7: + //don't care about this + break; + case 0x8: + //short chsDiff = (short)((param & 0xff0000) >>> 16); + int operand = sprm.Operand; + short chsDiff = (short)(operand & 0x0000ff); + newCHP.SetFChsDiff(GetFlag(chsDiff)); + newCHP.SetChse((short)(operand & 0xffff00)); + break; + case 0x9: + newCHP.SetFSpec(true); + newCHP.SetFtcSym(LittleEndian.GetShort(sprm.Grpprl, sprm.GrpprlOffset)); + newCHP.SetXchSym(LittleEndian.GetShort(sprm.Grpprl, sprm.GrpprlOffset + 2)); + break; + case 0xa: + newCHP.SetFOle2(GetFlag(sprm.Operand)); + break; + case 0xb: + + // Obsolete + break; + case 0xc: + newCHP.SetIcoHighlight((byte)sprm.Operand); + newCHP.SetFHighlight(GetFlag(sprm.Operand)); + break; + case 0xd: + + // undocumented + break; + case 0xe: + newCHP.SetFcObj(sprm.Operand); + break; + case 0xf: + + // undocumented + break; + case 0x10: + + // undocumented + break; + + // undocumented till 0x30 + + case 0x11: + // sprmCFWebHidden + break; + case 0x12: + break; + case 0x13: + break; + case 0x14: + break; + case 0x15: + // sprmCRsidProp + break; + case 0x16: + // sprmCRsidText + break; + case 0x17: + // sprmCRsidRMDel + break; + case 0x18: + // sprmCFSpecVanish + break; + case 0x19: + break; + case 0x1a: + // sprmCFMathPr + break; + case 0x1b: + break; + case 0x1c: + break; + case 0x1d: + break; + case 0x1e: + break; + case 0x1f: + break; + case 0x20: + break; + case 0x21: + break; + case 0x22: + break; + case 0x23: + break; + case 0x24: + break; + case 0x25: + break; + case 0x26: + break; + case 0x27: + break; + case 0x28: + break; + case 0x29: + break; + case 0x2a: + break; + case 0x2b: + break; + case 0x2c: + break; + case 0x2d: + break; + case 0x2e: + break; + case 0x2f: + break; + case 0x30: + newCHP.SetIstd(sprm.Operand); + break; + case 0x31: + + //permutation vector for fast saves, who cares! + break; + case 0x32: + newCHP.SetFBold(false); + newCHP.SetFItalic(false); + newCHP.SetFOutline(false); + newCHP.SetFStrike(false); + newCHP.SetFShadow(false); + newCHP.SetFSmallCaps(false); + newCHP.SetFCaps(false); + newCHP.SetFVanish(false); + newCHP.SetKul((byte)0); + newCHP.SetIco((byte)0); + break; + case 0x33: + // preserve the fSpec Setting from the original CHP + bool fSpec = newCHP.IsFSpec(); + newCHP = (CharacterProperties)oldCHP.Clone(); + newCHP.SetFSpec(fSpec); + + return; + case 0x34: + // sprmCKcd + break; + case 0x35: + newCHP.SetFBold(GetCHPFlag((byte)sprm.Operand, oldCHP.IsFBold())); + break; + case 0x36: + newCHP.SetFItalic(GetCHPFlag((byte)sprm.Operand, oldCHP.IsFItalic())); + break; + case 0x37: + newCHP.SetFStrike(GetCHPFlag((byte)sprm.Operand, oldCHP.IsFStrike())); + break; + case 0x38: + newCHP.SetFOutline(GetCHPFlag((byte)sprm.Operand, oldCHP.IsFOutline())); + break; + case 0x39: + newCHP.SetFShadow(GetCHPFlag((byte)sprm.Operand, oldCHP.IsFShadow())); + break; + case 0x3a: + newCHP.SetFSmallCaps(GetCHPFlag((byte)sprm.Operand, oldCHP.IsFSmallCaps())); + break; + case 0x3b: + newCHP.SetFCaps(GetCHPFlag((byte)sprm.Operand, oldCHP.IsFCaps())); + break; + case 0x3c: + newCHP.SetFVanish(GetCHPFlag((byte)sprm.Operand, oldCHP.IsFVanish())); + break; + case 0x3d: + newCHP.SetFtcAscii((short)sprm.Operand); + break; + case 0x3e: + newCHP.SetKul((byte)sprm.Operand); + break; + case 0x3f: + operand = sprm.Operand; + int hps = operand & 0xff; + if (hps != 0) + { + newCHP.SetHps(hps); + } + + //byte cInc = (byte)(((byte)(param & 0xfe00) >>> 4) >> 1); + byte cInc = (byte)((operand & 0xff00) >> 8); + cInc = (byte)(cInc >> 1); + if (cInc != 0) + { + newCHP.SetHps(Math.Max(newCHP.GetHps() + (cInc * 2), 2)); + } + + //byte hpsPos = (byte)((param & 0xff0000) >>> 8); + byte hpsPos = (byte)((operand & 0xff0000) >> 16); + if (hpsPos != 0x80) + { + newCHP.SetHpsPos(hpsPos); + } + bool fAdjust = (operand & 0x0100) > 0; + if (fAdjust && hpsPos != 128 && hpsPos != 0 && oldCHP.GetHpsPos() == 0) + { + newCHP.SetHps(Math.Max(newCHP.GetHps() + (-2), 2)); + } + if (fAdjust && hpsPos == 0 && oldCHP.GetHpsPos() != 0) + { + newCHP.SetHps(Math.Max(newCHP.GetHps() + 2, 2)); + } + break; + case 0x40: + newCHP.SetDxaSpace(sprm.Operand); + break; + case 0x41: + newCHP.SetLidDefault((short)sprm.Operand); + break; + case 0x42: + newCHP.SetIco((byte)sprm.Operand); + break; + case 0x43: + newCHP.SetHps(sprm.Operand); + break; + case 0x44: + byte hpsLvl = (byte)sprm.Operand; + newCHP.SetHps(Math.Max(newCHP.GetHps() + (hpsLvl * 2), 2)); + break; + case 0x45: + newCHP.SetHpsPos((short)sprm.Operand); + break; + case 0x46: + if (sprm.Operand != 0) + { + if (oldCHP.GetHpsPos() == 0) + { + newCHP.SetHps(Math.Max(newCHP.GetHps() + (-2), 2)); + } + } + else + { + if (oldCHP.GetHpsPos() != 0) + { + newCHP.SetHps(Math.Max(newCHP.GetHps() + 2, 2)); + } + } + break; + case 0x47: + /*CharacterProperties genCHP = new CharacterProperties (); + genCHP.SetFtcAscii (4); + genCHP = (CharacterProperties) unCompressProperty (varParam, genCHP, + styleSheet); + CharacterProperties styleCHP = styleSheet.GetStyleDescription (oldCHP. + GetBaseIstd ()).GetCHP (); + if (genCHP.IsFBold () == newCHP.IsFBold ()) + { + newCHP.SetFBold (styleCHP.IsFBold ()); + } + if (genCHP.IsFItalic () == newCHP.IsFItalic ()) + { + newCHP.SetFItalic (styleCHP.IsFItalic ()); + } + if (genCHP.IsFSmallCaps () == newCHP.IsFSmallCaps ()) + { + newCHP.SetFSmallCaps (styleCHP.IsFSmallCaps ()); + } + if (genCHP.IsFVanish () == newCHP.IsFVanish ()) + { + newCHP.SetFVanish (styleCHP.IsFVanish ()); + } + if (genCHP.IsFStrike () == newCHP.IsFStrike ()) + { + newCHP.SetFStrike (styleCHP.IsFStrike ()); + } + if (genCHP.IsFCaps () == newCHP.IsFCaps ()) + { + newCHP.SetFCaps (styleCHP.IsFCaps ()); + } + if (genCHP.GetFtcAscii () == newCHP.GetFtcAscii ()) + { + newCHP.SetFtcAscii (styleCHP.GetFtcAscii ()); + } + if (genCHP.GetFtcFE () == newCHP.GetFtcFE ()) + { + newCHP.SetFtcFE (styleCHP.GetFtcFE ()); + } + if (genCHP.GetFtcOther () == newCHP.GetFtcOther ()) + { + newCHP.SetFtcOther (styleCHP.GetFtcOther ()); + } + if (genCHP.GetHps () == newCHP.GetHps ()) + { + newCHP.SetHps (styleCHP.GetHps ()); + } + if (genCHP.GetHpsPos () == newCHP.GetHpsPos ()) + { + newCHP.SetHpsPos (styleCHP.GetHpsPos ()); + } + if (genCHP.GetKul () == newCHP.GetKul ()) + { + newCHP.SetKul (styleCHP.GetKul ()); + } + if (genCHP.GetDxaSpace () == newCHP.GetDxaSpace ()) + { + newCHP.SetDxaSpace (styleCHP.GetDxaSpace ()); + } + if (genCHP.GetIco () == newCHP.GetIco ()) + { + newCHP.SetIco (styleCHP.GetIco ()); + } + if (genCHP.GetLidDefault () == newCHP.GetLidDefault ()) + { + newCHP.SetLidDefault (styleCHP.GetLidDefault ()); + } + if (genCHP.GetLidFE () == newCHP.GetLidFE ()) + { + newCHP.SetLidFE (styleCHP.GetLidFE ()); + }*/ + break; + case 0x48: + newCHP.SetIss((byte)sprm.Operand); + break; + case 0x49: + newCHP.SetHps(LittleEndian.GetShort(sprm.Grpprl, sprm.GrpprlOffset)); + break; + case 0x4a: + int increment = LittleEndian.GetShort(sprm.Grpprl, sprm.GrpprlOffset); + newCHP.SetHps(Math.Max(newCHP.GetHps() + increment, 8)); + break; + case 0x4b: + newCHP.SetHpsKern(sprm.Operand); + break; + case 0x4c: + // unCompressCHPOperation (oldCHP, newCHP, 0x47, param, varParam, + // styleSheet, opSize); + break; + case 0x4d: + float percentage = sprm.Operand / 100.0f; + int add = (int)(percentage * newCHP.GetHps()); + newCHP.SetHps(newCHP.GetHps() + add); + break; + case 0x4e: + newCHP.SetYsr((byte)sprm.Operand); + break; + case 0x4f: + newCHP.SetFtcAscii((short)sprm.Operand); + break; + case 0x50: + newCHP.SetFtcFE((short)sprm.Operand); + break; + case 0x51: + newCHP.SetFtcOther((short)sprm.Operand); + break; + case 0x52: + // sprmCCharScale + break; + case 0x53: + newCHP.SetFDStrike(GetFlag(sprm.Operand)); + break; + case 0x54: + newCHP.SetFImprint(GetFlag(sprm.Operand)); + break; + case 0x55: + newCHP.SetFSpec(GetFlag(sprm.Operand)); + break; + case 0x56: + newCHP.SetFObj(GetFlag(sprm.Operand)); + break; + case 0x57: + byte[] buf = sprm.Grpprl; + int offset = sprm.GrpprlOffset; + newCHP.SetFPropMark(buf[offset]); + newCHP.SetIbstPropRMark(LittleEndian.GetShort(buf, offset + 1)); + newCHP.SetDttmPropRMark(new DateAndTime(buf, offset + 3)); + break; + case 0x58: + newCHP.SetFEmboss(GetFlag(sprm.Operand)); + break; + case 0x59: + newCHP.SetSfxtText((byte)sprm.Operand); + break; + case 0x5a: + // sprmCFBiDi + break; + case 0x5b: + break; + case 0x5c: + // sprmCFBoldBi + break; + case 0x5d: + // sprmCFItalicBi + break; + case 0x5e: + // sprmCFtcBi + break; + case 0x5f: + // sprmCLidBi + break; + case 0x60: + // sprmCIcoBi + break; + case 0x61: + // sprmCHpsBi + break; + case 0x62: + byte[] xstDispFldRMark = new byte[32]; + buf = sprm.Grpprl; + offset = sprm.GrpprlOffset; + newCHP.SetFDispFldRMark(buf[offset]); + newCHP.SetIbstDispFldRMark(LittleEndian.GetShort(buf, offset + 1)); + newCHP.SetDttmDispFldRMark(new DateAndTime(buf, offset + 3)); + Array.Copy(buf, offset + 7, xstDispFldRMark, 0, 32); + newCHP.SetXstDispFldRMark(xstDispFldRMark); + break; + case 0x63: + newCHP.SetIbstRMarkDel((short)sprm.Operand); + break; + case 0x64: + newCHP.SetDttmRMarkDel(new DateAndTime(sprm.Grpprl, sprm.GrpprlOffset)); + break; + case 0x65: + newCHP.SetBrc(new BorderCode(sprm.Grpprl, sprm.GrpprlOffset)); + break; + case 0x66: + newCHP.SetShd(new ShadingDescriptor(sprm.Grpprl, sprm.GrpprlOffset)); + break; + case 0x67: + // Obsolete + break; + case 0x68: + // sprmCFUsePgsuSettings + break; + case 0x69: + break; + case 0x6a: + break; + case 0x6b: + break; + case 0x6c: + break; + case 0x6d: + newCHP.SetLidDefault((short)sprm.Operand); + break; + case 0x6e: + newCHP.SetLidFE((short)sprm.Operand); + break; + case 0x6f: + newCHP.SetIdctHint((byte)sprm.Operand); + break; + case 0x70: + newCHP.SetIco24(sprm.Operand); + break; + case 0x71: + // sprmCShd + break; + case 0x72: + // sprmCBrc + break; + case 0x73: + // sprmCRgLid0 + break; + case 0x74: + // sprmCRgLid1 + break; + } + } + + /** + * Converts an int into a bool. If the int is non-zero, it returns true. + * Otherwise it returns false. + * + * @param x The int to Convert. + * + * @return A bool whose value depends on x. + */ + public static bool GetFlag(int x) + { + return x != 0; + } + + private static bool GetCHPFlag(byte x, bool oldVal) + { + /* + switch(x) + { + case 0: + return false; + case 1: + return true; + case (byte)0x80: + return oldVal; + case (byte)0x81: + return !oldVal; + default: + return false; + } + */ + if (x == 0) + { + return false; + } + else if (x == 1) + { + return true; + } + else if ((x & 0x81) == 0x80) + { + return oldVal; + } + else if ((x & 0x81) == 0x81) + { + return !oldVal; + } + else + { + return false; + } + } + + } +} + diff --git a/scratchpad/HWPF/SPRM/ParagraphSprmCompressor.cs b/scratchpad/HWPF/SPRM/ParagraphSprmCompressor.cs new file mode 100644 index 0000000..f380343 --- /dev/null +++ b/scratchpad/HWPF/SPRM/ParagraphSprmCompressor.cs @@ -0,0 +1,386 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.SPRM +{ + using System; + using System.Collections; + using NPOI.HWPF.UserModel; + using NPOI.Util; + + public class ParagraphSprmCompressor + { + public ParagraphSprmCompressor() + { + } + + public static byte[] CompressParagraphProperty(ParagraphProperties newPAP, + ParagraphProperties oldPAP) + { + // page numbers links to Word97-2007BinaryFileFormat(doc)Specification.pdf, accessible from microsoft.com + ArrayList sprmList = new ArrayList(); + int size = 0; + + // Page 50 of public specification begins + if (newPAP.GetIstd() != oldPAP.GetIstd()) + { + // sprmPIstd + size += SprmUtils.AddSprm((short)0x4600, newPAP.GetIstd(), null, sprmList); + } + if (newPAP.GetJc() != oldPAP.GetJc()) + { + // sprmPJc80 + size += SprmUtils.AddSprm((short)0x2403, newPAP.GetJc(), null, sprmList); + } + if (newPAP.GetFSideBySide() != oldPAP.GetFSideBySide()) + { + // sprmPFSideBySide + size += SprmUtils.AddSprm((short)0x2404, Convert.ToBoolean(newPAP.GetFSideBySide()), sprmList); + } + if (newPAP.GetFKeep() != oldPAP.GetFKeep()) + { + size += SprmUtils.AddSprm((short)0x2405, newPAP.GetFKeep(), sprmList); + } + if (newPAP.GetFKeepFollow() != oldPAP.GetFKeepFollow()) + { + size += SprmUtils.AddSprm((short)0x2406, newPAP.GetFKeepFollow(), sprmList); + } + if (newPAP.GetFPageBreakBefore() != oldPAP.GetFPageBreakBefore()) + { + size += SprmUtils.AddSprm((short)0x2407, newPAP.GetFPageBreakBefore(), sprmList); + } + if (newPAP.GetBrcl() != oldPAP.GetBrcl()) + { + size += SprmUtils.AddSprm((short)0x2408, newPAP.GetBrcl(), null, sprmList); + } + if (newPAP.GetBrcp() != oldPAP.GetBrcp()) + { + size += SprmUtils.AddSprm((short)0x2409, newPAP.GetBrcp(), null, sprmList); + } + if (newPAP.GetIlvl() != oldPAP.GetIlvl()) + { + size += SprmUtils.AddSprm((short)0x260A, newPAP.GetIlvl(), null, sprmList); + } + if (newPAP.GetIlfo() != oldPAP.GetIlfo()) + { + size += SprmUtils.AddSprm((short)0x460b, newPAP.GetIlfo(), null, sprmList); + } + if (newPAP.GetFNoLnn() != oldPAP.GetFNoLnn()) + { + size += SprmUtils.AddSprm((short)0x240C, newPAP.GetFNoLnn(), sprmList); + } + + if (newPAP.GetItbdMac() != oldPAP.GetItbdMac() || + !Arrays.Equals(newPAP.GetRgdxaTab(), oldPAP.GetRgdxaTab()) || + !Arrays.Equals(newPAP.GetRgtbd(), oldPAP.GetRgtbd())) + { + /** @todo revisit this */ + // byte[] oldTabArray = oldPAP.GetRgdxaTab(); + // byte[] newTabArray = newPAP.GetRgdxaTab(); + // byte[] newTabDescriptors = newPAP.GetRgtbd(); + // byte[] varParam = new byte[2 + oldTabArray.Length + newTabArray.Length + + // newTabDescriptors.Length]; + // varParam[0] = (byte)(oldTabArray.Length/2); + // int offset = 1; + // Array.Copy(oldTabArray, 0, varParam, offset, oldTabArray.Length); + // offset += oldTabArray.Length; + // varParam[offset] = (byte)(newTabArray.Length/2); + // offset += 1; + // Array.Copy(newTabArray, 0, varParam, offset, newTabArray.Length); + // offset += newTabArray.Length; + // Array.Copy(newTabDescriptors, 0, varParam, offset, newTabDescriptors.Length); + // + // size += SprmUtils.AddSprm((short)0xC60D, 0, varParam, sprmList); + } + if (newPAP.GetDxaLeft() != oldPAP.GetDxaLeft()) + { + // sprmPDxaLeft80 + size += SprmUtils.AddSprm(unchecked((short)0x840F), newPAP.GetDxaLeft(), null, sprmList); + } + + // Page 51 of public specification begins + if (newPAP.GetDxaLeft1() != oldPAP.GetDxaLeft1()) + { + // sprmPDxaLeft180 + size += SprmUtils.AddSprm(unchecked((short)0x8411), newPAP.GetDxaLeft1(), null, sprmList); + } + if (newPAP.GetDxaRight() != oldPAP.GetDxaRight()) + { + // sprmPDxaRight80 + size += SprmUtils.AddSprm(unchecked((short)0x840E), newPAP.GetDxaRight(), null, sprmList); + } + if (newPAP.GetDxcLeft() != oldPAP.GetDxcLeft()) + { + // sprmPDxcLeft + size += SprmUtils.AddSprm((short)0x4456, newPAP.GetDxcLeft(), null, sprmList); + } + if (newPAP.GetDxcLeft1() != oldPAP.GetDxcLeft1()) + { + // sprmPDxcLeft1 + size += SprmUtils.AddSprm((short)0x4457, newPAP.GetDxcLeft1(), null, sprmList); + } + if (newPAP.GetDxcRight() != oldPAP.GetDxcRight()) + { + // sprmPDxcRight + size += SprmUtils.AddSprm((short)0x4455, newPAP.GetDxcRight(), null, sprmList); + } + if (!newPAP.GetLspd().Equals(oldPAP.GetLspd())) + { + // sprmPDyaLine + byte[] buf = new byte[4]; + newPAP.GetLspd().Serialize(buf, 0); + + size += SprmUtils.AddSprm((short)0x6412, LittleEndian.GetInt(buf), null, sprmList); + } + if (newPAP.GetDyaBefore() != oldPAP.GetDyaBefore()) + { + // sprmPDyaBefore + size += SprmUtils.AddSprm(unchecked((short)0xA413), newPAP.GetDyaBefore(), null, sprmList); + } + if (newPAP.GetDyaAfter() != oldPAP.GetDyaAfter()) + { + // sprmPDyaAfter + size += SprmUtils.AddSprm(unchecked((short)0xA414), newPAP.GetDyaAfter(), null, sprmList); + } + if (newPAP.GetFDyaBeforeAuto() != oldPAP.GetFDyaBeforeAuto()) + { + // sprmPFDyaBeforeAuto + size += SprmUtils.AddSprm((short)0x245B, newPAP.GetFDyaBeforeAuto(), sprmList); + } + if (newPAP.GetFDyaAfterAuto() != oldPAP.GetFDyaAfterAuto()) + { + // sprmPFDyaAfterAuto + size += SprmUtils.AddSprm((short)0x245C, newPAP.GetFDyaAfterAuto(), sprmList); + } + if (newPAP.GetFInTable() != oldPAP.GetFInTable()) + { + // sprmPFInTable + size += SprmUtils.AddSprm((short)0x2416, newPAP.GetFInTable(), sprmList); + } + if (newPAP.GetFTtp() != oldPAP.GetFTtp()) + { + // sprmPFTtp + size += SprmUtils.AddSprm((short)0x2417, newPAP.GetFTtp(), sprmList); + } + if (newPAP.GetDxaAbs() != oldPAP.GetDxaAbs()) + { + // sprmPDxaAbs + size += SprmUtils.AddSprm(unchecked((short)0x8418), newPAP.GetDxaAbs(), null, sprmList); + } + if (newPAP.GetDyaAbs() != oldPAP.GetDyaAbs()) + { + // sprmPDyaAbs + size += SprmUtils.AddSprm(unchecked((short)0x8419), newPAP.GetDyaAbs(), null, sprmList); + } + + if (newPAP.GetDxaWidth() != oldPAP.GetDxaWidth()) + { + // sprmPDxaWidth + size += SprmUtils.AddSprm(unchecked((short)0x841A), newPAP.GetDxaWidth(), null, sprmList); + } + + + if (newPAP.GetWr() != oldPAP.GetWr()) + { + size += SprmUtils.AddSprm((short)0x2423, newPAP.GetWr(), null, sprmList); + } + if (newPAP.GetBrcBar().Equals(oldPAP.GetBrcBar())) + { + // XXX: sprm code 0x6428 is sprmPBrcBetween80, but accessed property linked to sprmPBrcBar80 (0x6629) + int brc = newPAP.GetBrcBar().ToInt(); + size += SprmUtils.AddSprm((short)0x6428, brc, null, sprmList); + } + if (!newPAP.GetBrcBottom().Equals(oldPAP.GetBrcBottom())) + { + // sprmPBrcBottom80 + int brc = newPAP.GetBrcBottom().ToInt(); + size += SprmUtils.AddSprm((short)0x6426, brc, null, sprmList); + } + if (!newPAP.GetBrcLeft().Equals(oldPAP.GetBrcLeft())) + { + // sprmPBrcLeft80 + int brc = newPAP.GetBrcLeft().ToInt(); + size += SprmUtils.AddSprm((short)0x6425, brc, null, sprmList); + } + // Page 53 of public specification begins + if (!newPAP.GetBrcRight().Equals(oldPAP.GetBrcRight())) + { + // sprmPBrcRight80 + int brc = newPAP.GetBrcRight().ToInt(); + size += SprmUtils.AddSprm((short)0x6427, brc, null, sprmList); + } + if (!newPAP.GetBrcTop().Equals(oldPAP.GetBrcTop())) + { + // sprmPBrcTop80 + int brc = newPAP.GetBrcTop().ToInt(); + size += SprmUtils.AddSprm((short)0x6424, brc, null, sprmList); + } + if (newPAP.GetFNoAutoHyph() != oldPAP.GetFNoAutoHyph()) + { + size += SprmUtils.AddSprm((short)0x242A, newPAP.GetFNoAutoHyph(), sprmList); + } + if (newPAP.GetDyaHeight() != oldPAP.GetDyaHeight() || + newPAP.GetFMinHeight() != oldPAP.GetFMinHeight()) + { + // sprmPWHeightAbs + short val = (short)newPAP.GetDyaHeight(); + if (newPAP.GetFMinHeight()) + { + val |= unchecked((short)0x8000); + } + size += SprmUtils.AddSprm((short)0x442B, val, null, sprmList); + } + if (newPAP.GetDcs() != null && !newPAP.GetDcs().Equals(oldPAP.GetDcs())) + { + // sprmPDcs + size += SprmUtils.AddSprm((short)0x442C, newPAP.GetDcs().ToShort(), null, sprmList); + } + if (newPAP.GetShd() != null && !newPAP.GetShd().Equals(oldPAP.GetShd())) + { + // sprmPShd80 + size += SprmUtils.AddSprm((short)0x442D, newPAP.GetShd().ToShort(), null, sprmList); + } + if (newPAP.GetDyaFromText() != oldPAP.GetDyaFromText()) + { + // sprmPDyaFromText + size += SprmUtils.AddSprm(unchecked((short)0x842E), newPAP.GetDyaFromText(), null, sprmList); + } + if (newPAP.GetDxaFromText() != oldPAP.GetDxaFromText()) + { + // sprmPDxaFromText + size += SprmUtils.AddSprm(unchecked((short)0x842F), newPAP.GetDxaFromText(), null, sprmList); + } + if (newPAP.GetFLocked() != oldPAP.GetFLocked()) + { + // sprmPFLocked + size += SprmUtils.AddSprm((short)0x2430, newPAP.GetFLocked(), sprmList); + } + if (newPAP.GetFWidowControl() != oldPAP.GetFWidowControl()) + { + // sprmPFWidowControl + size += SprmUtils.AddSprm((short)0x2431, newPAP.GetFWidowControl(), sprmList); + } + if (newPAP.GetFKinsoku() != oldPAP.GetFKinsoku()) + { + size += SprmUtils.AddSprm((short)0x2433, newPAP.GetDyaBefore(), null, sprmList); + } + if (newPAP.GetFWordWrap() != oldPAP.GetFWordWrap()) + { + size += SprmUtils.AddSprm((short)0x2434, newPAP.GetFWordWrap(), sprmList); + } + if (newPAP.GetFOverflowPunct() != oldPAP.GetFOverflowPunct()) + { + size += SprmUtils.AddSprm((short)0x2435, newPAP.GetFOverflowPunct(), sprmList); + } + if (newPAP.GetFTopLinePunct() != oldPAP.GetFTopLinePunct()) + { + size += SprmUtils.AddSprm((short)0x2436, newPAP.GetFTopLinePunct(), sprmList); + } + if (newPAP.GetFAutoSpaceDE() != oldPAP.GetFAutoSpaceDE()) + { + size += SprmUtils.AddSprm((short)0x2437, newPAP.GetFAutoSpaceDE(), sprmList); + } + if (newPAP.GetFAutoSpaceDN() != oldPAP.GetFAutoSpaceDN()) + { + size += SprmUtils.AddSprm((short)0x2438, newPAP.GetFAutoSpaceDN(), sprmList); + } + if (newPAP.GetWAlignFont() != oldPAP.GetWAlignFont()) + { + size += SprmUtils.AddSprm((short)0x4439, newPAP.GetWAlignFont(), null, sprmList); + } + // Page 54 of public specification begins + if (newPAP.IsFBackward() != oldPAP.IsFBackward() || + newPAP.IsFVertical() != oldPAP.IsFVertical() || + newPAP.IsFRotateFont() != oldPAP.IsFRotateFont()) + { + int val = 0; + if (newPAP.IsFBackward()) + { + val |= 0x2; + } + if (newPAP.IsFVertical()) + { + val |= 0x1; + } + if (newPAP.IsFRotateFont()) + { + val |= 0x4; + } + size += SprmUtils.AddSprm((short)0x443A, val, null, sprmList); + } + if (!Arrays.Equals(newPAP.GetAnld(), oldPAP.GetAnld())) + { + // sprmPAnld80 + size += SprmUtils.AddSprm(unchecked((short)0xC63E), 0, newPAP.GetAnld(), sprmList); + } + if (newPAP.GetFPropRMark() != oldPAP.GetFPropRMark() || + newPAP.GetIbstPropRMark() != oldPAP.GetIbstPropRMark() || + !newPAP.GetDttmPropRMark().Equals(oldPAP.GetDttmPropRMark())) + { + // sprmPPropRMark + byte[] buf = new byte[7]; + buf[0] = (byte)(newPAP.GetFPropRMark() ? 1 : 0); + LittleEndian.PutShort(buf, 1, (short)newPAP.GetIbstPropRMark()); + newPAP.GetDttmPropRMark().Serialize(buf, 3); + size += SprmUtils.AddSprm(unchecked((short)0xC63F), 0, buf, sprmList); + } + if (newPAP.GetLvl() != oldPAP.GetLvl()) + { + // sprmPOutLvl + size += SprmUtils.AddSprm((short)0x2640, newPAP.GetLvl(), null, sprmList); + } + if (newPAP.GetFBiDi() != oldPAP.GetFBiDi()) + { + // sprmPFBiDi + size += SprmUtils.AddSprm((short)0x2441, newPAP.GetFBiDi(), sprmList); + } + if (newPAP.GetFNumRMIns() != oldPAP.GetFNumRMIns()) + { + // sprmPFNumRMIns + size += SprmUtils.AddSprm((short)0x2443, newPAP.GetFNumRMIns(), sprmList); + } + + if (!Arrays.Equals(newPAP.GetNumrm(), oldPAP.GetNumrm())) + { + // sprmPNumRM + size += SprmUtils.AddSprm(unchecked((short)0xC645), 0, newPAP.GetNumrm(), sprmList); + } + + if (newPAP.GetFInnerTableCell() != oldPAP.GetFInnerTableCell()) + { + // sprmPFInnerTableCell + size += SprmUtils.AddSprm((short)0x244b, newPAP.GetFInnerTableCell(), sprmList); + } + + if (newPAP.GetFTtpEmbedded() != oldPAP.GetFTtpEmbedded()) + { + // sprmPFInnerTtp + size += SprmUtils.AddSprm((short)0x244c, newPAP.GetFTtpEmbedded(), sprmList); + } + // Page 55 of public specification begins + if (newPAP.GetItap() != oldPAP.GetItap()) + { + // sprmPItap + size += SprmUtils.AddSprm((short)0x6649, newPAP.GetItap(), null, sprmList); + } + + return SprmUtils.GetGrpprl(sprmList, size); + + } + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/SPRM/ParagraphSprmUncompressor.cs b/scratchpad/HWPF/SPRM/ParagraphSprmUncompressor.cs new file mode 100644 index 0000000..c47c32d --- /dev/null +++ b/scratchpad/HWPF/SPRM/ParagraphSprmUncompressor.cs @@ -0,0 +1,490 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.SPRM +{ + using System; + using System.Collections; + using NPOI.HWPF.UserModel; + using NPOI.Util; + using NPOI.Util.Collections; + + + public class ParagraphSprmUncompressor + : SprmUncompressor + { + public ParagraphSprmUncompressor() + { + } + + public static ParagraphProperties UncompressPAP(ParagraphProperties parent, + byte[] grpprl, + int Offset) + { + ParagraphProperties newProperties = null; + newProperties = (ParagraphProperties)parent.Clone(); + + SprmIterator sprmIt = new SprmIterator(grpprl, Offset); + + while (sprmIt.HasNext()) + { + SprmOperation sprm = sprmIt.Next(); + + // PAPXs can contain table sprms if the paragraph marks the end of a + // table row + if (sprm.Type == SprmOperation.TYPE_PAP) + { + UncompressPAPOperation(newProperties, sprm); + } + } + + return newProperties; + } + + /** + * Performs an operation on a ParagraphProperties object. Used to uncompress + * from a papx. + * + * @param newPAP The ParagraphProperties object to perform the operation on. + * @param operand The operand that defines the operation. + * @param param The operation's parameter. + * @param varParam The operation's variable length parameter. + * @param grpprl The original papx. + * @param offset The current offset in the papx. + * @param spra A part of the sprm that defined this operation. + */ + static void UncompressPAPOperation(ParagraphProperties newPAP, SprmOperation sprm) + { + switch (sprm.Operation) + { + case 0: + newPAP.SetIstd(sprm.Operand); + break; + case 0x1: + + // Used only for piece table grpprl's not for PAPX + // int istdFirst = LittleEndian.Getshort (varParam, 2); + // int istdLast = LittleEndian.Getshort (varParam, 4); + // if ((newPAP.GetIstd () > istdFirst) || (newPAP.GetIstd () <= istdLast)) + // { + // permuteIstd (newPAP, varParam, opSize); + // } + break; + case 0x2: + if (newPAP.GetIstd() <= 9 || newPAP.GetIstd() >= 1) + { + byte paramTmp = (byte)sprm.Operand; + newPAP.SetIstd(newPAP.GetIstd() + paramTmp); + newPAP.SetLvl((byte)(newPAP.GetLvl() + paramTmp)); + + if (((paramTmp >> 7) & 0x01) == 1) + { + newPAP.SetIstd(Math.Max(newPAP.GetIstd(), 1)); + } + else + { + newPAP.SetIstd(Math.Min(newPAP.GetIstd(), 9)); + } + + } + break; + case 0x3: + // Physical justification of the paragraph + newPAP.SetJc((byte)sprm.Operand); + break; + case 0x4: + newPAP.SetFSideBySide(sprm.Operand!=0); + break; + case 0x5: + newPAP.SetFKeep(sprm.Operand!=0); + break; + case 0x6: + newPAP.SetFKeepFollow(sprm.Operand!=0); + break; + case 0x7: + newPAP.SetFPageBreakBefore(sprm.Operand!=0); + break; + case 0x8: + newPAP.SetBrcl((byte)sprm.Operand); + break; + case 0x9: + newPAP.SetBrcp((byte)sprm.Operand); + break; + case 0xa: + newPAP.SetIlvl((byte)sprm.Operand); + break; + case 0xb: + newPAP.SetIlfo(sprm.Operand); + break; + case 0xc: + newPAP.SetFNoLnn(sprm.Operand!=0); + break; + case 0xd: + /**handle tabs . variable parameter. seperate Processing needed*/ + handleTabs(newPAP, sprm); + break; + case 0xe: + newPAP.SetDxaRight(sprm.Operand); + break; + case 0xf: + newPAP.SetDxaLeft(sprm.Operand); + break; + case 0x10: + + // sprmPNest is only stored in grpprls linked to a piece table. + newPAP.SetDxaLeft(newPAP.GetDxaLeft() + sprm.Operand); + newPAP.SetDxaLeft(Math.Max(0, newPAP.GetDxaLeft())); + break; + case 0x11: + newPAP.SetDxaLeft1(sprm.Operand); + break; + case 0x12: + newPAP.SetLspd(new LineSpacingDescriptor(sprm.Grpprl, sprm.GrpprlOffset)); + break; + case 0x13: + newPAP.SetDyaBefore(sprm.Operand); + break; + case 0x14: + newPAP.SetDyaAfter(sprm.Operand); + break; + case 0x15: + // fast saved only + //ApplySprmPChgTabs (newPAP, varParam, opSize); + break; + case 0x16: + newPAP.SetFInTable(sprm.Operand!=0); + break; + case 0x17: + newPAP.SetFTtp(sprm.Operand!=0); + break; + case 0x18: + newPAP.SetDxaAbs(sprm.Operand); + break; + case 0x19: + newPAP.SetDyaAbs(sprm.Operand); + break; + case 0x1a: + newPAP.SetDxaWidth(sprm.Operand); + break; + case 0x1b: + byte param = (byte)sprm.Operand; + /** @todo handle paragraph postioning*/ + byte pcVert = (byte)((param & 0x0c) >> 2); + byte pcHorz = (byte)(param & 0x03); + if (pcVert != 3) + { + newPAP.SetPcVert(pcVert); + } + if (pcHorz != 3) + { + newPAP.SetPcHorz(pcHorz); + } + break; + + // BrcXXX1 is older Version. Brc is used + case 0x1c: + + //newPAP.SetBrcTop1((short)param); + break; + case 0x1d: + + //newPAP.SetBrcLeft1((short)param); + break; + case 0x1e: + + //newPAP.SetBrcBottom1((short)param); + break; + case 0x1f: + + //newPAP.SetBrcRight1((short)param); + break; + case 0x20: + + //newPAP.SetBrcBetween1((short)param); + break; + case 0x21: + + //newPAP.SetBrcBar1((byte)param); + break; + case 0x22: + newPAP.SetDxaFromText(sprm.Operand); + break; + case 0x23: + newPAP.SetWr((byte)sprm.Operand); + break; + case 0x24: + newPAP.SetBrcTop(new BorderCode(sprm.Grpprl, sprm.GrpprlOffset)); + break; + case 0x25: + newPAP.SetBrcLeft(new BorderCode(sprm.Grpprl, sprm.GrpprlOffset)); + break; + case 0x26: + newPAP.SetBrcBottom(new BorderCode(sprm.Grpprl, sprm.GrpprlOffset)); + break; + case 0x27: + newPAP.SetBrcRight(new BorderCode(sprm.Grpprl, sprm.GrpprlOffset)); + break; + case 0x28: + newPAP.SetBrcBetween(new BorderCode(sprm.Grpprl, sprm.GrpprlOffset)); + break; + case 0x29: + newPAP.SetBrcBar(new BorderCode(sprm.Grpprl, sprm.GrpprlOffset)); + break; + case 0x2a: + newPAP.SetFNoAutoHyph(sprm.Operand!=0); + break; + case 0x2b: + newPAP.SetDyaHeight(sprm.Operand); + break; + case 0x2c: + newPAP.SetDcs(new DropCapSpecifier((short)sprm.Operand)); + break; + case 0x2d: + newPAP.SetShd(new ShadingDescriptor((short)sprm.Operand)); + break; + case 0x2e: + newPAP.SetDyaFromText(sprm.Operand); + break; + case 0x2f: + newPAP.SetDxaFromText(sprm.Operand); + break; + case 0x30: + newPAP.SetFLocked(sprm.Operand!=0); + break; + case 0x31: + newPAP.SetFWidowControl(sprm.Operand!=0); + break; + case 0x32: + + //undocumented + break; + case 0x33: + newPAP.SetFKinsoku(sprm.Operand!=0); + break; + case 0x34: + newPAP.SetFWordWrap(sprm.Operand!=0); + break; + case 0x35: + newPAP.SetFOverflowPunct(sprm.Operand!=0); + break; + case 0x36: + newPAP.SetFTopLinePunct(sprm.Operand!=0); + break; + case 0x37: + newPAP.SetFAutoSpaceDE(sprm.Operand!=0); + break; + case 0x38: + newPAP.SetFAutoSpaceDN(sprm.Operand!=0); + break; + case 0x39: + newPAP.SetWAlignFont(sprm.Operand); + break; + case 0x3a: + newPAP.SetFontAlign((short)sprm.Operand); + break; + case 0x3b: + + //obsolete + break; + case 0x3e: + byte[] buf = new byte[sprm.Size - 3]; + Array.Copy(buf, 0, sprm.Grpprl, sprm.GrpprlOffset, + buf.Length); + newPAP.SetAnld(buf); + break; + case 0x3f: + //don't really need this. spec is confusing regarding this + //sprm + byte[] varParam = sprm.Grpprl; + int offset = sprm.GrpprlOffset; + newPAP.SetFPropRMark(varParam[offset]!=0); + newPAP.SetIbstPropRMark(LittleEndian.GetShort(varParam, offset + 1)); + newPAP.SetDttmPropRMark(new DateAndTime(varParam, offset + 3)); + + break; + case 0x40: + // This condition commented out, as Word seems to set outline levels even for + // paragraph with other styles than Heading 1..9, even though specification + // does not say so. See bug 49820 for discussion. + //if (newPAP.GetIstd () < 1 && newPAP.GetIstd () > 9) + //{ + newPAP.SetLvl((byte)sprm.Operand); + //} + break; + case 0x41: + + // undocumented + break; + case 0x43: + + //pap.fNumRMIns + newPAP.SetFNumRMIns(sprm.Operand!=0); + break; + case 0x44: + + //undocumented + break; + case 0x45: + if (sprm.SizeCode == 6) + { + byte[] buf1 = new byte[sprm.Size - 3]; + Array.Copy(buf1, 0, sprm.Grpprl, sprm.GrpprlOffset, buf1.Length); + newPAP.SetNumrm(buf1); + } + else + { + /**@todo handle large PAPX from data stream*/ + } + break; + + case 0x47: + newPAP.SetFUsePgsuSettings(sprm.Operand!=0); + break; + case 0x48: + newPAP.SetFAdjustRight(sprm.Operand!=0); + break; + case 0x49: + // sprmPItap -- 0x6649 + newPAP.SetItap(sprm.Operand); + break; + case 0x4a: + // sprmPDtap -- 0x664a + newPAP.SetItap((byte)(newPAP.GetItap() + sprm.Operand)); + break; + case 0x4b: + // sprmPFInnerTableCell -- 0x244b + newPAP.SetFInnerTableCell(sprm.Operand!=0); + break; + case 0x4c: + // sprmPFInnerTtp -- 0x244c + newPAP.SetFTtpEmbedded(sprm.Operand!=0); + break; + case 0x61: + // sprmPJc + newPAP.SetJustificationLogical((byte)sprm.Operand); + break; + default: + break; + } + } + + private static void handleTabs(ParagraphProperties pap, SprmOperation sprm) + { + byte[] grpprl = sprm.Grpprl; + int offset = sprm.GrpprlOffset; + int delSize = grpprl[offset++]; + int[] tabPositions = pap.GetRgdxaTab(); + byte[] tabDescriptors = pap.GetRgtbd(); + + Hashtable tabMap = new Hashtable(); + for (int x = 0; x < tabPositions.Length; x++) + { + tabMap.Add(tabPositions[x], tabDescriptors[x]); + } + + for (int x = 0; x < delSize; x++) + { + tabMap.Remove(LittleEndian.GetShort(grpprl, offset)); + offset += LittleEndianConsts.SHORT_SIZE; + } + + int addSize = grpprl[offset++]; + int start = offset; + for (int x = 0; x < addSize; x++) + { + int key = LittleEndian.GetShort(grpprl, offset); + Byte val = grpprl[start + ((LittleEndianConsts.SHORT_SIZE * addSize) + x)]; + tabMap.Add(key, val); + offset += LittleEndianConsts.SHORT_SIZE; + } + + tabPositions = new int[tabMap.Count]; + tabDescriptors = new byte[tabPositions.Length]; + ArrayList list = new ArrayList(); + + IEnumerator keyIT = tabMap.Keys.GetEnumerator(); + while (keyIT.MoveNext()) + { + list.Add(keyIT.Current); + } + list.Sort(); + + for (int x = 0; x < tabPositions.Length; x++) + { + int key = (int)list[x]; + tabPositions[x] = key; + tabDescriptors[x] = (byte)tabMap[key]; + } + + pap.SetRgdxaTab(tabPositions); + pap.SetRgtbd(tabDescriptors); + } + + // private static void handleTabsAgain(ParagraphProperties pap, SprmOperation sprm) + // { + // byte[] grpprl = sprm.Grpprl; + // int offset = sprm.GrpprlOffset; + // int delSize = grpprl[Offset++]; + // int[] tabPositions = pap.GetRgdxaTab(); + // byte[] tabDescriptors = pap.GetRgtbd(); + // + // HashMap tabMap = new HashMap(); + // for (int x = 0; x < tabPositions.Length; x++) + // { + // tabMap.Put(Int32.ValueOf(tabPositions[x]), Byte.ValueOf(tabDescriptors[x])); + // } + // + // for (int x = 0; x < delSize; x++) + // { + // tabMap.Remove(Int32.valueOf(LittleEndian.getInt(grpprl, Offset))); + // offset += LittleEndian.INT_SIZE;; + // } + // + // int AddSize = grpprl[Offset++]; + // for (int x = 0; x < AddSize; x++) + // { + // Integer key = Int32.ValueOf(LittleEndian.getInt(grpprl, Offset)); + // Byte val = Byte.ValueOf(grpprl[(LittleEndian.INT_SIZE * (AddSize - x)) + x]); + // tabMap.Put(key, val); + // offset += LittleEndian.INT_SIZE; + // } + // + // tabPositions = new int[tabMap.Count]; + // tabDescriptors = new byte[tabPositions.Length]; + // ArrayList list = new ArrayList(); + // + // Iterator keyIT = tabMap.keySet().iterator(); + // while (keyIT.hasNext()) + // { + // list.Add(keyIT.next()); + // } + // Collections.sort(list); + // + // for (int x = 0; x < tabPositions.Length; x++) + // { + // Integer key = ((Integer)list.Get(x)); + // tabPositions[x] = key.intValue(); + // tabDescriptors[x] = ((Byte)tabMap.Get(key)).byteValue(); + // } + // + // pap.SetRgdxaTab(tabPositions); + // pap.SetRgtbd(tabDescriptors); + // } + + } + +} \ No newline at end of file diff --git a/scratchpad/HWPF/SPRM/SectionSprmCompressor.cs b/scratchpad/HWPF/SPRM/SectionSprmCompressor.cs new file mode 100644 index 0000000..be50656 --- /dev/null +++ b/scratchpad/HWPF/SPRM/SectionSprmCompressor.cs @@ -0,0 +1,238 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +namespace NPOI.HWPF.SPRM +{ + + using System; + using System.Collections; + using NPOI.HWPF.UserModel; + using NPOI.Util; + using NPOI.HWPF.Model.Types; + + + public class SectionSprmCompressor + { + private static SectionProperties DEFAULT_SEP = new SectionProperties(); + public SectionSprmCompressor() + { + } + public static byte[] CompressSectionProperty(SectionProperties newSEP) + { + int size = 0; + ArrayList sprmList = new ArrayList(); + + if (newSEP.GetCnsPgn() != DEFAULT_SEP.GetCnsPgn()) + { + size += SprmUtils.AddSprm((short)0x3000, newSEP.GetCnsPgn(), null, sprmList); + } + if (newSEP.GetIHeadingPgn() != DEFAULT_SEP.GetIHeadingPgn()) + { + size += SprmUtils.AddSprm((short)0x3001, newSEP.GetIHeadingPgn(), null, sprmList); + } + if (!Arrays.Equals(newSEP.GetOlstAnm(), DEFAULT_SEP.GetOlstAnm())) + { + size += SprmUtils.AddSprm(unchecked((short)0xD202), 0, newSEP.GetOlstAnm(), sprmList); + } + if (newSEP.GetFEvenlySpaced() != DEFAULT_SEP.GetFEvenlySpaced()) + { + size += SprmUtils.AddSprm((short)0x3005, newSEP.GetFEvenlySpaced() ? 1 : 0, null, sprmList); + } + if (newSEP.GetFUnlocked() != DEFAULT_SEP.GetFUnlocked()) + { + size += SprmUtils.AddSprm((short)0x3006, newSEP.GetFUnlocked() ? 1 : 0, null, sprmList); + } + if (newSEP.GetDmBinFirst() != DEFAULT_SEP.GetDmBinFirst()) + { + size += SprmUtils.AddSprm((short)0x5007, newSEP.GetDmBinFirst(), null, sprmList); + } + if (newSEP.GetDmBinOther() != DEFAULT_SEP.GetDmBinOther()) + { + size += SprmUtils.AddSprm((short)0x5008, newSEP.GetDmBinOther(), null, sprmList); + } + if (newSEP.GetBkc() != DEFAULT_SEP.GetBkc()) + { + size += SprmUtils.AddSprm((short)0x3009, newSEP.GetBkc(), null, sprmList); + } + if (newSEP.GetFTitlePage() != DEFAULT_SEP.GetFTitlePage()) + { + size += SprmUtils.AddSprm((short)0x300A, newSEP.GetFTitlePage() ? 1 : 0, null, sprmList); + } + if (newSEP.GetCcolM1() != DEFAULT_SEP.GetCcolM1()) + { + size += SprmUtils.AddSprm((short)0x500B, newSEP.GetCcolM1(), null, sprmList); + } + if (newSEP.GetDxaColumns() != DEFAULT_SEP.GetDxaColumns()) + { + size += SprmUtils.AddSprm(unchecked((short)0x900C), newSEP.GetDxaColumns(), null, sprmList); + } + if (newSEP.GetFAutoPgn() != DEFAULT_SEP.GetFAutoPgn()) + { + size += SprmUtils.AddSprm((short)0x300D, newSEP.GetFAutoPgn() ? 1 : 0, null, sprmList); + } + if (newSEP.GetNfcPgn() != DEFAULT_SEP.GetNfcPgn()) + { + size += SprmUtils.AddSprm((short)0x300E, newSEP.GetNfcPgn(), null, sprmList); + } + if (newSEP.GetDyaPgn() != DEFAULT_SEP.GetDyaPgn()) + { + size += SprmUtils.AddSprm(unchecked((short)0xB00F), newSEP.GetDyaPgn(), null, sprmList); + } + if (newSEP.GetDxaPgn() != DEFAULT_SEP.GetDxaPgn()) + { + size += SprmUtils.AddSprm(unchecked((short)0xB010), newSEP.GetDxaPgn(), null, sprmList); + } + if (newSEP.GetFPgnRestart() != DEFAULT_SEP.GetFPgnRestart()) + { + size += SprmUtils.AddSprm((short)0x3011, newSEP.GetFPgnRestart() ? 1 : 0, null, sprmList); + } + if (newSEP.GetFEndNote() != DEFAULT_SEP.GetFEndNote()) + { + size += SprmUtils.AddSprm((short)0x3012, newSEP.GetFEndNote() ? 1 : 0, null, sprmList); + } + if (newSEP.GetLnc() != DEFAULT_SEP.GetLnc()) + { + size += SprmUtils.AddSprm((short)0x3013, newSEP.GetLnc(), null, sprmList); + } + if (newSEP.GetGrpfIhdt() != DEFAULT_SEP.GetGrpfIhdt()) + { + size += SprmUtils.AddSprm((short)0x3014, newSEP.GetGrpfIhdt(), null, sprmList); + } + if (newSEP.GetNLnnMod() != DEFAULT_SEP.GetNLnnMod()) + { + size += SprmUtils.AddSprm((short)0x5015, newSEP.GetNLnnMod(), null, sprmList); + } + if (newSEP.GetDxaLnn() != DEFAULT_SEP.GetDxaLnn()) + { + size += SprmUtils.AddSprm(unchecked((short)0x9016), newSEP.GetDxaLnn(), null, sprmList); + } + if (newSEP.GetDyaHdrTop() != DEFAULT_SEP.GetDyaHdrTop()) + { + size += SprmUtils.AddSprm(unchecked((short)0xB017), newSEP.GetDyaHdrTop(), null, sprmList); + } + if (newSEP.GetDyaHdrBottom() != DEFAULT_SEP.GetDyaHdrBottom()) + { + size += SprmUtils.AddSprm(unchecked((short)0xB018), newSEP.GetDyaHdrBottom(), null, sprmList); + } + if (newSEP.GetFLBetween() != DEFAULT_SEP.GetFLBetween()) + { + size += SprmUtils.AddSprm((short)0x3019, newSEP.GetFLBetween() ? 1 : 0, null, sprmList); + } + if (newSEP.GetVjc() != DEFAULT_SEP.GetVjc()) + { + size += SprmUtils.AddSprm((short)0x301A, newSEP.GetVjc(), null, sprmList); + } + if (newSEP.GetLnnMin() != DEFAULT_SEP.GetLnnMin()) + { + size += SprmUtils.AddSprm((short)0x501B, newSEP.GetLnnMin(), null, sprmList); + } + if (newSEP.GetPgnStart() != DEFAULT_SEP.GetPgnStart()) + { + size += SprmUtils.AddSprm((short)0x501C, newSEP.GetPgnStart(), null, sprmList); + } + if (newSEP.GetDmOrientPage() != DEFAULT_SEP.GetDmOrientPage()) + { + size += SprmUtils.AddSprm((short)0x301D, newSEP.GetDmOrientPage()?1:0, null, sprmList); + } + if (newSEP.GetXaPage() != DEFAULT_SEP.GetXaPage()) + { + size += SprmUtils.AddSprm(unchecked((short)0xB01F), newSEP.GetXaPage(), null, sprmList); + } + if (newSEP.GetYaPage() != DEFAULT_SEP.GetYaPage()) + { + size += SprmUtils.AddSprm(unchecked((short)0xB020), newSEP.GetYaPage(), null, sprmList); + } + if (newSEP.GetDxaLeft() != DEFAULT_SEP.GetDxaLeft()) + { + size += SprmUtils.AddSprm(unchecked((short)0xB021), newSEP.GetDxaLeft(), null, sprmList); + } + if (newSEP.GetDxaRight() != DEFAULT_SEP.GetDxaRight()) + { + size += SprmUtils.AddSprm(unchecked((short)0xB022), newSEP.GetDxaRight(), null, sprmList); + } + if (newSEP.GetDyaTop() != DEFAULT_SEP.GetDyaTop()) + { + size += SprmUtils.AddSprm(unchecked((short)0x9023), newSEP.GetDyaTop(), null, sprmList); + } + if (newSEP.GetDyaBottom() != DEFAULT_SEP.GetDyaBottom()) + { + size += SprmUtils.AddSprm(unchecked((short)0x9024), newSEP.GetDyaBottom(), null, sprmList); + } + if (newSEP.GetDzaGutter() != DEFAULT_SEP.GetDzaGutter()) + { + size += SprmUtils.AddSprm(unchecked((short)0xB025), newSEP.GetDzaGutter(), null, sprmList); + } + if (newSEP.GetDmPaperReq() != DEFAULT_SEP.GetDmPaperReq()) + { + size += SprmUtils.AddSprm((short)0x5026, newSEP.GetDmPaperReq(), null, sprmList); + } + if (newSEP.GetFPropMark() != DEFAULT_SEP.GetFPropMark() || + newSEP.GetIbstPropRMark() != DEFAULT_SEP.GetIbstPropRMark() || + !newSEP.GetDttmPropRMark().Equals(DEFAULT_SEP.GetDttmPropRMark())) + { + byte[] buf = new byte[7]; + buf[0] = (byte)(newSEP.GetFPropMark() ? 1 : 0); + int offset = LittleEndianConsts.BYTE_SIZE; + LittleEndian.PutShort(buf, (short)newSEP.GetIbstPropRMark()); + offset += LittleEndianConsts.SHORT_SIZE; + newSEP.GetDttmPropRMark().Serialize(buf, offset); + size += SprmUtils.AddSprm(unchecked((short)0xD227), -1, buf, sprmList); + } + if (!newSEP.GetBrcTop().Equals(DEFAULT_SEP.GetBrcTop())) + { + size += SprmUtils.AddSprm((short)0x702B, newSEP.GetBrcTop().ToInt(), null, sprmList); + } + if (!newSEP.GetBrcLeft().Equals(DEFAULT_SEP.GetBrcLeft())) + { + size += SprmUtils.AddSprm((short)0x702C, newSEP.GetBrcLeft().ToInt(), null, sprmList); + } + if (!newSEP.GetBrcBottom().Equals(DEFAULT_SEP.GetBrcBottom())) + { + size += SprmUtils.AddSprm((short)0x702D, newSEP.GetBrcBottom().ToInt(), null, sprmList); + } + if (!newSEP.GetBrcRight().Equals(DEFAULT_SEP.GetBrcRight())) + { + size += SprmUtils.AddSprm((short)0x702E, newSEP.GetBrcRight().ToInt(), null, sprmList); + } + if (newSEP.GetPgbProp() != DEFAULT_SEP.GetPgbProp()) + { + size += SprmUtils.AddSprm((short)0x522F, newSEP.GetPgbProp(), null, sprmList); + } + if (newSEP.GetDxtCharSpace() != DEFAULT_SEP.GetDxtCharSpace()) + { + size += SprmUtils.AddSprm((short)0x7030, newSEP.GetDxtCharSpace(), null, sprmList); + } + if (newSEP.GetDyaLinePitch() != DEFAULT_SEP.GetDyaLinePitch()) + { + size += SprmUtils.AddSprm(unchecked((short)0x9031), newSEP.GetDyaLinePitch(), null, sprmList); + } + if (newSEP.GetClm() != DEFAULT_SEP.GetClm()) + { + size += SprmUtils.AddSprm((short)0x5032, newSEP.GetClm(), null, sprmList); + } + if (newSEP.GetWTextFlow() != DEFAULT_SEP.GetWTextFlow()) + { + size += SprmUtils.AddSprm((short)0x5033, newSEP.GetWTextFlow(), null, sprmList); + } + + return SprmUtils.GetGrpprl(sprmList, size); + } + } + +} \ No newline at end of file diff --git a/scratchpad/HWPF/SPRM/SectionSprmUncompressor.cs b/scratchpad/HWPF/SPRM/SectionSprmUncompressor.cs new file mode 100644 index 0000000..df71b17 --- /dev/null +++ b/scratchpad/HWPF/SPRM/SectionSprmUncompressor.cs @@ -0,0 +1,219 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.SPRM +{ + using System; + using System.Collections; + using NPOI.HWPF.UserModel; + + public class SectionSprmUncompressor : SprmUncompressor + { + public SectionSprmUncompressor() + { + } + public static SectionProperties UncompressSEP(byte[] grpprl, int offset) + { + SectionProperties newProperties = new SectionProperties(); + + SprmIterator sprmIt = new SprmIterator(grpprl, offset); + + while (sprmIt.HasNext()) + { + SprmOperation sprm = (SprmOperation)sprmIt.Next(); + UncompressSEPOperation(newProperties, sprm); + } + + return newProperties; + } + + /** + * Used in decompression of a sepx. This performs an operation defined by + * a single sprm. + * + * @param newSEP The SectionProperty to perfrom the operation on. + * @param operand The operation to perform. + * @param param The operation's parameter. + * @param varParam The operation variable length parameter. + */ + static void UncompressSEPOperation(SectionProperties newSEP, SprmOperation sprm) + { + switch (sprm.Operation) + { + case 0: + newSEP.SetCnsPgn((byte)sprm.Operand); + break; + case 0x1: + newSEP.SetIHeadingPgn((byte)sprm.Operand); + break; + case 0x2: + byte[] buf = new byte[sprm.Size - 3]; + Array.Copy(sprm.Grpprl, sprm.GrpprlOffset, buf, 0, buf.Length); + newSEP.SetOlstAnm(buf); + break; + case 0x3: + //not quite sure + break; + case 0x4: + //not quite sure + break; + case 0x5: + newSEP.SetFEvenlySpaced(GetFlag(sprm.Operand)); + break; + case 0x6: + newSEP.SetFUnlocked(GetFlag(sprm.Operand)); + break; + case 0x7: + newSEP.SetDmBinFirst((short)sprm.Operand); + break; + case 0x8: + newSEP.SetDmBinOther((short)sprm.Operand); + break; + case 0x9: + newSEP.SetBkc((byte)sprm.Operand); + break; + case 0xa: + newSEP.SetFTitlePage(GetFlag(sprm.Operand)); + break; + case 0xb: + newSEP.SetCcolM1((short)sprm.Operand); + break; + case 0xc: + newSEP.SetDxaColumns(sprm.Operand); + break; + case 0xd: + newSEP.SetFAutoPgn(GetFlag(sprm.Operand)); + break; + case 0xe: + newSEP.SetNfcPgn((byte)sprm.Operand); + break; + case 0xf: + newSEP.SetDyaPgn((short)sprm.Operand); + break; + case 0x10: + newSEP.SetDxaPgn((short)sprm.Operand); + break; + case 0x11: + newSEP.SetFPgnRestart(GetFlag(sprm.Operand)); + break; + case 0x12: + newSEP.SetFEndNote(GetFlag(sprm.Operand)); + break; + case 0x13: + newSEP.SetLnc((byte)sprm.Operand); + break; + case 0x14: + newSEP.SetGrpfIhdt((byte)sprm.Operand); + break; + case 0x15: + newSEP.SetNLnnMod((short)sprm.Operand); + break; + case 0x16: + newSEP.SetDxaLnn(sprm.Operand); + break; + case 0x17: + newSEP.SetDyaHdrTop(sprm.Operand); + break; + case 0x18: + newSEP.SetDyaHdrBottom(sprm.Operand); + break; + case 0x19: + newSEP.SetFLBetween(GetFlag(sprm.Operand)); + break; + case 0x1a: + newSEP.SetVjc((byte)sprm.Operand); + break; + case 0x1b: + newSEP.SetLnnMin((short)sprm.Operand); + break; + case 0x1c: + newSEP.SetPgnStart((short)sprm.Operand); + break; + case 0x1d: + newSEP.SetDmOrientPage(sprm.Operand!=0); + break; + case 0x1e: + + //nothing + break; + case 0x1f: + newSEP.SetXaPage(sprm.Operand); + break; + case 0x20: + newSEP.SetYaPage(sprm.Operand); + break; + case 0x21: + newSEP.SetDxaLeft(sprm.Operand); + break; + case 0x22: + newSEP.SetDxaRight(sprm.Operand); + break; + case 0x23: + newSEP.SetDyaTop(sprm.Operand); + break; + case 0x24: + newSEP.SetDyaBottom(sprm.Operand); + break; + case 0x25: + newSEP.SetDzaGutter(sprm.Operand); + break; + case 0x26: + newSEP.SetDmPaperReq((short)sprm.Operand); + break; + case 0x27: + newSEP.SetFPropMark(GetFlag(sprm.Operand)); + break; + case 0x28: + break; + case 0x29: + break; + case 0x2a: + break; + case 0x2b: + newSEP.SetBrcTop(new BorderCode(sprm.Grpprl, sprm.GrpprlOffset)); + break; + case 0x2c: + newSEP.SetBrcLeft(new BorderCode(sprm.Grpprl, sprm.GrpprlOffset)); + break; + case 0x2d: + newSEP.SetBrcBottom(new BorderCode(sprm.Grpprl, sprm.GrpprlOffset)); + break; + case 0x2e: + newSEP.SetBrcRight(new BorderCode(sprm.Grpprl, sprm.GrpprlOffset)); + break; + case 0x2f: + newSEP.SetPgbProp(sprm.Operand); + break; + case 0x30: + newSEP.SetDxtCharSpace(sprm.Operand); + break; + case 0x31: + newSEP.SetDyaLinePitch(sprm.Operand); + break; + case 0x33: + newSEP.SetWTextFlow((short)sprm.Operand); + break; + default: + break; + } + + } + + + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/SPRM/SprmBuffer.cs b/scratchpad/HWPF/SPRM/SprmBuffer.cs new file mode 100644 index 0000000..f5e0f3b --- /dev/null +++ b/scratchpad/HWPF/SPRM/SprmBuffer.cs @@ -0,0 +1,211 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +namespace NPOI.HWPF.SPRM +{ + using System; + using System.Collections; + using NPOI.Util; + + + public class SprmBuffer : ICloneable + { + byte[] _buf; + int _offset; + bool _istd; + private int _sprmsStartOffset; + + public SprmBuffer(byte[] buf, bool Istd) + { + _offset = buf.Length; + _buf = buf; + _istd = Istd; + } + public SprmBuffer(byte[] buf) + : this(buf, false) + { + + } + public SprmBuffer(byte[] buf, bool istd, int sprmsStartOffset) + { + _offset = buf.Length; + _buf = buf; + _istd = istd; + _sprmsStartOffset = sprmsStartOffset; + } + public SprmBuffer(byte[] buf, int _sprmsStartOffset) + :this(buf, false, _sprmsStartOffset) + { + + } + + public SprmBuffer(int sprmsStartOffset) + { + _buf = new byte[sprmsStartOffset + 4]; + _offset = sprmsStartOffset; + _sprmsStartOffset = sprmsStartOffset; + } + + public SprmBuffer() + { + _buf = new byte[4]; + _offset = 0; + } + + internal SprmOperation FindSprm(short opcode) + { + int operation = SprmOperation.GetOperationFromOpcode(opcode); + int type = SprmOperation.GetTypeFromOpcode(opcode); + + SprmIterator si = new SprmIterator(_buf, 2); + while (si.HasNext()) + { + SprmOperation i = si.Next(); + if (i.Operation == operation && i.Type == type) + return i; + } + return null; + } + + + public SprmIterator Iterator() + { + return new SprmIterator(_buf, _sprmsStartOffset); + } + + internal int FindSprmOffset(short opcode) + { + SprmOperation sprmOperation = FindSprm(opcode); + if (sprmOperation == null) + return -1; + + return sprmOperation.GrpprlOffset; + } + public void UpdateSprm(short opcode, byte operand) + { + int grpprlOffset = FindSprmOffset(opcode); + if (grpprlOffset != -1) + { + _buf[grpprlOffset] = operand; + return; + } + else AddSprm(opcode, operand); + } + + public void UpdateSprm(short opcode, short operand) + { + int grpprlOffset = FindSprmOffset(opcode); + if (grpprlOffset != -1) + { + LittleEndian.PutShort(_buf, grpprlOffset, operand); + return; + } + else AddSprm(opcode, operand); + } + + public void UpdateSprm(short opcode, int operand) + { + int grpprlOffset = FindSprmOffset(opcode); + if (grpprlOffset != -1) + { + LittleEndian.PutInt(_buf, grpprlOffset, operand); + return; + } + else AddSprm(opcode, operand); + } + + public void AddSprm(short opcode, byte operand) + { + int addition = LittleEndianConsts.SHORT_SIZE + LittleEndianConsts.BYTE_SIZE; + EnsureCapacity(addition); + LittleEndian.PutShort(_buf, _offset, opcode); + _offset += LittleEndianConsts.SHORT_SIZE; + _buf[_offset++] = operand; + } + public void AddSprm(short opcode, short operand) + { + int addition = LittleEndianConsts.SHORT_SIZE + LittleEndianConsts.SHORT_SIZE; + EnsureCapacity(addition); + LittleEndian.PutShort(_buf, _offset, opcode); + _offset += LittleEndianConsts.SHORT_SIZE; + LittleEndian.PutShort(_buf, _offset, operand); + _offset += LittleEndianConsts.SHORT_SIZE; + } + public void AddSprm(short opcode, int operand) + { + int addition = LittleEndianConsts.SHORT_SIZE + LittleEndianConsts.INT_SIZE; + EnsureCapacity(addition); + LittleEndian.PutShort(_buf, _offset, opcode); + _offset += LittleEndianConsts.SHORT_SIZE; + LittleEndian.PutInt(_buf, _offset, operand); + _offset += LittleEndianConsts.INT_SIZE; + } + public void AddSprm(short opcode, byte[] operand) + { + int addition = LittleEndianConsts.SHORT_SIZE + LittleEndianConsts.BYTE_SIZE + operand.Length; + EnsureCapacity(addition); + LittleEndian.PutShort(_buf, _offset, opcode); + _offset += LittleEndianConsts.SHORT_SIZE; + _buf[_offset++] = (byte)operand.Length; + Array.Copy(operand, 0, _buf, _offset, operand.Length); + } + + public byte[] ToByteArray() + { + return _buf; + } + + public override bool Equals(Object obj) + { + SprmBuffer sprmBuf = (SprmBuffer)obj; + return (Arrays.Equals(_buf, sprmBuf._buf)); + } + + public void Append(byte[] grpprl) + { + EnsureCapacity(grpprl.Length); + System.Array.Copy(grpprl, 0, _buf, _offset, grpprl.Length); + } + public void Append(byte[] grpprl, int offset) + { + EnsureCapacity(grpprl.Length - offset); + System.Array.Copy(grpprl, offset, _buf, _offset, grpprl.Length - offset); + _offset += grpprl.Length - offset; + } + + public Object Clone() + { + SprmBuffer retVal = new SprmBuffer(); + retVal._buf = new byte[_buf.Length]; + Array.Copy(_buf, 0, retVal._buf, 0, _buf.Length); + return retVal; + } + + private void EnsureCapacity(int Addition) + { + if (_offset + Addition >= _buf.Length) + { + // Add 6 more than they need for use the next iteration + byte[] newBuf = new byte[_offset + Addition + 6]; + Array.Copy(_buf, 0, newBuf, 0, _buf.Length); + _buf = newBuf; + } + } + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/SPRM/SprmIterator.cs b/scratchpad/HWPF/SPRM/SprmIterator.cs new file mode 100644 index 0000000..b347436 --- /dev/null +++ b/scratchpad/HWPF/SPRM/SprmIterator.cs @@ -0,0 +1,60 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +namespace NPOI.HWPF.SPRM +{ + using System; + using System.Collections; + + + /** + * This class Is used to iterate through a list of sprms from a Word 97/2000/XP + * document. + * @author Ryan Ackley + * @version 1.0 + */ + + public class SprmIterator + { + private byte[] _grpprl; + int _offset; + + public SprmIterator(byte[] grpprl, int offset) + { + _grpprl = grpprl; + _offset = offset; + } + + public bool HasNext() + { + // A Sprm is at least 2 bytes long + return _offset < _grpprl.Length-1; + } + + public SprmOperation Next() + { + SprmOperation op = new SprmOperation(_grpprl, _offset); + _offset += op.Size; + return op; + } + + + } + +} \ No newline at end of file diff --git a/scratchpad/HWPF/SPRM/SprmOperation.cs b/scratchpad/HWPF/SPRM/SprmOperation.cs new file mode 100644 index 0000000..52676dc --- /dev/null +++ b/scratchpad/HWPF/SPRM/SprmOperation.cs @@ -0,0 +1,205 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.SPRM +{ + using System; + using System.Collections; + using NPOI.Util; + + /** + * This class Is used to represent a sprm operation from a Word 97/2000/XP + * document. + * @author Ryan Ackley + * @version 1.0 + */ + public class SprmOperation + { + static private BitField OP_BITFIELD = BitFieldFactory.GetInstance(0x1ff); + static private BitField SPECIAL_BITFIELD = BitFieldFactory.GetInstance(0x200); + static private BitField TYPE_BITFIELD = BitFieldFactory.GetInstance(0x1c00); + static private BitField SIZECODE_BITFIELD = BitFieldFactory.GetInstance(0xe000); + + static private short LONG_SPRM_TABLE = unchecked((short)0xd608); + static private short LONG_SPRM_PARAGRAPH = unchecked((short)0xc615); + + public const int TYPE_PAP = 1; + public const int TYPE_CHP = 2; + public const int TYPE_PIC = 3; + public const int TYPE_SEP = 4; + public const int TYPE_TAP = 5; + + private int _type; + private int _operation; + private int _gOffset; + private byte[] _grpprl; + private int _sizeCode; + private int _size; + + public SprmOperation(byte[] grpprl, int offset) + { + _grpprl = grpprl; + + short sprmStart = LittleEndian.GetShort(grpprl, offset); + + _gOffset = offset + 2; + + _operation = OP_BITFIELD.GetValue(sprmStart); + _type = TYPE_BITFIELD.GetValue(sprmStart); + _sizeCode = SIZECODE_BITFIELD.GetValue(sprmStart); + _size = InitSize(sprmStart); + } + + public static int GetOperationFromOpcode(short opcode) + { + return OP_BITFIELD.GetValue(opcode); + } + + public static int GetTypeFromOpcode(short opcode) + { + return TYPE_BITFIELD.GetValue(opcode); + } + byte[] _buf; + public SprmOperation FindSprm(short opcode) + { + int operation = SprmOperation.GetOperationFromOpcode(opcode); + int type = SprmOperation.GetTypeFromOpcode(opcode); + + SprmIterator si = new SprmIterator(_buf, 2); + while (si.HasNext()) + { + SprmOperation i = si.Next(); + if (i.Operation == operation && i.Type == type) + return i; + } + return null; + } + public int Type + { + get + { + return _type; + } + } + + public int Operation + { + get + { + return _operation; + } + } + + public int GrpprlOffset + { + get + { + return _gOffset; + } + } + public int Operand + { + get + { + switch (_sizeCode) + { + case 0: + case 1: + return _grpprl[_gOffset]; + case 2: + case 4: + case 5: + return LittleEndian.GetShort(_grpprl, _gOffset); + case 3: + return LittleEndian.GetInt(_grpprl, _gOffset); + case 6: + byte operandLength = _grpprl[_gOffset + 1]; //surely shorter than an int... + + byte[] codeBytes = new byte[LittleEndianConsts.INT_SIZE]; //initialized to zeros by JVM + for (int i = 0; i < operandLength; i++) + if (_gOffset + i < _grpprl.Length) + codeBytes[i] = _grpprl[_gOffset + 1 + i]; + + return LittleEndian.GetInt(codeBytes, 0); + case 7: + byte[] threeByteInt = new byte[4]; + threeByteInt[0] = _grpprl[_gOffset]; + threeByteInt[1] = _grpprl[_gOffset + 1]; + threeByteInt[2] = _grpprl[_gOffset + 2]; + threeByteInt[3] = (byte)0; + return LittleEndian.GetInt(threeByteInt, 0); + default: + throw new ArgumentException("SPRM contains an invalid size code"); + } + } + } + public int SizeCode + { + get + { + return _sizeCode; + } + } + + public int Size + { + get + { + return _size; + } + } + + public byte[] Grpprl + { + get + { + return _grpprl; + } + } + private int InitSize(short sprm) + { + switch (_sizeCode) + { + case 0: + case 1: + return 3; + case 2: + case 4: + case 5: + return 4; + case 3: + return 6; + case 6: + if (sprm == LONG_SPRM_TABLE || sprm == LONG_SPRM_PARAGRAPH) + { + int retVal = (0x0000ffff & LittleEndian.GetShort(_grpprl, _gOffset)) + 3; + _gOffset += 2; + return retVal; + } + else + { + return (0x000000ff & _grpprl[_gOffset++]) + 3; + } + case 7: + return 5; + default: + throw new ArgumentException("SPRM contains an invalid size code"); + } + } + } +} diff --git a/scratchpad/HWPF/SPRM/SprmUncompressor.cs b/scratchpad/HWPF/SPRM/SprmUncompressor.cs new file mode 100644 index 0000000..8242e18 --- /dev/null +++ b/scratchpad/HWPF/SPRM/SprmUncompressor.cs @@ -0,0 +1,54 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.SPRM +{ + using System; + using System.Collections; + + + + public class SprmUncompressor + { + public SprmUncompressor() + { + } + + /** + * Converts an int into a boolean. If the int Is non-zero, it returns true. + * Otherwise it returns false. + * + * @param x The int to convert. + * + * @return A bool whose value depends on x. + */ + public static bool GetFlag(int x) + { + if (x != 0) + { + return true; + } + else + { + return false; + } + } + + + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/SPRM/SprmUtils.cs b/scratchpad/HWPF/SPRM/SprmUtils.cs new file mode 100644 index 0000000..2d4104c --- /dev/null +++ b/scratchpad/HWPF/SPRM/SprmUtils.cs @@ -0,0 +1,141 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.SPRM +{ + using System; + using System.Collections; + using NPOI.Util; + + + public class SprmUtils + { + public SprmUtils() + { + } + + public static byte[] shortArrayToByteArray(short[] convert) + { + byte[] buf = new byte[convert.Length * LittleEndianConsts.SHORT_SIZE]; + + for (int x = 0; x < convert.Length; x++) + { + LittleEndian.PutShort(buf, x * LittleEndianConsts.SHORT_SIZE, convert[x]); + } + + return buf; + } + + public static int AddSpecialSprm(short instruction, byte[] varParam, IList list) + { + byte[] sprm = new byte[varParam.Length + 4]; + System.Array.Copy(varParam, 0, sprm, 4, varParam.Length); + LittleEndian.PutShort(sprm, instruction); + LittleEndian.PutShort(sprm, 2, (short)(varParam.Length + 1)); + list.Add(sprm); + return sprm.Length; + } + + + public static int AddSprm(short instruction, bool param, + IList list) + { + return AddSprm(instruction, param ? 1 : 0, null, list); + } + + public static int AddSprm(short instruction, int param, byte[] varParam, IList list) + { + int type = (instruction & 0xe000) >> 13; + + byte[] sprm = null; + switch (type) + { + case 0: + case 1: + sprm = new byte[3]; + sprm[2] = (byte)param; + break; + case 2: + sprm = new byte[4]; + LittleEndian.PutShort(sprm, 2, (short)param); + break; + case 3: + sprm = new byte[6]; + LittleEndian.PutInt(sprm, 2, param); + break; + case 4: + case 5: + sprm = new byte[4]; + LittleEndian.PutShort(sprm, 2, (short)param); + break; + case 6: + int varLength=0; + if (varParam != null) + { + varLength=varParam.Length; + } + sprm = new byte[3 + varLength]; + sprm[2] = (byte)varLength; + if (varLength != 0) + { + System.Array.Copy(varParam, 0, sprm, 3, varLength); + } + break; + case 7: + sprm = new byte[5]; + // this Is a three byte int so it has to be handled special + byte[] temp = new byte[4]; + LittleEndian.PutInt(temp, 0, param); + System.Array.Copy(temp, 0, sprm, 2, 3); + break; + default: + //should never happen + break; + } + LittleEndian.PutShort(sprm, 0, instruction); + list.Add(sprm); + return sprm.Length; + } + + public static byte[] GetGrpprl(IList sprmList, int size) + { + // spit out the grpprl + byte[] grpprl = new byte[size]; + int listSize = sprmList.Count - 1; + int index = 0; + for (; listSize >= 0; listSize--) + { + byte[] sprm = (byte[])sprmList[0]; + sprmList.RemoveAt(0); + System.Array.Copy(sprm, 0, grpprl, index, sprm.Length); + index += sprm.Length; + } + + return grpprl; + + } + + public static int ConvertBrcToInt(short[] brc) + { + byte[] buf = new byte[4]; + LittleEndian.PutShort(buf, brc[0]); + LittleEndian.PutShort(buf, LittleEndianConsts.SHORT_SIZE, brc[1]); + return LittleEndian.GetInt(buf); + } + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/SPRM/TableSprmCompressor.cs b/scratchpad/HWPF/SPRM/TableSprmCompressor.cs new file mode 100644 index 0000000..10a1d77 --- /dev/null +++ b/scratchpad/HWPF/SPRM/TableSprmCompressor.cs @@ -0,0 +1,108 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.SPRM +{ + using System; + using System.Collections; + using NPOI.HWPF.UserModel; + using NPOI.Util; + + public class TableSprmCompressor + { + public TableSprmCompressor() + { + } + public static byte[] CompressTableProperty(TableProperties newTAP) + { + int size = 0; + ArrayList sprmList = new ArrayList(); + + if (newTAP.GetJc() != 0) + { + size += SprmUtils.AddSprm((short)0x5400, newTAP.GetJc(), null, sprmList); + } + if (newTAP.GetFCantSplit()) + { + size += SprmUtils.AddSprm((short)0x3403, 1, null, sprmList); + } + if (newTAP.GetFTableHeader()) + { + size += SprmUtils.AddSprm((short)0x3404, 1, null, sprmList); + } + byte[] brcBuf = new byte[6 * BorderCode.SIZE]; + int offset = 0; + newTAP.GetBrcTop().Serialize(brcBuf, offset); + offset += BorderCode.SIZE; + newTAP.GetBrcLeft().Serialize(brcBuf, offset); + offset += BorderCode.SIZE; + newTAP.GetBrcBottom().Serialize(brcBuf, offset); + offset += BorderCode.SIZE; + newTAP.GetBrcRight().Serialize(brcBuf, offset); + offset += BorderCode.SIZE; + newTAP.GetBrcHorizontal().Serialize(brcBuf, offset); + offset += BorderCode.SIZE; + newTAP.GetBrcVertical().Serialize(brcBuf, offset); + byte[] compare = new byte[6 * BorderCode.SIZE]; + if (!Arrays.Equals(brcBuf, compare)) + { + size += SprmUtils.AddSprm(unchecked((short)0xD605), 0, brcBuf, sprmList); + } + if (newTAP.GetDyaRowHeight() != 0) + { + size += SprmUtils.AddSprm(unchecked((short)0x9407), newTAP.GetDyaRowHeight(), null, sprmList); + } + if (newTAP.GetItcMac() > 0) + { + int itcMac = newTAP.GetItcMac(); + byte[] buf = new byte[1 + (LittleEndianConsts.SHORT_SIZE * (itcMac + 1)) + (TableCellDescriptor.SIZE * itcMac)]; + buf[0] = (byte)itcMac; + + short[] dxaCenters = newTAP.GetRgdxaCenter(); + for (int x = 0; x < dxaCenters.Length; x++) + { + LittleEndian.PutShort(buf, 1 + (x * LittleEndianConsts.SHORT_SIZE), + dxaCenters[x]); + } + + TableCellDescriptor[] cellDescriptors = newTAP.GetRgtc(); + for (int x = 0; x < cellDescriptors.Length; x++) + { + cellDescriptors[x].Serialize(buf, + 1 + ((itcMac + 1) * LittleEndianConsts.SHORT_SIZE) + (x * TableCellDescriptor.SIZE)); + } + size += SprmUtils.AddSpecialSprm(unchecked((short)0xD608), buf, sprmList); + + // buf = new byte[(itcMac * ShadingDescriptor.SIZE) + 1]; + // buf[0] = (byte)itcMac; + // ShadingDescriptor[] shds = newTAP.GetRgshd(); + // for (int x = 0; x < itcMac; x++) + // { + // shds[x].Serialize(buf, 1 + (x * ShadingDescriptor.SIZE)); + // } + // size += SprmUtils.AddSpecialSprm((short)0xD609, buf, sprmList); + } + if (newTAP.GetTlp() != 0) + { + size += SprmUtils.AddSprm((short)0x740a, newTAP.GetTlp(), null, sprmList); + } + + return SprmUtils.GetGrpprl(sprmList, size); + } + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/SPRM/TableSprmUncompressor.cs b/scratchpad/HWPF/SPRM/TableSprmUncompressor.cs new file mode 100644 index 0000000..705d03c --- /dev/null +++ b/scratchpad/HWPF/SPRM/TableSprmUncompressor.cs @@ -0,0 +1,303 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.SPRM +{ + using System; + + using NPOI.HWPF.UserModel; + using NPOI.Util; + + public class TableSprmUncompressor + : SprmUncompressor + { + public TableSprmUncompressor() + { + } + + public static TableProperties UncompressTAP(byte[] grpprl, + int Offset) + { + TableProperties newProperties = new TableProperties(); + + SprmIterator sprmIt = new SprmIterator(grpprl, Offset); + + while (sprmIt.HasNext()) + { + SprmOperation sprm = sprmIt.Next(); + + //TAPXs are actually PAPXs so we have to make sure we are only trying to + //uncompress the right type of sprm. + if (sprm.Type == SprmOperation.TYPE_TAP) + { + UncompressTAPOperation(newProperties, sprm); + } + } + + return newProperties; + } + public static TableProperties UncompressTAP(SprmBuffer sprmBuffer) + { + TableProperties tableProperties; + + SprmOperation sprmOperation = sprmBuffer.FindSprm(unchecked((short)0xd608)); + if (sprmOperation != null) + { + byte[] grpprl = sprmOperation.Grpprl; + int offset = sprmOperation.GrpprlOffset; + short itcMac = grpprl[offset]; + tableProperties = new TableProperties(itcMac); + } + else + { + //logger.log(POILogger.WARN, + // "Some table rows didn't specify number of columns in SPRMs"); + tableProperties = new TableProperties((short)1); + } + + for (SprmIterator iterator = sprmBuffer.Iterator(); iterator.HasNext(); ) + { + SprmOperation sprm = iterator.Next(); + + /* + * TAPXs are actually PAPXs so we have to make sure we are only + * trying to uncompress the right type of sprm. + */ + if (sprm.Type == SprmOperation.TYPE_TAP) + { + try + { + UncompressTAPOperation(tableProperties, sprm); + } + catch ( IndexOutOfRangeException ex) + { + //logger.log(POILogger.ERROR, "Unable to apply ", sprm, + // ": ", ex, ex); + } + } + } + return tableProperties; + } + /** + * Used to uncompress a table property. Performs an operation defined + * by a sprm stored in a tapx. + * + * @param newTAP The TableProperties object to perform the operation on. + * @param operand The operand that defines this operation. + * @param param The parameter for this operation. + * @param varParam Variable length parameter for this operation. + */ + static void UncompressTAPOperation(TableProperties newTAP, SprmOperation sprm) + { + switch (sprm.Operation) + { + case 0: + newTAP.SetJc((short)sprm.Operand); + break; + case 0x01: + { + short[] rgdxaCenter = newTAP.GetRgdxaCenter(); + short itcMac = newTAP.GetItcMac(); + int adjust = sprm.Operand - (rgdxaCenter[0] + newTAP.GetDxaGapHalf()); + for (int x = 0; x < itcMac; x++) + { + rgdxaCenter[x] += (short)adjust; + } + break; + } + case 0x02: + { + short[] rgdxaCenter = newTAP.GetRgdxaCenter(); + if (rgdxaCenter != null) + { + int adjust = newTAP.GetDxaGapHalf() - sprm.Operand; + rgdxaCenter[0] += (short)adjust; + } + newTAP.SetDxaGapHalf(sprm.Operand); + break; + } + case 0x03: + newTAP.SetFCantSplit(GetFlag(sprm.Operand)); + break; + case 0x04: + newTAP.SetFTableHeader(GetFlag(sprm.Operand)); + break; + case 0x05: + { + byte[] buf = sprm.Grpprl; + int offset = sprm.GrpprlOffset; + newTAP.SetBrcTop(new BorderCode(buf, offset)); + offset += BorderCode.SIZE; + newTAP.SetBrcLeft(new BorderCode(buf, offset)); + offset += BorderCode.SIZE; + newTAP.SetBrcBottom(new BorderCode(buf, offset)); + offset += BorderCode.SIZE; + newTAP.SetBrcRight(new BorderCode(buf, offset)); + offset += BorderCode.SIZE; + newTAP.SetBrcHorizontal(new BorderCode(buf, offset)); + offset += BorderCode.SIZE; + newTAP.SetBrcVertical(new BorderCode(buf, offset)); + break; + } + case 0x06: + + //obsolete, used in word 1.x + break; + case 0x07: + newTAP.SetDyaRowHeight(sprm.Operand); + break; + case 0x08: + { + byte[] grpprl = sprm.Grpprl; + int offset = sprm.GrpprlOffset; + short itcMac = grpprl[offset]; + short[] rgdxaCenter = new short[itcMac + 1]; + TableCellDescriptor[] rgtc = new TableCellDescriptor[itcMac]; + //I use varParam[0] and newTAP._itcMac interchangably + newTAP.SetItcMac(itcMac); + newTAP.SetRgdxaCenter(rgdxaCenter); + newTAP.SetRgtc(rgtc); + + // get the rgdxaCenters + for (int x = 0; x < itcMac; x++) + { + rgdxaCenter[x] = LittleEndian.GetShort(grpprl, offset + (1 + (x * 2))); + } + + // only try to get the TC entries if they exist... + int endOfSprm = offset + sprm.Size - 6; // -2 bytes for sprm - 2 for size short - 2 to correct Offsets being 0 based + int startOfTCs = offset + (1 + (itcMac + 1) * 2); + + bool hasTCs = startOfTCs < endOfSprm; + + for (int x = 0; x < itcMac; x++) + { + // Sometimes, the grpprl does not contain data at every Offset. I have no idea why this happens. + if (hasTCs && offset + (1 + ((itcMac + 1) * 2) + (x * 20)) < grpprl.Length) + rgtc[x] = TableCellDescriptor.ConvertBytesToTC(grpprl, + offset + (1 + ((itcMac + 1) * 2) + (x * 20))); + else + rgtc[x] = new TableCellDescriptor(); + } + + rgdxaCenter[itcMac] = LittleEndian.GetShort(grpprl, offset + (1 + (itcMac * 2))); + break; + } + case 0x09: + + /** @todo handle cell shading*/ + break; + case 0x0a: + + /** @todo handle word defined table styles*/ + break; + case 0x20: + // { + // TableCellDescriptor[] rgtc = newTAP.GetRgtc(); + // + // for (int x = varParam[0]; x < varParam[1]; x++) + // { + // + // if ((varParam[2] & 0x08) > 0) + // { + // short[] brcRight = rgtc[x].GetBrcRight (); + // brcRight[0] = LittleEndian.Getshort (varParam, 6); + // brcRight[1] = LittleEndian.Getshort (varParam, 8); + // } + // else if ((varParam[2] & 0x04) > 0) + // { + // short[] brcBottom = rgtc[x].GetBrcBottom (); + // brcBottom[0] = LittleEndian.Getshort (varParam, 6); + // brcBottom[1] = LittleEndian.Getshort (varParam, 8); + // } + // else if ((varParam[2] & 0x02) > 0) + // { + // short[] brcLeft = rgtc[x].GetBrcLeft (); + // brcLeft[0] = LittleEndian.Getshort (varParam, 6); + // brcLeft[1] = LittleEndian.Getshort (varParam, 8); + // } + // else if ((varParam[2] & 0x01) > 0) + // { + // short[] brcTop = rgtc[x].GetBrcTop (); + // brcTop[0] = LittleEndian.Getshort (varParam, 6); + // brcTop[1] = LittleEndian.Getshort (varParam, 8); + // } + // } + // break; + // } + break; + case 0x21: + { + int param = sprm.Operand; + int index = (int)(param & 0xff000000) >> 24; + int count = (param & 0x00ff0000) >> 16; + int width = (param & 0x0000ffff); + int itcMac = newTAP.GetItcMac(); + + short[] rgdxaCenter = new short[itcMac + count + 1]; + TableCellDescriptor[] rgtc = new TableCellDescriptor[itcMac + count]; + if (index >= itcMac) + { + index = itcMac; + Array.Copy(newTAP.GetRgdxaCenter(), 0, rgdxaCenter, 0, + itcMac + 1); + Array.Copy(newTAP.GetRgtc(), 0, rgtc, 0, itcMac); + } + else + { + //copy rgdxaCenter + Array.Copy(newTAP.GetRgdxaCenter(), 0, rgdxaCenter, 0, + index + 1); + Array.Copy(newTAP.GetRgdxaCenter(), index + 1, rgdxaCenter, + index + count, itcMac - (index)); + //copy rgtc + Array.Copy(newTAP.GetRgtc(), 0, rgtc, 0, index); + Array.Copy(newTAP.GetRgtc(), index, rgtc, index + count, + itcMac - index); + } + + for (int x = index; x < index + count; x++) + { + rgtc[x] = new TableCellDescriptor(); + rgdxaCenter[x] = (short)(rgdxaCenter[x - 1] + width); + } + rgdxaCenter[index + + count] = (short)(rgdxaCenter[(index + count) - 1] + width); + break; + } + /**@todo handle table sprms from complex files*/ + case 0x22: + case 0x23: + case 0x24: + case 0x25: + case 0x26: + case 0x27: + case 0x28: + case 0x29: + case 0x2a: + case 0x2b: + case 0x2c: + break; + default: + break; + } + } + + + + } +} diff --git a/scratchpad/HWPF/UserModel/Bookmark.cs b/scratchpad/HWPF/UserModel/Bookmark.cs new file mode 100644 index 0000000..99177f3 --- /dev/null +++ b/scratchpad/HWPF/UserModel/Bookmark.cs @@ -0,0 +1,36 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +using System; +namespace NPOI.HWPF.UserModel +{ + + /** + * User friendly interface to access information about document bookmarks + * + * @author Sergey Vladimirov (vlsergey {at} gmail {doc} com) + */ + public interface Bookmark + { + int End { get; } + + String Name{ get; set; } + + int Start { get; } + } + + +} \ No newline at end of file diff --git a/scratchpad/HWPF/UserModel/Bookmarks.cs b/scratchpad/HWPF/UserModel/Bookmarks.cs new file mode 100644 index 0000000..5be240e --- /dev/null +++ b/scratchpad/HWPF/UserModel/Bookmarks.cs @@ -0,0 +1,51 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +using System.Collections.Generic; +namespace NPOI.HWPF.UserModel +{ + /** + * User-friendly interface to access document bookmarks + * + * @author Sergey Vladimirov (vlsergey {at} gmail {dot} com) + */ + public interface Bookmarks + { + /** + * @param index + * bookmark document index + * @return {@link Bookmark} with specified index + * @throws IndexOutOfBoundsException + * if bookmark with specified index not present in document + */ + Bookmark GetBookmark(int index); + + /** + * @return count of {@link Bookmark}s in document + */ + int Count { get; } + + /** + * @return {@link Map} of bookmarks started in specified range, where key is + * start position and value is sorted {@link List} of + * {@link Bookmark} + */ + Dictionary> GetBookmarksStartedBetween( + int startInclusive, int endExclusive); + } + + +} \ No newline at end of file diff --git a/scratchpad/HWPF/UserModel/BookmarksImpl.cs b/scratchpad/HWPF/UserModel/BookmarksImpl.cs new file mode 100644 index 0000000..ef1830f --- /dev/null +++ b/scratchpad/HWPF/UserModel/BookmarksImpl.cs @@ -0,0 +1,237 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +using System; +using NPOI.HWPF.Model; +using System.Collections.Generic; +using NPOI.HWPF.UserModel; +using NPOI.Util; +namespace NPOI.HWPF.UserModel +{ + + /** + * Implementation of user-friendly interface for document bookmarks + * + * @author Sergey Vladimirov (vlsergey {at} gmail {doc} com) + */ + public class BookmarksImpl : Bookmarks + { + + private BookmarksTables bookmarksTables; + + private Dictionary> sortedDescriptors = null; + + private int[] sortedStartPositions = null; + + public BookmarksImpl(BookmarksTables bookmarksTables) + { + this.bookmarksTables = bookmarksTables; + } + + private Bookmark GetBookmark(GenericPropertyNode first) + { + return new BookmarkImpl(this.bookmarksTables, first); + } + + public Bookmark GetBookmark(int index) + { + GenericPropertyNode first = bookmarksTables + .GetDescriptorFirst(index); + return GetBookmark(first); + } + + public List GetBookmarksAt(int startCp) + { + UpdateSortedDescriptors(); + + List nodes = sortedDescriptors[startCp]; + if (nodes == null || nodes.Count == 0) + return new List(); + + List result = new List(nodes.Count); + foreach (GenericPropertyNode node in nodes) + { + result.Add(GetBookmark(node)); + } + return result; + } + + public int Count + { + get + { + return bookmarksTables.GetDescriptorsFirstCount(); + } + } + + public Dictionary> GetBookmarksStartedBetween( + int startInclusive, int endExclusive) + { + UpdateSortedDescriptors(); + + int startLookupIndex = Array.BinarySearch(this.sortedStartPositions, + startInclusive); + if (startLookupIndex < 0) + startLookupIndex = -(startLookupIndex + 1); + int endLookupIndex = Array.BinarySearch(this.sortedStartPositions, + endExclusive); + if (endLookupIndex < 0) + endLookupIndex = -(endLookupIndex + 1); + + Dictionary> result = new Dictionary>(); + for (int LookupIndex = startLookupIndex; LookupIndex < endLookupIndex; LookupIndex++) + { + int s = sortedStartPositions[LookupIndex]; + if (s < startInclusive) + continue; + if (s >= endExclusive) + break; + + List startedAt = GetBookmarksAt(s); + if (startedAt != null) + result[s] = startedAt; + } + + return result; + } + + private void UpdateSortedDescriptors() + { + if (sortedDescriptors != null) + return; + + Dictionary> result = new Dictionary>(); + for (int b = 0; b < bookmarksTables.GetDescriptorsFirstCount(); b++) + { + GenericPropertyNode property = bookmarksTables + .GetDescriptorFirst(b); + int positionKey = property.Start; + List atPositionList = result[positionKey]; + if (atPositionList == null) + { + atPositionList = new List(); + result[positionKey] = atPositionList; + } + atPositionList.Add(property); + } + + int counter = 0; + int[] indices = new int[result.Count]; + foreach (KeyValuePair> entry in result) + { + indices[counter++] = entry.Key; + List updated = new List( + entry.Value); + updated.Sort((IComparer)PropertyNode.EndComparator.instance); + result[entry.Key] = updated; + } + Array.Sort(indices); + + this.sortedDescriptors = result; + this.sortedStartPositions = indices; + } + + internal class BookmarkImpl : Bookmark + { + private GenericPropertyNode first; + private BookmarksTables bookmarksTables; + + internal BookmarkImpl(BookmarksTables bookmarksTables, GenericPropertyNode first) + { + this.bookmarksTables = bookmarksTables; + this.first = first; + } + + public override bool Equals(Object obj) + { + if (this == obj) + return true; + if (obj == null) + return false; + if (this.GetType() != obj.GetType()) + return false; + BookmarkImpl other = (BookmarkImpl)obj; + if (first == null) + { + if (other.first != null) + return false; + } + else if (!first.Equals(other.first)) + return false; + return true; + } + + public int End + { + get + { + int currentIndex = bookmarksTables.GetDescriptorFirstIndex(first); + try + { + GenericPropertyNode descriptorLim = bookmarksTables + .GetDescriptorLim(currentIndex); + return descriptorLim.Start; + } + catch (IndexOutOfRangeException) + { + return first.End; + } + } + } + + public String Name + { + get + { + int currentIndex = bookmarksTables.GetDescriptorFirstIndex(first); + try + { + return bookmarksTables.GetName(currentIndex); + } + catch (IndexOutOfRangeException) + { + return ""; + } + } + set + { + int currentIndex = bookmarksTables.GetDescriptorFirstIndex(first); + bookmarksTables.SetName(currentIndex, value); + } + } + + public int Start + { + get + { + return first.Start; + } + } + + public override int GetHashCode() + { + return 31 + (first == null ? 0 : first.GetHashCode()); + } + public override String ToString() + { + return "Bookmark [" + Start + "; " + End + "): name: " + + Name; + } + + } + } +} + diff --git a/scratchpad/HWPF/UserModel/BorderCode.cs b/scratchpad/HWPF/UserModel/BorderCode.cs new file mode 100644 index 0000000..2120af8 --- /dev/null +++ b/scratchpad/HWPF/UserModel/BorderCode.cs @@ -0,0 +1,212 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +namespace NPOI.HWPF.UserModel +{ + using System; + using NPOI.Util; + using NPOI.HWPF.Model; + + public class BorderCode:BaseObject + { + public static int SIZE = 4; + private short _info; + private static BitField _dptLineWidth = BitFieldFactory.GetInstance(0xff); + private static BitField _brcType = BitFieldFactory.GetInstance(0xff00); + private short _info2; + private static BitField _ico = BitFieldFactory.GetInstance(0xff); + private static BitField _dptSpace = BitFieldFactory.GetInstance(0x1f00); + private static BitField _fShadow = BitFieldFactory.GetInstance(0x2000); + private static BitField _fFrame = BitFieldFactory.GetInstance(0x4000); + + public BorderCode() + { + } + + public BorderCode(byte[] buf, int offset) + { + _info = LittleEndian.GetShort(buf, offset); + _info2 = LittleEndian.GetShort(buf, offset + LittleEndianConsts.SHORT_SIZE); + } + + public void Serialize(byte[] buf, int offset) + { + LittleEndian.PutShort(buf, offset, _info); + LittleEndian.PutShort(buf, offset + LittleEndianConsts.SHORT_SIZE, _info2); + } + + public int ToInt() + { + byte[] buf = new byte[4]; + Serialize(buf, 0); + return LittleEndian.GetInt(buf); + } + + public bool IsEmpty + { + get + { + return _info == 0 && _info2 == 0; + } + } + + public override bool Equals(Object o) + { + BorderCode brc = (BorderCode)o; + return _info == brc._info && _info2 == brc._info2; + } + /** + * Width of a single line in 1/8 pt, max of 32 pt. + */ + public int LineWidth + { + get + { + return _dptLineWidth.GetShortValue(_info); + } + set + { + _dptLineWidth.SetValue(_info, value); + } + } + + /** + * Border type code: + *

  • 0 none + *
  • 1 single + *
  • 2 thick + *
  • 3 double + *
  • 5 hairline + *
  • 6 dot + *
  • 7 dash large gap + *
  • 8 dot dash + *
  • 9 dot dot dash + *
  • 10 triple + *
  • 11 thin-thick small gap + *
  • 12 thick-thin small gap + *
  • 13 thin-thick-thin small gap + *
  • 14 thin-thick medium gap + *
  • 15 thick-thin medium gap + *
  • 16 thin-thick-thin medium gap + *
  • 17 thin-thick large gap + *
  • 18 thick-thin large gap + *
  • 19 thin-thick-thin large gap + *
  • 20 wave + *
  • 21 double wave + *
  • 22 dash small gap + *
  • 23 dash dot stroked + *
  • 24 emboss 3D + *
  • 25 engrave 3D + *
  • codes 64 - 230 represent border art types and are used only for page borders + */ + public int BorderType + { + get + { + return _brcType.GetShortValue(_info); + } + set + { + _brcType.SetValue(_info, value); + } + } + + /** + * Color: + *
  • 0 Auto + *
  • 1 Black + *
  • 2 Blue + *
  • 3 Cyan + *
  • 4 Green + *
  • 5 Magenta + *
  • 6 Red + *
  • 7 Yellow + *
  • 8 White + *
  • 9 DkBlue + *
  • 10 DkCyan + *
  • 11 DkGreen + *
  • 12 DkMagenta + *
  • 13 DkRed + *
  • 14 DkYellow + *
  • 15 DkGray + *
  • 16 LtGray + */ + public short Color + { + get + { + return _ico.GetShortValue(_info2); + } + set + { + _ico.SetValue(_info2, value); + } + } + + /** + * Width of space to maintain between border and text within border. + * + *

    Must be 0 when BRC is a substructure of TC. + * + *

    Stored in points. + */ + public int Space + { + get + { + return _dptSpace.GetShortValue(_info2); + } + set + { + _dptSpace.SetValue(_info2, value); + } + } + + /** + * When true, border is drawn with shadow + * Must be false when BRC is a substructure of the TC. + */ + public bool IsShadow + { + get{ + return _fShadow.GetValue(_info2) != 0; + } + set + { + _fShadow.SetValue(_info2, value ? 1 : 0); + } + } + + /** + * Don't reverse the border. + */ + public bool IsFrame + { + get + { + return _fFrame.GetValue(_info2) != 0; + } + set + { + _fFrame.SetValue(_info2, value ? 1 : 0); + } + } + + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/UserModel/CharacterProperties.cs b/scratchpad/HWPF/UserModel/CharacterProperties.cs new file mode 100644 index 0000000..6780131 --- /dev/null +++ b/scratchpad/HWPF/UserModel/CharacterProperties.cs @@ -0,0 +1,393 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +namespace NPOI.HWPF.UserModel +{ + using System; + using NPOI.HWPF.Model.Types; + + /** + * @author Ryan Ackley + */ + public class CharacterProperties + : CHPAbstractType //, ICloneable + { + public static short SPRM_FRMARKDEL = (short)0x0800; + public static short SPRM_FRMARK = 0x0801; + public static short SPRM_FFLDVANISH = 0x0802; + public static short SPRM_PICLOCATION = 0x6A03; + public static short SPRM_IBSTRMARK = 0x4804; + public static short SPRM_DTTMRMARK = 0x6805; + public static short SPRM_FDATA = 0x0806; + public static short SPRM_SYMBOL = 0x6A09; + public static short SPRM_FOLE2 = 0x080A; + public static short SPRM_HIGHLIGHT = 0x2A0C; + public static short SPRM_OBJLOCATION = 0x680E; + public static short SPRM_ISTD = 0x4A30; + public static short SPRM_FBOLD = 0x0835; + public static short SPRM_FITALIC = 0x0836; + public static short SPRM_FSTRIKE = 0x0837; + public static short SPRM_FOUTLINE = 0x0838; + public static short SPRM_FSHADOW = 0x0839; + public static short SPRM_FSMALLCAPS = 0x083A; + public static short SPRM_FCAPS = 0x083B; + public static short SPRM_FVANISH = 0x083C; + public static short SPRM_KUL = 0x2A3E; + public static short SPRM_DXASPACE = unchecked((short)0x8840); + public static short SPRM_LID = 0x4A41; + public static short SPRM_ICO = 0x2A42; + public static short SPRM_HPS = 0x4A43; + public static short SPRM_HPSPOS = 0x4845; + public static short SPRM_ISS = 0x2A48; + public static short SPRM_HPSKERN = 0x484B; + public static short SPRM_YSRI = 0x484E; + public static short SPRM_RGFTCASCII = 0x4A4F; + public static short SPRM_RGFTCFAREAST = 0x4A50; + public static short SPRM_RGFTCNOTFAREAST = 0x4A51; + public static short SPRM_CHARSCALE = 0x4852; + public static short SPRM_FDSTRIKE = 0x2A53; + public static short SPRM_FIMPRINT = 0x0854; + public static short SPRM_FSPEC = 0x0855; + public static short SPRM_FOBJ = 0x0856; + public static short SPRM_PROPRMARK = unchecked((short)0xCA57); + public static short SPRM_FEMBOSS = 0x0858; + public static short SPRM_SFXTEXT = 0x2859; + public static short SPRM_DISPFLDRMARK = unchecked((short)0xCA62); + public static short SPRM_IBSTRMARKDEL = 0x4863; + public static short SPRM_DTTMRMARKDEL = 0x6864; + public static short SPRM_BRC = 0x6865; + public static short SPRM_SHD = 0x4866; + public static short SPRM_IDSIRMARKDEL = 0x4867; + public static short SPRM_CPG = 0x486B; + public static short SPRM_NONFELID = 0x486D; + public static short SPRM_FELID = 0x486E; + public static short SPRM_IDCTHINT = 0x286F; + + int _ico24 = -1; // default to -1 so we can ignore it for word 97 files + + public CharacterProperties() + { + field_17_fcPic = -1; + field_22_dttmRMark = new DateAndTime(); + field_23_dttmRMarkDel = new DateAndTime(); + field_36_dttmPropRMark = new DateAndTime(); + field_40_dttmDispFldRMark = new DateAndTime(); + field_41_xstDispFldRMark = new byte[36]; + field_42_shd = new ShadingDescriptor(); + field_43_brc = new BorderCode(); + field_7_hps = 20; + field_24_istd = 10; + field_16_wCharScale = 100; + field_13_lidDefault = 0x0400; + field_14_lidFE = 0x0400; + } + + public bool IsMarkedDeleted() + { + return IsFRMarkDel(); + } + + public void markDeleted(bool mark) + { + base.SetFRMarkDel(mark); + } + + public bool IsBold() + { + return IsFBold(); + } + + public void SetBold(bool bold) + { + base.SetFBold(bold); + } + + public bool IsItalic() + { + return IsFItalic(); + } + + public void SetItalic(bool italic) + { + base.SetFItalic(italic); + } + + public bool IsOutlined() + { + return IsFOutline(); + } + + public void SetOutline(bool outlined) + { + base.SetFOutline(outlined); + } + + public bool IsFldVanished() + { + return IsFFldVanish(); + } + + public void SetFldVanish(bool fldVanish) + { + base.SetFFldVanish(fldVanish); + } + + public bool IsSmallCaps() + { + return IsFSmallCaps(); + } + + public void SetSmallCaps(bool smallCaps) + { + base.SetFSmallCaps(smallCaps); + } + + public bool IsCapitalized() + { + return IsFCaps(); + } + + public void SetCapitalized(bool caps) + { + base.SetFCaps(caps); + } + + public bool IsVanished() + { + return IsFVanish(); + } + + public void SetVanished(bool vanish) + { + base.SetFVanish(vanish); + + } + public bool IsMarkedInserted() + { + return IsFRMark(); + } + + public void markInserted(bool mark) + { + base.SetFRMark(mark); + } + + public bool IsStrikeThrough() + { + return IsFStrike(); + } + + public void strikeThrough(bool strike) + { + base.SetFStrike(strike); + } + + public bool IsShadowed() + { + return IsFShadow(); + } + + public void SetShadow(bool shadow) + { + base.SetFShadow(shadow); + + } + + public bool IsEmbossed() + { + return IsFEmboss(); + } + + public void SetEmbossed(bool emboss) + { + base.SetFEmboss(emboss); + } + + public bool IsImprinted() + { + return IsFImprint(); + } + + public void SetImprinted(bool imprint) + { + base.SetFImprint(imprint); + } + + public bool IsDoubleStrikeThrough() + { + return IsFDStrike(); + } + + public void SetDoubleStrikeThrough(bool dstrike) + { + base.SetFDStrike(dstrike); + } + + public int GetFontSize() + { + return GetHps(); + } + + public void SetFontSize(int halfPoints) + { + base.SetHps(halfPoints); + } + + public int GetCharacterSpacing() + { + return GetDxaSpace(); + } + + public void SetCharacterSpacing(int twips) + { + base.SetDxaSpace(twips); + } + + public short GetSubSuperScriptIndex() + { + return GetIss(); + } + + public void SetSubSuperScriptIndex(short Iss) + { + base.SetDxaSpace(Iss); + } + + public int GetUnderlineCode() + { + return base.GetKul(); + } + + public void SetUnderlineCode(int kul) + { + base.SetKul((byte)kul); + } + + public int GetColor() + { + return base.GetIco(); + } + + public void SetColor(int color) + { + base.SetIco((byte)color); + } + + public int GetVerticalOffset() + { + return base.GetHpsPos(); + } + + public void SetVerticalOffset(int hpsPos) + { + base.SetHpsPos(hpsPos); + } + + public int GetKerning() + { + return base.GetHpsKern(); + } + + public void SetKerning(int kern) + { + base.SetHpsKern(kern); + } + + public bool IsHighlighted() + { + return base.IsFHighlight(); + } + + public void SetHighlighted(byte color) + { + base.SetIcoHighlight(color); + } + + /** + * Get the ico24 field for the CHP record. + */ + public int GetIco24() + { + if (_ico24 == -1) + { + switch (field_11_ico) // convert word 97 colour numbers to 0xBBGGRR value + { + case 0: // auto + return -1; + case 1: // black + return 0x000000; + case 2: // blue + return 0xFF0000; + case 3: // cyan + return 0xFFFF00; + case 4: // green + return 0x00FF00; + case 5: // magenta + return 0xFF00FF; + case 6: // red + return 0x0000FF; + case 7: // yellow + return 0x00FFFF; + case 8: // white + return 0x0FFFFFF; + case 9: // dark blue + return 0x800000; + case 10: // dark cyan + return 0x808000; + case 11: // dark green + return 0x008000; + case 12: // dark magenta + return 0x800080; + case 13: // dark red + return 0x000080; + case 14: // dark yellow + return 0x008080; + case 15: // dark grey + return 0x808080; + case 16: // light grey + return 0xC0C0C0; + } + } + return _ico24; + } + + /** + * Set the ico24 field for the CHP record. + */ + public void SetIco24(int colour24) + { + _ico24 = colour24 & 0xFFFFFF; // only keep the 24bit 0xBBGGRR colour + } + + //public Object Clone() + //{ + // CharacterProperties cp = (CharacterProperties)base.Clone(); + // cp.field_22_dttmRMark = (DateAndTime)field_22_dttmRMark.Clone(); + // cp.field_23_dttmRMarkDel = (DateAndTime)field_23_dttmRMarkDel.Clone(); + // cp.field_36_dttmPropRMark = (DateAndTime)field_36_dttmPropRMark.Clone(); + // cp.field_40_dttmDispFldRMark = (DateAndTime)field_40_dttmDispFldRMark.Clone(); + // cp.field_41_xstDispFldRMark = (byte[])field_41_xstDispFldRMark.Clone(); + // cp.field_42_shd = (ShadingDescriptor)field_42_shd.Clone(); + + // cp._ico24 = _ico24; + + // return cp; + //} + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/UserModel/CharacterRun.cs b/scratchpad/HWPF/UserModel/CharacterRun.cs new file mode 100644 index 0000000..dde2cd0 --- /dev/null +++ b/scratchpad/HWPF/UserModel/CharacterRun.cs @@ -0,0 +1,630 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using NPOI.HWPF.SPRM; +using NPOI.HWPF.Model; +using System; +namespace NPOI.HWPF.UserModel +{ + + /** + * This class represents a run of text that share common properties. + * + * @author Ryan Ackley + */ + public class CharacterRun : Range + { + public const short SPRM_FRMARKDEL = (short)0x0800; + public const short SPRM_FRMARK = 0x0801; + public const short SPRM_FFLDVANISH = 0x0802; + public const short SPRM_PICLOCATION = 0x6A03; + public const short SPRM_IBSTRMARK = 0x4804; + public const short SPRM_DTTMRMARK = 0x6805; + public const short SPRM_FDATA = 0x0806; + public const short SPRM_SYMBOL = 0x6A09; + public const short SPRM_FOLE2 = 0x080A; + public const short SPRM_HIGHLIGHT = 0x2A0C; + public const short SPRM_OBJLOCATION = 0x680E; + public const short SPRM_ISTD = 0x4A30; + public const short SPRM_FBOLD = 0x0835; + public const short SPRM_FITALIC = 0x0836; + public const short SPRM_FSTRIKE = 0x0837; + public const short SPRM_FOUTLINE = 0x0838; + public const short SPRM_FSHADOW = 0x0839; + public const short SPRM_FSMALLCAPS = 0x083A; + public const short SPRM_FCAPS = 0x083B; + public const short SPRM_FVANISH = 0x083C; + public const short SPRM_KUL = 0x2A3E; + public const short SPRM_DXASPACE = unchecked((short)0x8840); + public const short SPRM_LID = 0x4A41; + public const short SPRM_ICO = 0x2A42; + public const short SPRM_HPS = 0x4A43; + public const short SPRM_HPSPOS = 0x4845; + public const short SPRM_ISS = 0x2A48; + public const short SPRM_HPSKERN = 0x484B; + public const short SPRM_YSRI = 0x484E; + public const short SPRM_RGFTCASCII = 0x4A4F; + public const short SPRM_RGFTCFAREAST = 0x4A50; + public const short SPRM_RGFTCNOTFAREAST = 0x4A51; + public const short SPRM_CHARSCALE = 0x4852; + public const short SPRM_FDSTRIKE = 0x2A53; + public const short SPRM_FIMPRINT = 0x0854; + public const short SPRM_FSPEC = 0x0855; + public const short SPRM_FOBJ = 0x0856; + public const short SPRM_PROPRMARK = unchecked((short)0xCA57); + public const short SPRM_FEMBOSS = 0x0858; + public const short SPRM_SFXTEXT = 0x2859; + public const short SPRM_DISPFLDRMARK = unchecked((short)0xCA62); + public const short SPRM_IBSTRMARKDEL = 0x4863; + public const short SPRM_DTTMRMARKDEL = 0x6864; + public const short SPRM_BRC = 0x6865; + public const short SPRM_SHD = 0x4866; + public const short SPRM_IDSIRMARKDEL = 0x4867; + public const short SPRM_CPG = 0x486B; + public const short SPRM_NONFELID = 0x486D; + public const short SPRM_FELID = 0x486E; + public const short SPRM_IDCTHINT = 0x286F; + + SprmBuffer _chpx; + CharacterProperties _props; + + /** + * + * @param chpx The chpx this object is based on. + * @param ss The stylesheet for the document this run belongs to. + * @param istd The style index if this Run's base style. + * @param parent The parent range of this character run (usually a paragraph). + */ + internal CharacterRun(CHPX chpx, StyleSheet ss, short istd, Range parent) + : base(Math.Max(parent._start, chpx.Start), Math.Min(parent._end, chpx.End), parent) + { + + _props = chpx.GetCharacterProperties(ss, istd); + _chpx = chpx.GetSprmBuf(); + } + + /** + * Here for Runtime type determination using a switch statement convenient. + * + * @return TYPE_CHARACTER + */ + public int type() + { + return TYPE_CHARACTER; + } + + public bool IsMarkedDeleted() + { + return _props.IsFRMarkDel(); + } + + public void MarkDeleted(bool mark) + { + _props.SetFRMarkDel(mark); + + byte newVal = (byte)(mark ? 1 : 0); + _chpx.UpdateSprm(SPRM_FRMARKDEL, newVal); + + } + + public bool IsBold() + { + return _props.IsFBold(); + } + + public void SetBold(bool bold) + { + _props.SetFBold(bold); + + byte newVal = (byte)(bold ? 1 : 0); + _chpx.UpdateSprm(SPRM_FBOLD, newVal); + + } + + public bool IsItalic() + { + return _props.IsFItalic(); + } + + public void SetItalic(bool italic) + { + _props.SetFItalic(italic); + + byte newVal = (byte)(italic ? 1 : 0); + _chpx.UpdateSprm(SPRM_FITALIC, newVal); + + } + + public bool IsOutlined() + { + return _props.IsFOutline(); + } + + public void SetOutline(bool outlined) + { + _props.SetFOutline(outlined); + + byte newVal = (byte)(outlined ? 1 : 0); + _chpx.UpdateSprm(SPRM_FOUTLINE, newVal); + + } + + public bool IsFldVanished() + { + return _props.IsFFldVanish(); + } + + public void SetFldVanish(bool fldVanish) + { + _props.SetFFldVanish(fldVanish); + + byte newVal = (byte)(fldVanish ? 1 : 0); + _chpx.UpdateSprm(SPRM_FFLDVANISH, newVal); + + } + + public bool IsSmallCaps() + { + return _props.IsFSmallCaps(); + } + + public void SetSmallCaps(bool smallCaps) + { + _props.SetFSmallCaps(smallCaps); + + byte newVal = (byte)(smallCaps ? 1 : 0); + _chpx.UpdateSprm(SPRM_FSMALLCAPS, newVal); + + } + + public bool IsCapitalized() + { + return _props.IsFCaps(); + } + + public void SetCapitalized(bool caps) + { + _props.SetFCaps(caps); + + byte newVal = (byte)(caps ? 1 : 0); + _chpx.UpdateSprm(SPRM_FCAPS, newVal); + + } + + public bool IsVanished() + { + return _props.IsFVanish(); + } + + public void SetVanished(bool vanish) + { + _props.SetFVanish(vanish); + + byte newVal = (byte)(vanish ? 1 : 0); + _chpx.UpdateSprm(SPRM_FVANISH, newVal); + + } + + public bool IsMarkedInserted() + { + return _props.IsFRMark(); + } + + public void MarkInserted(bool mark) + { + _props.SetFRMark(mark); + + byte newVal = (byte)(mark ? 1 : 0); + _chpx.UpdateSprm(SPRM_FRMARK, newVal); + + } + + public bool IsStrikeThrough() + { + return _props.IsFStrike(); + } + + public void StrikeThrough(bool strike) + { + _props.SetFStrike(strike); + + byte newVal = (byte)(strike ? 1 : 0); + _chpx.UpdateSprm(SPRM_FSTRIKE, newVal); + + } + + public bool IsShadowed() + { + return _props.IsFShadow(); + } + + public void SetShadow(bool shadow) + { + _props.SetFShadow(shadow); + + byte newVal = (byte)(shadow ? 1 : 0); + _chpx.UpdateSprm(SPRM_FSHADOW, newVal); + + } + + public bool IsEmbossed() + { + return _props.IsFEmboss(); + } + + public void SetEmbossed(bool emboss) + { + _props.SetFEmboss(emboss); + + byte newVal = (byte)(emboss ? 1 : 0); + _chpx.UpdateSprm(SPRM_FEMBOSS, newVal); + + } + + public bool IsImprinted() + { + return _props.IsFImprint(); + } + + public void SetImprinted(bool imprint) + { + _props.SetFImprint(imprint); + + byte newVal = (byte)(imprint ? 1 : 0); + _chpx.UpdateSprm(SPRM_FIMPRINT, newVal); + + } + + public bool IsDoubleStrikeThrough() + { + return _props.IsFDStrike(); + } + + public void SetDoubleStrikethrough(bool dstrike) + { + _props.SetFDStrike(dstrike); + + byte newVal = (byte)(dstrike ? 1 : 0); + _chpx.UpdateSprm(SPRM_FDSTRIKE, newVal); + + } + + public void SetFtcAscii(int ftcAscii) + { + _props.SetFtcAscii(ftcAscii); + + _chpx.UpdateSprm(SPRM_RGFTCASCII, (short)ftcAscii); + + } + + public void SetFtcFE(int ftcFE) + { + _props.SetFtcFE(ftcFE); + + _chpx.UpdateSprm(SPRM_RGFTCFAREAST, (short)ftcFE); + + } + + public void SetFtcOther(int ftcOther) + { + _props.SetFtcOther(ftcOther); + + _chpx.UpdateSprm(SPRM_RGFTCNOTFAREAST, (short)ftcOther); + + } + + public int GetFontSize() + { + return _props.GetHps(); + } + + public void SetFontSize(int halfPoints) + { + _props.SetHps(halfPoints); + + _chpx.UpdateSprm(SPRM_HPS, (short)halfPoints); + + } + + public int GetCharacterSpacing() + { + return _props.GetDxaSpace(); + } + + public void SetCharacterSpacing(int twips) + { + _props.SetDxaSpace(twips); + + _chpx.UpdateSprm(SPRM_DXASPACE, twips); + + } + + public short GetSubSuperScriptIndex() + { + return _props.GetIss(); + } + + public void SetSubSuperScriptIndex(short iss) + { + _props.SetDxaSpace(iss); + + _chpx.UpdateSprm(SPRM_DXASPACE, iss); + + } + + public int GetUnderlineCode() + { + return _props.GetKul(); + } + + public void SetUnderlineCode(int kul) + { + _props.SetKul((byte)kul); + _chpx.UpdateSprm(SPRM_KUL, (byte)kul); + } + + public int GetColor() + { + return _props.GetIco(); + } + + public void SetColor(int color) + { + _props.SetIco((byte)color); + _chpx.UpdateSprm(SPRM_ICO, (byte)color); + } + + public int GetVerticalOffset() + { + return _props.GetHpsPos(); + } + + public void SetVerticalOffset(int hpsPos) + { + _props.SetHpsPos(hpsPos); + _chpx.UpdateSprm(SPRM_HPSPOS, (byte)hpsPos); + } + + public int GetKerning() + { + return _props.GetHpsKern(); + } + + public void SetKerning(int kern) + { + _props.SetHpsKern(kern); + _chpx.UpdateSprm(SPRM_HPSKERN, (short)kern); + } + + public bool IsHighlighted() + { + return _props.IsFHighlight(); + } + + public void SetHighlighted(byte color) + { + _props.SetFHighlight(true); + _props.SetIcoHighlight(color); + _chpx.UpdateSprm(SPRM_HIGHLIGHT, color); + } + + public String GetFontName() + { + return _doc.GetFontTable().GetMainFont(_props.GetFtcAscii()); + } + + public bool IsSpecialCharacter() + { + return _props.IsFSpec(); + } + + public void SetSpecialCharacter(bool spec) + { + _props.SetFSpec(spec); + + byte newVal = (byte)(spec ? 1 : 0); + _chpx.UpdateSprm(SPRM_FSPEC, newVal); + } + + public bool IsObj() + { + return _props.IsFObj(); + } + + public void SetObj(bool obj) + { + _props.SetFObj(obj); + + byte newVal = (byte)(obj ? 1 : 0); + _chpx.UpdateSprm(SPRM_FOBJ, newVal); + } + + public int GetPicOffset() + { + return _props.GetFcPic(); + } + + public void SetPicOffset(int offset) + { + _props.SetFcPic(offset); + _chpx.UpdateSprm(SPRM_PICLOCATION, offset); + } + + /** + * Does the picture offset represent picture + * or binary data? + * If it's Set, then the picture offset refers to + * a NilPICFAndBinData structure, otherwise to a + * PICFAndOfficeArtData + */ + public bool IsData() + { + return _props.IsFData(); + } + + public void SetData(bool data) + { + _props.SetFData(data); + + byte newVal = (byte)(data ? 1 : 0); + _chpx.UpdateSprm(SPRM_FOBJ, newVal); + } + + public bool IsOle2() + { + return _props.IsFOle2(); + } + + public void SetOle2(bool ole) + { + _props.SetFOle2(ole); + + byte newVal = (byte)(ole ? 1 : 0); + _chpx.UpdateSprm(SPRM_FOBJ, newVal); + } + + public int GetObjOffset() + { + return _props.GetFcObj(); + } + + public void SetObjOffset(int obj) + { + _props.SetFcObj(obj); + _chpx.UpdateSprm(SPRM_OBJLOCATION, obj); + } + + /** + * Get the ico24 field for the CHP record. + */ + public int GetIco24() + { + return _props.GetIco24(); + } + + /** + * Set the ico24 field for the CHP record. + */ + public void SetIco24(int colour24) + { + _props.SetIco24(colour24); + } + + /** + * clone the CharacterProperties object associated with this + * characterRun so that you can apply it to another CharacterRun + */ + public CharacterProperties CloneProperties() + { + return (CharacterProperties)_props.Clone(); + + } + + /** + * Used to create a deep copy of this object. + * + * @return A deep copy. + * @throws CloneNotSupportedException never + */ + public override Object Clone() + { + CharacterRun cp = (CharacterRun)base.Clone(); + cp._props.SetDttmRMark((DateAndTime)_props.GetDttmRMark().Clone()); + cp._props.SetDttmRMarkDel((DateAndTime)_props.GetDttmRMarkDel().Clone()); + cp._props.SetDttmPropRMark((DateAndTime)_props.GetDttmPropRMark().Clone()); + cp._props.SetDttmDispFldRMark((DateAndTime)_props.GetDttmDispFldRMark(). + Clone()); + cp._props.SetXstDispFldRMark((byte[])_props.GetXstDispFldRMark().Clone()); + cp._props.SetShd((ShadingDescriptor)_props.GetShd().Clone()); + + return cp; + } + + /** + * Returns true, if the CharacterRun is a special character run Containing a symbol, otherwise false. + * + *

    In case of a symbol, the {@link #text()} method always returns a single character 0x0028, but word actually stores + * the character in a different field. Use {@link #GetSymbolCharacter()} to get that character and {@link #GetSymbolFont()} + * to determine its font. + */ + public bool IsSymbol() + { + return IsSpecialCharacter() && Text.Equals("\u0028"); + } + + /** + * Returns the symbol character, if this is a symbol character Run. + * + * @see #isSymbol() + * @throws InvalidOperationException If this is not a symbol character Run: call {@link #isSymbol()} first. + */ + public char GetSymbolCharacter() + { + if (IsSymbol()) + { + return (char)_props.GetXchSym(); + } + else + throw new InvalidOperationException("Not a symbol CharacterRun"); + } + + /** + * Returns the symbol font, if this is a symbol character Run. Might return null, if the font index is not found in the font table. + * + * @see #isSymbol() + * @throws InvalidOperationException If this is not a symbol character Run: call {@link #isSymbol()} first. + */ + public Ffn GetSymbolFont() + { + if (IsSymbol()) + { + Ffn[] fontNames = _doc.GetFontTable().GetFontNames(); + + if (fontNames.Length <= _props.GetFtcSym()) + return null; + + return fontNames[_props.GetFtcSym()]; + } + else + throw new InvalidOperationException("Not a symbol CharacterRun"); + } + + public BorderCode GetBorder() + { + return _props.GetBrc(); + } + + public bool isHighlighted() + { + return _props.IsFHighlight(); + } + public byte GetHighlightedColor() + { + return _props.GetIcoHighlight(); + } + public void setHighlighted(byte color) + { + _props.SetFHighlight(true); + _props.SetIcoHighlight(color); + _chpx.UpdateSprm(SPRM_HIGHLIGHT, color); + } + public int getLanguageCode() + { + return _props.GetLidDefault(); + } + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/UserModel/DateAndTime.cs b/scratchpad/HWPF/UserModel/DateAndTime.cs new file mode 100644 index 0000000..848dcb7 --- /dev/null +++ b/scratchpad/HWPF/UserModel/DateAndTime.cs @@ -0,0 +1,65 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +namespace NPOI.HWPF.UserModel +{ + using System; + using NPOI.Util; + using NPOI.HWPF.Model; + + /** + * This class Is used to represent a date and time in a Word document. + * + * @author Ryan Ackley + */ + public class DateAndTime : BaseObject + { + public static int SIZE = 4; + private short _info; + private static BitField _minutes = BitFieldFactory.GetInstance(0x3f); + private static BitField _hours = BitFieldFactory.GetInstance(0x7c0); + private static BitField _dom = BitFieldFactory.GetInstance(0xf800); + private short _info2; + private static BitField _months = BitFieldFactory.GetInstance(0xf); + private static BitField _years = BitFieldFactory.GetInstance(0x1ff0); + private static BitField _weekday = BitFieldFactory.GetInstance(0xe000); + + public DateAndTime() + { + } + + public DateAndTime(byte[] buf, int offset) + { + _info = LittleEndian.GetShort(buf, offset); + _info2 = LittleEndian.GetShort(buf, offset + LittleEndianConsts.SHORT_SIZE); + } + + public void Serialize(byte[] buf, int offset) + { + LittleEndian.PutShort(buf, offset, _info); + LittleEndian.PutShort(buf, offset + LittleEndianConsts.SHORT_SIZE, _info2); + } + + public override bool Equals(Object o) + { + DateAndTime dttm = (DateAndTime)o; + return _info == dttm._info && _info2 == dttm._info2; + } + + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/UserModel/DocumentPosition.cs b/scratchpad/HWPF/UserModel/DocumentPosition.cs new file mode 100644 index 0000000..573a019 --- /dev/null +++ b/scratchpad/HWPF/UserModel/DocumentPosition.cs @@ -0,0 +1,31 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.UserModel +{ + + public class DocumentPosition + : Range + { + public DocumentPosition(HWPFDocument doc, int pos):base(pos, pos, doc) + { + + } + + } +} + diff --git a/scratchpad/HWPF/UserModel/DropCapSpecifier.cs b/scratchpad/HWPF/UserModel/DropCapSpecifier.cs new file mode 100644 index 0000000..2a1b160 --- /dev/null +++ b/scratchpad/HWPF/UserModel/DropCapSpecifier.cs @@ -0,0 +1,59 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.UserModel +{ + using System; + using NPOI.Util; + using NPOI.HWPF.Model; + + /** + * This data structure Is used by a paragraph to determine how it should drop + * its first letter. I think its the visual effect that will show a giant first + * letter to a paragraph. I've seen this used in the first paragraph of a + * book + * + * @author Ryan Ackley + */ + public class DropCapSpecifier:BaseObject + { + private short _info; + private static BitField _type = BitFieldFactory.GetInstance(0x07); + private static BitField _lines = BitFieldFactory.GetInstance(0xf8); + + public DropCapSpecifier() + { + this._info = 0; + } + + public DropCapSpecifier(byte[] buf, int offset) + : this(LittleEndian.GetShort(buf, offset)) + { + + } + + public DropCapSpecifier(short info) + { + _info = info; + } + + public short ToShort() + { + return _info; + } + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/UserModel/Field.cs b/scratchpad/HWPF/UserModel/Field.cs new file mode 100644 index 0000000..4fd4da7 --- /dev/null +++ b/scratchpad/HWPF/UserModel/Field.cs @@ -0,0 +1,82 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using System; +using System.Collections.Generic; +using System.Text; + +namespace NPOI.HWPF.UserModel +{ + public interface Field + { + Range FirstSubrange(Range parent); + + /** + * @return character position of first character after field (i.e. + * {@link #getMarkEndOffset()} + 1) + */ + int GetFieldEndOffset(); + + /** + * @return character position of first character in field (i.e. + * {@link #getFieldStartOffset()}) + */ + int GetFieldStartOffset(); + + CharacterRun GetMarkEndCharacterRun(Range parent); + + /** + * @return character position of end field mark + */ + int GetMarkEndOffset(); + + CharacterRun GetMarkSeparatorCharacterRun(Range parent); + + /** + * @return character position of separator field mark (if present, + * {@link NullPointerException} otherwise) + */ + int GetMarkSeparatorOffset(); + + CharacterRun GetMarkStartCharacterRun(Range parent); + + /** + * @return character position of start field mark + */ + int GetMarkStartOffset(); + + int Type { get; } + + bool HasSeparator(); + + bool IsHasSep(); + + bool IsLocked(); + + bool IsNested(); + + bool IsPrivateResult(); + + bool IsResultDirty(); + + bool IsResultEdited(); + + bool IsZombieEmbed(); + + Range SecondSubrange(Range parent); + } +} diff --git a/scratchpad/HWPF/UserModel/FieldImpl.cs b/scratchpad/HWPF/UserModel/FieldImpl.cs new file mode 100644 index 0000000..19b7fe7 --- /dev/null +++ b/scratchpad/HWPF/UserModel/FieldImpl.cs @@ -0,0 +1,233 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +using System; +using NPOI.HWPF.Model; +using NPOI.Util; +namespace NPOI.HWPF.UserModel +{ + + /** + * TODO: document me + * + * @author Sergey Vladimirov (vlsergey {at} gmail {dot} com) + */ + + public class FieldImpl : Field + { + private PlexOfField endPlex; + private PlexOfField separatorPlex; + private PlexOfField startPlex; + + public FieldImpl(PlexOfField startPlex, PlexOfField separatorPlex, + PlexOfField endPlex) + { + if (startPlex == null) + throw new ArgumentException("startPlex == null"); + if (endPlex == null) + throw new ArgumentException("endPlex == null"); + + if (startPlex.Fld.GetBoundaryType() != FieldDescriptor.FIELD_BEGIN_MARK) + throw new ArgumentException("startPlex (" + startPlex + + ") is not type of FIELD_BEGIN"); + + if (separatorPlex != null + && separatorPlex.Fld.GetBoundaryType() != FieldDescriptor.FIELD_SEPARATOR_MARK) + throw new ArgumentException("separatorPlex" + separatorPlex + + ") is not type of FIELD_SEPARATOR"); + + if (endPlex.Fld.GetBoundaryType() != FieldDescriptor.FIELD_END_MARK) + throw new ArgumentException("endPlex (" + endPlex + + ") is not type of FIELD_END"); + + this.startPlex = startPlex; + this.separatorPlex = separatorPlex; + this.endPlex = endPlex; + } + + + public class FieldSubRange : Range + { + string className; + + public FieldSubRange(int start, int end, Range parent, string className) + : base(start, end, parent) + { + this.className = className; + } + public override String ToString() + { + return this.className + " (" + base.ToString() + ")"; + } + } + + public Range FirstSubrange(Range parent) + { + if (HasSeparator()) + { + if (GetMarkStartOffset() + 1 == GetMarkSeparatorOffset()) + return null; + + return new FieldSubRange(GetMarkStartOffset() + 1, + GetMarkSeparatorOffset(), parent, "FieldSubrange1"); + + } + + if (GetMarkStartOffset() + 1 == GetMarkEndOffset()) + return null; + + return new FieldSubRange(GetMarkStartOffset() + 1, GetMarkEndOffset(), parent, "FieldSubrange1"); + + } + + /** + * @return character position of first character after field (i.e. + * {@link #getMarkEndOffset()} + 1) + */ + public int GetFieldEndOffset() + { + /* + * sometimes plex looks like [100, 2000), where 100 is the position of + * field-end character, and 2000 - some other char position, far away + * from field (not inside). So taking into account only start --sergey + */ + return endPlex.FcStart + 1; + } + + /** + * @return character position of first character in field (i.e. + * {@link #getFieldStartOffset()}) + */ + public int GetFieldStartOffset() + { + return startPlex.FcStart; + } + + public CharacterRun GetMarkEndCharacterRun(Range parent) + { + return new Range(GetMarkEndOffset(), GetMarkEndOffset() + 1, parent) + .GetCharacterRun(0); + } + + /** + * @return character position of end field mark + */ + public int GetMarkEndOffset() + { + return endPlex.FcStart; + } + + public CharacterRun GetMarkSeparatorCharacterRun(Range parent) + { + if (!HasSeparator()) + return null; + + return new Range(GetMarkSeparatorOffset(), + GetMarkSeparatorOffset() + 1, parent).GetCharacterRun(0); + } + + /** + * @return character position of separator field mark (if present, + * {@link NullPointerException} otherwise) + */ + public int GetMarkSeparatorOffset() + { + return separatorPlex.FcStart; + } + + public CharacterRun GetMarkStartCharacterRun(Range parent) + { + return new Range(GetMarkStartOffset(), GetMarkStartOffset() + 1, + parent).GetCharacterRun(0); + } + + /** + * @return character position of start field mark + */ + public int GetMarkStartOffset() + { + return startPlex.FcStart; + } + + public int Type + { + get + { + return startPlex.Fld.GetFieldType(); + } + } + + public bool HasSeparator() + { + return separatorPlex != null; + } + + public bool IsHasSep() + { + return endPlex.Fld.IsFHasSep(); + } + + public bool IsLocked() + { + return endPlex.Fld.IsFLocked(); + } + + public bool IsNested() + { + return endPlex.Fld.IsFNested(); + } + + public bool IsPrivateResult() + { + return endPlex.Fld.IsFPrivateResult(); + } + + public bool IsResultDirty() + { + return endPlex.Fld.IsFResultDirty(); + } + + public bool IsResultEdited() + { + return endPlex.Fld.IsFResultEdited(); + } + + public bool IsZombieEmbed() + { + return endPlex.Fld.IsFZombieEmbed(); + } + + public Range SecondSubrange(Range parent) + { + if (!HasSeparator() + || GetMarkSeparatorOffset() + 1 == GetMarkEndOffset()) + return null; + + return new FieldSubRange(GetMarkSeparatorOffset() + 1, GetMarkEndOffset(), + parent, "FieldSubrange2"); + } + + + public override String ToString() + { + return "Field [" + GetFieldStartOffset() + "; " + GetFieldEndOffset() + + "] (type: 0x" + StringUtil.ToHexString(Type) + " = " + + GetType() + " )"; + } + } + +} + diff --git a/scratchpad/HWPF/UserModel/Fields.cs b/scratchpad/HWPF/UserModel/Fields.cs new file mode 100644 index 0000000..e31be95 --- /dev/null +++ b/scratchpad/HWPF/UserModel/Fields.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; +using NPOI.HWPF.Model; +using System.Collections.ObjectModel; + +namespace NPOI.HWPF.UserModel +{ + public interface Fields + { + Field GetFieldByStartOffset(FieldsDocumentPart documentPart, int offset); + + List GetFields(FieldsDocumentPart part); + } +} diff --git a/scratchpad/HWPF/UserModel/FieldsImpl.cs b/scratchpad/HWPF/UserModel/FieldsImpl.cs new file mode 100644 index 0000000..2dafd4b --- /dev/null +++ b/scratchpad/HWPF/UserModel/FieldsImpl.cs @@ -0,0 +1,273 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +using NPOI.HWPF.Model; +using NPOI.HWPF.UserModel; +using System.Collections.Generic; +using System; +namespace NPOI.HWPF.UserModel +{ + + /** + * Default implementation of {@link Field} + * + * @author Sergey Vladimirov (vlsergey {at} gmail {dot} com) + */ + + public class FieldsImpl : Fields + { + /** + * This is port and adaptation of Arrays.binarySearch from Java 6 (Apache + * Harmony). + */ + private static int BinarySearch(List list, + int startIndex, int endIndex, int requiredStartOffset) + { + CheckIndexForBinarySearch(list.Count, startIndex, endIndex); + + int low = startIndex, mid = -1, high = endIndex - 1, result = 0; + while (low <= high) + { + mid = (low + high) >> 1; + int midStart = list[mid].FcStart; + + if (midStart == requiredStartOffset) + { + return mid; + } + else if (midStart < requiredStartOffset) + { + low = mid + 1; + } + else + { + high = mid - 1; + } + } + if (mid < 0) + { + int insertPoint = endIndex; + for (int index = startIndex; index < endIndex; index++) + { + if (requiredStartOffset < list[index].FcStart) + { + insertPoint = index; + } + } + return -insertPoint - 1; + } + return -mid - (result >= 0 ? 1 : 2); + } + + private static void CheckIndexForBinarySearch(int length, int start, + int end) + { + if (start > end) + { + throw new ArgumentException(); + } + if (length < end || 0 > start) + { + throw new IndexOutOfRangeException(); + } + } + + private Dictionary> _fieldsByOffset; + + private PlexOfFieldComparator comparator = new PlexOfFieldComparator(); + + public FieldsImpl(FieldsTables fieldsTables) + { + _fieldsByOffset = new Dictionary>( + ); + + foreach (FieldsDocumentPart part in Enum.GetValues(typeof(FieldsDocumentPart))) + { + List plexOfCps = fieldsTables.GetFieldsPLCF(part); + _fieldsByOffset.Add(part, ParseFieldStructure(plexOfCps)); + } + } + + public List GetFields(FieldsDocumentPart part) + { + Dictionary map = _fieldsByOffset[part]; + if (map == null || map.Count == 0) + return new List(); + + List vList=new List(); + foreach(Field f in map.Values) + { + vList.Add(f); + } + return vList; + } + + public Field GetFieldByStartOffset(FieldsDocumentPart documentPart, + int offset) + { + Dictionary map = _fieldsByOffset[documentPart]; + if (map == null || map.Count == 0) + return null; + + return map[offset]; + } + + private Dictionary ParseFieldStructure( + List plexOfFields) + { + if (plexOfFields == null || plexOfFields.Count == 0) + return new Dictionary(); + + plexOfFields.Sort(comparator); + List fields = new List( + plexOfFields.Count / 3 + 1); + ParseFieldStructureImpl(plexOfFields, 0, plexOfFields.Count, fields); + + Dictionary result = new Dictionary( + fields.Count); + foreach (FieldImpl field in fields) + { + result.Add(field.GetFieldStartOffset(), field); + } + return result; + } + + private void ParseFieldStructureImpl(List plexOfFields, + int startOffsetInclusive, int endOffsetExclusive, + List result) + { + int next = startOffsetInclusive; + while (next < endOffsetExclusive) + { + PlexOfField startPlexOfField = plexOfFields[next]; + if (startPlexOfField.Fld.GetBoundaryType() != FieldDescriptor.FIELD_BEGIN_MARK) + { + /* Start mark seems to be missing */ + next++; + continue; + } + + /* + * we have start node. end offset points to next node, separator or + * end + */ + int nextNodePositionInList = BinarySearch(plexOfFields, next + 1, + endOffsetExclusive, startPlexOfField.FcEnd); + if (nextNodePositionInList < 0) + { + /* + * too bad, this start field mark doesn't have corresponding end + * field mark or separator field mark in fields table + */ + next++; + continue; + } + PlexOfField nextPlexOfField = plexOfFields + [nextNodePositionInList]; + + switch (nextPlexOfField.Fld.GetBoundaryType()) + { + case FieldDescriptor.FIELD_SEPARATOR_MARK: + { + PlexOfField separatorPlexOfField = nextPlexOfField; + + int endNodePositionInList = BinarySearch(plexOfFields, + nextNodePositionInList, endOffsetExclusive, + separatorPlexOfField.FcEnd); + if (endNodePositionInList < 0) + { + /* + * too bad, this separator field mark doesn't have + * corresponding end field mark in fields table + */ + next++; + continue; + } + PlexOfField endPlexOfField = plexOfFields + [endNodePositionInList]; + + if (endPlexOfField.Fld.GetBoundaryType() != FieldDescriptor.FIELD_END_MARK) + { + /* Not and ending mark */ + next++; + continue; + } + + FieldImpl field = new FieldImpl(startPlexOfField, + separatorPlexOfField, endPlexOfField); + result.Add(field); + + // Adding included fields + if (startPlexOfField.FcStart + 1 < separatorPlexOfField + .FcStart - 1) + { + ParseFieldStructureImpl(plexOfFields, next + 1, + nextNodePositionInList, result); + } + if (separatorPlexOfField.FcStart + 1 < endPlexOfField + .FcStart - 1) + { + ParseFieldStructureImpl(plexOfFields, + nextNodePositionInList + 1, endNodePositionInList, + result); + } + + next = endNodePositionInList + 1; + + break; + } + case FieldDescriptor.FIELD_END_MARK: + { + // we have no separator + FieldImpl field = new FieldImpl(startPlexOfField, null, + nextPlexOfField); + result.Add(field); + + // Adding included fields + if (startPlexOfField.FcStart + 1 < nextPlexOfField + .FcStart - 1) + { + ParseFieldStructureImpl(plexOfFields, next + 1, + nextNodePositionInList, result); + } + + next = nextNodePositionInList + 1; + break; + } + case FieldDescriptor.FIELD_BEGIN_MARK: + default: + { + /* something is wrong, ignoring this mark along with start mark */ + next++; + continue; + } + } + } + } + + private class PlexOfFieldComparator : + IComparer + { + public int Compare(PlexOfField o1, PlexOfField o2) + { + int thisVal = o1.FcStart; + int anotherVal = o2.FcStart; + return thisVal < anotherVal ? -1 : thisVal == anotherVal ? 0 : 1; + } + } + + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/UserModel/HWPFList.cs b/scratchpad/HWPF/UserModel/HWPFList.cs new file mode 100644 index 0000000..9a94445 --- /dev/null +++ b/scratchpad/HWPF/UserModel/HWPFList.cs @@ -0,0 +1,109 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +namespace NPOI.HWPF.UserModel +{ + using NPOI.HWPF.Model; + using NPOI.HWPF.SPRM; + using System; + /** + * This class is used to create a list in a Word document. It is used in + * conjunction with {@link + * NPOI.HWPF.HWPFDocument#registerList(HWPFList) registerList} in + * {@link NPOI.HWPF.HWPFDocument HWPFDocument}. + * + * In Word, lists are not ranged entities, meaning you can't actually add one + * to the document. Lists only act as properties for list entries. Once you + * register a list, you can add list entries to a document that are a part of + * the list. + * + * The only benefit of this that I see, is that you can add a list entry + * anywhere in the document and continue numbering from the previous list. + * + * @author Ryan Ackley + */ + public class HWPFList + { + private ListData _listData; + private ListFormatOverride _override; + private bool _registered; + private StyleSheet _styleSheet; + + /** + * + * @param numbered true if the list should be numbered; false if it should be + * bulleted. + * @param styleSheet The document's stylesheet. + */ + public HWPFList(bool numbered, StyleSheet styleSheet) + { + _listData = new ListData((int)(new Random((int)DateTime.Now.Ticks).Next(0,100)/100 * DateTime.Now.Millisecond), numbered); + _override = new ListFormatOverride(_listData.GetLsid()); + _styleSheet = styleSheet; + } + + /** + * Sets the character properties of the list numbers. + * + * @param level the level number that the properties should apply to. + * @param chp The character properties. + */ + public void SetLevelNumberProperties(int level, CharacterProperties chp) + { + ListLevel listLevel = _listData.GetLevel(level); + int styleIndex = _listData.GetLevelStyle(level); + CharacterProperties base1 = _styleSheet.GetCharacterStyle(styleIndex); + + byte[] grpprl = CharacterSprmCompressor.CompressCharacterProperty(chp, base1); + listLevel.SetNumberProperties(grpprl); + } + + /** + * Sets the paragraph properties for a particular level of the list. + * + * @param level The level number. + * @param pap The paragraph properties + */ + public void SetLevelParagraphProperties(int level, ParagraphProperties pap) + { + ListLevel listLevel = _listData.GetLevel(level); + int styleIndex = _listData.GetLevelStyle(level); + ParagraphProperties base1 = _styleSheet.GetParagraphStyle(styleIndex); + + byte[] grpprl = ParagraphSprmCompressor.CompressParagraphProperty(pap, base1); + listLevel.SetLevelProperties(grpprl); + } + + public void SetLevelStyle(int level, int styleIndex) + { + _listData.SetLevelStyle(level, styleIndex); + } + + public ListData GetListData() + { + return _listData; + } + + public ListFormatOverride GetOverride() + { + return _override; + } + + } + +} \ No newline at end of file diff --git a/scratchpad/HWPF/UserModel/HeaderStories.cs b/scratchpad/HWPF/UserModel/HeaderStories.cs new file mode 100644 index 0000000..65ed47e --- /dev/null +++ b/scratchpad/HWPF/UserModel/HeaderStories.cs @@ -0,0 +1,274 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using NPOI.HWPF.UserModel; +using NPOI.HWPF.Model; +using System; +namespace NPOI.HWPF.UserModel +{ + + /** + * A HeaderStory is a Header, a Footer, or footnote/endnote + * separator. + * All the Header Stories get stored in the same Range in the + * document, and this handles Getting out all the individual + * parts. + * + * WARNING - you shouldn't change the headers or footers, + * as offSets are not yet updated! + */ + public class HeaderStories + { + private Range headerStories; + private PlexOfCps plcfHdd; + + private bool stripFields = false; + + public HeaderStories(HWPFDocument doc) + { + this.headerStories = doc.GetHeaderStoryRange(); + FileInformationBlock fib = doc.GetFileInformationBlock(); + + // If there's no PlcfHdd, nothing to do + if (fib.GetCcpHdd() == 0) + { + return; + } + if (fib.GetPlcfHddSize() == 0) + { + return; + } + + // Handle the PlcfHdd + plcfHdd = new PlexOfCps( + doc.GetTableStream(), fib.GetPlcfHddOffset(), + fib.GetPlcfHddSize(), 0 + ); + } + + public String FootnoteSeparator + { + get{ + return GetAt(0); + } + } + public String FootnoteContSeparator + { + get{ + return GetAt(1); + } + } + public String FootnoteContNote + { + get{ + return GetAt(2); + } + } + public String EndnoteSeparator + { + get{ + return GetAt(3); + } + } + public String EndnoteContSeparator + { + get{ + return GetAt(4); + } + } + public String EndnoteContNote + { + get + { + return GetAt(5); + } + } + + + public String EvenHeader + { + get + { + return GetAt(6 + 0); + } + } + public String OddHeader + { + get + { + return GetAt(6 + 1); + } + } + public String FirstHeader + { + get + { + return GetAt(6 + 4); + } + } + /** + * Returns the correct, defined header for the given + * one based page + * @param pageNumber The one based page number + */ + public String GetHeader(int pageNumber) + { + // First page header is optional, only return + // if it's set + if (pageNumber == 1) + { + if (FirstHeader.Length > 0) + { + return FirstHeader; + } + } + // Even page header is optional, only return + // if it's set + if (pageNumber % 2 == 0) + { + if (EvenHeader.Length > 0) + { + return EvenHeader; + } + } + // Odd is the default + return OddHeader; + } + + + public String EvenFooter + { + get + { + return GetAt(6 + 2); + } + } + public String OddFooter + { + get + { + return GetAt(6 + 3); + } + } + public String FirstFooter + { + get + { + return GetAt(6 + 5); + } + } + /** + * Returns the correct, defined footer for the given + * one based page + * @param pageNumber The one based page number + */ + public String GetFooter(int pageNumber) + { + // First page footer is optional, only return + // if it's set + if (pageNumber == 1) + { + if (FirstFooter.Length > 0) + { + return FirstFooter; + } + } + // Even page footer is optional, only return + // if it's set + if (pageNumber % 2 == 0) + { + if (EvenFooter.Length > 0) + { + return EvenFooter; + } + } + // Odd is the default + return OddFooter; + } + + + /** + * Get the string that's pointed to by the + * given plcfHdd index + */ + private String GetAt(int plcfHddIndex) + { + if (plcfHdd == null) return null; + + GenericPropertyNode prop = plcfHdd.GetProperty(plcfHddIndex); + if (prop.Start == prop.End) + { + // Empty story + return ""; + } + if (prop.End < prop.Start) + { + // Broken properties? + return ""; + } + + // Ensure we're Getting a sensible length + String rawText = headerStories.Text; + int start = Math.Min(prop.Start, rawText.Length); + int end = Math.Min(prop.End, rawText.Length); + + // Grab the contents + String text = rawText.Substring(start, end-start); + + // Strip off fields and macros if requested + if (stripFields) + { + return Range.StripFields(text); + } + // If you create a header/footer, then remove it again, word + // will leave \r\r. Turn these back into an empty string, + // which is more what you'd expect + if (text.Equals("\r\r")) + { + return ""; + } + + return text; + } + + public Range GetRange() + { + return headerStories; + } + internal PlexOfCps GetPlcfHdd() + { + return plcfHdd; + } + + /** + * Are fields currently being stripped from + * the text that this {@link HeaderStories} returns? + * Default is false, but can be Changed + */ + public bool AreFieldsStripped + { + get + { + return stripFields; + } + set + { + this.stripFields = value; + } + } + } +} diff --git a/scratchpad/HWPF/UserModel/LineSpacingDescriptor.cs b/scratchpad/HWPF/UserModel/LineSpacingDescriptor.cs new file mode 100644 index 0000000..117dc23 --- /dev/null +++ b/scratchpad/HWPF/UserModel/LineSpacingDescriptor.cs @@ -0,0 +1,73 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.UserModel +{ + using System; + using NPOI.Util; + using NPOI.HWPF.Model; + + /** + * This class Is used to determine line spacing for a paragraph. + * + * @author Ryan Ackley + */ + public class LineSpacingDescriptor:BaseObject + { + short _dyaLine; + short _fMultiLinespace; + + public LineSpacingDescriptor() + { + } + + public LineSpacingDescriptor(byte[] buf, int offset) + { + _dyaLine = LittleEndian.GetShort(buf, offset); + _fMultiLinespace = LittleEndian.GetShort(buf, offset + LittleEndianConsts.SHORT_SIZE); + } + + public void SetMultiLinespace(short fMultiLinespace) + { + _fMultiLinespace = fMultiLinespace; + } + + public int ToInt() + { + byte[] intHolder = new byte[4]; + Serialize(intHolder, 0); + return LittleEndian.GetInt(intHolder); + } + + public void Serialize(byte[] buf, int offset) + { + LittleEndian.PutShort(buf, offset, _dyaLine); + LittleEndian.PutShort(buf, offset + LittleEndianConsts.SHORT_SIZE, _fMultiLinespace); + } + + public void SetDyaLine(short dyaLine) + { + _dyaLine = dyaLine; + } + public override bool Equals(Object o) + { + LineSpacingDescriptor lspd = (LineSpacingDescriptor)o; + + return _dyaLine == lspd._dyaLine && _fMultiLinespace == lspd._fMultiLinespace; + } + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/UserModel/ListEntry.cs b/scratchpad/HWPF/UserModel/ListEntry.cs new file mode 100644 index 0000000..78605e3 --- /dev/null +++ b/scratchpad/HWPF/UserModel/ListEntry.cs @@ -0,0 +1,56 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.UserModel +{ + + using NPOI.HWPF.Model; + using NPOI.HWPF.UserModel; + + public class ListEntry: Paragraph + { + //private static POILogger log = POILogFactory.GetLogger(ListEntry.class); + + ListLevel _level; + ListFormatOverrideLevel _overrideLevel; + + internal ListEntry(PAPX papx, Range parent, ListTables tables) + : base(papx, parent) + { + + if (tables != null) + { + ListFormatOverride override1 = tables.GetOverride(_props.GetIlfo()); + _overrideLevel = override1.GetOverrideLevel(_props.GetIlvl()); + _level = tables.GetLevel(override1.GetLsid(), _props.GetIlvl()); + } + else + { + //log.log(POILogger.WARN, "No ListTables found for ListEntry - document probably partly corrupt, and you may experience problems"); + } + } + + public override int Type + { + get + { + return Range.TYPE_LISTENTRY; + } + } + } +} + diff --git a/scratchpad/HWPF/UserModel/Notes.cs b/scratchpad/HWPF/UserModel/Notes.cs new file mode 100644 index 0000000..8084f20 --- /dev/null +++ b/scratchpad/HWPF/UserModel/Notes.cs @@ -0,0 +1,57 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +namespace NPOI.HWPF.UserModel +{ + + /** + * User-friendly interface to access document notes information + * + * @author Sergey Vladimirov (vlsergey {at} gmail {doc} com) + */ + public interface Notes + { + /** + * Returns the location of note anchor in main textspace + */ + int GetNoteAnchorPosition(int index); + + /** + * Returns count of notes in document + */ + int GetNotesCount(); + + /** + * Returns index of note (if exists, otherwise -1) with specified anchor + * position + */ + int GetNoteIndexByAnchorPosition(int anchorPosition); + + /** + * Returns the end offset of the text corresponding to the reference within + * the footnote text Address space + */ + int GetNoteTextEndOffSet(int index); + + /** + * Returns the start offset of the text corresponding to the reference + * within the footnote text Address space + */ + int GetNoteTextStartOffSet(int index); + } + + +} \ No newline at end of file diff --git a/scratchpad/HWPF/UserModel/NotesImpl.cs b/scratchpad/HWPF/UserModel/NotesImpl.cs new file mode 100644 index 0000000..5c2255e --- /dev/null +++ b/scratchpad/HWPF/UserModel/NotesImpl.cs @@ -0,0 +1,85 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +using System.Collections.Generic; +using NPOI.HWPF.Model; +namespace NPOI.HWPF.UserModel +{ + + /** + * Default implementation of {@link Notes} interface + * + * @author Sergey Vladimirov (vlsergey {at} gmail {doc} com) + */ + public class NotesImpl : Notes + { + private Dictionary anchorToIndexMap = null; + + private NotesTables notesTables; + + public NotesImpl(NotesTables notesTables) + { + this.notesTables = notesTables; + } + + public int GetNoteAnchorPosition(int index) + { + return notesTables.GetDescriptor(index).Start; + } + + public int GetNoteIndexByAnchorPosition(int anchorPosition) + { + UpdateAnchorToIndexMap(); + + if(!anchorToIndexMap.ContainsKey(anchorPosition)) + return -1; + int index = anchorToIndexMap + [anchorPosition]; + + return index; + } + + public int GetNotesCount() + { + return notesTables.GetDescriptorsCount(); + } + + public int GetNoteTextEndOffSet(int index) + { + return notesTables.GetTextPosition(index).End; + } + + public int GetNoteTextStartOffSet(int index) + { + return notesTables.GetTextPosition(index).Start; + } + + private void UpdateAnchorToIndexMap() + { + if (anchorToIndexMap != null) + return; + + Dictionary result = new Dictionary(); + for (int n = 0; n < notesTables.GetDescriptorsCount(); n++) + { + int anchorPosition = notesTables.GetDescriptor(n).Start; + result[anchorPosition] = n; + } + this.anchorToIndexMap = result; + } + } +} + diff --git a/scratchpad/HWPF/UserModel/ObjectPoolImpl.cs b/scratchpad/HWPF/UserModel/ObjectPoolImpl.cs new file mode 100644 index 0000000..447c56f --- /dev/null +++ b/scratchpad/HWPF/UserModel/ObjectPoolImpl.cs @@ -0,0 +1,56 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +using NPOI.POIFS.FileSystem; +using System.IO; +using NPOI.Util; +using System; +namespace NPOI.HWPF.UserModel +{ + + public class ObjectPoolImpl : ObjectsPool + { + private DirectoryEntry _objectPool; + + public ObjectPoolImpl(DirectoryEntry _objectPool) + : base() + { + + this._objectPool = _objectPool; + } + + public Entry GetObjectById(String objId) + { + if (_objectPool == null) + return null; + + try + { + return _objectPool.GetEntry(objId); + } + catch (FileNotFoundException) + { + return null; + } + } + + public void WriteTo(DirectoryEntry directoryEntry) + { + if (_objectPool != null) + POIUtils.CopyNodeRecursively(_objectPool, directoryEntry); + } + } +} diff --git a/scratchpad/HWPF/UserModel/ObjectsPool.cs b/scratchpad/HWPF/UserModel/ObjectsPool.cs new file mode 100644 index 0000000..e426966 --- /dev/null +++ b/scratchpad/HWPF/UserModel/ObjectsPool.cs @@ -0,0 +1,29 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +using System; +using NPOI.POIFS.FileSystem; +namespace NPOI.HWPF.UserModel +{ + + + public interface ObjectsPool + { + Entry GetObjectById(String objId); + } + + +} \ No newline at end of file diff --git a/scratchpad/HWPF/UserModel/OfficeDrawing.cs b/scratchpad/HWPF/UserModel/OfficeDrawing.cs new file mode 100644 index 0000000..88c78b9 --- /dev/null +++ b/scratchpad/HWPF/UserModel/OfficeDrawing.cs @@ -0,0 +1,189 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +namespace NPOI.HWPF.UserModel +{ + + + public enum HorizontalPositioning + { + + /** + * The shape is horizontally offset by an absolute distance from the + * page element. + */ + ABSOLUTE, + + /** + * The shape is horizontally positioned at the center of the page + * element. + */ + CENTER, + + /** + * The shape is horizontally positioned like {@link #LEFT} on + * odd-numbered pages and like {@link #RIGHT} on even-numbered pages. + */ + INSIDE, + + /** + * The shape is horizontally positioned at the left side of the page + * element. + */ + LEFT, + + /** + * The shape is horizontally positioned like {@link #RIGHT} on + * odd-numbered pages and like {@link #LEFT} on even-numbered pages. + */ + OUTSIDE, + + /** + * The shape is horizontally positioned at the right side of the page + * element. + */ + RIGHT + } + + public enum HorizontalRelativeElement + { + CHAR, MARGIN, PAGE, TEXT + } + + public enum VerticalPositioning + { + + /** + * The shape is vertically offset by an absolute distance from the page + * element + */ + ABSOLUTE, + + /** + * The shape is vertically positioned at the bottom of the page element + */ + BOTTOM, + + /** + * The shape is vertically positioned in the center of the page element + */ + CENTER, + + /** + * The shape is vertically positioned like msopvTop on odd-numbered + * pages and like msopvBottom on even-numbered pages + */ + INSIDE, + + /** + * The shape is vertically positioned like {@link #BOTTOM} on + * odd-numbered pages and like {@link #TOP} on even-numbered pages + */ + OUTSIDE, + + /** + * The shape is vertically positioned at the top of the page element + */ + TOP + } + + public enum VerticalRelativeElement + { + LINE, MARGIN, PAGE, TEXT + } + /** + * User-friendly interface to office drawing objects. + *

    + * Some properties and enumeration constants description are quotes from the + * following sources: + *

      + *
    • [MS-ODRAW] -- v20110608; Office Drawing Binary File Format; Copyright (c) + * 2011 Microsoft Corporation. + *
    + * + * @author Sergey Vladimirov (vlsergey {at} gmail {dot} com) + */ + public interface OfficeDrawing + { + + + + /** + * Returns the type of horizontal positioning to use for a shape + * + * @return the type of horizontal positioning to use for a shape + */ + HorizontalPositioning GetHorizontalPositioning(); + + /** + * Specifies a page element relative to which a shape is horizontally + * positioned + * + * @return a page element relative to which a shape is horizontally + * positioned + */ + HorizontalRelativeElement GetHorizontalRelative(); + + /** + * Returns picture data if this shape has (Single?) associated picture data + */ + byte[] GetPictureData(); + + /** + * Bottom of the rectangle enclosing shape relative to the origin of the + * shape + */ + int GetRectangleBottom(); + + /** + * Left of rectangle enclosing shape relative to the origin of the shape + */ + int GetRectangleLeft(); + + /** + * Right of rectangle enclosing shape relative to the origin of the shape + */ + int GetRectangleRight(); + + /** + * Top of rectangle enclosing shape relative to the origin of the shape + */ + int GetRectangleTop(); + + /** + * Shape Identifier + */ + int GetShapeId(); + + /** + * Specifies the type of vertical positioning to use for a shape + * + * @return return the type of vertical positioning to use for a shape + */ + VerticalPositioning GetVerticalPositioning(); + + /** + * Specifies a page element relative to which a shape is vertically + * positioned + * + * @return a page element relative to which a shape is vertically positioned + */ + VerticalRelativeElement GetVerticalRelativeElement(); + + } + + +} \ No newline at end of file diff --git a/scratchpad/HWPF/UserModel/OfficeDrawings.cs b/scratchpad/HWPF/UserModel/OfficeDrawings.cs new file mode 100644 index 0000000..b909447 --- /dev/null +++ b/scratchpad/HWPF/UserModel/OfficeDrawings.cs @@ -0,0 +1,33 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using System.Collections.Generic; +namespace NPOI.HWPF.UserModel +{ + + /** + * User-friendly interface to access document part's office drawings + * + * @author Sergey Vladimirov (vlsergey {at} gmail {dot} com) + */ + public interface OfficeDrawings + { + OfficeDrawing GetOfficeDrawingAt(int characterPosition); + + List GetOfficeDrawings(); + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/UserModel/OfficeDrawingsImpl.cs b/scratchpad/HWPF/UserModel/OfficeDrawingsImpl.cs new file mode 100644 index 0000000..651fbf0 --- /dev/null +++ b/scratchpad/HWPF/UserModel/OfficeDrawingsImpl.cs @@ -0,0 +1,309 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +using System.Collections.Generic; +using NPOI.DDF; +using NPOI.HWPF.Model; +using System.Collections; +using System.Collections.ObjectModel; +using System; +namespace NPOI.HWPF.UserModel +{ + + public class OfficeDrawingsImpl : OfficeDrawings + { + private EscherRecordHolder _escherRecordHolder; + private FSPATable _fspaTable; + private byte[] _mainStream; + + public OfficeDrawingsImpl(FSPATable fspaTable, + EscherRecordHolder escherRecordHolder, byte[] mainStream) + { + this._fspaTable = fspaTable; + this._escherRecordHolder = escherRecordHolder; + this._mainStream = mainStream; + } + + private EscherBlipRecord GetBitmapRecord(int bitmapIndex) + { + List bContainers = _escherRecordHolder + .GetBStoreContainers(); + if (bContainers == null || bContainers.Count != 1) + return null; + + EscherContainerRecord bContainer = bContainers[0]; + IList bitmapRecords = bContainer.ChildRecords; + + if (bitmapRecords.Count < bitmapIndex) + return null; + + EscherRecord imageRecord = (EscherRecord)bitmapRecords[bitmapIndex - 1]; + + if (imageRecord is EscherBlipRecord) + { + return (EscherBlipRecord)imageRecord; + } + + if (imageRecord is EscherBSERecord) + { + EscherBSERecord bseRecord = (EscherBSERecord)imageRecord; + + EscherBlipRecord blip = bseRecord.BlipRecord; + if (blip != null) + { + return blip; + } + + if (bseRecord.Offset > 0) + { + /* + * Blip stored in delay stream, which in a word doc, is the main + * stream + */ + IEscherRecordFactory recordFactory = new DefaultEscherRecordFactory(); + EscherRecord record = recordFactory.CreateRecord(_mainStream, + bseRecord.Offset); + + if (record is EscherBlipRecord) + { + record.FillFields(_mainStream, bseRecord.Offset, + recordFactory); + return (EscherBlipRecord)record; + } + } + } + + return null; + } + + private EscherContainerRecord GetEscherShapeRecordContainer( + int shapeId) + { + foreach (EscherContainerRecord spContainer in _escherRecordHolder + .GetSpContainers()) + { + EscherSpRecord escherSpRecord = (EscherSpRecord)spContainer + .GetChildById(unchecked((short)0xF00A)); + if (escherSpRecord != null + && escherSpRecord.ShapeId == shapeId) + return spContainer; + } + + return null; + } + + private OfficeDrawing GetOfficeDrawing(FSPA fspa) + { + return new OfficeDrawingImpl(this,fspa); + } + + public OfficeDrawing GetOfficeDrawingAt(int characterPosition) + { + FSPA fspa = _fspaTable.GetFspaFromCp(characterPosition); + if (fspa == null) + return null; + + return GetOfficeDrawing(fspa); + } + + public List GetOfficeDrawings() + { + List result = new List(); + foreach (FSPA fspa in _fspaTable.GetShapes()) + { + result.Add(GetOfficeDrawing(fspa)); + } + return result; + } + + internal class OfficeDrawingImpl : OfficeDrawing + { + FSPA fspa; + OfficeDrawingsImpl od; + public OfficeDrawingImpl(OfficeDrawingsImpl od,FSPA fspa) + { + this.fspa = fspa; + this.od = od; + } + + public HorizontalPositioning GetHorizontalPositioning() + { + int value = GetTertiaryPropertyValue( + EscherProperties.GROUPSHAPE__POSH, -1); + + switch (value) + { + case 0: + return HorizontalPositioning.ABSOLUTE; + case 1: + return HorizontalPositioning.LEFT; + case 2: + return HorizontalPositioning.CENTER; + case 3: + return HorizontalPositioning.RIGHT; + case 4: + return HorizontalPositioning.INSIDE; + case 5: + return HorizontalPositioning.OUTSIDE; + } + + return HorizontalPositioning.ABSOLUTE; + } + + public HorizontalRelativeElement GetHorizontalRelative() + { + int value = GetTertiaryPropertyValue( + EscherProperties.GROUPSHAPE__POSRELH, -1); + + switch (value) + { + case 1: + return HorizontalRelativeElement.MARGIN; + case 2: + return HorizontalRelativeElement.PAGE; + case 3: + return HorizontalRelativeElement.TEXT; + case 4: + return HorizontalRelativeElement.CHAR; + } + + return HorizontalRelativeElement.TEXT; + } + + public byte[] GetPictureData() + { + EscherContainerRecord shapeDescription = od.GetEscherShapeRecordContainer(GetShapeId()); + if (shapeDescription == null) + return null; + + EscherRecord escherOptRecord = (EscherRecord)shapeDescription + .GetChildById(EscherOptRecord.RECORD_ID); + if (escherOptRecord == null) + return null; + + EscherSimpleProperty escherProperty = (EscherSimpleProperty)((EscherOptRecord)escherOptRecord) + .Lookup(EscherProperties.BLIP__BLIPTODISPLAY); + if (escherProperty == null) + return null; + + int bitmapIndex = escherProperty.PropertyValue; + EscherBlipRecord escherBlipRecord = od.GetBitmapRecord(bitmapIndex); + if (escherBlipRecord == null) + return null; + + return escherBlipRecord.PictureData; + } + + public int GetRectangleBottom() + { + return fspa.GetYaBottom(); + } + + public int GetRectangleLeft() + { + return fspa.GetXaLeft(); + } + + public int GetRectangleRight() + { + return fspa.GetXaRight(); + } + + public int GetRectangleTop() + { + return fspa.GetYaTop(); + } + + public int GetShapeId() + { + return fspa.GetSpid(); + } + + private int GetTertiaryPropertyValue(int propertyId, + int defaultValue) + { + EscherContainerRecord shapeDescription = od.GetEscherShapeRecordContainer(GetShapeId()); + if (shapeDescription == null) + return defaultValue; + + EscherRecord escherTertiaryOptRecord = (EscherRecord)shapeDescription + .GetChildById(EscherTertiaryOptRecord.RECORD_ID); + if (escherTertiaryOptRecord == null) + return defaultValue; + + EscherSimpleProperty escherProperty = (EscherSimpleProperty)((EscherOptRecord)escherTertiaryOptRecord) + .Lookup(propertyId); + if (escherProperty == null) + return defaultValue; + int value = escherProperty.PropertyValue; + + return value; + } + + public VerticalPositioning GetVerticalPositioning() + { + int value = GetTertiaryPropertyValue( + EscherProperties.GROUPSHAPE__POSV, -1); + + switch (value) + { + case 0: + return VerticalPositioning.ABSOLUTE; + case 1: + return VerticalPositioning.TOP; + case 2: + return VerticalPositioning.CENTER; + case 3: + return VerticalPositioning.BOTTOM; + case 4: + return VerticalPositioning.INSIDE; + case 5: + return VerticalPositioning.OUTSIDE; + } + + return VerticalPositioning.ABSOLUTE; + } + + public VerticalRelativeElement GetVerticalRelativeElement() + { + int value = GetTertiaryPropertyValue( + EscherProperties.GROUPSHAPE__POSV, -1); + + switch (value) + { + case 1: + return VerticalRelativeElement.MARGIN; + case 2: + return VerticalRelativeElement.PAGE; + case 3: + return VerticalRelativeElement.TEXT; + case 4: + return VerticalRelativeElement.LINE; + } + + return VerticalRelativeElement.TEXT; + } + + public override String ToString() + { + return "OfficeDrawingImpl: " + fspa.ToString(); + } + }; + + } +} + + diff --git a/scratchpad/HWPF/UserModel/Paragraph.cs b/scratchpad/HWPF/UserModel/Paragraph.cs new file mode 100644 index 0000000..1a93ba9 --- /dev/null +++ b/scratchpad/HWPF/UserModel/Paragraph.cs @@ -0,0 +1,521 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using NPOI.HWPF.Model; +using System; +using NPOI.HWPF.SPRM; +namespace NPOI.HWPF.UserModel +{ + + public class Paragraph : Range + { + public const short SPRM_JC = 0x2403; + public const short SPRM_FSIDEBYSIDE = 0x2404; + public const short SPRM_FKEEP = 0x2405; + public const short SPRM_FKEEPFOLLOW = 0x2406; + public const short SPRM_FPAGEBREAKBEFORE = 0x2407; + public const short SPRM_BRCL = 0x2408; + public const short SPRM_BRCP = 0x2409; + public const short SPRM_ILVL = 0x260A; + public const short SPRM_ILFO = 0x460B; + public const short SPRM_FNOLINENUMB = 0x240C; + public const short SPRM_CHGTABSPAPX = unchecked((short)0xC60D); + public const short SPRM_DXARIGHT = unchecked((short)0x840E); + public const short SPRM_DXALEFT = unchecked((short)0x840F); + public const short SPRM_DXALEFT1 = unchecked((short)0x8411); + public const short SPRM_DYALINE = 0x6412; + public const short SPRM_DYABEFORE = unchecked((short)0xA413); + public const short SPRM_DYAAFTER = unchecked((short)0xA414); + public const short SPRM_CHGTABS = unchecked((short)0xC615); + public const short SPRM_FINTABLE = 0x2416; + public const short SPRM_FTTP = 0x2417; + public const short SPRM_DXAABS = unchecked((short)0x8418); + public const short SPRM_DYAABS = unchecked((short)0x8419); + public const short SPRM_DXAWIDTH = unchecked((short)0x841A); + public const short SPRM_PC = 0x261B; + public const short SPRM_WR = 0x2423; + public const short SPRM_BRCTOP = 0x6424; + public const short SPRM_BRCLEFT = 0x6425; + public const short SPRM_BRCBOTTOM = 0x6426; + public const short SPRM_BRCRIGHT = 0x6427; + public const short SPRM_BRCBAR = 0x6629; + public const short SPRM_FNOAUTOHYPH = 0x242A; + public const short SPRM_WHEIGHTABS = 0x442B; + public const short SPRM_DCS = 0x442C; + public const short SPRM_SHD = 0x442D; + public const short SPRM_DYAFROMTEXT = unchecked((short)0x842E); + public const short SPRM_DXAFROMTEXT = unchecked((short)0x842F); + public const short SPRM_FLOCKED = 0x2430; + public const short SPRM_FWIDOWCONTROL = 0x2431; + public const short SPRM_RULER = unchecked((short)0xC632); + public const short SPRM_FKINSOKU = 0x2433; + public const short SPRM_FWORDWRAP = 0x2434; + public const short SPRM_FOVERFLOWPUNCT = 0x2435; + public const short SPRM_FTOPLINEPUNCT = 0x2436; + public const short SPRM_AUTOSPACEDE = 0x2437; + public const short SPRM_AUTOSPACEDN = 0x2438; + public const short SPRM_WALIGNFONT = 0x4439; + public const short SPRM_FRAMETEXTFLOW = 0x443A; + public const short SPRM_ANLD = unchecked((short)0xC63E); + public const short SPRM_PROPRMARK = unchecked((short)0xC63F); + public const short SPRM_OUTLVL = 0x2640; + public const short SPRM_FBIDI = 0x2441; + public const short SPRM_FNUMRMLNS = 0x2443; + public const short SPRM_CRLF = 0x2444; + public const short SPRM_NUMRM = unchecked((short)0xC645); + public const short SPRM_USEPGSUSETTINGS = 0x2447; + public const short SPRM_FADJUSTRIGHT = 0x2448; + + + internal short _istd; + protected ParagraphProperties _props; + internal SprmBuffer _papx; + + internal Paragraph(int startIdx, int endIdx, Table parent) + : base(startIdx, endIdx, parent) + { + InitAll(); + PAPX papx = (PAPX)_paragraphs[_parEnd - 1]; + _props = papx.GetParagraphProperties(_doc.GetStyleSheet()); + _papx = papx.GetSprmBuf(); + _istd = papx.GetIstd(); + } + + internal Paragraph(PAPX papx, Range parent) + : base(Math.Max(parent._start, papx.Start), Math.Min(parent._end, papx.End), parent) + { + + _props = papx.GetParagraphProperties(_doc.GetStyleSheet()); + _papx = papx.GetSprmBuf(); + _istd = papx.GetIstd(); + } + + internal Paragraph(PAPX papx, Range parent, int start) + : base(Math.Max(parent._start, start), Math.Min(parent._end, papx.End), parent) + { + + _props = papx.GetParagraphProperties(_doc.GetStyleSheet()); + _papx = papx.GetSprmBuf(); + _istd = papx.GetIstd(); + } + + public short GetStyleIndex() + { + return _istd; + } + + public override int Type + { + get + { + return TYPE_PARAGRAPH; + } + } + + public bool IsInTable() + { + return _props.GetFInTable(); + } + + public bool IsTableRowEnd() + { + return _props.GetFTtp() || _props.GetFTtpEmbedded(); + } + + public int GetTableLevel() + { + return _props.GetItap(); + } + + public bool IsEmbeddedCellMark() + { + return _props.GetFInnerTableCell(); + } + + public int GetJustification() + { + return _props.GetJc(); + } + + public void SetJustification(byte jc) + { + _props.SetJc(jc); + _papx.UpdateSprm(SPRM_JC, jc); + } + + public bool KeepOnPage() + { + return _props.GetFKeep(); + } + + public void SetKeepOnPage(bool fKeep) + { + _props.SetFKeep(fKeep); + _papx.UpdateSprm(SPRM_FKEEP, Convert.ToByte(fKeep)); + } + + public bool KeepWithNext() + { + return _props.GetFKeepFollow(); + } + + public void SetKeepWithNext(bool fKeepFollow) + { + _props.SetFKeepFollow(fKeepFollow); + _papx.UpdateSprm(SPRM_FKEEPFOLLOW, Convert.ToByte(fKeepFollow)); + } + + public bool PageBreakBefore() + { + return _props.GetFPageBreakBefore(); + } + + public void SetPageBreakBefore(bool fPageBreak) + { + _props.SetFPageBreakBefore(fPageBreak); + _papx.UpdateSprm(SPRM_FPAGEBREAKBEFORE, Convert.ToByte(fPageBreak)); + } + + public bool IsLineNotNumbered() + { + return _props.GetFNoLnn(); + } + + public void SetLineNotNumbered(bool fNoLnn) + { + _props.SetFNoLnn(fNoLnn); + _papx.UpdateSprm(SPRM_FNOLINENUMB, Convert.ToByte(fNoLnn)); + } + + public bool IsSideBySide() + { + return _props.GetFSideBySide(); + } + + public void SetSideBySide(bool fSideBySide) + { + byte sideBySide = (byte)(fSideBySide ? 1 : 0); + _props.SetFSideBySide(fSideBySide); + _papx.UpdateSprm(SPRM_FSIDEBYSIDE, sideBySide); + } + + public bool IsAutoHyphenated + { + get + { + return !_props.GetFNoAutoHyph(); + } + set + { + _props.SetFNoAutoHyph(!value); + _papx.UpdateSprm(SPRM_FNOAUTOHYPH, Convert.ToByte(!value)); + + } + } + + public bool IsWidowControlled() + { + return _props.GetFWidowControl(); + } + + public void SetWidowControl(bool widowControl) + { + _props.SetFWidowControl(widowControl); + _papx.UpdateSprm(SPRM_FWIDOWCONTROL, Convert.ToByte(widowControl)); + } + + public int GetIndentFromRight() + { + return _props.GetDxaRight(); + } + + public void SetIndentFromRight(int dxaRight) + { + _props.SetDxaRight(dxaRight); + _papx.UpdateSprm(SPRM_DXARIGHT, (short)dxaRight); + } + + public int GetIndentFromLeft() + { + return _props.GetDxaLeft(); + } + + public void SetIndentFromLeft(int dxaLeft) + { + _props.SetDxaLeft(dxaLeft); + _papx.UpdateSprm(SPRM_DXALEFT, (short)dxaLeft); + } + + public int GetFirstLineIndent() + { + return _props.GetDxaLeft1(); + } + + public void SetFirstLineIndent(int first) + { + _props.SetDxaLeft1(first); + _papx.UpdateSprm(SPRM_DXALEFT1, (short)first); + } + + public LineSpacingDescriptor GetLineSpacing() + { + return _props.GetLspd(); + } + + public void SetLineSpacing(LineSpacingDescriptor lspd) + { + _props.SetLspd(lspd); + _papx.UpdateSprm(SPRM_DYALINE, lspd.ToInt()); + } + + public int GetSpacingBefore() + { + return _props.GetDyaBefore(); + } + + public void SetSpacingBefore(int before) + { + _props.SetDyaBefore(before); + _papx.UpdateSprm(SPRM_DYABEFORE, (short)before); + } + + public int GetSpacingAfter() + { + return _props.GetDyaAfter(); + } + + public void SetSpacingAfter(int after) + { + _props.SetDyaAfter(after); + _papx.UpdateSprm(SPRM_DYAAFTER, (short)after); + } + + public bool IsKinsoku() + { + return _props.GetFKinsoku(); + } + + public void SetKinsoku(bool kinsoku) + { + byte kin = (byte)(kinsoku ? 1 : 0); + _props.SetFKinsoku(kinsoku); + _papx.UpdateSprm(SPRM_FKINSOKU, kin); + } + + public bool IsWordWrapped() + { + return _props.GetFWordWrap(); + } + + public void SetWordWrapped(bool wrap) + { + byte wordWrap = (byte)(wrap ? 1 : 0); + _props.SetFWordWrap(wrap); + _papx.UpdateSprm(SPRM_FWORDWRAP, wordWrap); + } + + public int GetFontAlignment() + { + return _props.GetWAlignFont(); + } + + public void SetFontAlignment(int align) + { + _props.SetWAlignFont(align); + _papx.UpdateSprm(SPRM_WALIGNFONT, (short)align); + } + + public bool IsVertical() + { + return _props.IsFVertical(); + } + + public void SetVertical(bool vertical) + { + _props.SetFVertical(vertical); + _papx.UpdateSprm(SPRM_FRAMETEXTFLOW, GetFrameTextFlow()); + } + + public bool IsBackward() + { + return _props.IsFBackward(); + } + + public void SetBackward(bool bward) + { + _props.SetFBackward(bward); + _papx.UpdateSprm(SPRM_FRAMETEXTFLOW, GetFrameTextFlow()); + } + + public virtual BorderCode GetTopBorder() + { + return _props.GetBrcTop(); + } + + public void SetTopBorder(BorderCode top) + { + _props.SetBrcTop(top); + _papx.UpdateSprm(SPRM_BRCTOP, top.ToInt()); + } + + public virtual BorderCode GetLeftBorder() + { + return _props.GetBrcLeft(); + } + + public void SetLeftBorder(BorderCode left) + { + _props.SetBrcLeft(left); + _papx.UpdateSprm(SPRM_BRCLEFT, left.ToInt()); + } + + public virtual BorderCode GetBottomBorder() + { + return _props.GetBrcBottom(); + } + + public void SetBottomBorder(BorderCode bottom) + { + _props.SetBrcBottom(bottom); + _papx.UpdateSprm(SPRM_BRCBOTTOM, bottom.ToInt()); + } + + public virtual BorderCode GetRightBorder() + { + return _props.GetBrcRight(); + } + + public void SetRightBorder(BorderCode right) + { + _props.SetBrcRight(right); + _papx.UpdateSprm(SPRM_BRCRIGHT, right.ToInt()); + } + + public virtual BorderCode GetBarBorder() + { + return _props.GetBrcBar(); + } + + public void SetBarBorder(BorderCode bar) + { + _props.SetBrcBar(bar); + _papx.UpdateSprm(SPRM_BRCBAR, bar.ToInt()); + } + + public ShadingDescriptor GetShading() + { + return _props.GetShd(); + } + + public void SetShading(ShadingDescriptor shd) + { + _props.SetShd(shd); + _papx.UpdateSprm(SPRM_SHD, shd.ToShort()); + } + + public DropCapSpecifier GetDropCap() + { + return _props.GetDcs(); + } + + public void SetDropCap(DropCapSpecifier dcs) + { + _props.SetDcs(dcs); + _papx.UpdateSprm(SPRM_DCS, dcs.ToShort()); + } + + /** + * Returns the ilfo, an index to the document's hpllfo, which + * describes the automatic number formatting of the paragraph. + * A value of zero means it isn't numbered. + */ + public int GetIlfo() + { + return _props.GetIlfo(); + } + + /** + * Returns the multi-level indent for the paragraph. Will be + * zero for non-list paragraphs, and the first level of any + * list. Subsequent levels in hold values 1-8. + */ + public int GetIlvl() + { + return _props.GetIlvl(); + } + + /** + * Returns the heading level (1-8), or 9 if the paragraph + * isn't in a heading style. + */ + public int GetLvl() + { + return _props.GetLvl(); + } + + internal void SetTableRowEnd(TableProperties props) + { + SetTableRowEnd(true); + byte[] grpprl = TableSprmCompressor.CompressTableProperty(props); + _papx.Append(grpprl); + } + + private void SetTableRowEnd(bool val) + { + _props.SetFTtp(val); + _papx.UpdateSprm(SPRM_FTTP, Convert.ToByte(val)); + } + + /** + * clone the ParagraphProperties object associated with this Paragraph so + * that you can apply the same properties to another paragraph. + * + */ + public ParagraphProperties CloneProperties() + { + return (ParagraphProperties)_props.Clone(); + } + + public override Object Clone() + { + Paragraph p = (Paragraph)base.Clone(); + p._props = (ParagraphProperties)_props.Clone(); + //p._baseStyle = _baseStyle; + p._papx = new SprmBuffer(); + return p; + } + + private short GetFrameTextFlow() + { + short retVal = 0; + if (_props.IsFVertical()) + { + retVal |= 1; + } + if (_props.IsFBackward()) + { + retVal |= 2; + } + if (_props.IsFRotateFont()) + { + retVal |= 4; + } + return retVal; + } + + } +} diff --git a/scratchpad/HWPF/UserModel/ParagraphProperties.cs b/scratchpad/HWPF/UserModel/ParagraphProperties.cs new file mode 100644 index 0000000..b319e9a --- /dev/null +++ b/scratchpad/HWPF/UserModel/ParagraphProperties.cs @@ -0,0 +1,346 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using NPOI.HWPF.Model.Types; +using System; +using NPOI.Util; +namespace NPOI.HWPF.UserModel +{ + + public class ParagraphProperties : PAPAbstractType + { + + private bool jcLogical = false; + + public ParagraphProperties() + { + SetAnld(new byte[84]); + SetPhe(new byte[12]); + } + + public override Object Clone() + { + + ParagraphProperties pp = (ParagraphProperties)base.Clone(); + + byte[] anld=GetAnld(); + byte[] anldcopy=new byte[anld.Length]; + Array.Copy(anld,anldcopy,anld.Length); + pp.SetAnld(anldcopy); + pp.SetBrcTop((BorderCode)GetBrcTop().Clone()); + pp.SetBrcLeft((BorderCode)GetBrcLeft().Clone()); + pp.SetBrcBottom((BorderCode)GetBrcBottom().Clone()); + pp.SetBrcRight((BorderCode)GetBrcRight().Clone()); + pp.SetBrcBetween((BorderCode)GetBrcBetween().Clone()); + pp.SetBrcBar((BorderCode)GetBrcBar().Clone()); + pp.SetDcs((DropCapSpecifier)GetDcs().Clone()); + pp.SetLspd((LineSpacingDescriptor)GetLspd().Clone()); + pp.SetShd((ShadingDescriptor)GetShd().Clone()); + byte[] phe = GetPhe(); + byte[] phecopy = new byte[phe.Length]; + Array.Copy(phe, phecopy, phe.Length); + pp.SetPhe(phecopy); + return pp; + } + + public BorderCode GetBarBorder() + { + return base.GetBrcBar(); + } + + public BorderCode GetBottomBorder() + { + return base.GetBrcBottom(); + } + + public DropCapSpecifier GetDropCap() + { + return base.GetDcs(); + } + + public int GetFirstLineIndent() + { + return base.GetDxaLeft1(); + } + + public int GetFontAlignment() + { + return base.GetWAlignFont(); + } + + public int GetIndentFromLeft() + { + return base.GetDxaLeft(); + } + + public int GetIndentFromRight() + { + return base.GetDxaRight(); + } + + public int GetJustification() + { + if (jcLogical) + { + if (!GetFBiDi()) + return GetJc(); + + switch (GetJc()) + { + case 0: + return 2; + case 2: + return 0; + default: + return GetJc(); + } + } + + return GetJc(); + } + + public BorderCode GetLeftBorder() + { + return base.GetBrcLeft(); + } + + public LineSpacingDescriptor GetLineSpacing() + { + return base.GetLspd(); + } + + public BorderCode GetRightBorder() + { + return base.GetBrcRight(); + } + + public ShadingDescriptor GetShading() + { + return base.GetShd(); + } + + public int GetSpacingAfter() + { + return base.GetDyaAfter(); + } + + public int GetSpacingBefore() + { + return base.GetDyaBefore(); + } + + public BorderCode GetTopBorder() + { + return base.GetBrcTop(); + } + + public bool IsAutoHyphenated() + { + return !base.GetFNoAutoHyph(); + } + + public bool IsBackward() + { + return base.IsFBackward(); + } + + public bool IsKinsoku() + { + return base.GetFKinsoku(); + } + + public bool IsLineNotNumbered() + { + return base.GetFNoLnn(); + } + + public bool IsSideBySide() + { + return base.GetFSideBySide(); + } + + public bool IsVertical() + { + return base.IsFVertical(); + } + + public bool IsWidowControlled() + { + return base.GetFWidowControl(); + } + + public bool IsWordWrapped() + { + return base.GetFWordWrap(); + } + + public bool keepOnPage() + { + return base.GetFKeep(); + } + + public bool keepWithNext() + { + return base.GetFKeepFollow(); + } + + public bool pageBreakBefore() + { + return base.GetFPageBreakBefore(); + } + + public void SetAutoHyphenated(bool auto) + { + base.SetFNoAutoHyph(!auto); + } + + public void SetBackward(bool bward) + { + base.SetFBackward(bward); + } + + public void SetBarBorder(BorderCode bar) + { + base.SetBrcBar(bar); + } + + public void SetBottomBorder(BorderCode bottom) + { + base.SetBrcBottom(bottom); + } + + public void SetDropCap(DropCapSpecifier dcs) + { + base.SetDcs(dcs); + } + + public void SetFirstLineIndent(int first) + { + base.SetDxaLeft1(first); + } + + public void SetFontAlignment(int align) + { + base.SetWAlignFont(align); + } + + public void SetIndentFromLeft(int dxaLeft) + { + base.SetDxaLeft(dxaLeft); + } + + public void SetIndentFromRight(int dxaRight) + { + base.SetDxaRight(dxaRight); + } + + public void SetJustification(byte jc) + { + base.SetJc(jc); + this.jcLogical = false; + } + + public void SetJustificationLogical(byte jc) + { + base.SetJc(jc); + this.jcLogical = true; + } + + public void SetKeepOnPage(bool fKeep) + { + base.SetFKeep(fKeep); + } + + public void SetKeepWithNext(bool fKeepFollow) + { + base.SetFKeepFollow(fKeepFollow); + } + + public void SetKinsoku(bool kinsoku) + { + base.SetFKinsoku(kinsoku); + } + + public void SetLeftBorder(BorderCode left) + { + base.SetBrcLeft(left); + } + + public void SetLineNotNumbered(bool fNoLnn) + { + base.SetFNoLnn(fNoLnn); + } + + public void SetLineSpacing(LineSpacingDescriptor lspd) + { + base.SetLspd(lspd); + } + + public void SetPageBreakBefore(bool fPageBreak) + { + base.SetFPageBreakBefore(fPageBreak); + } + + public void SetRightBorder(BorderCode right) + { + base.SetBrcRight(right); + } + + public void SetShading(ShadingDescriptor shd) + { + base.SetShd(shd); + } + + public void SetSideBySide(bool fSideBySide) + { + base.SetFSideBySide(fSideBySide); + } + + public void SetSpacingAfter(int after) + { + base.SetDyaAfter(after); + } + + public void SetSpacingBefore(int before) + { + base.SetDyaBefore(before); + } + + public void SetTopBorder(BorderCode top) + { + base.SetBrcTop(top); + } + + public void SetVertical(bool vertical) + { + base.SetFVertical(vertical); + } + + public void SetWidowControl(bool widowControl) + { + base.SetFWidowControl(widowControl); + } + + public void SetWordWrapped(bool wrap) + { + base.SetFWordWrap(wrap); + } + + } + + +} \ No newline at end of file diff --git a/scratchpad/HWPF/UserModel/Picture.cs b/scratchpad/HWPF/UserModel/Picture.cs new file mode 100644 index 0000000..0362e47 --- /dev/null +++ b/scratchpad/HWPF/UserModel/Picture.cs @@ -0,0 +1,539 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using NPOI.Util; +using System; +using System.IO; +using NPOI.HWPF.Model; +using System.IO.Compression; +using ICSharpCode.SharpZipLib.Zip; +namespace NPOI.HWPF.UserModel +{ + + /** + * Represents embedded picture extracted from Word Document + * @author Dmitry Romanov + */ + public partial class Picture: PictureDescriptor + { + //private static POILogger log = POILogFactory.GetLogger(Picture.class); + + // public static int FILENAME_OFFSET = 0x7C; + // public static int FILENAME_SIZE_OFFSET = 0x6C; + internal const int PICF_OFFSET = 0x0; + internal const int PICT_HEADER_OFFSET = 0x4; + internal const int MFPMM_OFFSET = 0x6; + internal const int PICF_SHAPE_OFFSET = 0xE; + internal const int PICMD_OFFSET = 0x1C; + internal const int UNKNOWN_HEADER_SIZE = 0x49; + + + public static byte[] IHDR = new byte[] { (byte)'I', (byte)'H', (byte)'D', (byte)'R' }; + + public static byte[] COMPRESSED1 = { (byte) 0xFE, 0x78, (byte) 0xDA }; + public static byte[] COMPRESSED2 = { (byte) 0xFE, 0x78, (byte) 0x9C }; + + private int dataBlockStartOfsset; + private int pictureBytesStartOffset; + private int dataBlockSize; + private int size; + // private String fileName; + private byte[] rawContent; + private byte[] content; + private byte[] _dataStream; + private int height = -1; + private int width = -1; + + + public Picture(int dataBlockStartOfsset, byte[] _dataStream, bool fillBytes) + :base(_dataStream, dataBlockStartOfsset) + //: base(_dataStream, dataBlockStartOfsset) + { + + this._dataStream = _dataStream; + this.dataBlockStartOfsset = dataBlockStartOfsset; + this.dataBlockSize = LittleEndian.GetInt(_dataStream, dataBlockStartOfsset); + this.pictureBytesStartOffset = GetPictureBytesStartOffset(dataBlockStartOfsset, _dataStream, dataBlockSize); + this.size = dataBlockSize - (pictureBytesStartOffset - dataBlockStartOfsset); + + if (fillBytes) + { + FillImageContent(); + } + } + + public Picture(byte[] _dataStream) : base() + { + this._dataStream = _dataStream; + this.dataBlockStartOfsset = 0; + this.dataBlockSize = _dataStream.Length; + this.pictureBytesStartOffset = 0; + this.size = _dataStream.Length; + } + + private void FillWidthHeight() + { + PictureType pictureType = SuggestPictureType(); + // trying to extract width and height from pictures content: + if (pictureType == PictureType.JPEG) + { + FillJPGWidthHeight(); + } + else if (pictureType == PictureType.PNG) + { + FillPNGWidthHeight(); + } + } + + /** + * Tries to suggest a filename: hex representation of picture structure offset in "Data" stream plus extension that + * is tried to determine from first byte of picture's content. + * + * @return suggested file name + */ + public String SuggestFullFileName() + { + String fileExt = SuggestFileExtension(); + return StringUtil.ToHexString(dataBlockStartOfsset) + (fileExt.Length > 0 ? "." + fileExt : ""); + } + + /** + * Writes Picture's content bytes to specified OutputStream. + * Is useful when there is need to write picture bytes directly to stream, omitting its representation in + * memory as distinct byte array. + * + * @param out a stream to write to + * @throws IOException if some exception is occured while writing to specified out + */ + public void WriteImageContent(Stream out1) + { + if (rawContent != null && rawContent.Length > 0) + { + out1.Write(rawContent, 0, size); + } + else + { + out1.Write(_dataStream, dataBlockStartOfsset, size); + } + } + + /** + * @return The offset of this picture in the picture bytes, used when + * matching up with {@link CharacterRun#getPicOffset()} + */ + public int getStartOffset() + { + return dataBlockStartOfsset; + } + + /** + * @return picture's content as byte array + */ + public byte[] GetContent() + { + if (content == null || content.Length <= 0) + { + FillImageContent(); + } + return content; + } + + /** + * Returns picture's content as it stored in Word file, i.e. possibly in + * compressed form. + * + * @return picture's content as it stored in Word file + */ + public byte[] GetRawContent() + { + FillRawImageContent(); + return rawContent; + } + + /** + * + * @return size in bytes of the picture + */ + public int Size + { + get + { + return size; + } + } + + /** + * returns horizontal aspect ratio for picture provided by user + */ + public int AspectRatioX + { + get + { + return mx/10; + } + } + + /** + * @return Horizontal scaling factor supplied by user expressed in .001% + * units + */ + public int HorizontalScalingFactor + { +get{ + return mx; +} + } + /** + * returns vertical aspect ratio for picture provided by user + */ + public int AspectRatioY + { + get + { + return my/10; + } + } + + /** + * @return Vertical scaling factor supplied by user expressed in .001% units + */ + public int VerticalScalingFactor + { +get{ + return my; +} + } + + /** + * Gets the initial width of the picture, in twips, prior to cropping or + * scaling. + * + * @return the initial width of the picture in twips + */ + public int DxaGoal + { + get + { + return dxaGoal; + } + } + + /** + * Gets the initial height of the picture, in twips, prior to cropping or + * scaling. + * + * @return the initial width of the picture in twips + */ + public int DyaGoal + { + get + { + return dyaGoal; + } + } + + /** + * @return The amount the picture has been cropped on the left in twips + */ + public int DxaCropLeft + { + get + { + return dxaCropLeft; + } + } + + /** + * @return The amount the picture has been cropped on the top in twips + */ + public int DyaCropTop + { + get + { + return dyaCropTop; + } + } + + /** + * @return The amount the picture has been cropped on the right in twips + */ + public int DxaCropRight + { + get + { + return dxaCropRight; + } + } + + /** + * @return The amount the picture has been cropped on the bottom in twips + */ + public int DyaCropBottom + { + get + { + return dyaCropBottom; + } + } + /** + * tries to suggest extension for picture's file by matching signatures of popular image formats to first bytes + * of picture's contents + * @return suggested file extension + */ + public String SuggestFileExtension() + { + return SuggestPictureType().Extension; + } + + public PictureType SuggestPictureType() + { + return PictureType.FindMatchingType(GetContent()); + } + + + /** + * Returns the mime type for the image + */ + public String MimeType + { + get + { + return SuggestPictureType().Mime; + } + } + + private static bool MatchSignature(byte[] dataStream, byte[] signature, int pictureBytesOffset) + { + bool matched = pictureBytesOffset < dataStream.Length; + for (int i = 0; (i + pictureBytesOffset) < dataStream.Length && i < signature.Length; i++) + { + if (dataStream[i + pictureBytesOffset] != signature[i]) + { + matched = false; + break; + } + } + return matched; + } + + // public String GetFileName() + // { + // return fileName; + // } + + // private static String extractFileName(int blockStartIndex, byte[] dataStream) { + // int fileNameStartOffset = blockStartIndex + 0x7C; + // int fileNameSizeOffset = blockStartIndex + FILENAME_SIZE_OFFSET; + // int fileNameSize = LittleEndian.GetShort(dataStream, fileNameSizeOffSet); + // + // int fileNameIndex = fileNameStartOffSet; + // char[] fileNameChars = new char[(fileNameSize-1)/2]; + // int charIndex = 0; + // while(charIndex 0) + { + out1.Write(buf, 0, readBytes); + } + content = out1.ToArray(); + } + catch (IOException) + { + // Problems Reading from the actual MemoryStream should never happen + // so this will only ever be a ZipException. + //log.log(POILogger.INFO, "Possibly corrupt compression or non-compressed data", e); + } + } else { + // Raw data is not compressed. + content = rawContent; + } + } + + private static int GetPictureBytesStartOffset(int dataBlockStartOffset, byte[] _dataStream, int dataBlockSize) + { + int realPicoffset = dataBlockStartOffset; + int dataBlockEndOffset = dataBlockSize + dataBlockStartOffset; + + // Skip over the PICT block + int PICTFBlockSize = LittleEndian.GetShort(_dataStream, dataBlockStartOffset + PICT_HEADER_OFFSET); // Should be 68 bytes + + // Now the PICTF1 + int PICTF1BlockOffset = PICTFBlockSize + PICT_HEADER_OFFSET; + short MM_TYPE = LittleEndian.GetShort(_dataStream, dataBlockStartOffset + PICT_HEADER_OFFSET + 2); + if (MM_TYPE == 0x66) + { + // Skip the stPicName + int cchPicName = LittleEndian.GetUByte(_dataStream, PICTF1BlockOffset); + PICTF1BlockOffset += 1 + cchPicName; + } + int PICTF1BlockSize = LittleEndian.GetShort(_dataStream, dataBlockStartOffset + PICTF1BlockOffset); + + int unknownHeaderOffset = (PICTF1BlockSize + PICTF1BlockOffset) < dataBlockEndOffset ? (PICTF1BlockSize + PICTF1BlockOffset) : PICTF1BlockOffset; + realPicoffset += (unknownHeaderOffset + UNKNOWN_HEADER_SIZE); + if (realPicoffset >= dataBlockEndOffset) + { + realPicoffset -= UNKNOWN_HEADER_SIZE; + } + return realPicoffset; + } + + private void FillJPGWidthHeight() + { + /* + * http://www.codecomments.com/archive281-2004-3-158083.html + * + * Algorhitm proposed by Patrick TJ McPhee: + * + * read 2 bytes make sure they are 'ffd8'x repeatedly: read 2 bytes make + * sure the first one is 'ff'x if the second one is 'd9'x stop else if + * the second one is c0 or c2 (or possibly other values ...) skip 2 + * bytes read one byte into depth read two bytes into height read two + * bytes into width else read two bytes into length skip forward + * length-2 bytes + * + * Also used Ruby code snippet from: + * http://www.bigbold.com/snippets/posts/show/805 for reference + */ + int pointer = pictureBytesStartOffset + 2; + int firstByte = _dataStream[pointer]; + int secondByte = _dataStream[pointer + 1]; + + int endOfPicture = pictureBytesStartOffset + size; + while (pointer < endOfPicture - 1) + { + do + { + firstByte = _dataStream[pointer]; + secondByte = _dataStream[pointer + 1]; + pointer += 2; + } while (!(firstByte == (byte)0xFF) && pointer < endOfPicture - 1); + + if (firstByte == ((byte)0xFF) && pointer < endOfPicture - 1) + { + if (secondByte == (byte)0xD9 || secondByte == (byte)0xDA) + { + break; + } + else if ((secondByte & 0xF0) == 0xC0 && secondByte != (byte)0xC4 && secondByte != (byte)0xC8 && secondByte != (byte)0xCC) + { + pointer += 5; + this.height = GetBigEndianShort(_dataStream, pointer); + this.width = GetBigEndianShort(_dataStream, pointer + 2); + break; + } + else + { + pointer++; + pointer++; + int length = GetBigEndianShort(_dataStream, pointer); + pointer += length; + } + } + else + { + pointer++; + } + } + } + + private void FillPNGWidthHeight() + { + /* + Used PNG file format description from http://www.wotsit.org/download.asp?f=png + */ + int HEADER_START = pictureBytesStartOffset + PictureType.PNG.Signatures[0].Length + 4; + if (MatchSignature(_dataStream, IHDR, HEADER_START)) + { + int IHDR_CHUNK_WIDTH = HEADER_START + 4; + this.width = GetBigEndianInt(_dataStream, IHDR_CHUNK_WIDTH); + this.height = GetBigEndianInt(_dataStream, IHDR_CHUNK_WIDTH + 4); + } + } + + /** + * returns pixel width of the picture or -1 if dimensions determining was failed + */ + public int Width + { + get + { + if (width == -1) + { + FillWidthHeight(); + } + return width; + } + } + + /** + * returns pixel height of the picture or -1 if dimensions determining was failed + */ + public int Height + { + get + { + if (height == -1) + { + FillWidthHeight(); + } + return height; + } + } + + private static int GetBigEndianInt(byte[] data, int offset) + { + return (((data[offset] & 0xFF) << 24) + ((data[offset + 1] & 0xFF) << 16) + ((data[offset + 2] & 0xFF) << 8) + (data[offset + 3] & 0xFF)); + } + + private static int GetBigEndianShort(byte[] data, int offset) + { + return (((data[offset] & 0xFF) << 8) + (data[offset + 1] & 0xFF)); + } + + } + +} \ No newline at end of file diff --git a/scratchpad/HWPF/UserModel/PictureType.cs b/scratchpad/HWPF/UserModel/PictureType.cs new file mode 100644 index 0000000..ebc4b6f --- /dev/null +++ b/scratchpad/HWPF/UserModel/PictureType.cs @@ -0,0 +1,131 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +using System; +namespace NPOI.HWPF.UserModel +{ + + /** + * Picture types supported by MS Word format + * + * @author Sergey Vladimirov (vlsergey {at} gmail {dot} com) + */ + public class PictureType + { + + public static PictureType BMP = new PictureType("image/bmp", "bmp", new byte[][] { new byte[] { (byte)'B', (byte)'M' } }); + + public static PictureType EMF = new PictureType("image/x-emf", "emf", new byte[][] { new byte[] { 0x01, 0x00, 0x00, 0x00 } }); + + public static PictureType GIF = new PictureType("image/gif", "gif", new byte[][] { new byte[] { (byte)'G', (byte)'I', (byte)'F' } }); + + public static PictureType JPEG = new PictureType("image/jpeg", "jpg", new byte[][] { new byte[] { (byte)0xFF, (byte)0xD8 } }); + + public static PictureType PICT = new PictureType("image/pict", ".pict", new byte[0][]); + + public static PictureType PNG = new PictureType("image/png", "png", new byte[][] { new byte[]{ (byte) 0x89, 0x50, 0x4E, 0x47, + 0x0D, 0x0A, 0x1A, 0x0A } }); + + public static PictureType TIFF = new PictureType("image/tiff", "tiff", new byte[][] { new byte[]{ 0x49, 0x49, 0x2A, 0x00 }, + new byte[]{ 0x4D, 0x4D, 0x00, 0x2A } }); + + public static PictureType UNKNOWN = new PictureType("image/unknown", "", new byte[][] { new byte[] { } }); + + public static PictureType WMF = new PictureType("image/x-wmf", "wmf", new byte[][] { + new byte[]{ (byte) 0xD7, (byte) 0xCD, (byte) 0xC6, (byte) 0x9A, 0x00, 0x00 }, + new byte[]{ 0x01, 0x00, 0x09, 0x00, 0x00, 0x03 } }); + + public static PictureType[] Values = new PictureType[] + { + PictureType.BMP,PictureType.EMF,PictureType.GIF, + PictureType.JPEG,PictureType.PNG,PictureType.TIFF, + PictureType.WMF,PictureType.UNKNOWN + }; + + public static PictureType FindMatchingType(byte[] pictureContent) + { + foreach (PictureType pictureType in PictureType.Values) + for (int i = 0; i < pictureType.Signatures.Length; i++) + { + if (MatchSignature(pictureContent, pictureType.Signatures[i])) + return pictureType; + } + + // TODO: DIB, PICT + return PictureType.UNKNOWN; + } + + private static bool MatchSignature(byte[] pictureData, byte[] signature) + { + if (pictureData.Length < signature.Length) + return false; + + for (int i = 0; i < signature.Length; i++) + if (pictureData[i] != signature[i]) + return false; + + return true; + } + + private String _extension; + + private String _mime; + + private byte[][] _signatures; + + private PictureType(String mime, String extension, byte[][] signatures) + { + this._mime = mime; + this._extension = extension; + this._signatures = signatures; + } + + public String Extension + { + get + { + return _extension; + } + } + + public String Mime + { + get + { + return _mime; + } + } + + public byte[][] Signatures + { + get + { + return _signatures; + } + } + + public bool MatchSignature(byte[] pictureData) + { + foreach (byte[] signature in Signatures) + if (MatchSignature(signature, pictureData)) + return true; + return false; + } + } + +} + + diff --git a/scratchpad/HWPF/UserModel/Range.cs b/scratchpad/HWPF/UserModel/Range.cs new file mode 100644 index 0000000..1695588 --- /dev/null +++ b/scratchpad/HWPF/UserModel/Range.cs @@ -0,0 +1,1289 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +namespace NPOI.HWPF.UserModel +{ + using NPOI.HWPF.Model; + using System.Collections.Generic; + using System; + using System.Text; + using NPOI.HWPF.SPRM; + using System.IO; + using NPOI.Util; + using System.Diagnostics; + /** + * This class is the central class of the HWPF object model. All properties that + * apply to a range of characters in a Word document extend this class. + * + * It is possible to insert text and/or properties at the beginning or end of a + * range. + * + * Ranges are only valid if there hasn't been an insert in a prior Range since + * the Range's creation. Once an element (text, paragraph, etc.) has been + * inserted into a Range, subsequent Ranges become unstable. + * + * @author Ryan Ackley + */ + public class Range : BaseObject + { // TODO -instantiable superclass + + public const int TYPE_PARAGRAPH = 0; + public const int TYPE_CHARACTER = 1; + public const int TYPE_SECTION = 2; + public const int TYPE_TEXT = 3; + public const int TYPE_LISTENTRY = 4; + public const int TYPE_TABLE = 5; + public const int TYPE_UNDEFINED = 6; + + /** Needed so inserts and deletes will ripple up through Containing Ranges */ + internal Range _parent; + + /** The starting character offset of this range. */ + internal int _start; + + /** The ending character offset of this range. */ + internal int _end; + + /** The document this range blongs to. */ + protected HWPFDocumentCore _doc; + + /** Have we loaded the section indexes yet */ + bool _sectionRangeFound; + + /** All sections that belong to the document this Range belongs to. */ + protected List _sections; + + /** The start index in the sections list for this Range */ + protected int _sectionStart; + + /** The end index in the sections list for this Range. */ + protected int _sectionEnd; + + /** Have we loaded the paragraph indexes yet. */ + protected bool _parRangeFound; + + /** All paragraphs that belong to the document this Range belongs to. */ + internal List _paragraphs; + + /** The start index in the paragraphs list for this Range */ + internal int _parStart; + + /** The end index in the paragraphs list for this Range. */ + internal int _parEnd; + + /** Have we loaded the characterRun indexes yet. */ + protected bool _charRangeFound; + + /** All CharacterRuns that belong to the document this Range belongs to. */ + protected List _characters; + + /** The start index in the characterRuns list for this Range */ + protected int _charStart; + + /** The end index in the characterRuns list for this Range. */ + protected int _charEnd; + + /** Have we loaded the Text indexes yet */ + protected bool _textRangeFound; + + /** All text pieces that belong to the document this Range belongs to. */ + protected StringBuilder _text; + + /** The start index in the text list for this Range. */ + protected int _textStart; + + /** The end index in the text list for this Range. */ + protected int _textEnd; + + // protected Range() + // { + // + // } + + /** + * Used to construct a Range from a document. This is generally used to + * create a Range that spans the whole document, or at least one whole part + * of the document (eg main text, header, comment) + * + * @param start + * Starting character offset of the range. + * @param end + * Ending character offset of the range. + * @param doc + * The HWPFDocument the range is based on. + */ + public Range(int start, int end, HWPFDocumentCore doc) + { + _start = start; + _end = end; + _doc = doc; + _sections = _doc.SectionTable.GetSections(); + _paragraphs = _doc.ParagraphTable.GetParagraphs(); + _characters = _doc.CharacterTable.GetTextRuns(); + _text = _doc.Text; + _parent = null; + + SanityCheckStartEnd(); + } + + + /** + * Used to create Ranges that are children of other Ranges. + * + * @param start + * Starting character offset of the range. + * @param end + * Ending character offset of the range. + * @param parent + * The parent this range belongs to. + */ + internal Range(int start, int end, Range parent) + { + _start = start; + _end = end; + _doc = parent._doc; + _sections = parent._sections; + _paragraphs = parent._paragraphs; + _characters = parent._characters; + _text = parent._text; + _parent = parent; + + SanityCheckStartEnd(); + SanityCheck(); + } + + + /** + * Ensures that the start and end were were given are actually valid, to + * avoid issues later on if they're not + */ + private void SanityCheckStartEnd() + { + if (_start < 0) + { + throw new ArgumentException("Range start must not be negative. Given " + _start); + } + if (_end < _start) + { + throw new ArgumentException("The end (" + _end + + ") must not be before the start (" + _start + ")"); + } + } + + /** + * Does any TextPiece in this Range use unicode? + * + * @return true if it does and false if it doesn't + */ + [Obsolete] + public bool UsesUnicode + { + + get + { + return true; + } + } + /** + * Gets the text that this Range contains. + * + * @return The text for this range. + */ + public String Text + { + get + { + return _text.ToString().Substring(_start, _end - _start); + } + } + + /** + * Removes any fields (eg macros, page markers etc) from the string. + * Normally used to make some text suitable for Showing to humans, and the + * resultant text should not normally be saved back into the document! + */ + public static String StripFields(String text) + { + // First up, fields can be nested... + // A field can be 0x13 [contents] 0x15 + // Or it can be 0x13 [contents] 0x14 [real text] 0x15 + + // If there are no fields, all easy + if (text.IndexOf('\u0013') == -1) + return text; + + // Loop over until they're all gone + // That's when we're out of both 0x13s and 0x15s + while (text.IndexOf('\u0013') > -1 && text.IndexOf('\u0015') > -1) + { + int first13 = text.IndexOf('\u0013'); + int next13 = text.IndexOf('\u0013', first13 + 1); + int first14 = text.IndexOf('\u0014', first13 + 1); + int last15 = text.LastIndexOf('\u0015'); + + // If they're the wrong way around, give up + if (last15 < first13) + { + break; + } + + // If no more 13s and 14s, just zap + if (next13 == -1 && first14 == -1) + { + text = text.Substring(0, first13) + text.Substring(last15 + 1); + break; + } + + // If a 14 comes before the next 13, then + // zap from the 13 to the 14, and remove + // the 15 + if (first14 != -1 && (first14 < next13 || next13 == -1)) + { + text = text.Substring(0, first13) + text.Substring(first14 + 1, last15 - first14 - 1) + + text.Substring(last15 + 1); + continue; + } + + // Another 13 comes before the next 14. + // This means there's nested stuff, so we + // can just zap the lot + text = text.Substring(0, first13) + text.Substring(last15 + 1); + continue; + } + + return text; + } + + /** + * Used to get the number of sections in a range. If this range is smaller + * than a section, it will return 1 for its Containing section. + * + * @return The number of sections in this range. + */ + public int NumSections + { + get + { + InitSections(); + return _sectionEnd - _sectionStart; + } + } + + /** + * Used to get the number of paragraphs in a range. If this range is smaller + * than a paragraph, it will return 1 for its Containing paragraph. + * + * @return The number of paragraphs in this range. + */ + + public int NumParagraphs + { + get + { + InitParagraphs(); + return _parEnd - _parStart; + } + } + + /** + * + * @return The number of characterRuns in this range. + */ + + public int NumCharacterRuns + { + get + { + InitCharacterRuns(); + return _charEnd - _charStart; + } + } + + /** + * Inserts text into the front of this range. + * + * @param text + * The text to insert + * @return The character run that text was inserted into. + */ + public CharacterRun InsertBefore(String text) + // + { + InitAll(); + + _text.Insert(_start, text); + + _doc.CharacterTable.AdjustForInsert(_charStart, text.Length); + _doc.ParagraphTable.AdjustForInsert(_parStart, text.Length); + _doc.SectionTable.AdjustForInsert(_sectionStart, text.Length); + AdjustForInsert(text.Length); + + // update the FIB.CCPText + friends fields + AdjustFIB(text.Length); + + SanityCheck(); + + return GetCharacterRun(0); + } + + /** + * Inserts text onto the end of this range + * + * @param text + * The text to insert + * @return The character run the text was inserted into. + */ + public CharacterRun InsertAfter(String text) + { + InitAll(); + + _text.Insert(_end, text); + _doc.CharacterTable.AdjustForInsert(_charEnd - 1, text.Length); + _doc.ParagraphTable.AdjustForInsert(_parEnd - 1, text.Length); + _doc.SectionTable.AdjustForInsert(_sectionEnd - 1, text.Length); + AdjustForInsert(text.Length); + + return GetCharacterRun(NumCharacterRuns - 1); + + } + + /** + * Inserts text into the front of this range and it gives that text the + * CharacterProperties specified in props. + * + * @param text + * The text to insert. + * @param props + * The CharacterProperties to give the text. + * @return A new CharacterRun that has the given text and properties and is + * n ow a part of the document. + */ + [Obsolete] + public CharacterRun InsertBefore(String text, CharacterProperties props) + // + { + InitAll(); + PAPX papx = _paragraphs[_parStart]; + short istd = papx.GetIstd(); + + StyleSheet ss = _doc.GetStyleSheet(); + CharacterProperties baseStyle = ss.GetCharacterStyle(istd); + byte[] grpprl = CharacterSprmCompressor.CompressCharacterProperty(props, baseStyle); + SprmBuffer buf = new SprmBuffer(grpprl); + _doc.CharacterTable.Insert(_charStart, _start, buf); + + return InsertBefore(text); + } + + /** + * Inserts text onto the end of this range and gives that text the + * CharacterProperties specified in props. + * + * @param text + * The text to insert. + * @param props + * The CharacterProperties to give the text. + * @return A new CharacterRun that has the given text and properties and is + * n ow a part of the document. + */ + [Obsolete] + public CharacterRun InsertAfter(String text, CharacterProperties props) + // + { + InitAll(); + PAPX papx = _paragraphs[_parEnd - 1]; + short istd = papx.GetIstd(); + + StyleSheet ss = _doc.GetStyleSheet(); + CharacterProperties baseStyle = ss.GetCharacterStyle(istd); + byte[] grpprl = CharacterSprmCompressor.CompressCharacterProperty(props, baseStyle); + SprmBuffer buf = new SprmBuffer(grpprl); + _doc.CharacterTable.Insert(_charEnd, _end, buf); + _charEnd++; + return InsertAfter(text); + } + + /** + * Inserts and empty paragraph into the front of this range. + * + * @param props + * The properties that the new paragraph will have. + * @param styleIndex + * The index into the stylesheet for the new paragraph. + * @return The newly inserted paragraph. + */ + [Obsolete] + public Paragraph InsertBefore(ParagraphProperties props, int styleIndex) + // + { + return this.InsertBefore(props, styleIndex, "\r"); + } + + /** + * Inserts a paragraph into the front of this range. The paragraph will + * contain one character run that has the default properties for the + * paragraph's style. + * + * It is necessary for the text to end with the character '\r' + * + * @param props + * The paragraph's properties. + * @param styleIndex + * The index of the paragraph's style in the style sheet. + * @param text + * The text to insert. + * @return A newly inserted paragraph. + */ + [Obsolete] + protected Paragraph InsertBefore(ParagraphProperties props, int styleIndex, String text) + // + { + InitAll(); + StyleSheet ss = _doc.GetStyleSheet(); + ParagraphProperties baseStyle = ss.GetParagraphStyle(styleIndex); + CharacterProperties baseChp = ss.GetCharacterStyle(styleIndex); + + byte[] grpprl = ParagraphSprmCompressor.CompressParagraphProperty(props, baseStyle); + byte[] withIndex = new byte[grpprl.Length + LittleEndianConsts.SHORT_SIZE]; + LittleEndian.PutShort(withIndex, (short)styleIndex); + Array.Copy(grpprl, 0, withIndex, LittleEndianConsts.SHORT_SIZE, grpprl.Length); + SprmBuffer buf = new SprmBuffer(withIndex); + + _doc.ParagraphTable.Insert(_parStart, _start, buf); + InsertBefore(text, baseChp); + return GetParagraph(0); + } + + /** + * Inserts and empty paragraph into the end of this range. + * + * @param props + * The properties that the new paragraph will have. + * @param styleIndex + * The index into the stylesheet for the new paragraph. + * @return The newly inserted paragraph. + */ + [Obsolete] + public Paragraph InsertAfter(ParagraphProperties props, int styleIndex) + // + { + return this.InsertAfter(props, styleIndex, "\r"); + } + + /** + * Inserts a paragraph into the end of this range. The paragraph will + * contain one character run that has the default properties for the + * paragraph's style. + * + * It is necessary for the text to end with the character '\r' + * + * @param props + * The paragraph's properties. + * @param styleIndex + * The index of the paragraph's style in the style sheet. + * @param text + * The text to insert. + * @return A newly inserted paragraph. + */ + [Obsolete] + protected Paragraph InsertAfter(ParagraphProperties props, int styleIndex, String text) + // + { + InitAll(); + StyleSheet ss = _doc.GetStyleSheet(); + ParagraphProperties baseStyle = ss.GetParagraphStyle(styleIndex); + CharacterProperties baseChp = ss.GetCharacterStyle(styleIndex); + + byte[] grpprl = ParagraphSprmCompressor.CompressParagraphProperty(props, baseStyle); + byte[] withIndex = new byte[grpprl.Length + LittleEndianConsts.SHORT_SIZE]; + LittleEndian.PutShort(withIndex, (short)styleIndex); + Array.Copy(grpprl, 0, withIndex, LittleEndianConsts.SHORT_SIZE, grpprl.Length); + SprmBuffer buf = new SprmBuffer(withIndex); + + _doc.ParagraphTable.Insert(_parEnd, _end, buf); + _parEnd++; + InsertAfter(text, baseChp); + return GetParagraph(NumParagraphs - 1); + } + + public void Delete() + { + + InitAll(); + + int numSections = _sections.Count; + int numRuns = _characters.Count; + int numParagraphs = _paragraphs.Count; + + for (int x = _charStart; x < numRuns; x++) + { + CHPX chpx = _characters[x]; + chpx.AdjustForDelete(_start, _end - _start); + } + + for (int x = _parStart; x < numParagraphs; x++) + { + PAPX papx = _paragraphs[x]; + // System.err.println("Paragraph " + x + " was " + papx.Start + + // " -> " + papx.End); + papx.AdjustForDelete(_start, _end - _start); + // System.err.println("Paragraph " + x + " is now " + + // papx.Start + " -> " + papx.End); + } + + for (int x = _sectionStart; x < numSections; x++) + { + SEPX sepx = _sections[x]; + // System.err.println("Section " + x + " was " + sepx.Start + + // " -> " + sepx.End); + sepx.AdjustForDelete(_start, _end - _start); + // System.err.println("Section " + x + " is now " + sepx.Start + // + " -> " + sepx.End); + } + _text = _text.Remove(_start, _end - _start); + Range parent = _parent; + if (parent != null) + { + parent.AdjustForInsert(-(_end - _start)); + } + // update the FIB.CCPText + friends field + AdjustFIB(-(_end - _start)); + } + + /** + * Inserts a simple table into the beginning of this range. The number of + * columns is determined by the TableProperties passed into this function. + * + * @param props + * The table properties for the table. + * @param rows + * The number of rows. + * @return The empty Table that is now part of the document. + */ + [Obsolete] + public Table InsertBefore(TableProperties props, int rows) + { + ParagraphProperties parProps = new ParagraphProperties(); + parProps.SetFInTable(true); + parProps.SetItap(1); + + int columns = props.GetItcMac(); + for (int x = 0; x < rows; x++) + { + Paragraph cell = this.InsertBefore(parProps, StyleSheet.NIL_STYLE); + cell.InsertAfter("\u0007"); + for (int y = 1; y < columns; y++) + { + cell = cell.InsertAfter(parProps, StyleSheet.NIL_STYLE); + cell.InsertAfter("\u0007"); + } + cell = cell.InsertAfter(parProps, StyleSheet.NIL_STYLE, "\u0007"); + cell.SetTableRowEnd(props); + } + return new Table(_start, _start + (rows * (columns + 1)), this, 1); + } + + /** + * Inserts a simple table into the beginning of this range. + * + * @param columns + * The number of columns + * @param rows + * The number of rows. + * @return The empty Table that is now part of the document. + */ + public Table InsertTableBefore(short columns, int rows) + { + ParagraphProperties parProps = new ParagraphProperties(); + parProps.SetFInTable(true); + parProps.SetItap(1); + + int oldEnd = this._end; + + for (int x = 0; x < rows; x++) + { + Paragraph cell = this.InsertBefore(parProps, StyleSheet.NIL_STYLE); + cell.InsertAfter(Convert.ToString('\u0007')); + for (int y = 1; y < columns; y++) + { + cell = cell.InsertAfter(parProps, StyleSheet.NIL_STYLE); + cell.InsertAfter(Convert.ToString('\u0007')); + } + cell = cell.InsertAfter(parProps, StyleSheet.NIL_STYLE, + Convert.ToString('\u0007')); + cell.SetTableRowEnd(new TableProperties(columns)); + } + + int newEnd = this._end; + int diff = newEnd - oldEnd; + + return new Table(_start, _start + diff, this, 1); + } + /** + * Inserts a list into the beginning of this range. + * + * @param props + * The properties of the list entry. All list entries are + * paragraphs. + * @param listID + * The id of the list that Contains the properties. + * @param level + * The indentation level of the list. + * @param styleIndex + * The base style's index in the stylesheet. + * @return The empty ListEntry that is now part of the document. + */ + public ListEntry InsertBefore(ParagraphProperties props, int listID, int level, int styleIndex) + { + ListTables lt = _doc.GetListTables(); + if (lt.GetLevel(listID, level) == null) + { + throw new InvalidDataException("The specified list and level do not exist"); + } + + int ilfo = lt.GetOverrideIndexFromListID(listID); + props.SetIlfo(ilfo); + props.SetIlvl((byte)level); + + return (ListEntry)InsertBefore(props, styleIndex); + } + + /** + * Inserts a list into the beginning of this range. + * + * @param props + * The properties of the list entry. All list entries are + * paragraphs. + * @param listID + * The id of the list that Contains the properties. + * @param level + * The indentation level of the list. + * @param styleIndex + * The base style's index in the stylesheet. + * @return The empty ListEntry that is now part of the document. + */ + public ListEntry InsertAfter(ParagraphProperties props, int listID, int level, int styleIndex) + { + ListTables lt = _doc.GetListTables(); + if (lt.GetLevel(listID, level) == null) + { + throw new InvalidDataException("The specified list and level do not exist"); + } + int ilfo = lt.GetOverrideIndexFromListID(listID); + props.SetIlfo(ilfo); + props.SetIlvl((byte)level); + + return (ListEntry)InsertAfter(props, styleIndex); + } + + /** + * Replace (one instance of) a piece of text with another... + * + * @param pPlaceHolder + * The text to be Replaced (e.g., "${organization}") + * @param pValue + * The Replacement text (e.g., "Apache Software Foundation") + * @param pOffset + * The offset or index where the text to be Replaced begins + * (relative to/within this Range) + */ + public void ReplaceText(String pPlaceHolder, String pValue, int pOffSet) + { + int absPlaceHolderIndex = StartOffset + pOffSet; + Range subRange = new Range(absPlaceHolderIndex, (absPlaceHolderIndex + pPlaceHolder + .Length), this); + + subRange.InsertBefore(pValue); + + // re-create the sub-range so we can delete it + subRange = new Range((absPlaceHolderIndex + pValue.Length), (absPlaceHolderIndex + + pPlaceHolder.Length + pValue.Length), GetDocument()); + + // deletes are automagically propagated + subRange.Delete(); + } + + /** + * Replace (all instances of) a piece of text with another... + * + * @param pPlaceHolder + * The text to be Replaced (e.g., "${organization}") + * @param pValue + * The Replacement text (e.g., "Apache Software Foundation") + */ + public void ReplaceText(String pPlaceHolder, String pValue) + { + bool keepLooking = true; + while (keepLooking) + { + + String text = Text; + int offset = text.IndexOf(pPlaceHolder); + if (offset >= 0) + ReplaceText(pPlaceHolder, pValue, offset); + else + keepLooking = false; + } + } + + /** + * Gets the character run at index. The index is relative to this range. + * + * @param index + * The index of the character run to Get. + * @return The character run at the specified index in this range. + */ + public CharacterRun GetCharacterRun(int index) + { + InitCharacterRuns(); + + if (index + _charStart >= _charEnd) + throw new IndexOutOfRangeException("CHPX #" + index + " (" + + (index + _charStart) + ") not in range [" + _charStart + + "; " + _charEnd + ")"); + + CHPX chpx = _characters[index + _charStart]; + + if (chpx == null) + { + return null; + } + short istd; + if ( this is Paragraph ) + { + istd = ((Paragraph) this)._istd; + } + else + { + int[] point = FindRange(_paragraphs, Math.Max(chpx.Start, _start), Math.Min(chpx.End, _end)); + InitParagraphs(); + int parStart = Math.Max( point[0], _parStart ); + if ( parStart >= _paragraphs.Count ) + { + return null; + } + PAPX papx = _paragraphs[point[0]]; + istd = papx.GetIstd(); + } + + CharacterRun chp = new CharacterRun(chpx, _doc.GetStyleSheet(), istd, this); + + return chp; + } + + /** + * Gets the section at index. The index is relative to this range. + * + * @param index + * The index of the section to Get. + * @return The section at the specified index in this range. + */ + public Section GetSection(int index) + { + InitSections(); + SEPX sepx = _sections[index + _sectionStart]; + Section sep = new Section(sepx, this); + return sep; + } + + /** + * Gets the paragraph at index. The index is relative to this range. + * + * @param index + * The index of the paragraph to Get. + * @return The paragraph at the specified index in this range. + */ + + public Paragraph GetParagraph(int index) + { + InitParagraphs(); + PAPX papx = _paragraphs[index + _parStart]; + + ParagraphProperties props = papx.GetParagraphProperties(_doc.GetStyleSheet()); + Paragraph pap = null; + if (props.GetIlfo() > 0) + { + pap = new ListEntry(papx, this, _doc.GetListTables()); + } + else + { + if (((index + _parStart) == 0) && papx.Start > 0) + { + pap = new Paragraph(papx, this, 0); + } + else + { + pap = new Paragraph(papx, this); + } + } + + return pap; + } + + /** + * This method is used to determine the type. Handy for switch statements + * Compared to the is operator. + * + * @return A TYPE constant. + */ + public virtual int Type + { + get + { + return TYPE_UNDEFINED; + } + } + + /** + * Gets the table that starts with paragraph. In a Word file, a table + * consists of a group of paragraphs with certain flags Set. + * + * @param paragraph + * The paragraph that is the first paragraph in the table. + * @return The table that starts with paragraph + */ + public Table GetTable(Paragraph paragraph) + { + if (!paragraph.IsInTable()) + { + throw new ArgumentException("This paragraph doesn't belong to a table"); + } + + Range r = paragraph; + if (r._parent != this) + { + throw new ArgumentException("This paragraph is not a child of this range"); + } + + r.InitAll(); + int tableLevel = paragraph.GetTableLevel(); + int tableEndInclusive = r._parStart; + + if (r._parStart != 0) + { + Paragraph previous = new Paragraph( + _paragraphs[r._parStart - 1], this); + if (previous.IsInTable() + && previous.GetTableLevel() == tableLevel + && previous._sectionEnd >= r._sectionStart) + throw new ArgumentException("This paragraph is not the first one in the table"); + } + + Range overallRange = _doc.GetOverallRange(); + int limit = _paragraphs.Count; + for (; tableEndInclusive < limit; tableEndInclusive++) + { + Paragraph next = new Paragraph( + _paragraphs[tableEndInclusive + 1], overallRange); + if (!next.IsInTable() || next.GetTableLevel() < tableLevel) + break; + } + + InitAll(); + if (tableEndInclusive > _parEnd) + { + throw new IndexOutOfRangeException( + "The table's bounds fall outside of this Range"); + } + if (tableEndInclusive < 0) + { + throw new IndexOutOfRangeException( + "The table's end is negative, which isn't allowed!"); + } + int endOffsetExclusive = _paragraphs[tableEndInclusive].End; + + return new Table(paragraph.StartOffset, endOffsetExclusive, this, paragraph.GetTableLevel()); + } + + /** + * loads all of the list indexes. + */ + protected void InitAll() + { + InitCharacterRuns(); + InitParagraphs(); + InitSections(); + } + + /** + * Inits the paragraph list indexes. + */ + private void InitParagraphs() + { + if (!_parRangeFound) + { + int[] point = FindRange(_paragraphs, _start, _end); + _parStart = point[0]; + _parEnd = point[1]; + _parRangeFound = true; + } + } + + /** + * Inits the character run list indexes. + */ + private void InitCharacterRuns() + { + if (!_charRangeFound) + { + int[] point = FindRange(_characters, _start, _end); + _charStart = point[0]; + _charEnd = point[1]; + _charRangeFound = true; + } + } + + /** + * Inits the section list indexes. + */ + private void InitSections() + { + if (!_sectionRangeFound) + { + int[] point = FindRange(_sections,_sectionStart, _start, _end); + _sectionStart = point[0]; + _sectionEnd = point[1]; + _sectionRangeFound = true; + } + } + + + private static int BinarySearchStart(List rpl, + int start) where T : PropertyNode + { + if (rpl[0].Start >= start) + return 0; + + int low = 0; + int high = rpl.Count - 1; + + while (low <= high) + { + int mid = (low + high) >> 1; + PropertyNode node = rpl[mid]; + + if (node.Start < start) + { + low = mid + 1; + } + else if (node.Start > start) + { + high = mid - 1; + } + else + { + return mid; + } + } + return low - 1; + } + private static int BinarySearchEnd(List rpl, + int foundStart, int end) where T : PropertyNode + { + if (rpl[rpl.Count - 1].End <= end) + return rpl.Count - 1; + + int low = foundStart; + int high = rpl.Count - 1; + + while (low <= high) + { + int mid = (low + high) >> 1; + PropertyNode node = rpl[mid]; + + if (node.End < end) + { + low = mid + 1; + } + else if (node.End > end) + { + high = mid - 1; + } + else + { + return mid; + } + } + return low; + } + + + + /** + * Used to find the list indexes of a particular property. + * + * @param rpl + * A list of property nodes. + * @param min + * A hint on where to start looking. + * @param start + * The starting character offSet. + * @param end + * The ending character offSet. + * @return An int array of length 2. The first int is the start index and + * the second int is the end index. + */ + private int[] FindRange(List rpl, int start, int end) where T : PropertyNode + { + int startIndex = BinarySearchStart(rpl, start); + while (startIndex > 0 && rpl[startIndex - 1].Start >= start) + startIndex--; + + int endIndex = BinarySearchEnd(rpl, startIndex, end); + while (endIndex < rpl.Count - 1 + && rpl[endIndex + 1].End <= end) + endIndex++; + + if (startIndex < 0 || startIndex >= rpl.Count + || startIndex > endIndex || endIndex < 0 + || endIndex >= rpl.Count) + throw new Exception(); + + return new int[] { startIndex, endIndex + 1 }; + } + /** + * Used to find the list indexes of a particular property. + * + * @param rpl + * A list of property nodes. + * @param min + * A hint on where to start looking. + * @param start + * The starting character offset. + * @param end + * The ending character offset. + * @return An int array of length 2. The first int is the start index and + * the second int is the end index. + */ + private int[] FindRange(List rpl, int min, int start, int end) where T : PropertyNode + { + int x = min; + + if ( rpl.Count == min ) + return new int[] { min, min }; + + T node = rpl[x]; + + while (node==null || (node.End <= start && x < rpl.Count - 1)) { + x++; + + if (x>=rpl.Count) { + return new int[] {0, 0}; + } + + node = rpl[x]; + } + + if ( node.Start > end ) + { + return new int[] { 0, 0 }; + } + + if ( node.End <= start ) + { + return new int[] { rpl.Count, rpl.Count }; + } + + for ( int y = x; y < rpl.Count; y++ ) + { + node = rpl[y]; + if ( node == null ) + continue; + + if ( node.Start < end && node.End <= end ) + continue; + + if ( node.Start < end ) + return new int[] { x, y +1 }; + + return new int[] { x, y }; + } + return new int[] { x, rpl.Count }; + } + /** + * reSets the list indexes. + */ + protected virtual void Reset() + { + _textRangeFound = false; + _charRangeFound = false; + _parRangeFound = false; + _sectionRangeFound = false; + } + + /** + * Adjust the value of the various FIB character count fields, eg + * FIB.CCPText after an insert or a delete... + * + * Works on all CCP fields from this range onwards + * + * @param adjustment + * The (signed) value that should be Added to the FIB CCP fields + */ + protected void AdjustFIB(int adjustment) + { + //Assert(_doc is HWPFDocument); + + // update the FIB.CCPText field (this should happen once per adjustment, + // so we don't want it in + // adjustForInsert() or it would get updated multiple times if the range + // has a parent) + // without this, OpenOffice.org (v. 2.2.x) does not see all the text in + // the document + + //CPSplitCalculator cpS = ((HWPFDocument)_doc).GetCPSplitCalculator(); + FileInformationBlock fib = _doc.GetFileInformationBlock(); + + // Do for each affected part + //if (_start < cpS.GetMainDocumentEnd()) + //{ + // fib.SetCcpText(fib.GetCcpText() + adjustment); + //} + + //if (_start < cpS.GetCommentsEnd()) + //{ + // fib.SetCcpAtn(fib.GetCcpAtn() + adjustment); + //} + //if (_start < cpS.GetEndNoteEnd()) + //{ + // fib.SetCcpEdn(fib.GetCcpEdn() + adjustment); + //} + //if (_start < cpS.GetFootnoteEnd()) + //{ + // fib.SetCcpFtn(fib.GetCcpFtn() + adjustment); + //} + //if (_start < cpS.GetHeaderStoryEnd()) + //{ + // fib.SetCcpHdd(fib.GetCcpHdd() + adjustment); + //} + //if (_start < cpS.GetHeaderTextboxEnd()) + //{ + // fib.SetCcpHdrTxtBx(fib.GetCcpHdrTxtBx() + adjustment); + //} + //if (_start < cpS.GetMainTextboxEnd()) + //{ + // fib.SetCcpTxtBx(fib.GetCcpTxtBx() + adjustment); + //} + + int currentEnd = 0; + foreach (SubdocumentType type in HWPFDocument.ORDERED) + { + int currentLength = fib.GetSubdocumentTextStreamLength(type); + currentEnd += currentLength; + + // do we need to shift this part? + if (_start > currentEnd) + continue; + + fib.SetSubdocumentTextStreamLength(type, currentLength + + adjustment); + + break; + } + } + + /** + * adjust this range after an insert happens. + * + * @param length + * the length to adjust for (expected to be a count of + * code-points, not necessarily chars) + */ + private void AdjustForInsert(int length) + { + _end += length; + + Reset(); + Range parent = (Range)_parent; + if (parent != null) + { + parent.AdjustForInsert(length); + } + } + + + public int StartOffset + { + get + { + return _start; + } + } + + public int EndOffset + { + get + { + return _end; + } + } + + + + internal HWPFDocumentCore GetDocument() + { + return _doc; + } + + + public override String ToString() + { + return "Range from " + StartOffset + " to " + EndOffset + + " (chars)"; + } + /** + * Method for debug purposes. Checks that all resolved elements are inside + * of current range. + */ + public bool SanityCheck() + { + Debug.Assert(_start >= 0, "start < 0"); + Debug.Assert(_start <= _text.Length, "start > text length"); + Debug.Assert(_end >= 0, "end < 0"); + Debug.Assert(_end <= _text.Length, "end > text length"); + Debug.Assert(_start <= _end, "start > end"); + + + if (_charRangeFound) + { + for (int c = _charStart; c < _charEnd; c++) + { + CHPX chpx = _characters[c]; + + int left = Math.Max(this._start, chpx.Start); + int right = Math.Min(this._end, chpx.End); + Debug.Assert(left < right, "left >= right"); + } + } + if (_parRangeFound) + { + for (int p = _parStart; p < _parEnd; p++) + { + PAPX papx = _paragraphs[p]; + + int left = Math.Max(this._start, papx.Start); + int right = Math.Min(this._end, papx.End); + + Debug.Assert(left < right, "left >= right"); + } + } + + return true; + } + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/UserModel/Section.cs b/scratchpad/HWPF/UserModel/Section.cs new file mode 100644 index 0000000..f22f1f6 --- /dev/null +++ b/scratchpad/HWPF/UserModel/Section.cs @@ -0,0 +1,141 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +namespace NPOI.HWPF.UserModel +{ + + using System; + using NPOI.HWPF.Model; + public class Section : Range + { + + private SectionProperties _props; + + public Section(SEPX sepx, Range parent) + : base(Math.Max(parent._start, sepx.Start), Math.Min(parent._end, sepx.End), parent) + { + + _props = sepx.GetSectionProperties(); + } + + public override int Type + { + get + { + return TYPE_SECTION; + } + } + + public int NumColumns + { + get + { + return _props.GetCcolM1() + 1; + } + } + + public override Object Clone() + { + Section s = (Section)base.Clone(); + s._props = (SectionProperties)_props.Clone(); + return s; + } + + /** + * @return distance to be maintained between columns, in twips. Used when + * {@link #isColumnsEvenlySpaced()} == true + */ + public int DistanceBetweenColumns + { + get + { + return _props.GetDxaColumns(); + } + } + + public int MarginBottom + { + get + { + return _props.GetDyaBottom(); + } + } + + public int MarginLeft + { + get + { + return _props.GetDxaLeft(); + } + } + + public int MarginRight + { + get + { + return _props.GetDxaRight(); + } + } + + public int MarginTop + { + get + { + return _props.GetDyaTop(); + } + } + + /** + * @return page height (in twips) in current section. Default value is 15840 + * twips + */ + public int PageHeight + { + get + { + return _props.GetYaPage(); + } + } + + /** + * @return page width (in twips) in current section. Default value is 12240 + * twips + */ + public int PageWidth + { + get + { + return _props.GetXaPage(); + } + } + + public bool IsColumnsEvenlySpaced + { + get + { + return _props.GetFEvenlySpaced(); + } + } + + public override String ToString() + { + return "Section [" + StartOffset + "; " + EndOffset + ")"; + } + } +} + diff --git a/scratchpad/HWPF/UserModel/SectionProperties.cs b/scratchpad/HWPF/UserModel/SectionProperties.cs new file mode 100644 index 0000000..5f96359 --- /dev/null +++ b/scratchpad/HWPF/UserModel/SectionProperties.cs @@ -0,0 +1,77 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +namespace NPOI.HWPF.UserModel +{ + using System; + using System.Reflection; + using NPOI.HWPF.Model.Types; + + public class SectionProperties + : SEPAbstractType + { + public SectionProperties() + { + field_20_brcTop = new BorderCode(); + field_21_brcLeft = new BorderCode(); + field_22_brcBottom = new BorderCode(); + field_23_brcRight = new BorderCode(); + field_26_dttmPropRMark = new DateAndTime(); + } + + //public Object Clone() + //{ + // SectionProperties copy = (SectionProperties)base.Clone(); + // copy.field_20_brcTop = (BorderCode)field_20_brcTop.Clone(); + // copy.field_21_brcLeft = (BorderCode)field_21_brcLeft.Clone(); + // copy.field_22_brcBottom = (BorderCode)field_22_brcBottom.clone(); + // copy.field_23_brcRight = (BorderCode)field_23_brcRight.clone(); + // copy.field_26_dttmPropRMark = (DateAndTime)field_26_dttmPropRMark.clone(); + + // return copy; + //} + + public override bool Equals(Object obj) + { + FieldInfo[] fields = typeof(SectionProperties).BaseType.GetFields(); + try + { + for (int x = 0; x < fields.Length; x++) + { + Object obj1 = fields[x].GetValue(this); + Object obj2 = fields[x].GetValue(obj); + if (obj1 == null && obj2 == null) + { + continue; + } + if (!obj1.Equals(obj2)) + { + return false; + } + } + return true; + } + catch (Exception) + { + return false; + } + } + + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/UserModel/ShadingDescriptor.cs b/scratchpad/HWPF/UserModel/ShadingDescriptor.cs new file mode 100644 index 0000000..cf249cb --- /dev/null +++ b/scratchpad/HWPF/UserModel/ShadingDescriptor.cs @@ -0,0 +1,59 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.UserModel +{ + using System; + using NPOI.Util; + using NPOI.HWPF.Model; + + public class ShadingDescriptor : BaseObject + { + public static int SIZE = 2; + + private short _info; + private static BitField _icoFore = BitFieldFactory.GetInstance(0x1f); + private static BitField _icoBack = BitFieldFactory.GetInstance(0x3e0); + private static BitField _ipat = BitFieldFactory.GetInstance(0xfc00); + + public ShadingDescriptor() + { + } + + public ShadingDescriptor(byte[] buf, int offset) + : this(LittleEndian.GetShort(buf, offset)) + { + + } + + public ShadingDescriptor(short info) + { + _info = info; + } + + public short ToShort() + { + return _info; + } + + public void Serialize(byte[] buf, int offset) + { + LittleEndian.PutShort(buf, offset, _info); + } + } +} diff --git a/scratchpad/HWPF/UserModel/Shape.cs b/scratchpad/HWPF/UserModel/Shape.cs new file mode 100644 index 0000000..b42353e --- /dev/null +++ b/scratchpad/HWPF/UserModel/Shape.cs @@ -0,0 +1,110 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.UserModel +{ + using System; + using NPOI.HWPF.Model; + using NPOI.Util; + + public class Shape + { + int _id, _left, _right, _top, _bottom; + /** + * true if the Shape bounds are within document (for + * example, it's false if the image left corner Is outside the doc, like for + * embedded documents) + */ + bool _inDoc; + + public Shape(GenericPropertyNode nodo) + { + byte[] contenuto = nodo.Bytes; + _id = LittleEndian.GetInt(contenuto); + _left = LittleEndian.GetInt(contenuto, 4); + _top = LittleEndian.GetInt(contenuto, 8); + _right = LittleEndian.GetInt(contenuto, 12); + _bottom = LittleEndian.GetInt(contenuto, 16); + _inDoc = (_left >= 0 && _right >= 0 && _top >= 0 && _bottom >= +0); + } + + public int Id + { + get + { + return _id; + } + } + + public int Left + { + get + { + return _left; + } + } + + public int Right + { + get + { + return _right; + } + } + + public int Top + { + get + { + return _top; + } + } + + public int Bottom + { + get + { + return _bottom; + } + } + + public int Width + { + get + { + return _right - _left + 1; + } + } + + public int Height + { + get + { + return _bottom - _top + 1; + } + } + + public bool IsWithinDocument + { + get + { + return _inDoc; + } + } + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/UserModel/Table.cs b/scratchpad/HWPF/UserModel/Table.cs new file mode 100644 index 0000000..6ae0404 --- /dev/null +++ b/scratchpad/HWPF/UserModel/Table.cs @@ -0,0 +1,97 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using System.Collections; +using System.Collections.Generic; +namespace NPOI.HWPF.UserModel +{ + + public class Table : Range + { + List _rows; + + internal Table(int startIdx, int endIdx, Range parent, int levelNum) + : base(startIdx, endIdx, parent) + { + _tableLevel = levelNum; + InitRows(); + } + private int _tableLevel; + private bool _rowsFound = false; + private void InitRows() + { + if (_rowsFound) + return; + + _rows = new List(); + int rowStart = 0; + int rowEnd = 0; + + int numParagraphs = NumParagraphs; + while (rowEnd < numParagraphs) + { + Paragraph startRowP = GetParagraph(rowStart); + Paragraph endRowP = GetParagraph(rowEnd); + rowEnd++; + if (endRowP.IsTableRowEnd() + && endRowP.GetTableLevel() == _tableLevel) + { + _rows.Add(new TableRow(startRowP.StartOffset, endRowP + .EndOffset, this, _tableLevel)); + rowStart = rowEnd; + } + } + _rowsFound = true; + } + public int NumRows + { + get + { + InitRows(); + return _rows.Count; + } + } + + public override int Type + { + get + { + return TYPE_TABLE; + } + } + + public TableRow GetRow(int index) + { + InitRows(); + return (TableRow)_rows[index]; + } + + public int TableLevel + { + get + { + return _tableLevel; + } + } + protected override void Reset() + { + _rowsFound = false; + } + + } + +} \ No newline at end of file diff --git a/scratchpad/HWPF/UserModel/TableAutoformatLookSpecifier.cs b/scratchpad/HWPF/UserModel/TableAutoformatLookSpecifier.cs new file mode 100644 index 0000000..b042ceb --- /dev/null +++ b/scratchpad/HWPF/UserModel/TableAutoformatLookSpecifier.cs @@ -0,0 +1,70 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +using NPOI.HWPF.Model.Types; +using System; +namespace NPOI.HWPF.UserModel +{ + + public class TableAutoformatLookSpecifier : TLPAbstractType + { + public static int SIZE = 4; + + public TableAutoformatLookSpecifier() + : base() + { + } + + public TableAutoformatLookSpecifier(byte[] data, int offset) + : base() + { + + FillFields(data, offset); + } + + public override bool Equals(Object obj) + { + if (this == obj) + return true; + if (obj == null) + return false; + if (this.GetType() != obj.GetType()) + return false; + TableAutoformatLookSpecifier other = (TableAutoformatLookSpecifier)obj; + if (field_1_itl != other.field_1_itl) + return false; + if (field_2_tlp_flags != other.field_2_tlp_flags) + return false; + return true; + } + + public override int GetHashCode() + { + int prime = 31; + int result = 1; + result = prime * result + field_1_itl; + result = prime * result + field_2_tlp_flags; + return result; + } + + public bool IsEmpty() + { + return field_1_itl == 0 && field_2_tlp_flags == 0; + } + } + + +} \ No newline at end of file diff --git a/scratchpad/HWPF/UserModel/TableCell.cs b/scratchpad/HWPF/UserModel/TableCell.cs new file mode 100644 index 0000000..c6287d5 --- /dev/null +++ b/scratchpad/HWPF/UserModel/TableCell.cs @@ -0,0 +1,116 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.UserModel +{ + + public class TableCell + : Range + { + private int _levelNum; + private TableCellDescriptor _tcd; + private int _leftEdge; + private int _width; + + public TableCell(int startIdx, int endIdx, TableRow parent, int levelNum, TableCellDescriptor tcd, int leftEdge, int width) + : base(startIdx, endIdx,parent) + { + _tcd = tcd; + _leftEdge = leftEdge; + _width = width; + _levelNum = levelNum; + } + + public bool IsFirstMerged() + { + return _tcd.IsFFirstMerged(); + } + + public bool IsMerged() + { + return _tcd.IsFMerged(); + } + + public bool IsVertical() + { + return _tcd.IsFVertical(); + } + + public bool IsBackward() + { + return _tcd.IsFBackward(); + } + + public bool IsRotateFont() + { + return _tcd.IsFRotateFont(); + } + + public bool IsVerticallyMerged() + { + return _tcd.IsFVertMerge(); + } + + public bool IsFirstVerticallyMerged() + { + return _tcd.IsFVertRestart(); + } + + public byte GetVertAlign() + { + return _tcd.GetVertAlign(); + } + + public BorderCode GetBrcTop() + { + return _tcd.GetBrcTop(); + } + + public BorderCode GetBrcBottom() + { + return _tcd.GetBrcBottom(); + } + + public BorderCode GetBrcLeft() + { + return _tcd.GetBrcLeft(); + } + + public BorderCode GetBrcRight() + { + return _tcd.GetBrcRight(); + } + + public int GetLeftEdge() // twips + { + return _leftEdge; + } + + public int GetWidth() // twips + { + return _width; + } + + /** Returns the TableCellDescriptor for this cell.*/ + public TableCellDescriptor GetDescriptor() + { + return _tcd; + } + + } + +} \ No newline at end of file diff --git a/scratchpad/HWPF/UserModel/TableCellDescriptor.cs b/scratchpad/HWPF/UserModel/TableCellDescriptor.cs new file mode 100644 index 0000000..877afa0 --- /dev/null +++ b/scratchpad/HWPF/UserModel/TableCellDescriptor.cs @@ -0,0 +1,75 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.UserModel +{ + using System; + using NPOI.HWPF.Model.Types; + using NPOI.Util; + + public class TableCellDescriptor : TCAbstractType + { + public static int SIZE = 20; + protected short field_x_unused; + + public TableCellDescriptor() + { + SetBrcTop(new BorderCode()); + SetBrcLeft(new BorderCode()); + SetBrcBottom(new BorderCode()); + SetBrcRight(new BorderCode()); + } + + //public Object Clone() + //{ + // TableCellDescriptor tc = (TableCellDescriptor)base.Clone(); + // tc.field_3_brcTop = (BorderCode)field_3_brcTop.Clone(); + // tc.field_4_brcLeft = (BorderCode)field_4_brcLeft.Clone(); + // tc.field_5_brcBottom = (BorderCode)field_5_brcBottom.clone(); + // tc.field_6_brcRight = (BorderCode)field_6_brcRight.clone(); + // return tc; + //} + + protected void FillFields(byte[] data, int offset) + { + field_1_rgf = LittleEndian.GetShort(data, 0x0 + offset); + field_x_unused = LittleEndian.GetShort(data, 0x2 + offset); + SetBrcTop(new BorderCode(data, 0x4 + offset)); + SetBrcLeft(new BorderCode(data, 0x8 + offset)); + SetBrcBottom(new BorderCode(data, 0xc + offset)); + SetBrcRight(new BorderCode(data, 0x10 + offset)); + } + + public static TableCellDescriptor ConvertBytesToTC(byte[] buf, int offset) + { + TableCellDescriptor tc = new TableCellDescriptor(); + tc.FillFields(buf, offset); + return tc; + } + + public void Serialize(byte[] data, int offset) + { + LittleEndian.PutShort(data, 0x0 + offset, field_1_rgf); + LittleEndian.PutShort(data, 0x2 + offset, field_x_unused); + GetBrcTop().Serialize(data, 0x4 + offset); + GetBrcLeft().Serialize(data, 0x8 + offset); + GetBrcBottom().Serialize(data, 0xc + offset); + GetBrcRight().Serialize(data, 0x10 + offset); + } + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/UserModel/TableIterator.cs b/scratchpad/HWPF/UserModel/TableIterator.cs new file mode 100644 index 0000000..44be4f8 --- /dev/null +++ b/scratchpad/HWPF/UserModel/TableIterator.cs @@ -0,0 +1,74 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +namespace NPOI.HWPF.UserModel +{ + + public class TableIterator + { + Range _range; + int _index; + int _levelNum; + + TableIterator(Range range, int levelNum) + { + _range = range; + _index = 0; + _levelNum = levelNum; + } + + public TableIterator(Range range) + : this(range, 1) + { + + } + + + public bool HasNext() + { + int numParagraphs = _range.NumParagraphs; + for (; _index < numParagraphs; _index++) + { + Paragraph paragraph = _range.GetParagraph(_index); + if (paragraph.IsInTable() && paragraph.GetTableLevel() == _levelNum) + { + return true; + } + } + return false; + } + + public Table Next() + { + int numParagraphs = _range.NumParagraphs; + int startIndex = _index; + int endIndex = _index; + + for (; _index < numParagraphs; _index++) + { + Paragraph paragraph = _range.GetParagraph(_index); + if (!paragraph.IsInTable() || paragraph.GetTableLevel() < _levelNum) + { + endIndex = _index; + break; + } + } + return new Table(startIndex, endIndex, _range, _levelNum); + } + + } +} diff --git a/scratchpad/HWPF/UserModel/TableProperties.cs b/scratchpad/HWPF/UserModel/TableProperties.cs new file mode 100644 index 0000000..90b2bd6 --- /dev/null +++ b/scratchpad/HWPF/UserModel/TableProperties.cs @@ -0,0 +1,80 @@ + +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License Is distributed on an "AS Is" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + + +namespace NPOI.HWPF.UserModel +{ + using System; + using NPOI.HWPF.Model.Types; + + + public class TableProperties : TAPAbstractType + // implements Cloneable + { + + public TableProperties() + { + + } + public TableProperties(int columns) + { + field_7_itcMac = (short)columns; + field_10_rgshd = new ShadingDescriptor[columns]; + for (int x = 0; x < columns; x++) + { + field_10_rgshd[x] = new ShadingDescriptor(); + } + field_11_brcBottom = new BorderCode(); + field_12_brcTop = new BorderCode(); + field_13_brcLeft = new BorderCode(); + field_14_brcRight = new BorderCode(); + field_15_brcVertical = new BorderCode(); + field_16_brcHorizontal = new BorderCode(); + field_8_rgdxaCenter = new short[columns]; + field_9_rgtc = new TableCellDescriptor[columns]; + for (int x = 0; x < columns; x++) + { + field_9_rgtc[x] = new TableCellDescriptor(); + } + } + + //public Object Clone() + //{ + // TableProperties tap = (TableProperties)super.clone(); + // tap.field_10_rgshd = new ShadingDescriptor[field_10_rgshd.Length]; + // for (int x = 0; x < field_10_rgshd.Length; x++) + // { + // tap.field_10_rgshd[x] = (ShadingDescriptor)field_10_rgshd[x].clone(); + // } + // tap.field_11_brcBottom = (BorderCode)field_11_brcBottom.clone(); + // tap.field_12_brcTop = (BorderCode)field_12_brcTop.clone(); + // tap.field_13_brcLeft = (BorderCode)field_13_brcLeft.clone(); + // tap.field_14_brcRight = (BorderCode)field_14_brcRight.clone(); + // tap.field_15_brcVertical = (BorderCode)field_15_brcVertical.clone(); + // tap.field_16_brcHorizontal = (BorderCode)field_16_brcHorizontal.clone(); + // tap.field_8_rgdxaCenter = (short[])field_8_rgdxaCenter.clone(); + // tap.field_9_rgtc = new TableCellDescriptor[field_9_rgtc.Length]; + // for (int x = 0; x < field_9_rgtc.Length; x++) + // { + // tap.field_9_rgtc[x] = (TableCellDescriptor)field_9_rgtc[x].clone(); + // } + // return tap; + //} + + } +} \ No newline at end of file diff --git a/scratchpad/HWPF/UserModel/TableRow.cs b/scratchpad/HWPF/UserModel/TableRow.cs new file mode 100644 index 0000000..7b4d28a --- /dev/null +++ b/scratchpad/HWPF/UserModel/TableRow.cs @@ -0,0 +1,235 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for Additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ + +using System; +using NPOI.HWPF.SPRM; +using System.Collections.Generic; +namespace NPOI.HWPF.UserModel +{ + + public class TableRow + : Paragraph + { + private static char TABLE_CELL_MARK = '\u0007'; + + private static short SPRM_TJC = 0x5400; + private static short SPRM_DXAGAPHALF = unchecked((short)0x9602); + private static short SPRM_FCANTSPLIT = 0x3403; + private static short SPRM_FTABLEHEADER = 0x3404; + private static short SPRM_DYAROWHEIGHT = unchecked((short)0x9407); + + int _levelNum; + private TableProperties _tprops; + private TableCell[] _cells; + + public TableRow(int startIdx, int endIdx, Table parent, int levelNum) + : base(startIdx, endIdx, parent) + { + + Paragraph last = GetParagraph(NumParagraphs - 1); + _papx = last._papx; + _tprops = TableSprmUncompressor.UncompressTAP(_papx); + _levelNum = levelNum; + initCells(); + + } + + private void initCells() + { + if ( _cellsFound ) + return; + + short expectedCellsCount = _tprops.GetItcMac(); + + int lastCellStart = 0; + List cells = new List( + expectedCellsCount + 1 ); + for ( int p = 0; p < NumParagraphs; p++ ) + { + Paragraph paragraph = GetParagraph( p ); + String s = paragraph.Text; + + if ( ( ( s.Length > 0 && s[s.Length - 1]== TABLE_CELL_MARK ) || paragraph + .IsEmbeddedCellMark() ) + && paragraph.GetTableLevel() == _levelNum ) + { + TableCellDescriptor tableCellDescriptor = _tprops.GetRgtc() != null + && _tprops.GetRgtc().Length > cells.Count ? _tprops + .GetRgtc()[cells.Count] : new TableCellDescriptor(); + short leftEdge = (_tprops.GetRgdxaCenter() != null + && _tprops.GetRgdxaCenter().Length > cells.Count) ? (short)_tprops + .GetRgdxaCenter()[cells.Count] : (short)0; + short rightEdge = (_tprops.GetRgdxaCenter() != null + && _tprops.GetRgdxaCenter().Length > cells.Count + 1) ? (short)_tprops + .GetRgdxaCenter()[cells.Count + 1] : (short)0; + + TableCell tableCell = new TableCell( GetParagraph( + lastCellStart ).StartOffset, GetParagraph( p ) + .EndOffset, this, _levelNum, tableCellDescriptor, + leftEdge, rightEdge - leftEdge ); + cells.Add( tableCell ); + lastCellStart = p + 1; + } + } + + if ( lastCellStart < ( NumParagraphs - 1 ) ) + { + TableCellDescriptor tableCellDescriptor = _tprops.GetRgtc() != null + && _tprops.GetRgtc().Length > cells.Count ? _tprops + .GetRgtc()[cells.Count] : new TableCellDescriptor(); + short leftEdge = _tprops.GetRgdxaCenter() != null + && _tprops.GetRgdxaCenter().Length > cells.Count ? (short)_tprops + .GetRgdxaCenter()[cells.Count] : (short)0; + short rightEdge = _tprops.GetRgdxaCenter() != null + && _tprops.GetRgdxaCenter().Length > cells.Count + 1 ? (short)_tprops + .GetRgdxaCenter()[cells.Count + 1] : (short)0; + + TableCell tableCell = new TableCell( lastCellStart, + ( NumParagraphs - 1 ), this, _levelNum, + tableCellDescriptor, leftEdge, rightEdge - leftEdge ); + cells.Add( tableCell ); + } + + if ( cells.Count>0 ) + { + TableCell lastCell = cells[cells.Count - 1]; + if ( lastCell.NumParagraphs == 1 + && ( lastCell.GetParagraph( 0 ).IsTableRowEnd() ) ) + { + // remove "fake" cell + cells.RemoveAt( cells.Count - 1 ); + } + } + + if ( cells.Count != expectedCellsCount ) + { + _tprops.SetItcMac( (short) cells.Count); + } + + _cells = cells.ToArray(); + _cellsFound = true; + } + private bool _cellsFound = false; + protected void Reset() + { + _cellsFound = false; + } + public int GetRowJustification() + { + return _tprops.GetJc(); + } + + public void SetRowJustification(int jc) + { + _tprops.SetJc(jc); + _papx.UpdateSprm(SPRM_TJC, (short)jc); + } + + public int GetGapHalf() + { + return _tprops.GetDxaGapHalf(); + } + + public void SetGapHalf(int dxaGapHalf) + { + _tprops.SetDxaGapHalf(dxaGapHalf); + _papx.UpdateSprm(SPRM_DXAGAPHALF, (short)dxaGapHalf); + } + + public int GetRowHeight() + { + return _tprops.GetDyaRowHeight(); + } + + public void SetRowHeight(int dyaRowHeight) + { + _tprops.SetDyaRowHeight(dyaRowHeight); + _papx.UpdateSprm(SPRM_DYAROWHEIGHT, (short)dyaRowHeight); + } + + public bool cantSplit() + { + return _tprops.GetFCantSplit(); + } + + public void SetCantSplit(bool cantSplit) + { + _tprops.SetFCantSplit(cantSplit); + _papx.UpdateSprm(SPRM_FCANTSPLIT, (byte)(cantSplit ? 1 : 0)); + } + + public bool isTableHeader() + { + return _tprops.GetFTableHeader(); + } + + public void SetTableHeader(bool tableHeader) + { + _tprops.SetFTableHeader(tableHeader); + _papx.UpdateSprm(SPRM_FTABLEHEADER, (byte)(tableHeader ? 1 : 0)); + } + + public int NumCells() + { + initCells(); + return _cells.Length; + } + + public TableCell GetCell(int index) + { + initCells(); + return _cells[index]; + } + + public override BorderCode GetTopBorder() + { + return _tprops.GetBrcBottom(); + } + + public override BorderCode GetBottomBorder() + { + return _tprops.GetBrcBottom(); + } + + public override BorderCode GetLeftBorder() + { + return _tprops.GetBrcLeft(); + } + + public override BorderCode GetRightBorder() + { + return _tprops.GetBrcRight(); + } + + public BorderCode GetHorizontalBorder() + { + return _tprops.GetBrcHorizontal(); + } + + public BorderCode GetVerticalBorder() + { + return _tprops.GetBrcVertical(); + } + + public override BorderCode GetBarBorder() + { + throw new NotImplementedException("not applicable for TableRow"); + } + + } + +} \ No newline at end of file diff --git a/scratchpad/HWPF/npoi.snk b/scratchpad/HWPF/npoi.snk new file mode 100644 index 0000000000000000000000000000000000000000..59d06b5ad010ba0de4cc50910d7a6abe0834d347 GIT binary patch literal 596 zcmV-a0;~N80ssI2Bme+XQ$aES1ONa50097%%-LG=vz?2=1w_;If6_}+>&48rlj`je zVvu5=jM#$6C+pP_tyx5pB=B*KKb-@%Nkyi}wq!zP02_>iCKyvN%ytGkMW!?MkC!2<|&dUDt)MY6r5|XyYP(M3uGA zz)`C_R3*~Y#JQ*Sq$1sTZ@BG#8IH9KRCOHfl)X?B=A7WuZ~ztbN<9U(ejK^BBM~M# zr0&u5$TT1__qg|4O>}@5vOWz{0=drdXBD=U=uc8aQ*BE<8dX6n*GtkugQT}?Yr+(X za3LQ=Hegq&%f$Ycy)&sOc*$XRil)0iza*x;Er}nS#swh|3)SotY|s|)9%M^h&6-^H z#T$f6@|9OK-|Lcp?xn(6^{^fh33R#4~#Rxfq zHLh7#({>uo3i~jjc<@~8q{tC}nZeBZ`otwq&XzHw*Hr>u^=fx~h88X4oCoO|>sE75 zNNdL%pfDgn1dP13z0Pj_YJAM6q9G$nxulxMT*FzbM;QBNcq2$}v>)vB*)RRK1l#f+ iAabeuj>V=NU|7jz7W)yXmzNNRJJCo4qoAZMc>jzI`yqk= literal 0 HcmV?d00001 From c7592c02e96983ca68a90a29e2475d40f17fc4e2 Mon Sep 17 00:00:00 2001 From: h Date: Sat, 8 Sep 2018 20:04:17 +0800 Subject: [PATCH 2/9] convert HWPF project to net core --- DotNetCore.NPOI.sln | 12 ++++++++++++ scratchpad/HWPF/HWPF.csproj | 31 +++++++++++++------------------ 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/DotNetCore.NPOI.sln b/DotNetCore.NPOI.sln index d1a763f..e8b0930 100644 --- a/DotNetCore.NPOI.sln +++ b/DotNetCore.NPOI.sln @@ -33,6 +33,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Itmes", "Solution build\version.props = build\version.props EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HWPF", "scratchpad\HWPF\HWPF.csproj", "{F040162E-F6F3-4B09-809B-3095A07A6687}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution .net 2 Release|Any CPU = .net 2 Release|Any CPU @@ -122,6 +124,16 @@ Global {4D493C32-B246-4DB5-B0DF-9AF3B63C230D}.NPOI.Tools|Any CPU.Build.0 = Debug|Any CPU {4D493C32-B246-4DB5-B0DF-9AF3B63C230D}.Release|Any CPU.ActiveCfg = Release|Any CPU {4D493C32-B246-4DB5-B0DF-9AF3B63C230D}.Release|Any CPU.Build.0 = Release|Any CPU + {F040162E-F6F3-4B09-809B-3095A07A6687}..net 2 Release|Any CPU.ActiveCfg = Release|Any CPU + {F040162E-F6F3-4B09-809B-3095A07A6687}..net 2 Release|Any CPU.Build.0 = Release|Any CPU + {F040162E-F6F3-4B09-809B-3095A07A6687}..net 4 Release|Any CPU.ActiveCfg = Release|Any CPU + {F040162E-F6F3-4B09-809B-3095A07A6687}..net 4 Release|Any CPU.Build.0 = Release|Any CPU + {F040162E-F6F3-4B09-809B-3095A07A6687}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F040162E-F6F3-4B09-809B-3095A07A6687}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F040162E-F6F3-4B09-809B-3095A07A6687}.NPOI.Tools|Any CPU.ActiveCfg = Release|Any CPU + {F040162E-F6F3-4B09-809B-3095A07A6687}.NPOI.Tools|Any CPU.Build.0 = Release|Any CPU + {F040162E-F6F3-4B09-809B-3095A07A6687}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F040162E-F6F3-4B09-809B-3095A07A6687}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/scratchpad/HWPF/HWPF.csproj b/scratchpad/HWPF/HWPF.csproj index 63f57d5..279b71a 100644 --- a/scratchpad/HWPF/HWPF.csproj +++ b/scratchpad/HWPF/HWPF.csproj @@ -1,5 +1,8 @@  - + +falsefalsefalsefalse + + Debug AnyCPU @@ -10,7 +13,7 @@ Properties NPOI.HWPF NPOI.ScratchPad.HWPF - v2.0 + netcoreapp2.1 512 @@ -50,20 +53,6 @@ npoi.snk - - - False - ..\..\build\Release\Net20\ICSharpCode.SharpZipLib.dll - - - False - ..\..\build\Release\Net20\NPOI.dll - - - - - - @@ -206,7 +195,7 @@ Code - + Code @@ -288,7 +277,13 @@ - + + + + + + + Code diff --git a/scratchpad/HWPF/Model/CHPBinTable.cs b/scratchpad/HWPF/Model/CHPBinTable.cs index 27d0a01..143d4af 100644 --- a/scratchpad/HWPF/Model/CHPBinTable.cs +++ b/scratchpad/HWPF/Model/CHPBinTable.cs @@ -22,10 +22,12 @@ limitations under the License. using System.IO; using NPOI.HWPF.SPRM; using System; + +[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("TestCases,PublicKey=002400000480000094000000060200000024000052534131000400000100010095ccd95af3b39d8bc20544d3f47fd24b53ebc5ccb693eaed116290629f8cd882c827ebd511ad59449224f0718d3f9d03b64945a6c8b6644266001b8c8426185330e3d96da70ae16d4acc21b8d4d480f1385c7e924273179375aa88f81380a72fb115712a313379d16aed4aa36208ee3b4a5dd785b06a07b2d868e3227f4495b5")] + namespace NPOI.HWPF.Model { - /** * This class holds all of the character formatting properties. * diff --git a/test/scratchpad/TestCases.csproj b/test/scratchpad/TestCases.csproj deleted file mode 100644 index 635cb5e..0000000 --- a/test/scratchpad/TestCases.csproj +++ /dev/null @@ -1,176 +0,0 @@ - - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {81F02870-E6BA-42D9-8E8C-DD16699DCABE} - Library - Properties - TestCases - TestCases - v4.0 - 512 - {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - - - - - 3.5 - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - true - - - npoi.snk - - - - ..\..\build\Release\Net20\ICSharpCode.SharpZipLib.dll - - - ..\..\build\Release\Net20\NPOI.dll - - - ..\..\solution\Lib\nunit.framework.dll - - - - - - - - - - - - - - - - - - Code - - - - - - - - - - - - Code - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - False - Microsoft .NET Framework 4 %28x86 and x64%29 - true - - - False - .NET Framework 3.5 SP1 Client Profile - false - - - False - .NET Framework 3.5 SP1 - false - - - False - Windows Installer 4.5 - true - - - - - {eb09bcca-0b45-4984-b4e6-bad8c0a9f8a9} - HSLF - - - {f040162e-f6f3-4b09-809b-3095a07a6687} - HWPF - - - - - \ No newline at end of file diff --git a/test/scratchpad/TestCases.sln b/test/scratchpad/TestCases.sln new file mode 100644 index 0000000..af5d4bd --- /dev/null +++ b/test/scratchpad/TestCases.sln @@ -0,0 +1,36 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28010.2016 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestCases", "TestCases.csproj", "{81F02870-E6BA-42D9-8E8C-DD16699DCABE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HWPF", "..\..\scratchpad\HWPF\HWPF.csproj", "{F040162E-F6F3-4B09-809B-3095A07A6687}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NPOI", "..\..\src\NPOI\NPOI.csproj", "{E467395B-9729-4C1A-8D16-D5D34BB7666A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {81F02870-E6BA-42D9-8E8C-DD16699DCABE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {81F02870-E6BA-42D9-8E8C-DD16699DCABE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {81F02870-E6BA-42D9-8E8C-DD16699DCABE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {81F02870-E6BA-42D9-8E8C-DD16699DCABE}.Release|Any CPU.Build.0 = Release|Any CPU + {F040162E-F6F3-4B09-809B-3095A07A6687}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F040162E-F6F3-4B09-809B-3095A07A6687}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F040162E-F6F3-4B09-809B-3095A07A6687}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F040162E-F6F3-4B09-809B-3095A07A6687}.Release|Any CPU.Build.0 = Release|Any CPU + {E467395B-9729-4C1A-8D16-D5D34BB7666A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E467395B-9729-4C1A-8D16-D5D34BB7666A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E467395B-9729-4C1A-8D16-D5D34BB7666A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E467395B-9729-4C1A-8D16-D5D34BB7666A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0CF05787-C160-489E-A93E-ABF0ABDBE5B5} + EndGlobalSection +EndGlobal From 867ab157be559d3f38c68ffcb1523468a5eb7f09 Mon Sep 17 00:00:00 2001 From: h Date: Sat, 22 Sep 2018 12:16:14 +0800 Subject: [PATCH 5/9] 1 --- test/scratchpad/TestCases.csproj | 178 +++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) create mode 100644 test/scratchpad/TestCases.csproj diff --git a/test/scratchpad/TestCases.csproj b/test/scratchpad/TestCases.csproj new file mode 100644 index 0000000..4f6bb67 --- /dev/null +++ b/test/scratchpad/TestCases.csproj @@ -0,0 +1,178 @@ + +falsefalsefalsefalse + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {81F02870-E6BA-42D9-8E8C-DD16699DCABE} + Library + Properties + TestCases + TestCases + + netcoreapp2.1 + 512 + + {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + + + + + 3.5 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + A .NET library for reading and writing Microsoft Office binary and OOXML file formats. + + + true + full + false + bin\Debug\ + TRACE;DEBUG;NETCOREAPP;NETCOREAPP2_1 + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + true + + + npoi.snk + + + + + + + + + + + + + + + + + Code + + + + + + + + + + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From cd5283731dd61a88d259766b70d483fc9abd3d0a Mon Sep 17 00:00:00 2001 From: lx Date: Sat, 22 Sep 2018 15:30:18 +0800 Subject: [PATCH 6/9] fix test-data path config and add support for MacOS --- test/scratchpad/App.config | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/scratchpad/App.config b/test/scratchpad/App.config index c6dbd77..0a6d848 100644 --- a/test/scratchpad/App.config +++ b/test/scratchpad/App.config @@ -5,13 +5,13 @@ if it is not set, NPOI.Util.NullLogger will be used --> - - - - - - - + + + + + + + From b88869aeeaa128bd855984dec3ca589e2a6b6d2b Mon Sep 17 00:00:00 2001 From: lx Date: Sat, 22 Sep 2018 15:30:35 +0800 Subject: [PATCH 7/9] fix Enncoding Error --- scratchpad/HWPF/HWPF.csproj | 1 + scratchpad/HWPF/Model/TextPiece.cs | 18 +++++++++++++++++- test/scratchpad/POIDataSamples.cs | 9 ++++++--- test/scratchpad/TestCases.csproj | 2 ++ 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/scratchpad/HWPF/HWPF.csproj b/scratchpad/HWPF/HWPF.csproj index 66cf8fa..62e6b34 100644 --- a/scratchpad/HWPF/HWPF.csproj +++ b/scratchpad/HWPF/HWPF.csproj @@ -280,6 +280,7 @@ + diff --git a/scratchpad/HWPF/Model/TextPiece.cs b/scratchpad/HWPF/Model/TextPiece.cs index afd32cc..b50a7bf 100644 --- a/scratchpad/HWPF/Model/TextPiece.cs +++ b/scratchpad/HWPF/Model/TextPiece.cs @@ -63,11 +63,20 @@ public TextPiece(int start, int end, byte[] text, PieceDescriptor pd) } } + private static bool inited; + /** * Create the StringBuilder from the text and unicode flag */ private static StringBuilder buildInitSB(byte[] text, PieceDescriptor pd) { + if (!inited) + { + // RegisterProvider is a thread safe method, does a lock required? + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + inited = true; + } + String str; try { @@ -78,7 +87,14 @@ private static StringBuilder buildInitSB(byte[] text, PieceDescriptor pd) else { //str = Encoding.GetEncoding("CP1252").GetString(text); - str = Encoding.GetEncoding("Windows-1252").GetString(text); +// try +// { + str = Encoding.GetEncoding("Windows-1252").GetString(text); +// } +// catch (Exception e) +// { +// str = Encoding.GetEncoding(1252).GetString(text); +// } } } catch (EncoderFallbackException) diff --git a/test/scratchpad/POIDataSamples.cs b/test/scratchpad/POIDataSamples.cs index 4a85c93..1925901 100644 --- a/test/scratchpad/POIDataSamples.cs +++ b/test/scratchpad/POIDataSamples.cs @@ -112,15 +112,18 @@ private Stream OpenClasspathResource(String sampleFileName) private void Initialise() { - String dataDirName = System.Configuration.ConfigurationSettings.AppSettings[TEST_PROPERTY]; + // String dataDirName = System.Configuration.ConfigurationSettings.AppSettings[TEST_PROPERTY]; + String dataDirName = System.Configuration.ConfigurationManager.AppSettings[TEST_PROPERTY]; if (dataDirName == null) throw new Exception("Must set system property '" + TEST_PROPERTY + "' before running tests"); - string dataDir = string.Format(@"{0}\{1}\", dataDirName, _moduleDir); - if (!Directory.Exists(dataDir)) + string dataDir = string.Format(@"{0}/{1}/", dataDirName, _moduleDir); + //if (!Directory.Exists(dataDir)) + var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, dataDir); + if (!Directory.Exists(path)) { throw new IOException("Data dir '" + dataDirName + "\\" + _moduleDir + "' specified by system property '" diff --git a/test/scratchpad/TestCases.csproj b/test/scratchpad/TestCases.csproj index 4f6bb67..592c705 100644 --- a/test/scratchpad/TestCases.csproj +++ b/test/scratchpad/TestCases.csproj @@ -172,7 +172,9 @@ --> + + \ No newline at end of file From 8ed51824eb9454a67ff7c0d570ccb4d5ee5d5602 Mon Sep 17 00:00:00 2001 From: lx Date: Sat, 22 Sep 2018 16:04:45 +0800 Subject: [PATCH 8/9] fix System.InvalidOperationException: Collection was modified; enumeration operation may not execute. at System.Collections.Generic.List`1.Enumerator.MoveNextRare() at System.Collections.Generic.List`1.Enumerator.MoveNext() at NPOI.HWPF.Model.CHPBinTable.Rebuild(ComplexFileTable complexFileTable) in /Users/Private/git/tianzen-third lib/NPOI-netcore/scratchpad/HWPF/Model/CHPBinTable.cs:line 287 at NPOI.HWPF.HWPFDocument..ctor(DirectoryNode directory) in /Users/Private/git/tianzen-third lib/NPOI-netcore/scratchpad/HWPF/HWPFDocument.cs:line 267 at NPOI.HWPF.HWPFDocument..ctor(POIFSFileSystem pfilesystem) in /Users/Private/git/tianzen-third lib/NPOI-netcore/scratchpad/HWPF/HWPFDocument.cs:line 154 at NPOI.HWPF.HWPFDocument..ctor(Stream istream) in /Users/Private/git/tianzen-third lib/NPOI-netcore/scratchpad/HWPF/HWPFDocument.cs:line 141 at Toxy.Parsers.Word2003TextParser.Parse() in G:\code\toxy\ToxyFramework\Parsers\Word2003TextParser.cs:line 23 --- scratchpad/HWPF/Model/CHPBinTable.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/scratchpad/HWPF/Model/CHPBinTable.cs b/scratchpad/HWPF/Model/CHPBinTable.cs index 143d4af..831fe08 100644 --- a/scratchpad/HWPF/Model/CHPBinTable.cs +++ b/scratchpad/HWPF/Model/CHPBinTable.cs @@ -22,6 +22,7 @@ limitations under the License. using System.IO; using NPOI.HWPF.SPRM; using System; +using System.Linq; [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("TestCases,PublicKey=002400000480000094000000060200000024000052534131000400000100010095ccd95af3b39d8bc20544d3f47fd24b53ebc5ccb693eaed116290629f8cd882c827ebd511ad59449224f0718d3f9d03b64945a6c8b6644266001b8c8426185330e3d96da70ae16d4acc21b8d4d480f1385c7e924273179375aa88f81380a72fb115712a313379d16aed4aa36208ee3b4a5dd785b06a07b2d868e3227f4495b5")] @@ -283,7 +284,18 @@ public void Rebuild(ComplexFileTable complexFileTable) _textRuns.Count, " elements)"); start = DateTime.Now.Ticks; + /** + * System.InvalidOperationException: Collection was modified; enumeration operation may not execute. + at System.Collections.Generic.List`1.Enumerator.MoveNextRare() + at System.Collections.Generic.List`1.Enumerator.MoveNext() + at NPOI.HWPF.Model.CHPBinTable.Rebuild(ComplexFileTable complexFileTable) in /Users/Private/git/tianzen-third lib/NPOI-netcore/scratchpad/HWPF/Model/CHPBinTable.cs:line 287 + at NPOI.HWPF.HWPFDocument..ctor(DirectoryNode directory) in /Users/Private/git/tianzen-third lib/NPOI-netcore/scratchpad/HWPF/HWPFDocument.cs:line 267 + at NPOI.HWPF.HWPFDocument..ctor(POIFSFileSystem pfilesystem) in /Users/Private/git/tianzen-third lib/NPOI-netcore/scratchpad/HWPF/HWPFDocument.cs:line 154 + at NPOI.HWPF.HWPFDocument..ctor(Stream istream) in /Users/Private/git/tianzen-third lib/NPOI-netcore/scratchpad/HWPF/HWPFDocument.cs:line 141 + at Toxy.Parsers.Word2003TextParser.Parse() in G:\code\toxy\ToxyFramework\Parsers\Word2003TextParser.cs:line 23 + */ CHPX previous = null; + var copy = _textRuns.ToList(); for (List.Enumerator iterator = _textRuns.GetEnumerator(); iterator .MoveNext(); ) { From 2197d2f2fa4a9985f39937e4424b8aa49ebf9e1b Mon Sep 17 00:00:00 2001 From: lx Date: Sat, 22 Sep 2018 16:08:50 +0800 Subject: [PATCH 9/9] fix System.InvalidOperationException: Collection was modified; enumeration operation may not execute. --- scratchpad/HWPF/Model/CHPBinTable.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scratchpad/HWPF/Model/CHPBinTable.cs b/scratchpad/HWPF/Model/CHPBinTable.cs index 831fe08..21cd47a 100644 --- a/scratchpad/HWPF/Model/CHPBinTable.cs +++ b/scratchpad/HWPF/Model/CHPBinTable.cs @@ -296,7 +296,7 @@ at Toxy.Parsers.Word2003TextParser.Parse() in G:\code\toxy\ToxyFramework\Parsers */ CHPX previous = null; var copy = _textRuns.ToList(); - for (List.Enumerator iterator = _textRuns.GetEnumerator(); iterator + for (List.Enumerator iterator = copy.GetEnumerator(); iterator .MoveNext(); ) { CHPX current = iterator.Current;