1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "oox/dump/dffdumper.hxx" 29 30 #if OOX_INCLUDE_DUMPER 31 32 namespace oox { 33 namespace dump { 34 35 // ============================================================================ 36 37 using ::rtl::OUString; 38 39 // ============================================================================ 40 41 namespace { 42 43 const sal_uInt16 DFF_ID_BSE = 0xF007; /// BLIP store entry. 44 const sal_uInt16 DFF_ID_BSTORECONTAINER = 0xF001; /// BLIP store container. 45 const sal_uInt16 DFF_ID_CHILDANCHOR = 0xF00F; /// Child anchor (in groups). 46 const sal_uInt16 DFF_ID_CLIENTANCHOR = 0xF010; /// Client anchor. 47 const sal_uInt16 DFF_ID_DG = 0xF008; /// Drawing. 48 const sal_uInt16 DFF_ID_DGG = 0xF006; /// Drawing group. 49 const sal_uInt16 DFF_ID_OPT = 0xF00B; /// Property set. 50 const sal_uInt16 DFF_ID_OPT2 = 0xF121; /// Secondary property set. 51 const sal_uInt16 DFF_ID_OPT3 = 0xF122; /// Ternary property set. 52 const sal_uInt16 DFF_ID_SP = 0xF00A; /// Shape. 53 const sal_uInt16 DFF_ID_SPGR = 0xF009; /// Shape group. 54 const sal_uInt16 DFF_ID_SPLITMENUCOLORS = 0xF11E; /// Current toolbar colors. 55 56 const sal_uInt16 DFF_OPT_IDMASK = 0x3FFF; 57 const sal_uInt16 DFF_OPT_PICTURE = 0x4000; 58 const sal_uInt16 DFF_OPT_COMPLEX = 0x8000; 59 const sal_uInt16 DFF_OPT_FLAGSMASK = 0x003F; 60 61 } // namespace 62 63 // ============================================================================ 64 65 void DffStreamObject::construct( const ObjectBase& rParent, const BinaryInputStreamRef& rxStrm, const OUString& rSysFileName ) 66 { 67 SequenceRecordObjectBase::construct( rParent, rxStrm, rSysFileName, "DFF-RECORD-NAMES" ); 68 constructDffObj(); 69 } 70 71 void DffStreamObject::construct( const OutputObjectBase& rParent, const BinaryInputStreamRef& rxStrm ) 72 { 73 SequenceRecordObjectBase::construct( rParent, rxStrm, "DFF-RECORD-NAMES" ); 74 constructDffObj(); 75 } 76 77 bool DffStreamObject::implReadRecordHeader( BinaryInputStream& rBaseStrm, sal_Int64& ornRecId, sal_Int64& ornRecSize ) 78 { 79 sal_uInt16 nRecId; 80 rBaseStrm >> mnInstVer >> nRecId >> mnRealSize; 81 ornRecId = nRecId; 82 ornRecSize = isContainer() ? 0 : mnRealSize; 83 return !rBaseStrm.isEof(); 84 } 85 86 void DffStreamObject::implWriteExtHeader() 87 { 88 const sal_Char* pcListName = "DFF-RECORD-INST"; 89 switch( getRecId() ) 90 { 91 case DFF_ID_BSE: pcListName = "DFFBSE-RECORD-INST"; break; // BLIP type 92 case DFF_ID_BSTORECONTAINER: pcListName = "DFFBSTORECONT-RECORD-INST"; break; // BLIP count 93 case DFF_ID_DG: pcListName = "DFFDG-RECORD-INST"; break; // drawing ID 94 case DFF_ID_OPT: pcListName = "DFFOPT-RECORD-INST"; break; // property count 95 case DFF_ID_SP: pcListName = "DFFSP-RECORD-INST"; break; // shape type 96 case DFF_ID_SPLITMENUCOLORS: pcListName = "DFFSPLITMENUC-RECORD-INST"; break; // number of colors 97 } 98 MultiItemsGuard aMultiGuard( mxOut ); 99 writeHexItem( "instance", mnInstVer, pcListName ); 100 if( isContainer() ) writeDecItem( "container-size", mnRealSize ); 101 } 102 103 void DffStreamObject::implDumpRecordBody() 104 { 105 switch( getRecId() ) 106 { 107 case DFF_ID_BSE: 108 dumpDec< sal_uInt8 >( "win-type", "DFFBSE-TYPE" ); 109 dumpDec< sal_uInt8 >( "mac-type", "DFFBSE-TYPE" ); 110 dumpGuid( "guid" ); 111 dumpDec< sal_uInt16 >( "tag" ); 112 dumpDec< sal_uInt32 >( "blip-size" ); 113 dumpDec< sal_uInt32 >( "blip-refcount" ); 114 dumpDec< sal_uInt32 >( "blip-streampos" ); 115 dumpDec< sal_uInt8 >( "blip-usage", "DFFBSE-USAGE" ); 116 dumpDec< sal_uInt8 >( "blip-name-len" ); 117 dumpUnused( 2 ); 118 break; 119 120 case DFF_ID_CHILDANCHOR: 121 dumpDec< sal_uInt32 >( "left" ); 122 dumpDec< sal_uInt32 >( "top" ); 123 dumpDec< sal_uInt32 >( "right" ); 124 dumpDec< sal_uInt32 >( "bottom" ); 125 break; 126 127 case DFF_ID_CLIENTANCHOR: 128 implDumpClientAnchor(); 129 break; 130 131 case DFF_ID_DG: 132 dumpDec< sal_uInt32 >( "shape-count" ); 133 dumpHex< sal_uInt32 >( "max-shape-id", "CONV-DEC" ); 134 break; 135 136 case DFF_ID_DGG: 137 { 138 dumpHex< sal_uInt32 >( "max-shape-id", "CONV-DEC" ); 139 sal_uInt32 nClusters = dumpDec< sal_uInt32 >( "id-cluster-count" ); 140 dumpDec< sal_uInt32 >( "shape-count" ); 141 dumpDec< sal_uInt32 >( "drawing-count" ); 142 mxOut->resetItemIndex( 1 ); 143 TableGuard aTabGuard( mxOut, 15, 16 ); 144 for( sal_uInt32 nCluster = 1; !mxStrm->isEof() && (nCluster < nClusters); ++nCluster ) 145 { 146 MultiItemsGuard aMultiGuard( mxOut ); 147 writeEmptyItem( "#cluster" ); 148 dumpDec< sal_uInt32 >( "drawing-id" ); 149 dumpHex< sal_uInt32 >( "next-free-id", "CONV-DEC" ); 150 } 151 } 152 break; 153 154 case DFF_ID_OPT: 155 case DFF_ID_OPT2: 156 case DFF_ID_OPT3: 157 dumpDffOpt(); 158 break; 159 160 case DFF_ID_SP: 161 dumpHex< sal_uInt32 >( "shape-id", "CONV-DEC" ); 162 dumpHex< sal_uInt32 >( "shape-flags", "DFFSP-FLAGS" ); 163 break; 164 165 case DFF_ID_SPGR: 166 dumpDec< sal_uInt32 >( "left" ); 167 dumpDec< sal_uInt32 >( "top" ); 168 dumpDec< sal_uInt32 >( "right" ); 169 dumpDec< sal_uInt32 >( "bottom" ); 170 break; 171 172 case DFF_ID_SPLITMENUCOLORS: 173 dumpDffSimpleColor( "fill-color" ); 174 dumpDffSimpleColor( "line-color" ); 175 dumpDffSimpleColor( "shadow-color" ); 176 dumpDffSimpleColor( "3d-color" ); 177 break; 178 } 179 } 180 181 void DffStreamObject::implDumpClientAnchor() 182 { 183 } 184 185 void DffStreamObject::constructDffObj() 186 { 187 mnInstVer = 0; 188 mnRealSize = 0; 189 if( SequenceRecordObjectBase::implIsValid() ) 190 { 191 maSimpleProps.insertFormats( cfg().getNameList( "DFFOPT-SIMPLE-PROPERTIES" ) ); 192 maComplexProps.insertFormats( cfg().getNameList( "DFFOPT-COMPLEX-PROPERTIES" ) ); 193 } 194 } 195 196 sal_uInt32 DffStreamObject::dumpDffSimpleColor( const String& rName ) 197 { 198 return dumpHex< sal_uInt32 >( rName, "DFF-SIMPLE-COLOR" ); 199 } 200 201 sal_uInt32 DffStreamObject::dumpDffColor( const String& rName ) 202 { 203 return dumpHex< sal_uInt32 >( rName, "DFF-COLOR" ); 204 } 205 206 namespace { 207 208 enum PropType { PROPTYPE_BINARY, PROPTYPE_STRING, PROPTYPE_BLIP, PROPTYPE_COLORARRAY }; 209 210 struct PropInfo 211 { 212 OUString maName; 213 PropType meType; 214 sal_uInt16 mnId; 215 sal_uInt32 mnSize; 216 inline explicit PropInfo( const OUString& rName, PropType eType, sal_uInt16 nId, sal_uInt32 nSize ) : 217 maName( rName ), meType( eType ), mnId( nId ), mnSize( nSize ) {} 218 }; 219 220 typedef ::std::vector< PropInfo > PropInfoVector; 221 222 } // namespace 223 224 void DffStreamObject::dumpDffOpt() 225 { 226 sal_uInt16 nPropCount = getInst(); 227 PropInfoVector aPropInfos; 228 mxOut->resetItemIndex(); 229 for( sal_uInt16 nPropIdx = 0; !mxStrm->isEof() && (nPropIdx < nPropCount); ++nPropIdx ) 230 { 231 sal_uInt16 nPropId = dumpDffOptPropHeader(); 232 sal_uInt16 nBaseId = nPropId & DFF_OPT_IDMASK; 233 sal_uInt32 nValue = mxStrm->readuInt32(); 234 235 IndentGuard aIndent( mxOut ); 236 if( getFlag( nPropId, DFF_OPT_COMPLEX ) ) 237 { 238 writeHexItem( "complex-size", nValue, "CONV-DEC" ); 239 String aName; 240 PropType eType = PROPTYPE_BINARY; 241 ItemFormatMap::const_iterator aIt = maComplexProps.find( nBaseId ); 242 if( aIt != maComplexProps.end() ) 243 { 244 const ItemFormat& rItemFmt = aIt->second; 245 aName = rItemFmt.maItemName; 246 if( rItemFmt.maListName.equalsAscii( "binary" ) ) 247 eType = PROPTYPE_BINARY; 248 else if( rItemFmt.maListName.equalsAscii( "string" ) ) 249 eType = PROPTYPE_STRING; 250 else if( rItemFmt.maListName.equalsAscii( "blip" ) ) 251 eType = PROPTYPE_BLIP; 252 else if( rItemFmt.maListName.equalsAscii( "colorarray" ) ) 253 eType = PROPTYPE_COLORARRAY; 254 } 255 aPropInfos.push_back( PropInfo( aName( "property-data" ), eType, nBaseId, nValue ) ); 256 } 257 else 258 { 259 ItemFormatMap::const_iterator aIt = maSimpleProps.find( nBaseId ); 260 if( aIt != maSimpleProps.end() ) 261 { 262 const ItemFormat& rItemFmt = aIt->second; 263 // flags always at end of block of 64 properties 264 if( (nBaseId & DFF_OPT_FLAGSMASK) == DFF_OPT_FLAGSMASK ) 265 { 266 FlagsList* pFlagsList = dynamic_cast< FlagsList* >( cfg().getNameList( rItemFmt.maListName ).get() ); 267 sal_Int64 nOldIgnoreFlags = 0; 268 if( pFlagsList ) 269 { 270 nOldIgnoreFlags = pFlagsList->getIgnoreFlags(); 271 pFlagsList->setIgnoreFlags( nOldIgnoreFlags | 0xFFFF0000 | ~(nValue >> 16) ); 272 } 273 writeValueItem( rItemFmt, nValue ); 274 if( pFlagsList ) 275 pFlagsList->setIgnoreFlags( nOldIgnoreFlags ); 276 } 277 else 278 writeValueItem( rItemFmt, nValue ); 279 } 280 else 281 writeHexItem( "value", nValue ); 282 } 283 } 284 285 mxOut->resetItemIndex(); 286 for( PropInfoVector::iterator aIt = aPropInfos.begin(), aEnd = aPropInfos.end(); !mxStrm->isEof() && (aIt != aEnd); ++aIt ) 287 { 288 mxOut->startMultiItems(); 289 writeEmptyItem( "#complex-data" ); 290 writeHexItem( "id", aIt->mnId, "DFFOPT-PROPERTY-NAMES" ); 291 mxOut->endMultiItems(); 292 IndentGuard aIndent( mxOut ); 293 switch( aIt->meType ) 294 { 295 case PROPTYPE_BINARY: 296 dumpBinary( aIt->maName, aIt->mnSize ); 297 break; 298 case PROPTYPE_STRING: 299 dumpUnicodeArray( aIt->maName, aIt->mnSize / 2, true ); 300 break; 301 case PROPTYPE_BLIP: 302 dumpBinary( aIt->maName, aIt->mnSize ); 303 break; 304 case PROPTYPE_COLORARRAY: 305 dumpBinary( aIt->maName, aIt->mnSize ); 306 break; 307 } 308 } 309 } 310 311 sal_uInt16 DffStreamObject::dumpDffOptPropHeader() 312 { 313 MultiItemsGuard aMultiGuard( mxOut ); 314 TableGuard aTabGuard( mxOut, 11 ); 315 writeEmptyItem( "#prop" ); 316 return dumpHex< sal_uInt16 >( "id", "DFFOPT-PROPERTY-ID" ); 317 } 318 319 // ============================================================================ 320 321 } // namespace dump 322 } // namespace oox 323 324 #endif 325