xref: /AOO42X/main/sw/source/filter/ww8/ww8par4.cxx (revision b1c5455db1639c48e26c568e4fa7ee78ca5d60ee)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 #include <doc.hxx>
27 #include "writerhelper.hxx"
28 #include <com/sun/star/embed/XClassifiedObject.hpp>
29 
30 #include <algorithm>
31 #include <functional>
32 #include <osl/endian.h>
33 #include <sot/storage.hxx>
34 #include <com/sun/star/drawing/XShape.hpp>
35 #include <hintids.hxx>
36 #include <svx/svdoole2.hxx>
37 #include <filter/msfilter/msdffimp.hxx>
38 #include <svx/unoapi.hxx>
39 #include <filter/msfilter/msocximex.hxx>
40 
41 #include <sot/exchange.hxx>
42 #include <swtypes.hxx>
43 #include <fmtanchr.hxx>
44 #include <fmtcntnt.hxx>
45 #include <dcontact.hxx>
46 #include <frmfmt.hxx>
47 #include <pam.hxx>
48 #include <ndgrf.hxx>
49 #include <docsh.hxx>            // fuer Ole-Node
50 #include <mdiexp.hxx>           // Progress
51 #include <redline.hxx>
52 #include <fltshell.hxx>
53 #include <unodraw.hxx>
54 #include <shellio.hxx>
55 #include <ndole.hxx>
56 
57 #include <svtools/filter.hxx>
58 
59 #include "ww8scan.hxx"
60 #include "ww8par.hxx"
61 #include "ww8par2.hxx"          // WWFlyPara::BoxUpWidth()
62 
63 struct OLE_MFP
64 {
65     sal_Int16 mm;       // 0x6  int
66     sal_Int16 xExt;     // 0x8  int in 1/100 mm
67     sal_Int16 yExt;     // 0xa  int in 1/100 mm
68     sal_Int16 hMF;      // 0xc  int
69 };
70 
71 using namespace ::com::sun::star;
72 
73 // SV_IMPL_OP_PTRARR_SORT(WW8AuthorInfos, WW8AuthorInfo_Ptr)
SV_IMPL_OP_PTRARR_SORT(WW8OleMaps,WW8OleMap_Ptr)74 SV_IMPL_OP_PTRARR_SORT(WW8OleMaps, WW8OleMap_Ptr)
75 
76 static bool SwWw8ReadScaling(long& rX, long& rY, SvStorageRef& rSrc1)
77 {
78     // Skalierungsfaktoren holen:
79     //      Informationen in PIC-Stream ( durch ausprobieren )
80     //      0x0  (l)cb
81     //      0x08 .. 0x0a Flags ??
82     //      0x08 Inh: 1 / 0
83     //      0x09 Inh: 0,8,0x18
84     //      0x0a Inh: immer 8, MAP_ANISOTROPIC ???
85     //      0x0b Inh: immer 0
86     //      0x0c, 0x10 Originalgroesse x,y in 1/100 mm
87     //      0x14, 0x16 Originalgroesse x,y in tw
88     //      0x2c, 0x30 Skalierung x,y in Promille
89     //      0x34, 0x38, 0x3c, 0x40 Crop Left, Top, Right, Bot in tw
90 
91     SvStorageStreamRef xSrc3 = rSrc1->OpenSotStream( CREATE_CONST_ASC( "\3PIC" ),
92         STREAM_STD_READ | STREAM_NOCREATE);
93     SvStorageStream* pS = xSrc3;
94     pS->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
95     pS->Seek( STREAM_SEEK_TO_END );
96 
97     ASSERT( pS->Tell() >=  76, "+OLE-PIC-Stream is shorter than 76 Byte" );
98 
99     sal_Int32 nOrgWidth,
100           nOrgHeight,
101           nScaleX,
102           nScaleY,
103           nCropLeft,
104           nCropTop,
105           nCropRight,
106           nCropBottom;
107     pS->Seek( 0x14 );
108     *pS >> nOrgWidth    // Original Size in 1/100 mm
109         >> nOrgHeight;
110     pS->Seek( 0x2c );
111     *pS >> nScaleX      // Scaling in Promille
112         >> nScaleY
113         >> nCropLeft    // Cropping in 1/100 mm
114         >> nCropTop
115         >> nCropRight
116         >> nCropBottom;
117 
118     rX = nOrgWidth  - nCropLeft - nCropRight;
119     rY = nOrgHeight - nCropTop  - nCropBottom;
120     if (10 > nScaleX || 65536 < nScaleX || 10 > nScaleY || 65536 < nScaleY)
121     {
122         ASSERT( !pS, "+OLE-Scalinginformation in PIC-Stream wrong" );
123         return false;
124     }
125     else
126     {
127         rX = (rX * nScaleX) / 1000;
128         rY = (rY * nScaleY) / 1000;
129     }
130     return true;
131 }
132 
SwWw6ReadMetaStream(GDIMetaFile & rWMF,OLE_MFP * pMfp,SvStorageRef & rSrc1)133 static bool SwWw6ReadMetaStream(GDIMetaFile& rWMF, OLE_MFP* pMfp,
134     SvStorageRef& rSrc1)
135 {
136     SvStorageStreamRef xSrc2 = rSrc1->OpenSotStream( CREATE_CONST_ASC("\3META"),
137         STREAM_STD_READ | STREAM_NOCREATE);
138     SvStorageStream* pSt = xSrc2;
139     pSt->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
140     sal_uLong nRead = pSt->Read( pMfp, sizeof(*pMfp ) );
141                                 // Mini-Placable-Header lesen
142     if (nRead != sizeof(*pMfp))
143         return false;
144 
145 #if defined  OSL_BIGENDIAN
146     pMfp->mm = SWAPSHORT( pMfp->mm );
147     pMfp->xExt = SWAPSHORT( pMfp->xExt );
148     pMfp->yExt = SWAPSHORT( pMfp->yExt );
149 #endif // OSL_BIGENDIAN
150 
151     if( pMfp->mm == 94 || pMfp->mm == 99 )
152     {
153         ASSERT( !pSt, "+OLE: Falscher Metafile-Typ" );
154         return false;
155     }
156     if( pMfp->mm != 8 )
157     {
158         ASSERT( !pSt, "+OLE: Falscher Metafile-Typ ( nicht Anisotropic )" );
159     }
160     if( !pMfp->xExt || !pMfp->yExt )
161     {
162         ASSERT( !pSt, "+OLE: Groesse von 0 ???" );
163         return false;
164     }
165     bool bOk = ReadWindowMetafile( *pSt, rWMF, NULL ) ? true : false;   // WMF lesen
166                     // *pSt >> aWMF  geht nicht ohne placable Header
167     if (!bOk || pSt->GetError() || rWMF.GetActionCount() == 0)
168     {
169         ASSERT( !pSt, "+OLE: Konnte Metafile nicht lesen" );
170         return false;
171     }
172 
173     rWMF.SetPrefMapMode( MapMode( MAP_100TH_MM ) );
174 
175 
176     // MetaFile auf neue Groesse skalieren und
177     // neue Groesse am MetaFile setzen
178     Size        aOldSiz( rWMF.GetPrefSize() );
179     Size        aNewSiz( pMfp->xExt, pMfp->yExt );
180     Fraction    aFracX( aNewSiz.Width(), aOldSiz.Width() );
181     Fraction    aFracY( aNewSiz.Height(), aOldSiz.Height() );
182 
183     rWMF.Scale( aFracX, aFracY );
184     rWMF.SetPrefSize( aNewSiz );
185 
186     return true;
187 }
188 
SwWw6ReadMacPICTStream(Graphic & rGraph,SvStorageRef & rSrc1)189 static bool SwWw6ReadMacPICTStream(Graphic& rGraph, SvStorageRef& rSrc1)
190 {
191     // 03-META-Stream nicht da. Vielleicht ein 03-PICT ?
192     SvStorageStreamRef xSrc4 = rSrc1->OpenSotStream( CREATE_CONST_ASC( "\3PICT" ));
193     SvStorageStream* pStp = xSrc4;
194     pStp->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
195     sal_uInt8 aTestA[10];        // Ist der 01Ole-Stream ueberhaupt vorhanden
196     sal_uLong nReadTst = pStp->Read( aTestA, sizeof( aTestA ) );
197     if (nReadTst != sizeof(aTestA))
198         return false;
199 
200     pStp->Seek( STREAM_SEEK_TO_BEGIN );
201 
202 #ifdef DEBUGDUMP
203     SvStream *pDbg = sw::hack::CreateDebuggingStream(CREATE_CONST_ASC(".pct"));
204     pDbg->Seek(0x200); //Prepend extra 0x200 of zeros to make this a valid PICT
205     sw::hack::DumpStream(*pStp, *pDbg);
206     delete pDbg;
207 #endif
208 
209     // Mac-Pict steht im 03PICT-StorageStream allerdings ohne die ersten 512
210     // Bytes, die bei einem MAC-PICT egal sind ( werden nicht ausgewertet )
211     return SwWW8ImplReader::GetPictGrafFromStream(rGraph, *pStp);
212 }
213 
InsertOle(SdrOle2Obj & rObject,const SfxItemSet & rFlySet,const SfxItemSet & rGrfSet)214 SwFlyFrmFmt* SwWW8ImplReader::InsertOle(SdrOle2Obj &rObject,
215     const SfxItemSet &rFlySet, const SfxItemSet &rGrfSet)
216 {
217     SfxObjectShell *pPersist = rDoc.GetPersist();
218     ASSERT(pPersist, "No persist, cannot insert objects correctly");
219     if (!pPersist)
220         return 0;
221 
222     SwFlyFrmFmt *pRet = 0;
223 
224     SfxItemSet *pMathFlySet = 0;
225     uno::Reference < embed::XClassifiedObject > xClass( rObject.GetObjRef(), uno::UNO_QUERY );
226     if( xClass.is() )
227     {
228         SvGlobalName aClassName( xClass->getClassID() );
229         if (SotExchange::IsMath(aClassName))
230         {
231             /*
232             StarMath sets it own fixed size, so its counter productive to use the
233             size word says it is. i.e. Don't attempt to override its size.
234             */
235             pMathFlySet = new SfxItemSet(rFlySet);
236             pMathFlySet->ClearItem(RES_FRM_SIZE);
237         }
238     }
239 
240     /*
241     Take complete responsibility of the object away from SdrOle2Obj and to
242     me here locally. This utility class now owns the object.
243     */
244 
245     // TODO/MBA: is the object inserted multiple times here? Testing!
246     // And is it a problem that we now use the same naming scheme as in the other apps?
247     sw::hack::DrawingOLEAdaptor aOLEObj(rObject, *pPersist);
248     ::rtl::OUString sNewName;
249     bool bSuccess = aOLEObj.TransferToDoc(sNewName);
250 
251     ASSERT(bSuccess, "Insert OLE failed");
252     if (bSuccess)
253     {
254         const SfxItemSet *pFlySet = pMathFlySet ? pMathFlySet : &rFlySet;
255         pRet = rDoc.InsertOLE(*pPaM, sNewName, rObject.GetAspect(), pFlySet, &rGrfSet, 0);
256     }
257     delete pMathFlySet;
258     return pRet;
259 }
260 
ImportOle(const Graphic * pGrf,const SfxItemSet * pFlySet,const SfxItemSet * pGrfSet,const Rectangle & aVisArea)261 SwFrmFmt* SwWW8ImplReader::ImportOle(const Graphic* pGrf,
262     const SfxItemSet* pFlySet, const SfxItemSet *pGrfSet, const Rectangle& aVisArea )
263 {
264     ::SetProgressState(nProgress, mpDocShell);     // Update
265     SwFrmFmt* pFmt = 0;
266 
267     GrafikCtor();
268 
269     Graphic aGraph;
270     SdrObject* pRet = ImportOleBase(aGraph, pGrf, pFlySet, aVisArea );
271 
272     // create flyset
273     SfxItemSet* pTempSet = 0;
274     if( !pFlySet )
275     {
276         pTempSet = new SfxItemSet( rDoc.GetAttrPool(), RES_FRMATR_BEGIN,
277             RES_FRMATR_END-1);
278 
279         pFlySet = pTempSet;
280 
281         // Abstand/Umrandung raus
282         if (!mbNewDoc)
283             Reader::ResetFrmFmtAttrs( *pTempSet );
284 
285         SwFmtAnchor aAnchor( FLY_AS_CHAR );
286         aAnchor.SetAnchor( pPaM->GetPoint() );
287         pTempSet->Put( aAnchor );
288 
289         const Size aSizeTwip = OutputDevice::LogicToLogic(
290             aGraph.GetPrefSize(), aGraph.GetPrefMapMode(), MAP_TWIP );
291 
292         pTempSet->Put( SwFmtFrmSize( ATT_FIX_SIZE, aSizeTwip.Width(),
293             aSizeTwip.Height() ) );
294         pTempSet->Put( SwFmtVertOrient( 0, text::VertOrientation::TOP, text::RelOrientation::FRAME ));
295 
296         if( pSFlyPara )
297         {
298             // OLE im Rahmen ?  ok, Rahmen auf Bildgroesse vergroessern (
299             // nur wenn Auto-Breite )
300             pSFlyPara->BoxUpWidth( aSizeTwip.Width() );
301         }
302     }
303 
304     if (pRet)       // Ole-Object wurde eingefuegt
305     {
306         if (pRet->ISA(SdrOle2Obj))
307         {
308             pFmt = InsertOle(*((SdrOle2Obj*)pRet), *pFlySet, *pGrfSet);
309             SdrObject::Free( pRet );        // das brauchen wir nicht mehr
310         }
311         else
312             pFmt = rDoc.InsertDrawObj(*pPaM, *pRet, *pFlySet );
313     }
314     else if (
315                 GRAPHIC_GDIMETAFILE == aGraph.GetType() ||
316                 GRAPHIC_BITMAP == aGraph.GetType()
317             )
318     {
319         pFmt = rDoc.Insert(*pPaM, aEmptyStr, aEmptyStr, &aGraph, pFlySet,
320             pGrfSet, NULL);
321     }
322     delete pTempSet;
323     return pFmt;
324 }
325 
ImportOleWMF(SvStorageRef xSrc1,GDIMetaFile & rWMF,long & rX,long & rY)326 bool SwWW8ImplReader::ImportOleWMF(SvStorageRef xSrc1,GDIMetaFile &rWMF,
327     long &rX,long &rY)
328 {
329     bool bOk = false;
330     OLE_MFP aMfp;
331     if( SwWw6ReadMetaStream( rWMF, &aMfp, xSrc1 ) )
332     {
333         /*
334         take scaling factor as found in PIC and apply it to graphic.
335         */
336         SwWw8ReadScaling( rX, rY, xSrc1 );
337         Size aFinalSize, aOrigSize;
338         aFinalSize.Width() = rX;
339         aFinalSize.Height() = rY;
340         aFinalSize = OutputDevice::LogicToLogic(
341             aFinalSize, MAP_TWIP, rWMF.GetPrefMapMode() );
342         aOrigSize = rWMF.GetPrefSize();
343         Fraction aScaleX(aFinalSize.Width(),aOrigSize.Width());
344         Fraction aScaleY(aFinalSize.Height(),aOrigSize.Height());
345         rWMF.Scale( aScaleX, aScaleY );
346         bOk = true;
347     }
348     return bOk;
349 }
350 
ImportOleBase(Graphic & rGraph,const Graphic * pGrf,const SfxItemSet * pFlySet,const Rectangle & aVisArea)351 SdrObject* SwWW8ImplReader::ImportOleBase( Graphic& rGraph,
352     const Graphic* pGrf, const SfxItemSet* pFlySet, const Rectangle& aVisArea )
353 {
354     SdrObject* pRet = 0;
355     ASSERT( pStg, "ohne storage geht hier fast gar nichts!" );
356 
357     ::SetProgressState( nProgress, rDoc.GetDocShell() );     // Update
358 
359     long nX=0, nY=0;                // nX, nY is graphic size
360     bool bOleOk = true;
361 
362     String aSrcStgName = '_';
363     // ergibt Name "_4711"
364     aSrcStgName += String::CreateFromInt32( nObjLocFc );
365 
366     SvStorageRef xSrc0 = pStg->OpenSotStorage(CREATE_CONST_ASC(SL::aObjectPool));
367     SvStorageRef xSrc1 = xSrc0->OpenSotStorage( aSrcStgName,
368             STREAM_READWRITE| STREAM_SHARE_DENYALL );
369 
370 
371     if (pGrf)
372     {
373         rGraph = *pGrf;
374         const Size aSizeTwip = OutputDevice::LogicToLogic(
375             rGraph.GetPrefSize(), rGraph.GetPrefMapMode(), MAP_TWIP );
376         nX = aSizeTwip.Width();
377         nY = aSizeTwip.Height();
378     }
379     else
380     {
381         GDIMetaFile aWMF;
382 
383         if (ImportOleWMF(xSrc1,aWMF,nX,nY))
384             rGraph = Graphic( aWMF );
385         else if( SwWw6ReadMacPICTStream( rGraph, xSrc1 ) )
386         {
387             // 03-META-Stream nicht da. Vielleicht ein 03-PICT ?
388             const Size aSizeTwip = OutputDevice::LogicToLogic(
389                 rGraph.GetPrefSize(), rGraph.GetPrefMapMode(), MAP_TWIP );
390             nX = aSizeTwip.Width();
391             nY = aSizeTwip.Height();
392             // PICT: kein WMF da -> Grafik statt OLE
393             bOleOk = false;
394         }
395     }       // StorageStreams wieder zu
396 
397 
398     Rectangle aRect(0, 0, nX, nY);
399 
400     if (pFlySet)
401     {
402         if (const SwFmtFrmSize* pSize =
403             (const SwFmtFrmSize*)pFlySet->GetItem(RES_FRM_SIZE, false))
404         {
405             aRect.SetSize(pSize->GetSize());
406         }
407     }
408 
409     if (!(bIsHeader || bIsFooter))
410     {
411         //Can't put them in headers/footers :-(
412         uno::Reference< drawing::XShape > xRef;
413         ASSERT(pFormImpl, "Impossible");
414         if (pFormImpl && pFormImpl->ReadOCXStream(xSrc1, &xRef, false))
415         {
416             pRet = GetSdrObjectFromXShape(xRef);
417             ASSERT(pRet, "Impossible");
418             if (pRet)
419                 pRet->SetLogicRect(aRect);
420             return pRet;
421         }
422     }
423 
424     if (GRAPHIC_GDIMETAFILE == rGraph.GetType() ||
425         GRAPHIC_BITMAP == rGraph.GetType())
426     {
427         ::SetProgressState(nProgress, mpDocShell);     // Update
428 
429         if (bOleOk)
430         {
431             sal_uLong nOldPos = pDataStream->Tell();
432             pDataStream->Seek(STREAM_SEEK_TO_END);
433             SvStream *pTmpData = 0;
434             if (nObjLocFc < pDataStream->Tell())
435             {
436                 pTmpData = pDataStream;
437                 pTmpData->Seek( nObjLocFc );
438             }
439 
440             sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT;
441 
442             {
443                 SvStorageStreamRef xObjInfoSrc = xSrc1->OpenSotStream( CREATE_CONST_ASC( "\3ObjInfo" ),
444                     STREAM_STD_READ | STREAM_NOCREATE );
445                 if ( xObjInfoSrc.Is() && !xObjInfoSrc->GetError() )
446                 {
447                     sal_uInt8 nByte = 0;
448                     *xObjInfoSrc >> nByte;
449                     if ( ( nByte >> 4 ) & embed::Aspects::MSOLE_ICON )
450                         nAspect = embed::Aspects::MSOLE_ICON;
451                 }
452             }
453 
454             ErrCode nError = ERRCODE_NONE;
455             pRet = SvxMSDffManager::CreateSdrOLEFromStorage(
456                 aSrcStgName, xSrc0, mpDocShell->GetStorage(), rGraph, aRect, aVisArea, pTmpData, nError,
457                 SwMSDffManager::GetFilterFlags(), nAspect );
458             pDataStream->Seek( nOldPos );
459         }
460     }
461     return pRet;
462 }
463 
ReadRevMarkAuthorStrTabl(SvStream & rStrm,sal_Int32 nTblPos,sal_Int32 nTblSiz,SwDoc & rDocOut)464 void SwWW8ImplReader::ReadRevMarkAuthorStrTabl( SvStream& rStrm,
465     sal_Int32 nTblPos, sal_Int32 nTblSiz, SwDoc& rDocOut )
466 {
467     ::std::vector<String> aAuthorNames;
468     WW8ReadSTTBF( !bVer67, rStrm, nTblPos, nTblSiz, bVer67 ? 2 : 0,
469         eStructCharSet, aAuthorNames );
470 
471     sal_uInt16 nCount = static_cast< sal_uInt16 >(aAuthorNames.size());
472     for( sal_uInt16 nAuthor = 0; nAuthor < nCount; ++nAuthor )
473     {
474         // Store author in doc
475         sal_uInt16 nSWId = rDocOut.InsertRedlineAuthor(aAuthorNames[nAuthor]);
476         // Store matchpair
477         if( !pAuthorInfos )
478             pAuthorInfos = new sw::util::AuthorInfos;
479         sw::util::AuthorInfo* pAutorInfo = new sw::util::AuthorInfo( nAuthor, nSWId );
480         if( 0 == pAuthorInfos->Insert( pAutorInfo ) )
481             delete pAutorInfo;
482     }
483 }
484 
485 /*
486    Revision Marks ( == Redlining )
487 */
488 // insert or delete content (change char attributes resp.)
Read_CRevisionMark(RedlineType_t eType,const sal_uInt8 * pData,short nLen)489 void SwWW8ImplReader::Read_CRevisionMark(RedlineType_t eType,
490     const sal_uInt8* pData, short nLen )
491 {
492     // there *must* be a SprmCIbstRMark[Del] and a SprmCDttmRMark[Del]
493     // pointing to the very same char position as our SprmCFRMark[Del]
494     if (!pPlcxMan)
495         return;
496     const sal_uInt8* pSprmCIbstRMark;
497     const sal_uInt8* pSprmCDttmRMark;
498     if( nsRedlineType_t::REDLINE_FORMAT == eType )
499     {
500         pSprmCIbstRMark = pData+1;
501         pSprmCDttmRMark = pData+3;
502     }
503     else
504     {
505         /*
506          #101578#
507          It is possible to have a number of date stamps for the created time
508          of the change, (possibly a word bug) so we must use the "get a full
509          list" variant of HasCharSprm and take the last one as the true one.
510         */
511         std::vector<const sal_uInt8 *> aResult;
512         bool bIns = (nsRedlineType_t::REDLINE_INSERT == eType);
513         if( bVer67 )
514         {
515             pPlcxMan->HasCharSprm(69, aResult);
516             pSprmCIbstRMark = aResult.empty() ? 0 : aResult.back();
517             aResult.clear();
518             pPlcxMan->HasCharSprm(70, aResult);
519             pSprmCDttmRMark = aResult.empty() ? 0 : aResult.back();
520         }
521         else
522         {
523             pPlcxMan->HasCharSprm( bIns ? 0x4804 : 0x4863, aResult);
524             pSprmCIbstRMark = aResult.empty() ? 0 : aResult.back();
525             aResult.clear();
526             pPlcxMan->HasCharSprm( bIns ? 0x6805 : 0x6864, aResult);
527             pSprmCDttmRMark = aResult.empty() ? 0 : aResult.back();
528         }
529     }
530 
531     if (nLen < 0)
532         mpRedlineStack->close(*pPaM->GetPoint(), eType, pTableDesc );
533     else
534     {
535         // start of new revision mark, if not there default to first entry
536         sal_uInt16 nWWAutNo = pSprmCIbstRMark ? SVBT16ToShort( pSprmCIbstRMark ) : 0;
537         sw::util::AuthorInfo aEntry(nWWAutNo);
538         sal_uInt16 nPos;
539         if (pAuthorInfos && pAuthorInfos->Seek_Entry(&aEntry, &nPos))
540         {
541             if (const sw::util::AuthorInfo* pAuthor = pAuthorInfos->GetObject(nPos))
542             {
543                 sal_uInt32 nWWDate = pSprmCDttmRMark ? SVBT32ToUInt32(pSprmCDttmRMark): 0;
544                 DateTime aStamp(sw::ms::DTTM2DateTime(nWWDate));
545                 sal_uInt16 nAutorNo = pAuthor->nOurId;
546                 SwFltRedline  aNewAttr(eType, nAutorNo, aStamp);
547 
548                 NewAttr(aNewAttr);
549             }
550         }
551     }
552 }
553 
554 // insert new content
Read_CFRMark(sal_uInt16,const sal_uInt8 * pData,short nLen)555 void SwWW8ImplReader::Read_CFRMark(sal_uInt16 , const sal_uInt8* pData, short nLen)
556 {
557     Read_CRevisionMark( nsRedlineType_t::REDLINE_INSERT, pData, nLen );
558 }
559 
560 // delete old content
Read_CFRMarkDel(sal_uInt16,const sal_uInt8 * pData,short nLen)561 void SwWW8ImplReader::Read_CFRMarkDel(sal_uInt16 , const sal_uInt8* pData, short nLen)
562 {
563     Read_CRevisionMark( nsRedlineType_t::REDLINE_DELETE, pData, nLen );
564 }
565 
566 // change properties of content ( == char formatting)
Read_CPropRMark(sal_uInt16,const sal_uInt8 * pData,short nLen)567 void SwWW8ImplReader::Read_CPropRMark(sal_uInt16 , const sal_uInt8* pData, short nLen)
568 {
569     // complex (len is always 7)
570     // 1 byte  - chp.fPropRMark
571     // 2 bytes - chp.ibstPropRMark
572     // 4 bytes - chp.dttmPropRMark;
573     Read_CRevisionMark( nsRedlineType_t::REDLINE_FORMAT, pData, nLen );
574 }
575 
576 /* vi:set tabstop=4 shiftwidth=4 expandtab: */
577