| /************************************************************** |
| * |
| * 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. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sw.hxx" |
| /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */ |
| #include <doc.hxx> |
| #include "writerhelper.hxx" |
| #include <com/sun/star/embed/XClassifiedObject.hpp> |
| |
| #include <algorithm> |
| #include <functional> |
| #include <osl/endian.h> |
| #include <sot/storage.hxx> |
| #include <com/sun/star/drawing/XShape.hpp> |
| #include <hintids.hxx> |
| #include <svx/svdoole2.hxx> |
| #include <filter/msfilter/msdffimp.hxx> |
| #include <svx/unoapi.hxx> |
| #include <filter/msfilter/msocximex.hxx> |
| |
| #include <sot/exchange.hxx> |
| #include <swtypes.hxx> |
| #include <fmtanchr.hxx> |
| #include <fmtcntnt.hxx> |
| #include <dcontact.hxx> |
| #include <frmfmt.hxx> |
| #include <pam.hxx> |
| #include <ndgrf.hxx> |
| #include <docsh.hxx> // fuer Ole-Node |
| #include <mdiexp.hxx> // Progress |
| #include <redline.hxx> |
| #include <fltshell.hxx> |
| #include <unodraw.hxx> |
| #include <shellio.hxx> |
| #include <ndole.hxx> |
| |
| #include <svtools/filter.hxx> |
| |
| #include "ww8scan.hxx" |
| #include "ww8par.hxx" |
| #include "ww8par2.hxx" // WWFlyPara::BoxUpWidth() |
| |
| struct OLE_MFP |
| { |
| sal_Int16 mm; // 0x6 int |
| sal_Int16 xExt; // 0x8 int in 1/100 mm |
| sal_Int16 yExt; // 0xa int in 1/100 mm |
| sal_Int16 hMF; // 0xc int |
| }; |
| |
| using namespace ::com::sun::star; |
| |
| // SV_IMPL_OP_PTRARR_SORT(WW8AuthorInfos, WW8AuthorInfo_Ptr) |
| SV_IMPL_OP_PTRARR_SORT(WW8OleMaps, WW8OleMap_Ptr) |
| |
| static bool SwWw8ReadScaling(long& rX, long& rY, SvStorageRef& rSrc1) |
| { |
| // Skalierungsfaktoren holen: |
| // Informationen in PIC-Stream ( durch ausprobieren ) |
| // 0x0 (l)cb |
| // 0x08 .. 0x0a Flags ?? |
| // 0x08 Inh: 1 / 0 |
| // 0x09 Inh: 0,8,0x18 |
| // 0x0a Inh: immer 8, MAP_ANISOTROPIC ??? |
| // 0x0b Inh: immer 0 |
| // 0x0c, 0x10 Originalgroesse x,y in 1/100 mm |
| // 0x14, 0x16 Originalgroesse x,y in tw |
| // 0x2c, 0x30 Skalierung x,y in Promille |
| // 0x34, 0x38, 0x3c, 0x40 Crop Left, Top, Right, Bot in tw |
| |
| SvStorageStreamRef xSrc3 = rSrc1->OpenSotStream( CREATE_CONST_ASC( "\3PIC" ), |
| STREAM_STD_READ | STREAM_NOCREATE); |
| SvStorageStream* pS = xSrc3; |
| pS->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); |
| pS->Seek( STREAM_SEEK_TO_END ); |
| |
| ASSERT( pS->Tell() >= 76, "+OLE-PIC-Stream is shorter than 76 Byte" ); |
| |
| sal_Int32 nOrgWidth, |
| nOrgHeight, |
| nScaleX, |
| nScaleY, |
| nCropLeft, |
| nCropTop, |
| nCropRight, |
| nCropBottom; |
| pS->Seek( 0x14 ); |
| *pS >> nOrgWidth // Original Size in 1/100 mm |
| >> nOrgHeight; |
| pS->Seek( 0x2c ); |
| *pS >> nScaleX // Scaling in Promille |
| >> nScaleY |
| >> nCropLeft // Cropping in 1/100 mm |
| >> nCropTop |
| >> nCropRight |
| >> nCropBottom; |
| |
| rX = nOrgWidth - nCropLeft - nCropRight; |
| rY = nOrgHeight - nCropTop - nCropBottom; |
| if (10 > nScaleX || 65536 < nScaleX || 10 > nScaleY || 65536 < nScaleY) |
| { |
| ASSERT( !pS, "+OLE-Scalinginformation in PIC-Stream wrong" ); |
| return false; |
| } |
| else |
| { |
| rX = (rX * nScaleX) / 1000; |
| rY = (rY * nScaleY) / 1000; |
| } |
| return true; |
| } |
| |
| static bool SwWw6ReadMetaStream(GDIMetaFile& rWMF, OLE_MFP* pMfp, |
| SvStorageRef& rSrc1) |
| { |
| SvStorageStreamRef xSrc2 = rSrc1->OpenSotStream( CREATE_CONST_ASC("\3META"), |
| STREAM_STD_READ | STREAM_NOCREATE); |
| SvStorageStream* pSt = xSrc2; |
| pSt->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); |
| sal_uLong nRead = pSt->Read( pMfp, sizeof(*pMfp ) ); |
| // Mini-Placable-Header lesen |
| if (nRead != sizeof(*pMfp)) |
| return false; |
| |
| #if defined OSL_BIGENDIAN |
| pMfp->mm = SWAPSHORT( pMfp->mm ); |
| pMfp->xExt = SWAPSHORT( pMfp->xExt ); |
| pMfp->yExt = SWAPSHORT( pMfp->yExt ); |
| #endif // OSL_BIGENDIAN |
| |
| if( pMfp->mm == 94 || pMfp->mm == 99 ) |
| { |
| ASSERT( !pSt, "+OLE: Falscher Metafile-Typ" ); |
| return false; |
| } |
| if( pMfp->mm != 8 ) |
| { |
| ASSERT( !pSt, "+OLE: Falscher Metafile-Typ ( nicht Anisotropic )" ); |
| } |
| if( !pMfp->xExt || !pMfp->yExt ) |
| { |
| ASSERT( !pSt, "+OLE: Groesse von 0 ???" ); |
| return false; |
| } |
| bool bOk = ReadWindowMetafile( *pSt, rWMF, NULL ) ? true : false; // WMF lesen |
| // *pSt >> aWMF geht nicht ohne placable Header |
| if (!bOk || pSt->GetError() || rWMF.GetActionCount() == 0) |
| { |
| ASSERT( !pSt, "+OLE: Konnte Metafile nicht lesen" ); |
| return false; |
| } |
| |
| rWMF.SetPrefMapMode( MapMode( MAP_100TH_MM ) ); |
| |
| |
| // MetaFile auf neue Groesse skalieren und |
| // neue Groesse am MetaFile setzen |
| Size aOldSiz( rWMF.GetPrefSize() ); |
| Size aNewSiz( pMfp->xExt, pMfp->yExt ); |
| Fraction aFracX( aNewSiz.Width(), aOldSiz.Width() ); |
| Fraction aFracY( aNewSiz.Height(), aOldSiz.Height() ); |
| |
| rWMF.Scale( aFracX, aFracY ); |
| rWMF.SetPrefSize( aNewSiz ); |
| |
| return true; |
| } |
| |
| static bool SwWw6ReadMacPICTStream(Graphic& rGraph, SvStorageRef& rSrc1) |
| { |
| // 03-META-Stream nicht da. Vielleicht ein 03-PICT ? |
| SvStorageStreamRef xSrc4 = rSrc1->OpenSotStream( CREATE_CONST_ASC( "\3PICT" )); |
| SvStorageStream* pStp = xSrc4; |
| pStp->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); |
| sal_uInt8 aTestA[10]; // Ist der 01Ole-Stream ueberhaupt vorhanden |
| sal_uLong nReadTst = pStp->Read( aTestA, sizeof( aTestA ) ); |
| if (nReadTst != sizeof(aTestA)) |
| return false; |
| |
| pStp->Seek( STREAM_SEEK_TO_BEGIN ); |
| |
| #ifdef DEBUGDUMP |
| SvStream *pDbg = sw::hack::CreateDebuggingStream(CREATE_CONST_ASC(".pct")); |
| pDbg->Seek(0x200); //Prepend extra 0x200 of zeros to make this a valid PICT |
| sw::hack::DumpStream(*pStp, *pDbg); |
| delete pDbg; |
| #endif |
| |
| // Mac-Pict steht im 03PICT-StorageStream allerdings ohne die ersten 512 |
| // Bytes, die bei einem MAC-PICT egal sind ( werden nicht ausgewertet ) |
| return SwWW8ImplReader::GetPictGrafFromStream(rGraph, *pStp); |
| } |
| |
| SwFlyFrmFmt* SwWW8ImplReader::InsertOle(SdrOle2Obj &rObject, |
| const SfxItemSet &rFlySet, const SfxItemSet &rGrfSet) |
| { |
| SfxObjectShell *pPersist = rDoc.GetPersist(); |
| ASSERT(pPersist, "No persist, cannot insert objects correctly"); |
| if (!pPersist) |
| return 0; |
| |
| SwFlyFrmFmt *pRet = 0; |
| |
| SfxItemSet *pMathFlySet = 0; |
| uno::Reference < embed::XClassifiedObject > xClass( rObject.GetObjRef(), uno::UNO_QUERY ); |
| if( xClass.is() ) |
| { |
| SvGlobalName aClassName( xClass->getClassID() ); |
| if (SotExchange::IsMath(aClassName)) |
| { |
| /* |
| StarMath sets it own fixed size, so its counter productive to use the |
| size word says it is. i.e. Don't attempt to override its size. |
| */ |
| pMathFlySet = new SfxItemSet(rFlySet); |
| pMathFlySet->ClearItem(RES_FRM_SIZE); |
| } |
| } |
| |
| /* |
| Take complete responsibility of the object away from SdrOle2Obj and to |
| me here locally. This utility class now owns the object. |
| */ |
| |
| // TODO/MBA: is the object inserted multiple times here? Testing! |
| // And is it a problem that we now use the same naming scheme as in the other apps? |
| sw::hack::DrawingOLEAdaptor aOLEObj(rObject, *pPersist); |
| ::rtl::OUString sNewName; |
| bool bSuccess = aOLEObj.TransferToDoc(sNewName); |
| |
| ASSERT(bSuccess, "Insert OLE failed"); |
| if (bSuccess) |
| { |
| const SfxItemSet *pFlySet = pMathFlySet ? pMathFlySet : &rFlySet; |
| pRet = rDoc.InsertOLE(*pPaM, sNewName, rObject.GetAspect(), pFlySet, &rGrfSet, 0); |
| } |
| delete pMathFlySet; |
| return pRet; |
| } |
| |
| SwFrmFmt* SwWW8ImplReader::ImportOle(const Graphic* pGrf, |
| const SfxItemSet* pFlySet, const SfxItemSet *pGrfSet, const Rectangle& aVisArea ) |
| { |
| ::SetProgressState(nProgress, mpDocShell); // Update |
| SwFrmFmt* pFmt = 0; |
| |
| GrafikCtor(); |
| |
| Graphic aGraph; |
| SdrObject* pRet = ImportOleBase(aGraph, pGrf, pFlySet, aVisArea ); |
| |
| // create flyset |
| SfxItemSet* pTempSet = 0; |
| if( !pFlySet ) |
| { |
| pTempSet = new SfxItemSet( rDoc.GetAttrPool(), RES_FRMATR_BEGIN, |
| RES_FRMATR_END-1); |
| |
| pFlySet = pTempSet; |
| |
| // Abstand/Umrandung raus |
| if (!mbNewDoc) |
| Reader::ResetFrmFmtAttrs( *pTempSet ); |
| |
| SwFmtAnchor aAnchor( FLY_AS_CHAR ); |
| aAnchor.SetAnchor( pPaM->GetPoint() ); |
| pTempSet->Put( aAnchor ); |
| |
| const Size aSizeTwip = OutputDevice::LogicToLogic( |
| aGraph.GetPrefSize(), aGraph.GetPrefMapMode(), MAP_TWIP ); |
| |
| pTempSet->Put( SwFmtFrmSize( ATT_FIX_SIZE, aSizeTwip.Width(), |
| aSizeTwip.Height() ) ); |
| pTempSet->Put( SwFmtVertOrient( 0, text::VertOrientation::TOP, text::RelOrientation::FRAME )); |
| |
| if( pSFlyPara ) |
| { |
| // OLE im Rahmen ? ok, Rahmen auf Bildgroesse vergroessern ( |
| // nur wenn Auto-Breite ) |
| pSFlyPara->BoxUpWidth( aSizeTwip.Width() ); |
| } |
| } |
| |
| if (pRet) // Ole-Object wurde eingefuegt |
| { |
| if (pRet->ISA(SdrOle2Obj)) |
| { |
| pFmt = InsertOle(*((SdrOle2Obj*)pRet), *pFlySet, *pGrfSet); |
| SdrObject::Free( pRet ); // das brauchen wir nicht mehr |
| } |
| else |
| pFmt = rDoc.InsertDrawObj(*pPaM, *pRet, *pFlySet ); |
| } |
| else if ( |
| GRAPHIC_GDIMETAFILE == aGraph.GetType() || |
| GRAPHIC_BITMAP == aGraph.GetType() |
| ) |
| { |
| pFmt = rDoc.Insert(*pPaM, aEmptyStr, aEmptyStr, &aGraph, pFlySet, |
| pGrfSet, NULL); |
| } |
| delete pTempSet; |
| return pFmt; |
| } |
| |
| bool SwWW8ImplReader::ImportOleWMF(SvStorageRef xSrc1,GDIMetaFile &rWMF, |
| long &rX,long &rY) |
| { |
| bool bOk = false; |
| OLE_MFP aMfp; |
| if( SwWw6ReadMetaStream( rWMF, &aMfp, xSrc1 ) ) |
| { |
| /* |
| take scaling factor as found in PIC and apply it to graphic. |
| */ |
| SwWw8ReadScaling( rX, rY, xSrc1 ); |
| Size aFinalSize, aOrigSize; |
| aFinalSize.Width() = rX; |
| aFinalSize.Height() = rY; |
| aFinalSize = OutputDevice::LogicToLogic( |
| aFinalSize, MAP_TWIP, rWMF.GetPrefMapMode() ); |
| aOrigSize = rWMF.GetPrefSize(); |
| Fraction aScaleX(aFinalSize.Width(),aOrigSize.Width()); |
| Fraction aScaleY(aFinalSize.Height(),aOrigSize.Height()); |
| rWMF.Scale( aScaleX, aScaleY ); |
| bOk = true; |
| } |
| return bOk; |
| } |
| |
| SdrObject* SwWW8ImplReader::ImportOleBase( Graphic& rGraph, |
| const Graphic* pGrf, const SfxItemSet* pFlySet, const Rectangle& aVisArea ) |
| { |
| SdrObject* pRet = 0; |
| ASSERT( pStg, "ohne storage geht hier fast gar nichts!" ); |
| |
| ::SetProgressState( nProgress, rDoc.GetDocShell() ); // Update |
| |
| long nX=0, nY=0; // nX, nY is graphic size |
| bool bOleOk = true; |
| |
| String aSrcStgName = '_'; |
| // ergibt Name "_4711" |
| aSrcStgName += String::CreateFromInt32( nObjLocFc ); |
| |
| SvStorageRef xSrc0 = pStg->OpenSotStorage(CREATE_CONST_ASC(SL::aObjectPool)); |
| SvStorageRef xSrc1 = xSrc0->OpenSotStorage( aSrcStgName, |
| STREAM_READWRITE| STREAM_SHARE_DENYALL ); |
| |
| |
| if (pGrf) |
| { |
| rGraph = *pGrf; |
| const Size aSizeTwip = OutputDevice::LogicToLogic( |
| rGraph.GetPrefSize(), rGraph.GetPrefMapMode(), MAP_TWIP ); |
| nX = aSizeTwip.Width(); |
| nY = aSizeTwip.Height(); |
| } |
| else |
| { |
| GDIMetaFile aWMF; |
| |
| if (ImportOleWMF(xSrc1,aWMF,nX,nY)) |
| rGraph = Graphic( aWMF ); |
| else if( SwWw6ReadMacPICTStream( rGraph, xSrc1 ) ) |
| { |
| // 03-META-Stream nicht da. Vielleicht ein 03-PICT ? |
| const Size aSizeTwip = OutputDevice::LogicToLogic( |
| rGraph.GetPrefSize(), rGraph.GetPrefMapMode(), MAP_TWIP ); |
| nX = aSizeTwip.Width(); |
| nY = aSizeTwip.Height(); |
| // PICT: kein WMF da -> Grafik statt OLE |
| bOleOk = false; |
| } |
| } // StorageStreams wieder zu |
| |
| |
| Rectangle aRect(0, 0, nX, nY); |
| |
| if (pFlySet) |
| { |
| if (const SwFmtFrmSize* pSize = |
| (const SwFmtFrmSize*)pFlySet->GetItem(RES_FRM_SIZE, false)) |
| { |
| aRect.SetSize(pSize->GetSize()); |
| } |
| } |
| |
| if (!(bIsHeader || bIsFooter)) |
| { |
| //Can't put them in headers/footers :-( |
| uno::Reference< drawing::XShape > xRef; |
| ASSERT(pFormImpl, "Impossible"); |
| if (pFormImpl && pFormImpl->ReadOCXStream(xSrc1, &xRef, false)) |
| { |
| pRet = GetSdrObjectFromXShape(xRef); |
| ASSERT(pRet, "Impossible"); |
| if (pRet) |
| pRet->SetLogicRect(aRect); |
| return pRet; |
| } |
| } |
| |
| if (GRAPHIC_GDIMETAFILE == rGraph.GetType() || |
| GRAPHIC_BITMAP == rGraph.GetType()) |
| { |
| ::SetProgressState(nProgress, mpDocShell); // Update |
| |
| if (bOleOk) |
| { |
| sal_uLong nOldPos = pDataStream->Tell(); |
| pDataStream->Seek(STREAM_SEEK_TO_END); |
| SvStream *pTmpData = 0; |
| if (nObjLocFc < pDataStream->Tell()) |
| { |
| pTmpData = pDataStream; |
| pTmpData->Seek( nObjLocFc ); |
| } |
| |
| sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT; |
| |
| { |
| SvStorageStreamRef xObjInfoSrc = xSrc1->OpenSotStream( CREATE_CONST_ASC( "\3ObjInfo" ), |
| STREAM_STD_READ | STREAM_NOCREATE ); |
| if ( xObjInfoSrc.Is() && !xObjInfoSrc->GetError() ) |
| { |
| sal_uInt8 nByte = 0; |
| *xObjInfoSrc >> nByte; |
| if ( ( nByte >> 4 ) & embed::Aspects::MSOLE_ICON ) |
| nAspect = embed::Aspects::MSOLE_ICON; |
| } |
| } |
| |
| ErrCode nError = ERRCODE_NONE; |
| pRet = SvxMSDffManager::CreateSdrOLEFromStorage( |
| aSrcStgName, xSrc0, mpDocShell->GetStorage(), rGraph, aRect, aVisArea, pTmpData, nError, |
| SwMSDffManager::GetFilterFlags(), nAspect ); |
| pDataStream->Seek( nOldPos ); |
| } |
| } |
| return pRet; |
| } |
| |
| void SwWW8ImplReader::ReadRevMarkAuthorStrTabl( SvStream& rStrm, |
| sal_Int32 nTblPos, sal_Int32 nTblSiz, SwDoc& rDocOut ) |
| { |
| ::std::vector<String> aAuthorNames; |
| WW8ReadSTTBF( !bVer67, rStrm, nTblPos, nTblSiz, bVer67 ? 2 : 0, |
| eStructCharSet, aAuthorNames ); |
| |
| sal_uInt16 nCount = static_cast< sal_uInt16 >(aAuthorNames.size()); |
| for( sal_uInt16 nAuthor = 0; nAuthor < nCount; ++nAuthor ) |
| { |
| // Store author in doc |
| sal_uInt16 nSWId = rDocOut.InsertRedlineAuthor(aAuthorNames[nAuthor]); |
| // Store matchpair |
| if( !pAuthorInfos ) |
| pAuthorInfos = new sw::util::AuthorInfos; |
| sw::util::AuthorInfo* pAutorInfo = new sw::util::AuthorInfo( nAuthor, nSWId ); |
| if( 0 == pAuthorInfos->Insert( pAutorInfo ) ) |
| delete pAutorInfo; |
| } |
| } |
| |
| /* |
| Revision Marks ( == Redlining ) |
| */ |
| // insert or delete content (change char attributes resp.) |
| void SwWW8ImplReader::Read_CRevisionMark(RedlineType_t eType, |
| const sal_uInt8* pData, short nLen ) |
| { |
| // there *must* be a SprmCIbstRMark[Del] and a SprmCDttmRMark[Del] |
| // pointing to the very same char position as our SprmCFRMark[Del] |
| if (!pPlcxMan) |
| return; |
| const sal_uInt8* pSprmCIbstRMark; |
| const sal_uInt8* pSprmCDttmRMark; |
| if( nsRedlineType_t::REDLINE_FORMAT == eType ) |
| { |
| pSprmCIbstRMark = pData+1; |
| pSprmCDttmRMark = pData+3; |
| } |
| else |
| { |
| /* |
| #101578# |
| It is possible to have a number of date stamps for the created time |
| of the change, (possibly a word bug) so we must use the "get a full |
| list" varient of HasCharSprm and take the last one as the true one. |
| */ |
| std::vector<const sal_uInt8 *> aResult; |
| bool bIns = (nsRedlineType_t::REDLINE_INSERT == eType); |
| if( bVer67 ) |
| { |
| pPlcxMan->HasCharSprm(69, aResult); |
| pSprmCIbstRMark = aResult.empty() ? 0 : aResult.back(); |
| aResult.clear(); |
| pPlcxMan->HasCharSprm(70, aResult); |
| pSprmCDttmRMark = aResult.empty() ? 0 : aResult.back(); |
| } |
| else |
| { |
| pPlcxMan->HasCharSprm( bIns ? 0x4804 : 0x4863, aResult); |
| pSprmCIbstRMark = aResult.empty() ? 0 : aResult.back(); |
| aResult.clear(); |
| pPlcxMan->HasCharSprm( bIns ? 0x6805 : 0x6864, aResult); |
| pSprmCDttmRMark = aResult.empty() ? 0 : aResult.back(); |
| } |
| } |
| |
| if (nLen < 0) |
| mpRedlineStack->close(*pPaM->GetPoint(), eType, pTableDesc ); |
| else |
| { |
| // start of new revision mark, if not there default to first entry |
| sal_uInt16 nWWAutNo = pSprmCIbstRMark ? SVBT16ToShort( pSprmCIbstRMark ) : 0; |
| sw::util::AuthorInfo aEntry(nWWAutNo); |
| sal_uInt16 nPos; |
| if (pAuthorInfos && pAuthorInfos->Seek_Entry(&aEntry, &nPos)) |
| { |
| if (const sw::util::AuthorInfo* pAuthor = pAuthorInfos->GetObject(nPos)) |
| { |
| sal_uInt32 nWWDate = pSprmCDttmRMark ? SVBT32ToUInt32(pSprmCDttmRMark): 0; |
| DateTime aStamp(sw::ms::DTTM2DateTime(nWWDate)); |
| sal_uInt16 nAutorNo = pAuthor->nOurId; |
| SwFltRedline aNewAttr(eType, nAutorNo, aStamp); |
| |
| NewAttr(aNewAttr); |
| } |
| } |
| } |
| } |
| |
| // insert new content |
| void SwWW8ImplReader::Read_CFRMark(sal_uInt16 , const sal_uInt8* pData, short nLen) |
| { |
| Read_CRevisionMark( nsRedlineType_t::REDLINE_INSERT, pData, nLen ); |
| } |
| |
| // delete old content |
| void SwWW8ImplReader::Read_CFRMarkDel(sal_uInt16 , const sal_uInt8* pData, short nLen) |
| { |
| Read_CRevisionMark( nsRedlineType_t::REDLINE_DELETE, pData, nLen ); |
| } |
| |
| // change properties of content ( == char formating) |
| void SwWW8ImplReader::Read_CPropRMark(sal_uInt16 , const sal_uInt8* pData, short nLen) |
| { |
| // complex (len is always 7) |
| // 1 byte - chp.fPropRMark |
| // 2 bytes - chp.ibstPropRMark |
| // 4 bytes - chp.dttmPropRMark; |
| Read_CRevisionMark( nsRedlineType_t::REDLINE_FORMAT, pData, nLen ); |
| } |
| |
| /* vi:set tabstop=4 shiftwidth=4 expandtab: */ |