LibreOffice Module sw (master)  1
wrtww8gr.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <memory>
21 #include <com/sun/star/embed/XEmbedPersist.hpp>
22 #include <com/sun/star/embed/Aspects.hpp>
23 #include <com/sun/star/embed/ElementModes.hpp>
24 #include <sal/log.hxx>
25 #include <vcl/graphicfilter.hxx>
26 #include <vcl/gdimtf.hxx>
27 #include <svl/itemiter.hxx>
28 #include <tools/UnitConversion.hxx>
29 
30 #include <svtools/embedhlp.hxx>
31 
32 #include <hintids.hxx>
33 #include <editeng/boxitem.hxx>
34 #include <editeng/shaditem.hxx>
36 #include <editeng/fhgtitem.hxx>
37 #include <svx/svdoole2.hxx>
38 
40 #include <fmtanchr.hxx>
41 #include <ndgrf.hxx>
42 #include <frmfmt.hxx>
43 #include <grfatr.hxx>
44 #include <ndole.hxx>
45 #include <fmtfsize.hxx>
46 #include <fmtornt.hxx>
47 
48 #include "sprmids.hxx"
49 
50 #include <doc.hxx>
51 #include "writerhelper.hxx"
52 #include "writerwordglue.hxx"
53 #include "ww8struc.hxx"
54 #include "wrtww8.hxx"
55 #include "ww8par.hxx"
56 #include "escher.hxx"
57 //Added for i120568
58 #include "ww8attributeoutput.hxx"
59 #include <fmturl.hxx>
60 
62 #include <drawdoc.hxx>
63 #include <o3tl/string_view.hxx>
64 
65 using namespace ::com::sun::star;
66 
67 // TODO:
68 // 5. convert the MapModes that Widows can't handle
69 
70 // OutGrf () is called for every GrfNode in the document. A PicLocFc-Sprm
71 // will be inserted, which contains a magic number instead of an address.
72 // The GrfNode-Ptr is saved in Graf-Class (used later for output of
73 // the graphic and patching of the PicLocFc attributes)
74 
75 void WW8Export::OutputGrfNode( const SwGrfNode& /*rNode*/ )
76 {
77  SAL_INFO("sw", "WW8Export::OutputGrfNode( const SwGrfNode& )" );
78  OSL_ENSURE( m_pParentFrame, "frame not set!" );
79  if ( m_pParentFrame )
80  {
82  m_pFib->m_fHasPic = true;
83  }
84 }
85 
87  const tools::SvRef<SotStorage>& xObjStg,
88  OUString const& rStorageName, SwOLENode* pOLENd)
89 {
90  bool bGraphicNeeded = false;
91  SfxItemIter aIter( rSet );
92  for (auto pItem = aIter.GetCurItem(); !bGraphicNeeded && pItem; pItem = aIter.NextItem())
93  {
94  switch (pItem->Which())
95  {
96  /*
97  For an inline object these properties are irrelevant because they
98  will be the same as the defaults that msword applies in their
99  absence, so if that is all that there is for these inline objects
100  then if there turns out to be enough information in the object
101  itself to regenerate the correct size and preview of the object
102  then we will not need to provide an additional graphics preview in
103  the data stream, which can save a lot of disk space.
104  */
105  case RES_FRM_SIZE:
106  case RES_CNTNT:
107  case RES_VERT_ORIENT:
108  case RES_ANCHOR:
109  break;
110  default:
111  bGraphicNeeded = true;
112  }
113  }
114 
115  /*
116  Now we must see if the object contains a preview itself which is equal to
117  the preview that we are currently using. If the graphics are equal then we
118  don't need to store another preview
119  */
120  GDIMetaFile aWMF;
121  tools::Long nX=0,nY=0;
122  if (!bGraphicNeeded && SwWW8ImplReader::ImportOleWMF(xOleStg,aWMF,nX,nY))
123  {
124  // bGraphicNeeded set to true is right / fixes #i51670#.
125  bGraphicNeeded = true;
126  tools::Rectangle aRect( Point(), Size( nX, nY ) );
127  Graphic aGraph(aWMF);
128 
129  ErrCode nErr = ERRCODE_NONE;
130  sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT;
131  if ( pOLENd )
132  nAspect = pOLENd->GetAspect();
135  rStorageName,
136  xObjStg,
138  aGraph,
139  aRect,
141  nullptr,
142  nErr,
143  0,
144  nAspect,
145  m_pWriter->GetBaseURL());
146 
147  if (pRet)
148  {
149  uno::Reference< embed::XEmbeddedObject > xObj = pOLENd->GetOLEObj().GetOleRef();
150  if ( xObj.is() )
151  {
152  std::unique_ptr<SvStream> pGraphicStream;
154  try
155  {
156  uno::Reference< embed::XEmbedPersist > xPersist(
157  xObj,
158  uno::UNO_QUERY_THROW );
159 
160  // it makes no sense to search the object in the container by reference since the object was created
161  // outside of the container and was not inserted there, only the name makes sense
162  pGraphicStream =
163  ::utl::UcbStreamHelper::CreateStream( aCnt.GetGraphicStream( xPersist->getEntryName() ) );
164  }
165  catch( const uno::Exception& )
166  {}
167 
168  OSL_ENSURE( pGraphicStream && !pGraphicStream->GetError(), "No graphic stream available!" );
169  if ( pGraphicStream && !pGraphicStream->GetError() )
170  {
171  Graphic aGr1;
173  if( rGF.ImportGraphic( aGr1, u"", *pGraphicStream ) == ERRCODE_NONE )
174  {
175  Graphic aGr2;
176  pGraphicStream =
177  ::utl::UcbStreamHelper::CreateStream( aCnt.GetGraphicStream( pRet->GetObjRef() ) );
178  if( pGraphicStream && rGF.ImportGraphic( aGr2, u"", *pGraphicStream ) == ERRCODE_NONE )
179  {
180  if ( aGr1 == aGr2 )
181  bGraphicNeeded = false;
182  }
183  }
184  }
185  }
186 
187  // always use SdrObject::Free(...) for SdrObjects (!)
188  SdrObject* pTemp(pRet);
189  SdrObject::Free(pTemp);
190  }
191  }
192  else
193  bGraphicNeeded = true;
194  return bGraphicNeeded;
195 }
196 
197 void WW8Export::OutputOLENode( const SwOLENode& rOLENode )
198 {
199  SAL_INFO("sw", "WW8Export::OutputOLENode( const SwOLENode& rOLENode )" );
200  sal_uInt8 *pSpecOLE;
201  sal_uInt8 *pDataAdr;
202  short nSize;
203  static sal_uInt8 aSpecOLE_WW8[] = {
204  0x03, 0x6a, 0, 0, 0, 0, // sprmCPicLocation
205  0x0a, 0x08, 1, // sprmCFOLE2
206  0x56, 0x08, 1 // sprmCFObj
207  };
208 
209  pSpecOLE = aSpecOLE_WW8;
210  nSize = sizeof( aSpecOLE_WW8 );
211  pDataAdr = pSpecOLE + 2; //WW6 sprm is 1 but has 1 byte len as well.
212 
214 
215  if( !xObjStg.is() )
216  return;
217 
218  uno::Reference < embed::XEmbeddedObject > xObj(const_cast<SwOLENode&>(rOLENode).GetOLEObj().GetOleRef());
219  if( !xObj.is() )
220  return;
221 
222  const embed::XEmbeddedObject *pObj = xObj.get();
223  //Don't want to use pointer ids, as is traditional, because we need
224  //to put this into a 32bit value, and on 64bit the bottom bits
225  //might collide and two unrelated ole objects end up considered the
226  //same. Don't want to simply start at 0 which is a special value
227  sal_Int32 nPictureId = SAL_MAX_INT32 - m_aOleMap.size();
228  WW8OleMap::value_type entry = std::make_pair(pObj, nPictureId);
229  std::pair<WW8OleMap::iterator, bool> aRes = m_aOleMap.insert(entry);
230  bool bIsNotDuplicate = aRes.second; //.second is false when element already existed
231  nPictureId = aRes.first->second;
232  Set_UInt32(pDataAdr, nPictureId);
233  OUString sStorageName = "_" + OUString::number( nPictureId );
234  tools::SvRef<SotStorage> xOleStg = xObjStg->OpenSotStorage( sStorageName );
235  if( !xOleStg.is() )
236  return;
237 
238  /*
239  If this object storage has been written already don't
240  waste time rewriting it
241  */
242  if (bIsNotDuplicate)
243  {
244  sal_Int64 nAspect = rOLENode.GetAspect();
245  svt::EmbeddedObjectRef aObjRef( xObj, nAspect );
246  m_pOLEExp->ExportOLEObject( aObjRef, *xOleStg );
247  if ( nAspect == embed::Aspects::MSOLE_ICON )
248  {
249  OUString aObjInfo( "\3ObjInfo" );
250  if ( !xOleStg->IsStream( aObjInfo ) )
251  {
252  const sal_uInt8 pObjInfoData[] = { 0x40, 0x00, 0x03, 0x00 };
253  tools::SvRef<SotStorageStream> rObjInfoStream = xOleStg->OpenSotStream( aObjInfo );
254  if ( rObjInfoStream.is() && !rObjInfoStream->GetError() )
255  {
256  rObjInfoStream->WriteBytes(pObjInfoData, sizeof(pObjInfoData));
257  xOleStg->Commit();
258  }
259  }
260  }
261  }
262 
263  // write as embedded field - the other things will be done
264  // in the escher export
265  OUString sServer = FieldString(ww::eEMBED) + xOleStg->GetUserName() + " ";
266 
267  OutputField(nullptr, ww::eEMBED, sServer, FieldFlags::Start |
269 
270  m_pChpPlc->AppendFkpEntry( Strm().Tell(),
271  nSize, pSpecOLE );
272 
273  bool bEndCR = true;
274  /*
275  In the word filter we only need a preview image for
276  floating images, and then only (the usual case) if the
277  object doesn't contain enough information to reconstruct
278  what we need.
279 
280  We don't need a graphic for inline objects, so we don't
281  even need the overhead of a graphic in that case.
282  */
283  bool bGraphicNeeded = false;
284 
285  if (m_pParentFrame)
286  {
287  bGraphicNeeded = true;
288 
289  if (m_pParentFrame->IsInline())
290  {
291  const SwAttrSet& rSet =
293  bEndCR = false;
294  bGraphicNeeded = TestOleNeedsGraphic(rSet,
295  xOleStg, xObjStg, sStorageName, const_cast<SwOLENode*>(&rOLENode));
296  }
297  }
298 
299  if (!bGraphicNeeded)
300  WriteChar(0x1);
301  else
302  {
303  /*
304  ##897##
305  We need to insert the graphic representation of
306  this object for the inline case, otherwise word
307  has no place to find the dimensions of the ole
308  object, and will not be able to draw it
309  */
311  }
312 
313  OutputField(nullptr, ww::eEMBED, OUString(),
315 
316  if (bEndCR) //No newline in inline case
317  WriteCR();
318 }
319 
320 void WW8Export::OutputLinkedOLE( const OUString& rOleId )
321 {
322  uno::Reference< embed::XStorage > xDocStg = m_rDoc.GetDocStorage();
323  uno::Reference< embed::XStorage > xOleStg = xDocStg->openStorageElement( "OLELinks", embed::ElementModes::READ );
324  tools::SvRef<SotStorage> xObjSrc = SotStorage::OpenOLEStorage( xOleStg, rOleId, StreamMode::READ );
325 
327 
328  if( !(xObjStg.is() && xObjSrc.is()) )
329  return;
330 
331  tools::SvRef<SotStorage> xOleDst = xObjStg->OpenSotStorage( rOleId );
332  if ( xOleDst.is() )
333  xObjSrc->CopyTo( xOleDst.get() );
334 
335  if ( xOleDst->GetError( ) )
336  return;
337 
338  xOleDst->Commit();
339 
340  // Output the cPicLocation attribute
341  std::unique_ptr<ww::bytes> pBuf( new ww::bytes );
343  SwWW8Writer::InsUInt32( *pBuf, o3tl::toInt32(rOleId.subView( 1 )) );
344 
346  pBuf->push_back( 1 );
347 
349  pBuf->push_back( 1 );
350 
352  pBuf->push_back( 1 );
353 
354  m_pChpPlc->AppendFkpEntry( Strm().Tell(), pBuf->size(), pBuf->data() );
355 }
356 
357 void WW8Export::OutGrf(const ww8::Frame &rFrame)
358 {
359  //Added for i120568,the hyperlink info within a graphic whose anchor type is "As character"
360  //will be exported to ensure the fidelity
361  const SwFormatURL& rURL = rFrame.GetFrameFormat().GetAttrSet().GetURL();
362  bool bURLStarted = false;
363  if( !rURL.GetURL().isEmpty() && rFrame.GetWriterType() == ww8::Frame::eGraphic)
364  {
365  bURLStarted = true;
366  m_pAttrOutput->StartURL( rURL.GetURL(), rURL.GetTargetFrameName() );
367  }
368 
369  // Store the graphic settings in GrfNode so they may be written-out later
370  m_pGrf->Insert(rFrame);
371 
372  m_pChpPlc->AppendFkpEntry( Strm().Tell(), m_pO->size(), m_pO->data() );
373  m_pO->clear();
374 
375  // #i29408#
376  // linked, as-character anchored graphics have to be exported as fields.
377  const SwGrfNode* pGrfNd = rFrame.IsInline() && rFrame.GetContent()
378  ? rFrame.GetContent()->GetGrfNode() : nullptr;
379  if ( pGrfNd && pGrfNd->IsLinkedFile() )
380  {
381  OUString sStr;
382  pGrfNd->GetFileFilterNms(&sStr, nullptr);
383  sStr = FieldString(ww::eINCLUDEPICTURE) + " \"" + sStr + "\" \\d";
384 
385  OutputField( nullptr, ww::eINCLUDEPICTURE, sStr,
387  }
388 
389  WriteChar( char(1) ); // paste graphic symbols in the main text
390 
391  sal_uInt8 aArr[ 18 ];
392  sal_uInt8* pArr = aArr;
393 
394  const SwFrameFormat &rFlyFormat = rFrame.GetFrameFormat();
395  const RndStdIds eAn = rFlyFormat.GetAttrSet().GetAnchor(false).GetAnchorId();
396  if (eAn == RndStdIds::FLY_AS_CHAR)
397  {
398  sal_Int16 eVert = rFlyFormat.GetVertOrient().GetVertOrient();
399  if ((eVert == text::VertOrientation::CHAR_CENTER) || (eVert == text::VertOrientation::LINE_CENTER))
400  {
401  bool bVert = false;
402  //The default for word in vertical text mode is to center,
403  //otherwise a sub/super script hack is employed
404  if (auto pTextNd = dynamic_cast< const SwContentNode *>( m_pOutFormatNode ) )
405  {
406  SwPosition aPos(*pTextNd);
407  bVert = m_rDoc.IsInVerticalText(aPos);
408  }
409  if (!bVert)
410  {
411  SwTwips nHeight = rFlyFormat.GetFrameSize().GetHeight();
412  nHeight/=20; //nHeight was in twips, want it in half points, but
413  //then half of total height.
414  tools::Long nFontHeight = GetItem(RES_CHRATR_FONTSIZE).GetHeight();
415  nHeight-=nFontHeight/20;
416 
418  Set_UInt16( pArr, - static_cast<sal_Int16>(nHeight));
419  }
420  }
421  }
422 
423  // sprmCFSpec
424  Set_UInt16( pArr, 0x855 );
425  Set_UInt8( pArr, 1 );
426 
427  // sprmCPicLocation
429  Set_UInt32( pArr, GRF_MAGIC_321 );
430 
431  // vary Magic, so that different graphic attributes will not be merged
432  static sal_uInt8 nAttrMagicIdx = 0;
433  --pArr;
434  Set_UInt8( pArr, nAttrMagicIdx++ );
435  m_pChpPlc->AppendFkpEntry( Strm().Tell(), static_cast< short >(pArr - aArr), aArr );
436 
437  // #i75464#
438  // Check, if graphic isn't exported as-character anchored.
439  // Otherwise, an additional paragraph is exported for a graphic, which is
440  // forced to be treated as inline, because it's anchored inside another frame.
441  if ( !rFrame.IsInline() &&
442  ( (eAn == RndStdIds::FLY_AT_PARA) ||
443  (eAn == RndStdIds::FLY_AT_PAGE) ) )
444  {
445  WriteChar( char(0x0d) ); // close the surrounding frame with CR
446 
447  static sal_uInt8 nSty[2] = { 0, 0 };
448  m_pO->insert( m_pO->end(), nSty, nSty+2 ); // Style #0
449  bool bOldGrf = m_bOutGrf;
450  m_bOutGrf = true;
451 
452  OutputFormat( rFrame.GetFrameFormat(), false, false, true ); // Fly-Attrs
453 
454  m_bOutGrf = bOldGrf;
455  m_pPapPlc->AppendFkpEntry( Strm().Tell(), m_pO->size(), m_pO->data() );
456  m_pO->clear();
457  }
458  // #i29408#
459  // linked, as-character anchored graphics have to be exported as fields.
460  else if ( pGrfNd && pGrfNd->IsLinkedFile() )
461  {
462  OutputField( nullptr, ww::eINCLUDEPICTURE, OUString(), FieldFlags::Close );
463  }
464  //Added for i120568,the hyperlink info within a graphic whose anchor type is
465  //"As character" will be exported to ensure the fidelity
466  if( bURLStarted )
467  m_pAttrOutput->EndURL(false);
468 }
469 
471 {
472  const Size aSize( rFly.GetLayoutSize() );
473  const sal_uInt16 nWidth = static_cast< sal_uInt16 >(aSize.Width());
474  const sal_uInt16 nHeight = static_cast< sal_uInt16 >(aSize.Height());
475  maDetails.emplace_back(rFly, nWidth, nHeight);
476 }
477 
479  sal_uInt16 mm, sal_uInt16 nWidth, sal_uInt16 nHeight, const SwAttrSet* pAttrSet)
480 {
481  sal_Int16 nXSizeAdd = 0, nYSizeAdd = 0;
482  sal_Int16 nCropL = 0, nCropR = 0, nCropT = 0, nCropB = 0;
483 
484  // write Crop-Attribute content in Header ( if available )
485  const SwCropGrf* pCropItem;
486  if (pAttrSet && (pCropItem
487  = pAttrSet->GetItemIfSet(RES_GRFATR_CROPGRF, false)))
488  {
489  nCropL = static_cast<sal_Int16>(pCropItem->GetLeft());
490  nCropR = static_cast<sal_Int16>(pCropItem->GetRight());
491  nCropT = static_cast<sal_Int16>(pCropItem->GetTop());
492  nCropB = static_cast<sal_Int16>(pCropItem->GetBottom());
493  nXSizeAdd = nXSizeAdd - static_cast<sal_Int16>( pCropItem->GetLeft() + pCropItem->GetRight() );
494  nYSizeAdd = nYSizeAdd - static_cast<sal_Int16>( pCropItem->GetTop() + pCropItem->GetBottom() );
495  }
496 
497  Size aGrTwipSz(rFly.GetSize());
498  sal_uInt16 nHdrLen = 0x44;
499 
500  sal_uInt8 aArr[ 0x44 ] = { 0 };
501 
502  sal_uInt8* pArr = aArr + 0x2E; // Do borders first
503 
504  const SwAttrSet& rAttrSet = rFly.GetFrameFormat().GetAttrSet();
505  if (const SvxBoxItem* pBox = rAttrSet.GetItemIfSet(RES_BOX, false))
506  {
507  bool bShadow = false; // Shadow ?
508  if (const SvxShadowItem* pSI = rAttrSet.GetItem<SvxShadowItem>(RES_SHADOW))
509  {
510  bShadow = (pSI->GetLocation() != SvxShadowLocation::NONE) &&
511  (pSI->GetWidth() != 0);
512  }
513 
514  static const SvxBoxItemLine aLnArr[4] = { SvxBoxItemLine::TOP, SvxBoxItemLine::LEFT,
515  SvxBoxItemLine::BOTTOM, SvxBoxItemLine::RIGHT };
516  for(const SvxBoxItemLine & i : aLnArr)
517  {
518  const ::editeng::SvxBorderLine* pLn = pBox->GetLine( i );
519  WW8_BRC aBrc;
520  if (pLn)
521  {
523  pBox->GetDistance( i ), bShadow );
525  aBrc90.cv()));
526  aBrc = WW8_BRC(aBrc90.dptLineWidth(), aBrc90.brcType(), ico,
527  aBrc90.dptSpace(), aBrc90.fShadow(), aBrc90.fFrame());
528  }
529 
530  // use importer logic to determine how large the exported
531  // border will really be in word and adjust accordingly
532  short nSpacing;
533  short nThick = aBrc.DetermineBorderProperties(&nSpacing);
534  switch (i)
535  {
536  case SvxBoxItemLine::TOP:
537  case SvxBoxItemLine::BOTTOM:
538  nHeight -= bShadow ? nThick*2 : nThick;
539  nHeight = nHeight - nSpacing;
540  break;
541  case SvxBoxItemLine::LEFT:
542  case SvxBoxItemLine::RIGHT:
543  default:
544  nWidth -= bShadow ? nThick*2 : nThick;
545  nWidth = nWidth - nSpacing;
546  break;
547  }
548  memcpy( pArr, &aBrc.aBits1, 2);
549  pArr+=2;
550 
551  memcpy( pArr, &aBrc.aBits2, 2);
552  pArr+=2;
553  }
554  }
555 
556  pArr = aArr + 4; // skip lcb
557  Set_UInt16( pArr, nHdrLen ); // set cbHeader
558 
559  Set_UInt16( pArr, mm ); // set mm
560 
561  /*
562  Just in case our original size is too big to fit inside a ushort we can
563  substitute the final size and lose on retaining the scaling factor but
564  still keep the correct display size anyway.
565  */
566  const bool bIsSubstitutedSize = (aGrTwipSz.Width() > SHRT_MAX) || (aGrTwipSz.Height() > SHRT_MAX) ||
567  aGrTwipSz.IsEmpty();
568  if ( bIsSubstitutedSize )
569  {
570  aGrTwipSz.setWidth( nWidth );
571  aGrTwipSz.setHeight( nHeight );
572  }
573  using namespace sw::types;
574  // set xExt & yExt
575  Set_UInt16(pArr, msword_cast<sal_uInt16>(convertTwipToMm100(aGrTwipSz.Width())));
576  Set_UInt16(pArr, msword_cast<sal_uInt16>(convertTwipToMm100(aGrTwipSz.Height())));
577  pArr += 16;
578  // skip hMF & rcWinMF
579  // set dxaGoal & dyaGoal
580  Set_UInt16(pArr, msword_cast<sal_uInt16>(aGrTwipSz.Width()));
581  Set_UInt16(pArr, msword_cast<sal_uInt16>(aGrTwipSz.Height()));
582 
583  if ( aGrTwipSz.Width() + nXSizeAdd ) // set mx
584  {
585  if ( !bIsSubstitutedSize )
586  {
587  const double fVal = nWidth * 1000.0 / (aGrTwipSz.Width() + nXSizeAdd );
588  Set_UInt16( pArr, o3tl::narrowing<sal_uInt16>(::rtl::math::round(fVal)) );
589  }
590  else
591  {
592  Set_UInt16( pArr, 1000 );
593  }
594  }
595  else
596  {
597  pArr += 2;
598  }
599 
600  if ( aGrTwipSz.Height() + nYSizeAdd ) // set my
601  {
602  if ( !bIsSubstitutedSize )
603  {
604  const double fVal = nHeight * 1000.0 / (aGrTwipSz.Height() + nYSizeAdd);
605  Set_UInt16( pArr, o3tl::narrowing<sal_uInt16>(::rtl::math::round(fVal)) );
606  }
607  else
608  {
609  Set_UInt16( pArr, 1000 );
610  }
611  }
612  else
613  {
614  pArr += 2;
615  }
616 
617  if ( !bIsSubstitutedSize )
618  {
619  Set_UInt16( pArr, nCropL ); // set dxaCropLeft
620  Set_UInt16( pArr, nCropT ); // set dyaCropTop
621  Set_UInt16( pArr, nCropR ); // set dxaCropRight
622  Set_UInt16( pArr, nCropB ); // set dyaCropBottom
623  }
624 
625  rStrm.WriteBytes(aArr, nHdrLen);
626 }
627 
629  const ww8::Frame &rFly, sal_uInt16 nWidth, sal_uInt16 nHeight)
630 {
631  if (rGrfNd.IsLinkedFile()) // Linked File
632  {
633  OUString aFileN;
634  rGrfNd.GetFileFilterNms( &aFileN, nullptr );
635 
636  sal_uInt16 const mm = 94; // 94 = BMP, GIF
637 
638  WritePICFHeader(rStrm, rFly, mm, nWidth, nHeight,
639  rGrfNd.GetpSwAttrSet());
640  rStrm.WriteUChar( aFileN.getLength() ); // write Pascal-String
641  SwWW8Writer::WriteString8(rStrm, aFileN, false,
642  RTL_TEXTENCODING_MS_1252);
643  }
644  else // Embedded File or DDE or something like that
645  {
646  WritePICFHeader(rStrm, rFly, 0x64, nWidth, nHeight,
647  rGrfNd.GetpSwAttrSet());
648  SwBasicEscherEx aInlineEscher(&rStrm, m_rWrt);
649  aInlineEscher.WriteGrfFlyFrame(rFly.GetFrameFormat(), 0x401);
650  aInlineEscher.WritePictures();
651  }
652 }
653 //For i120928,export graphic info of bullet
655  sal_uInt16 mm, sal_uInt16 nWidth, sal_uInt16 nHeight)
656 {
657  sal_Int16 nXSizeAdd = 0, nYSizeAdd = 0;
658 
659  Size aGrTwipSz(rGrf.GetPrefSize());
660  sal_uInt16 nHdrLen = 0x44;
661 
662  sal_uInt8 aArr[ 0x44 ] = { 0 };
663 
664  sal_uInt8* pArr = aArr + 0x2E; //Do borders first
665 
666  static const SvxBoxItemLine aLnArr[4] = { SvxBoxItemLine::TOP, SvxBoxItemLine::LEFT,
667  SvxBoxItemLine::BOTTOM, SvxBoxItemLine::RIGHT };
668  for(const SvxBoxItemLine & i : aLnArr)
669  {
670  WW8_BRC aBrc;
671 
672  short nSpacing;
673  short nThick = aBrc.DetermineBorderProperties(&nSpacing);
674  switch (i)
675  {
676  case SvxBoxItemLine::TOP:
677  case SvxBoxItemLine::BOTTOM:
678  nHeight -= nThick;
679  nHeight = nHeight - nSpacing;
680  break;
681  case SvxBoxItemLine::LEFT:
682  case SvxBoxItemLine::RIGHT:
683  default:
684  nWidth -= nThick;
685  nWidth = nWidth - nSpacing;
686  break;
687  }
688  memcpy( pArr, &aBrc.aBits1, 2);
689  pArr+=2;
690 
691  memcpy(pArr, &aBrc.aBits2, 2);
692  pArr+=2;
693  }
694 
695  pArr = aArr + 4; //skip lcb
696  Set_UInt16( pArr, nHdrLen ); // set cbHeader
697 
698  Set_UInt16( pArr, mm ); // set mm
699 
700  if ( (convertTwipToMm100(aGrTwipSz.Width()) > USHRT_MAX ) || ( convertTwipToMm100(aGrTwipSz.Height()) > USHRT_MAX )
701  || aGrTwipSz.IsEmpty() )
702  {
703  aGrTwipSz.setWidth( nWidth );
704  aGrTwipSz.setHeight( nHeight );
705  }
706  using namespace sw::types;
707  // set xExt & yExt
708  Set_UInt16(pArr, msword_cast<sal_uInt16>(convertTwipToMm100(aGrTwipSz.Width())));
709  Set_UInt16(pArr, msword_cast<sal_uInt16>(convertTwipToMm100(aGrTwipSz.Height())));
710  pArr += 16;
711  // skip hMF & rcWinMF
712  // set dxaGoal & dyaGoal
713  Set_UInt16(pArr, msword_cast<sal_uInt16>(aGrTwipSz.Width()));
714  Set_UInt16(pArr, msword_cast<sal_uInt16>(aGrTwipSz.Height()));
715 
716  if( aGrTwipSz.Width() + nXSizeAdd ) // set mx
717  {
718  double fVal = nWidth * 1000.0 / (aGrTwipSz.Width() + nXSizeAdd);
719  Set_UInt16( pArr, o3tl::narrowing<sal_uInt16>(::rtl::math::round(fVal)) );
720  }
721  else
722  pArr += 2;
723 
724  if( aGrTwipSz.Height() + nYSizeAdd ) // set my
725  {
726  double fVal = nHeight * 1000.0 / (aGrTwipSz.Height() + nYSizeAdd);
727  Set_UInt16( pArr, o3tl::narrowing<sal_uInt16>(::rtl::math::round(fVal)) );
728  }
729  else
730  pArr += 2;
731 
732  Set_UInt16( pArr, 0 ); // set dxaCropLeft
733  Set_UInt16( pArr, 0 ); // set dyaCropTop
734  Set_UInt16( pArr, 0 ); // set dxaCropRight
735  Set_UInt16( pArr, 0 ); // set dyaCropBottom
736 
737  rStrm.WriteBytes(aArr, nHdrLen);
738 }
739 
740 void SwWW8WrGrf::WriteGrfForBullet(SvStream& rStrm, const Graphic &rGrf, sal_uInt16 nWidth, sal_uInt16 nHeight)
741 {
742  WritePICBulletFHeader(rStrm,rGrf, 0x64,nWidth,nHeight);
743  SwBasicEscherEx aInlineEscher(&rStrm, m_rWrt);
744  aInlineEscher.WriteGrfBullet(rGrf);
745  aInlineEscher.WritePictures();
746 }
747 
749 {
750  sal_uInt16 nWidth = rItem.mnWid;
751  sal_uInt16 nHeight = rItem.mnHei;
752  sal_uInt32 nPos = rStrm.Tell(); // store start of graphic
753 
754  const ww8::Frame &rFly = rItem.maFly;
755  switch (rFly.GetWriterType())
756  {
758  {
759  const SwNode *pNode = rItem.maFly.GetContent();
760  const SwGrfNode *pNd = pNode ? pNode->GetGrfNode() : nullptr;
761  OSL_ENSURE(pNd, "Impossible");
762  if (pNd)
763  WriteGrfFromGrfNode(rStrm, *pNd, rItem.maFly, nWidth, nHeight);
764  }
765  break;
766  //For i120928,add branch to export graphic of bullet
768  {
769  if (rItem.maFly.HasGraphic())
770  {
771  const Graphic& rGrf = rItem.maFly.GetGraphic();
772  WriteGrfForBullet(rStrm, rGrf, nWidth, nHeight);
773  }
774  }
775  break;
776 
777  case ww8::Frame::eOle:
778  {
779  const SwNode *pNode = rItem.maFly.GetContent();
780  const SwOLENode *pNd = pNode ? pNode->GetOLENode() : nullptr;
781  OSL_ENSURE(pNd, "Impossible");
782  if (pNd)
783  {
784 #ifdef OLE_PREVIEW_AS_EMF
785  //Convert this ole2 preview in ww8+ to an EMF for better unicode
786  //support (note that at this moment this breaks StarSymbol
787  //using graphics because I need to embed starsymbol in exported
788  //documents.
789  WritePICFHeader(rStrm, rFly, 0x64, nWidth, nHeight,
790  pNd->GetpSwAttrSet());
791  SwBasicEscherEx aInlineEscher(&rStrm, m_rWrt);
792  aInlineEscher.WriteOLEFlyFrame(rFly.GetFrameFormat(), 0x401);
793  aInlineEscher.WritePictures();
794 #else
795  // cast away const
796  SwOLENode *pOleNd = const_cast<SwOLENode*>(pNd);
797  SwOLEObj& rSObj= pOleNd->GetOLEObj();
798 
799  // TODO/LATER: do we need to load object?
800  Graphic* pGr = SdrOle2Obj::GetGraphicFromObject( pOleNd->GetDoc()->GetDocStorage(), rObj );
801 
802  //TODO/LATER: do we really want to use GDIMetafile?!
803  GDIMetaFile aMtf;
804  if ( pGr )
805  aMtf = pGr->GetGDIMetaFile();
806 
807  Size aS(aMtf.GetPrefSize());
808  aMtf.WindStart();
809  aMtf.Play(Application::GetDefaultDevice(), Point(0, 0),
810  Size(2880, 2880));
811 
812  WritePICFHeader(rStrm, rFly, 8, nWidth, nHeight,
813  pNd->GetpSwAttrSet());
814  WriteWindowMetafileBits(rStrm, aMtf);
815  delete pGr;
816 #endif
817  }
818  }
819  break;
823  /*
824  #i3958# We only export an empty dummy picture frame here, this is
825  what word does the escher export should contain an anchored to
826  character element which is drawn over this dummy and the whole
827  shebang surrounded with a SHAPE field. This isn't *my* hack :-),
828  it's what word does.
829  */
830  {
831  WritePICFHeader(rStrm, rFly, 0x64, nWidth, nHeight);
832  SwBasicEscherEx aInlineEscher(&rStrm, m_rWrt);
833  aInlineEscher.WriteEmptyFlyFrame(rFly.GetFrameFormat(), 0x401);
834  }
835  break;
836  default:
837  OSL_ENSURE(false, "Some inline export not implemented");
838  break;
839  }
840 
841  sal_uInt32 nPos2 = rStrm.Tell(); // store the end
842  rStrm.Seek( nPos );
843  rStrm.WriteUInt32(nPos2 - nPos); // patch graphic length in the header
844  rStrm.Seek( nPos2 ); // restore Pos
845 }
846 
847 // SwWW8WrGrf::Write() is called after the text.
848 // It writes out all the graphics and remembers the file locations of the graphics,
849 // so when writing the attributes of the items it can be patched into PicLocFc-SPRMs.
850 // The search in the attributes for the Magic sal_uLong and patching
851 // happens when writing the attributes. Class SwWW8WrGrf provides with
852 // GetFPos() sequentially the positions
854 {
856  auto aEnd = maDetails.end();
857  for (auto aIter = maDetails.begin(); aIter != aEnd; ++aIter)
858  {
859  sal_uInt32 nPos = rStrm.Tell(); // align to 4 Bytes
860  if( nPos & 0x3 )
861  SwWW8Writer::FillCount( rStrm, 4 - ( nPos & 0x3 ) );
862 
863  auto aIter2 = std::find(maDetails.begin(), aIter, *aIter);
864  if (aIter2 != aIter)
865  {
866  aIter->mnPos = aIter2->mnPos;
867  }
868  else
869  {
870  aIter->mnPos = rStrm.Tell();
871  WriteGraphicNode(rStrm, *aIter);
872  }
873  }
874 }
875 
876 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::uno::Reference< css::embed::XStorage > GetDocStorage()
Definition: docnew.cxx:630
bool is() const
static void InsUInt32(ww::bytes &rO, sal_uInt32 n)
Definition: wrtww8.cxx:1715
const OUString & GetBaseURL() const
Definition: shellio.hxx:444
const sw::BroadcastingModify * m_pOutFormatNode
Definition: wrtww8.hxx:538
sal_Int64 GetAspect() const
Definition: ndole.hxx:139
sal_uInt8 brcType() const
Definition: ww8struc.hxx:325
SVBT16 aBits1
Definition: ww8struc.hxx:263
std::unique_ptr< SvxMSExportOLEObjects > m_pOLEExp
Definition: wrtww8.hxx:475
const T * GetItemIfSet(TypedWhichId< T > nWhich, bool bSrchInParent=true) const
Marks a position in the document model.
Definition: pam.hxx:36
sal_Int32 GetLeft() const
ErrCode ImportGraphic(Graphic &rGraphic, const INetURLObject &rPath, sal_uInt16 nFormat=GRFILTER_FORMAT_DONTKNOW, sal_uInt16 *pDeterminedFormat=nullptr, GraphicFilterImportFlags nImportFlags=GraphicFilterImportFlags::NONE)
const SfxPoolItem & GetItem(sal_uInt16 nWhich) const
Definition: wrtww8.cxx:780
css::uno::Reference< css::embed::XEmbeddedObject > const & GetObjRef() const
static SdrOle2Obj * CreateSdrOLEFromStorage(SdrModel &rSdrModel, const OUString &rStorageName, tools::SvRef< SotStorage > const &rSrcStorage, const css::uno::Reference< css::embed::XStorage > &xDestStg, const Graphic &rGraf, const tools::Rectangle &rBoundRect, const tools::Rectangle &rVisArea, SvStream *pDataStrrm, ErrCode &rError, sal_uInt32 nConvertFlags, sal_Int64 nAspect, OUString const &rBaseURL)
SwOLENode * GetOLENode()
Inline methods from Node.hxx.
Definition: ndole.hxx:164
const SwOLEObj & GetOLEObj() const
Definition: ndole.hxx:115
OUString GetUserName()
bool HasGraphic() const
const SwFormatVertOrient & GetVertOrient(bool=true) const
Definition: fmtornt.hxx:106
const SwFormatURL & GetURL(bool=true) const
Definition: fmturl.hxx:75
constexpr TypedWhichId< SwFormatFrameSize > RES_FRM_SIZE(89)
std::vector< sal_uInt8 > bytes
Definition: types.hxx:29
ErrCode GetError() const
sal_uInt8 TransColToIco(const Color &rCol)
long Long
static bool ImportOleWMF(const tools::SvRef< SotStorage > &xSrc1, GDIMetaFile &rWMF, tools::Long &rX, tools::Long &rY)
Definition: ww8par4.cxx:303
constexpr TypedWhichId< SvxFontHeightItem > RES_CHRATR_FONTSIZE(8)
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:78
static void WritePICBulletFHeader(SvStream &rStrm, const Graphic &rGrf, sal_uInt16 mm, sal_uInt16 nWidth, sal_uInt16 nHeight)
Definition: wrtww8gr.cxx:654
css::uno::Reference< css::embed::XEmbeddedObject > const & GetOleRef()
Definition: ndole.cxx:939
static SotStorage * OpenOLEStorage(css::uno::Reference< css::embed::XStorage > const &xStorage, OUString const &rEleName, StreamMode=StreamMode::STD_READWRITE)
bool IsLinkedFile() const
Definition: ndgrf.hxx:164
sal_uInt64 Seek(sal_uInt64 nPos)
static void WriteString8(SvStream &rStrm, std::u16string_view rStr, bool bAddZero, rtl_TextEncoding eCodeSet)
Definition: wrtww8.cxx:1765
bool IsStream(const OUString &rEleName) const
WW8Export & m_rWrt
for access to the variables
Definition: wrtww8.hxx:1412
void Set_UInt32(sal_uInt8 *&p, sal_uInt32 n)
Definition: ww8struc.hxx:53
static constexpr sal_uInt16 val
Definition: sprmids.hxx:278
static void Free(SdrObject *&_rpObject)
bool WriteWindowMetafileBits(SvStream &rStream, const GDIMetaFile &rMTF)
OUString FieldString(ww::eField eIndex)
Definition: ww8atr.cxx:2679
bool Commit()
std::unique_ptr< WW8Fib > m_pFib
File Information Block.
Definition: wrtww8.hxx:1000
IDocumentDrawModelAccess const & getIDocumentDrawModelAccess() const
Definition: doc.cxx:155
constexpr auto convertTwipToMm100(N n)
static OutputDevice * GetDefaultDevice()
static void WritePICFHeader(SvStream &rStrm, const ww8::Frame &rFly, sal_uInt16 mm, sal_uInt16 nWidth, sal_uInt16 nHeight, const SwAttrSet *pAttrSet=nullptr)
Definition: wrtww8gr.cxx:478
constexpr TypedWhichId< SwFormatVertOrient > RES_VERT_ORIENT(102)
const SfxPoolItem * NextItem()
virtual void OutputOLENode(const SwOLENode &) override
Output SwOLENode.
Definition: wrtww8gr.cxx:197
SotStorage * OpenSotStorage(const OUString &rEleName, StreamMode=StreamMode::STD_READWRITE, bool transacted=true)
virtual void OutputField(const SwField *pField, ww::eField eFieldType, const OUString &rFieldCmd, FieldFlags nMode=FieldFlags::All) override
Write the field.
Definition: ww8atr.cxx:1805
static std::unique_ptr< SvStream > CreateStream(const OUString &rFileName, StreamMode eOpenMode, css::uno::Reference< css::awt::XWindow > xParentWin=nullptr)
bool fFrame() const
Definition: ww8struc.hxx:331
void OutputFormat(const SwFormat &rFormat, bool bPapFormat, bool bChpFormat, bool bFlyFormat=false)
Output attributes.
Definition: ww8atr.cxx:819
sal_uInt32 cv() const
Definition: ww8struc.hxx:321
bool IsInVerticalText(const SwPosition &rPos) const
Definition: doclay.cxx:1662
sal_uInt8 dptSpace() const
Definition: ww8struc.hxx:327
const Size & GetLayoutSize() const
The layout size of the contained element.
bool CopyTo(SotStorage *pDestStg)
const GDIMetaFile & GetGDIMetaFile() const
SvStream & WriteUInt32(sal_uInt32 nUInt32)
short DetermineBorderProperties(short *pSpace) const
Definition: ww8scan.cxx:1364
void Set_UInt16(sal_uInt8 *&p, sal_uInt16 n)
Definition: ww8struc.hxx:47
void OutGrf(const ww8::Frame &rFrame)
Definition: wrtww8gr.cxx:357
static WW8_BRCVer9 TranslateBorderLine(const ::editeng::SvxBorderLine &pLine, sal_uInt16 nDist, bool bShadow)
Definition: ww8atr.cxx:4423
void WriteChar(sal_Unicode c) override
Definition: wrtww8.cxx:1871
bool GetFileFilterNms(OUString *pFileNm, OUString *pFilterNm) const
Definition: ndgrf.cxx:494
void WriteGraphicNode(SvStream &rStrm, const GraphicDetails &rItem)
Definition: wrtww8gr.cxx:748
void WriteGrfBullet(const Graphic &)
Definition: wrtw8esh.cxx:1561
const SwFrameFormat & GetFrameFormat() const
Get the writer SwFrameFormat that this object describes.
sal_uInt16 mnWid
Definition: wrtww8.hxx:1391
std::vector< GraphicDetails > maDetails
Definition: wrtww8.hxx:1414
const SwAttrSet * GetpSwAttrSet() const
Definition: node.hxx:457
std::unique_ptr< WW8_WrPlcPn > m_pPapPlc
Definition: wrtww8.hxx:499
T * get() const
static sal_uInt8 nAttrMagicIdx
Definition: wrtww8.cxx:1598
Style of a layout element.
Definition: frmfmt.hxx:59
#define SAL_MAX_INT32
int i
SwDoc & GetDoc()
Definition: node.hxx:213
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
tools::SvRef< SotStorageStream > OpenSotStream(const OUString &rEleName, StreamMode=StreamMode::STD_READWRITE)
constexpr TypedWhichId< SwCropGrf > RES_GRFATR_CROPGRF(134)
void WriteGrfFromGrfNode(SvStream &rStrm, const SwGrfNode &rNd, const ww8::Frame &rFly, sal_uInt16 nWidth, sal_uInt16 nHeight)
Definition: wrtww8gr.cxx:628
const SvxPageUsage aArr[]
const ww8::Frame * m_pParentFrame
Definition: wrtww8.hxx:519
eINCLUDEPICTURE
std::size_t WriteBytes(const void *pData, std::size_t nSize)
float u
const Graphic & GetGraphic() const
SwDoc & m_rDoc
Definition: wrtww8.hxx:575
virtual void WriteCR(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner=ww8::WW8TableNodeInfoInner::Pointer_t()) override
Definition: wrtww8.cxx:1861
SwWW8Writer & GetWriter() const
Definition: wrtww8.hxx:1185
::Color BGRToRGB(sal_uInt32 nColour)
WW8OleMap m_aOleMap
Definition: wrtww8.hxx:477
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
tools::Long GetHeight() const
tools::Long SwTwips
Definition: swtypes.hxx:51
constexpr TypedWhichId< SwFormatContent > RES_CNTNT(95)
SVBT16 aBits2
Definition: ww8struc.hxx:264
SwWW8Writer * m_pWriter
Pointer to the writer.
Definition: wrtww8.hxx:1009
sal_uInt8 dptLineWidth() const
Definition: ww8struc.hxx:323
Size GetPrefSize() const
sal_Int32 GetBottom() const
virtual void OutputGrfNode(const SwGrfNode &) override
Output SwGrfNode.
Definition: wrtww8gr.cxx:75
const SwNode * GetContent() const
Get the first node of content in the frame.
sal_Int32 GetTop() const
SotStorage & GetStorage() const
Definition: shellio.hxx:499
SvStream & Strm() const
Definition: wrtww8.hxx:1186
#define ERRCODE_NONE
unsigned char sal_uInt8
Make exporting a Writer Frame easy.
std::unique_ptr< SwWW8WrGrf > m_pGrf
Definition: wrtww8.hxx:536
const OUString & GetTargetFrameName() const
Definition: fmturl.hxx:65
virtual void WritePictures()
Definition: wrtw8esh.cxx:2161
#define GRF_MAGIC_321
Definition: wrtww8.hxx:138
#define SAL_INFO(area, stream)
SvStream & WriteUChar(unsigned char nChar)
const Size & GetSize() const
The Size of the contained element.
virtual SwDrawModel * GetOrCreateDrawModel()=0
virtual void OutputLinkedOLE(const OUString &) override
Definition: wrtww8gr.cxx:320
SvxBoxItemLine
SvStream * m_pDataStrm
Streams for WW97 Export.
Definition: wrtww8.hxx:998
sal_uInt64 Tell() const
void WriteEmptyFlyFrame(const SwFrameFormat &rFormat, sal_uInt32 nShapeId)
Definition: wrtw8esh.cxx:1527
bool TestOleNeedsGraphic(const SwAttrSet &rSet, tools::SvRef< SotStorage > const &xOleStg, const tools::SvRef< SotStorage > &xObjStg, OUString const &rStorageName, SwOLENode *pOLENd)
Definition: wrtww8gr.cxx:86
sal_Int16 GetVertOrient() const
Definition: fmtornt.hxx:54
static void InsUInt16(ww::bytes &rO, sal_uInt16 n)
Definition: wrtww8.cxx:1707
constexpr TypedWhichId< SvxBoxItem > RES_BOX(106)
const SwFormatFrameSize & GetFrameSize(bool=true) const
Definition: fmtfsize.hxx:104
void Write()
Definition: wrtww8gr.cxx:853
sal_Int32 GetRight() const
sal_uInt16 mnHei
Definition: wrtww8.hxx:1392
static GraphicFilter & GetGraphicFilter()
void Insert(const ww8::Frame &rFly)
Definition: wrtww8gr.cxx:470
void Set_UInt8(sal_uInt8 *&p, sal_uInt8 n)
Definition: ww8struc.hxx:41
RndStdIds
bool IsInline() const
Is this frame inline (as character)
WriterSource GetWriterType() const
Get the type of frame that this wraps.
ww8::Frame maFly
Definition: wrtww8.hxx:1389
SwGrfNode * GetGrfNode()
Definition: ndgrf.hxx:154
const SwAttrSet & GetAttrSet() const
For querying the attribute array.
Definition: format.hxx:136
std::unique_ptr< ww::bytes > m_pO
Buffer.
Definition: wrtww8.hxx:996
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
void SvStream & rStrm
void WriteGrfForBullet(SvStream &rStrm, const Graphic &rGrf, sal_uInt16 nWidth, sal_uInt16 nHeight)
Definition: wrtww8gr.cxx:740
static void FillCount(SvStream &rStrm, sal_uLong nCount)
Definition: wrtww8.cxx:931
std::unique_ptr< WW8_WrPlcPn > m_pChpPlc
Definition: wrtww8.hxx:500
constexpr TypedWhichId< SvxShadowItem > RES_SHADOW(107)
sal_uInt16 nPos
const SfxPoolItem * GetCurItem() const
constexpr TypedWhichId< SwFormatAnchor > RES_ANCHOR(104)
constexpr OUStringLiteral aObjectPool
Definition: ww8scan.hxx:45
const OUString & GetURL() const
Definition: fmturl.hxx:66
bool fShadow() const
Definition: ww8struc.hxx:329
Base class of the Writer document model elements.
Definition: node.hxx:81
std::unique_ptr< WW8AttributeOutput > m_pAttrOutput
Converting attributes to stream data.
Definition: wrtww8.hxx:1010