LibreOffice Module sw (master)  1
ww8graf.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 <comphelper/string.hxx>
21 #include <svl/urihelper.hxx>
22 #include <hintids.hxx>
23 #include <osl/endian.h>
24 #include <sal/log.hxx>
25 #include <editeng/lrspitem.hxx>
26 #include <svx/xflbmtit.hxx>
27 #include <svx/xfillit0.hxx>
28 #include <svx/xlineit0.hxx>
29 #include <svx/xlnclit.hxx>
30 #include <svx/xlnwtit.hxx>
31 #include <svx/xlndsit.hxx>
32 #include <svx/xlnstit.hxx>
33 #include <svx/xlnedit.hxx>
34 #include <svx/xlnstwit.hxx>
35 #include <svx/xlnedwit.hxx>
36 #include <svx/xlnstcit.hxx>
37 #include <svx/xlnedcit.hxx>
38 #include <svx/xflclit.hxx>
39 #include <svx/xbtmpit.hxx>
40 #include <svx/svdmodel.hxx>
41 #include <svx/svdocapt.hxx>
42 #include <svx/sxctitm.hxx>
43 #include <svx/sdggaitm.hxx>
44 #include <svx/sdgluitm.hxx>
45 #include <svx/sdgmoitm.hxx>
46 #include <svx/sdmetitm.hxx>
47 #include <svx/sdooitm.hxx>
48 #include <svx/sdshitm.hxx>
49 #include <svx/sdsxyitm.hxx>
50 #include <svx/sdtagitm.hxx>
51 #include <svx/sdtditm.hxx>
52 #include <svx/sdtfsitm.hxx>
53 #include <editeng/editeng.hxx>
54 #include <svx/svdpage.hxx>
55 #include <svx/svdopath.hxx>
56 #include <svx/svdocirc.hxx>
57 #include <editeng/outlobj.hxx>
58 #include <svx/svdogrp.hxx>
59 #include <svx/svdograf.hxx>
60 #include <svx/svdoole2.hxx>
61 #include <editeng/ulspitem.hxx>
62 #include <editeng/brushitem.hxx>
63 #include <editeng/opaqitem.hxx>
64 #include <editeng/shaditem.hxx>
65 #include <editeng/boxitem.hxx>
66 #include <editeng/outliner.hxx>
67 #include <editeng/frmdiritem.hxx>
68 #include <svx/xfltrit.hxx>
70 #include <grfatr.hxx>
71 #include <fmtornt.hxx>
72 #include <fmtcntnt.hxx>
73 #include <frmfmt.hxx>
74 #include <fmtanchr.hxx>
75 #include <pam.hxx>
76 #include <doc.hxx>
77 #include <drawdoc.hxx>
79 #include <ndgrf.hxx>
80 #include <dcontact.hxx>
81 #include <docsh.hxx>
82 #include <mdiexp.hxx>
83 #include "ww8struc.hxx"
84 #include "ww8scan.hxx"
85 #include "ww8par.hxx"
86 #include "ww8par2.hxx"
87 #include "ww8graf.hxx"
88 #include <fmtinfmt.hxx>
89 #include <editeng/eeitem.hxx>
90 #include <editeng/flditem.hxx>
91 #include <fmtfollowtextflow.hxx>
92 #include "writerhelper.hxx"
93 #include "writerwordglue.hxx"
96 #include <editeng/editobj.hxx>
97 #include <math.h>
98 #include <fmturl.hxx>
99 #include <o3tl/enumrange.hxx>
100 #include <o3tl/safeint.hxx>
101 #include <memory>
102 #include <optional>
104 #include "sprmids.hxx"
105 
106 using ::editeng::SvxBorderLine;
107 using namespace ::com::sun::star;
108 using namespace sw::types;
109 using namespace sw::util;
110 
111 // helper methods
112 static Color WW8TransCol(SVBT32 nWC)
113 {
114 #if 1 // 1 = use predefined color, 0 = ignore
115 
116  // color table to convert RGB values to pre-defined colors
117  // (to make the writer UI show the right color names)
118  // the table is split in base 3, the greys are missing as
119  // they don't fit into that system (4 values: bw, wb, 2 * grey)
120  static const Color eColA[] = { // B G R B G R B G R
121  COL_BLACK, COL_RED, COL_LIGHTRED, // 0 0 0, 0 0 1, 0 0 2
122  COL_GREEN, COL_BROWN, COL_BLACK, // 0 1 0, 0 1 1, 0 1 2
123  COL_LIGHTGREEN, COL_BLACK, COL_YELLOW, // 0 2 0, 0 2 1, 0 2 2
124  COL_BLUE, COL_MAGENTA, COL_BLACK, // 1 0 0, 1 0 1, 1 0 2
125  COL_CYAN, COL_LIGHTGRAY, COL_BLACK, // 1 1 0, 1 1 1, 1 1 2
126  COL_BLACK, COL_BLACK, COL_BLACK, // 1 2 0, 1 2 1, 1 2 2
127  COL_LIGHTBLUE, COL_BLACK, COL_LIGHTMAGENTA, // 2 0 0, 2 0 1, 2 0 2
128  COL_BLACK, COL_BLACK, COL_BLACK, // 2 1 0, 2 1 1, 2 1 2
129  COL_LIGHTCYAN, COL_BLACK, COL_WHITE }; // 2 2 0, 2 2 1, 2 2 2
130 
131  // In nWC[3] is a byte that's not described in the WW documentation.
132  // Its meaning appears to be the following: For 0, it's a normal color
133  // whose RGB values are in nWC[0..2]. If nWC[3] is 0x1, 0x7d or 0x83,
134  // it's a grey value whose black portion is given in 0.5% in nWC[0].
135  // I guess that BIT(0) in nWC[3] is relevant for distinguishing RGB/Grey.
136 
137  if( !( nWC[3] & 0x1 ) && // not special (grey)
138  ( ( nWC[0] == 0 || nWC[0]== 0x80 || nWC[0] == 0xff ) // R
139  && ( nWC[1] == 0 || nWC[1]== 0x80 || nWC[1] == 0xff ) // G
140  && ( nWC[2] == 0 || nWC[2]== 0x80 || nWC[2] == 0xff ) ) ){// B
141  int nIdx = 0; // and now: Idx-calculation in base 3
142  for (int i = 2; i >= 0; i--)
143  {
144  nIdx *= 3;
145  if (nWC[i])
146  nIdx += ((nWC[i] == 0xff) ? 2 : 1);
147  }
148  if (eColA[nIdx] != COL_BLACK)
149  return eColA[nIdx]; // default color
150  }
151 #endif
152 
153  if (nWC[3] & 0x1)
154  {
155  // Special color gray
156  sal_uInt8 u = static_cast<sal_uInt8>( static_cast<sal_uLong>( 200 - nWC[0] ) * 256 / 200 );
157  return Color(u, u, u);
158  }
159 
160  // User-Color
161  return Color(nWC[0], nWC[1], nWC[2]);
162 }
163 
164 void wwFrameNamer::SetUniqueGraphName(SwFrameFormat *pFrameFormat, std::u16string_view rFixed)
165 {
166  if (mbIsDisabled || rFixed.empty())
167  return;
168 
169  pFrameFormat->SetName(msSeed+OUString::number(++mnImportedGraphicsCount) + ": " + rFixed);
170 }
171 
172 // ReadGrafStart reads object data and if necessary creates an anchor
173 bool SwWW8ImplReader::ReadGrafStart(void* pData, short nDataSiz,
174  WW8_DPHEAD const * pHd, SfxAllItemSet &rSet)
175 {
176  if (SVBT16ToUInt16(pHd->cb) < sizeof(WW8_DPHEAD) + nDataSiz)
177  {
178  OSL_ENSURE( false, "+graphic element: too short?" );
179  m_pStrm->SeekRel(SVBT16ToUInt16(pHd->cb) - sizeof(WW8_DPHEAD));
180  return false;
181  }
182 
183  bool bCouldRead = checkRead(*m_pStrm, pData, nDataSiz);
184  OSL_ENSURE(bCouldRead, "Short Graphic header");
185  if (!bCouldRead)
186  return false;
187 
188  SwFormatAnchor aAnchor( RndStdIds::FLY_AT_CHAR );
189  aAnchor.SetAnchor( m_pPaM->GetPoint() );
190  rSet.Put( aAnchor );
191 
192  m_nDrawXOfs2 = m_nDrawXOfs;
193  m_nDrawYOfs2 = m_nDrawYOfs;
194 
195  return true;
196 }
197 
198 // SetStdAttr() sets standard attributes
199 static void SetStdAttr( SfxItemSet& rSet, WW8_DP_LINETYPE& rL,
200  WW8_DP_SHADOW const & rSh )
201 {
202  if( SVBT16ToUInt16( rL.lnps ) == 5 ){ // invisible
203  rSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
204  }else{ // visible
205  Color aCol( WW8TransCol( rL.lnpc ) ); // line color
206  rSet.Put( XLineColorItem( OUString(), aCol ) );
207  rSet.Put( XLineWidthItem( SVBT16ToUInt16( rL.lnpw ) ) );
208  // line thickness
209  if( SVBT16ToUInt16( rL.lnps ) >= 1
210  && SVBT16ToUInt16(rL.lnps ) <= 4 ){ // line style
211  rSet.Put( XLineStyleItem( drawing::LineStyle_DASH ) );
212  sal_Int16 nLen = SVBT16ToUInt16( rL.lnpw );
213  XDash aD( css::drawing::DashStyle_RECT, 1, 2 * nLen, 1, 5 * nLen, 5 * nLen );
214  switch( SVBT16ToUInt16( rL.lnps ) ){
215  case 1: aD.SetDots( 0 ); // Dash
216  aD.SetDashLen( 6 * nLen );
217  aD.SetDistance( 4 * nLen );
218  break;
219  case 2: aD.SetDashes( 0 ); break; // Dot
220  case 3: break; // Dash Dot
221  case 4: aD.SetDots( 2 ); break; // Dash Dot Dot
222  }
223  rSet.Put( XLineDashItem( OUString(), aD ) );
224  }else{
225  rSet.Put( XLineStyleItem( drawing::LineStyle_SOLID ) ); // needed for TextBox
226  }
227  }
228  if( SVBT16ToUInt16( rSh.shdwpi ) ){ // shadow
229  rSet.Put(makeSdrShadowItem(true));
230  rSet.Put( makeSdrShadowXDistItem( SVBT16ToUInt16( rSh.xaOffset ) ) );
231  rSet.Put( makeSdrShadowYDistItem( SVBT16ToUInt16( rSh.yaOffset ) ) );
232  }
233 }
234 
235 // SetFill() sets fill attributes such as fore- and background color and
236 // pattern by reducing to a color
237 // SetFill() doesn't yet set a pattern, because Sdr can't easily do that
238 // and the Sdr hatching (XDash) isn't finished yet.
239 // Instead, a mixed color will be picked that's between the selected ones.
240 static void SetFill( SfxItemSet& rSet, WW8_DP_FILL& rFill )
241 {
242  static const sal_uInt8 nPatA[] =
243  {
244  0, 0, 5, 10, 20, 25, 30, 40, 50, 60, 70, 75, 80,
245  90, 50, 50, 50, 50, 50, 50, 33, 33, 33, 33, 33, 33
246  };
247  sal_uInt16 nPat = SVBT16ToUInt16(rFill.flpp);
248 
249  if (nPat == 0) // transparent
250  rSet.Put(XFillStyleItem(drawing::FillStyle_NONE));
251  else
252  {
253  rSet.Put(XFillStyleItem(drawing::FillStyle_SOLID)); // necessary for textbox
254  if (nPat <= 1 || (SAL_N_ELEMENTS(nPatA) <= nPat))
255  {
256  // Solid background or unknown
257  rSet.Put(XFillColorItem(OUString(), WW8TransCol(rFill.dlpcBg)));
258  }
259  else
260  { // Brush -> color mix
261  Color aB( WW8TransCol( rFill.dlpcBg ) );
262  Color aF( WW8TransCol( rFill.dlpcFg ) );
263  aB.SetRed( static_cast<sal_uInt8>( ( static_cast<sal_uLong>(aF.GetRed()) * nPatA[nPat]
264  + static_cast<sal_uLong>(aB.GetRed()) * ( 100 - nPatA[nPat] ) ) / 100 ) );
265  aB.SetGreen( static_cast<sal_uInt8>( ( static_cast<sal_uLong>(aF.GetGreen()) * nPatA[nPat]
266  + static_cast<sal_uLong>(aB.GetGreen()) * ( 100 - nPatA[nPat] ) ) / 100 ) );
267  aB.SetBlue( static_cast<sal_uInt8>( ( static_cast<sal_uLong>(aF.GetBlue()) * nPatA[nPat]
268  + static_cast<sal_uLong>(aB.GetBlue()) * ( 100 - nPatA[nPat] ) ) / 100 ) );
269  rSet.Put( XFillColorItem( OUString(), aB ) );
270  }
271  }
272 }
273 
274 static void SetLineEndAttr( SfxItemSet& rSet, WW8_DP_LINEEND const & rLe,
275  WW8_DP_LINETYPE const & rLt )
276 {
277  sal_uInt16 aSB = SVBT16ToUInt16( rLe.aStartBits );
278  if( aSB & 0x3 )
279  {
280  ::basegfx::B2DPolygon aPolygon;
281  aPolygon.append(::basegfx::B2DPoint(0.0, 330.0));
282  aPolygon.append(::basegfx::B2DPoint(100.0, 0.0));
283  aPolygon.append(::basegfx::B2DPoint(200.0, 330.0));
284  aPolygon.setClosed(true);
285  rSet.Put( XLineEndItem( OUString(), ::basegfx::B2DPolyPolygon(aPolygon) ) );
286  sal_uInt16 nSiz = SVBT16ToUInt16( rLt.lnpw )
287  * ( ( aSB >> 2 & 0x3 ) + ( aSB >> 4 & 0x3 ) );
288  if( nSiz < 220 ) nSiz = 220;
289  rSet.Put(XLineEndWidthItem(nSiz));
290  rSet.Put(XLineEndCenterItem(false));
291  }
292 
293  sal_uInt16 aEB = SVBT16ToUInt16( rLe.aEndBits );
294  if( !(aEB & 0x3) ) return;
295 
296  ::basegfx::B2DPolygon aPolygon;
297  aPolygon.append(::basegfx::B2DPoint(0.0, 330.0));
298  aPolygon.append(::basegfx::B2DPoint(100.0, 0.0));
299  aPolygon.append(::basegfx::B2DPoint(200.0, 330.0));
300  aPolygon.setClosed(true);
301  rSet.Put( XLineStartItem( OUString(), ::basegfx::B2DPolyPolygon(aPolygon) ) );
302  sal_uInt16 nSiz = SVBT16ToUInt16( rLt.lnpw )
303  * ( ( aEB >> 2 & 0x3 ) + ( aEB >> 4 & 0x3 ) );
304  if( nSiz < 220 ) nSiz = 220;
305  rSet.Put(XLineStartWidthItem(nSiz));
306  rSet.Put(XLineStartCenterItem(false));
307 }
308 
309 // start of routines for the different objects
311 {
312  WW8_DP_LINE aLine;
313 
314  if( !ReadGrafStart( static_cast<void*>(&aLine), sizeof( aLine ), pHd, rSet ) )
315  return nullptr;
316 
317  Point aP[2];
318  {
319  Point& rP0 = aP[0];
320  Point& rP1 = aP[1];
321 
322  rP0.setX( static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa )) + m_nDrawXOfs2 );
323  rP0.setY( static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya )) + m_nDrawYOfs2 );
324  rP1 = rP0;
325  rP0.AdjustX(static_cast<sal_Int16>(SVBT16ToUInt16( aLine.xaStart )) );
326  rP0.AdjustY(static_cast<sal_Int16>(SVBT16ToUInt16( aLine.yaStart )) );
327  rP1.AdjustX(static_cast<sal_Int16>(SVBT16ToUInt16( aLine.xaEnd )) );
328  rP1.AdjustY(static_cast<sal_Int16>(SVBT16ToUInt16( aLine.yaEnd )) );
329  }
330 
331  ::basegfx::B2DPolygon aPolygon;
332  aPolygon.append(::basegfx::B2DPoint(aP[0].X(), aP[0].Y()));
333  aPolygon.append(::basegfx::B2DPoint(aP[1].X(), aP[1].Y()));
334  SdrObject* pObj = new SdrPathObj(
335  *m_pDrawModel,
336  SdrObjKind::Line,
337  ::basegfx::B2DPolyPolygon(aPolygon));
338 
339  SetStdAttr( rSet, aLine.aLnt, aLine.aShd );
340  SetLineEndAttr( rSet, aLine.aEpp, aLine.aLnt );
341 
342  return pObj;
343 }
344 
346 {
347  WW8_DP_RECT aRect;
348 
349  if( !ReadGrafStart( static_cast<void*>(&aRect), sizeof( aRect ), pHd, rSet ) )
350  return nullptr;
351 
352  Point aP0( static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa )) + m_nDrawXOfs2,
353  static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya )) + m_nDrawYOfs2 );
354  Point aP1( aP0 );
355  aP1.AdjustX(static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dxa )) );
356  aP1.AdjustY(static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dya )) );
357 
358  SdrObject* pObj = new SdrRectObj(
359  *m_pDrawModel,
360  tools::Rectangle(aP0, aP1));
361 
362  SetStdAttr( rSet, aRect.aLnt, aRect.aShd );
363  SetFill( rSet, aRect.aFill );
364 
365  return pObj;
366 }
367 
369 {
370  WW8_DP_ELLIPSE aEllipse;
371 
372  if( !ReadGrafStart( static_cast<void*>(&aEllipse), sizeof( aEllipse ), pHd, rSet ) )
373  return nullptr;
374 
375  Point aP0( static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa )) + m_nDrawXOfs2,
376  static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya )) + m_nDrawYOfs2 );
377  Point aP1( aP0 );
378  aP1.AdjustX(static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dxa )) );
379  aP1.AdjustY(static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dya )) );
380 
381  SdrObject* pObj = new SdrCircObj(
382  *m_pDrawModel,
383  SdrCircKind::Full,
384  tools::Rectangle(aP0, aP1));
385 
386  SetStdAttr( rSet, aEllipse.aLnt, aEllipse.aShd );
387  SetFill( rSet, aEllipse.aFill );
388 
389  return pObj;
390 }
391 
393 {
394  WW8_DP_ARC aArc;
395 
396  if( !ReadGrafStart( static_cast<void*>(&aArc), sizeof( aArc ), pHd, rSet ) )
397  return nullptr;
398 
399  Point aP0( static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa )) + m_nDrawXOfs2,
400  static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya )) + m_nDrawYOfs2 );
401  Point aP1( aP0 );
402  aP1.AdjustX(static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dxa )) * 2 );
403  aP1.AdjustY(static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dya )) * 2 );
404 
405  short nA[] = { 2, 3, 1, 0 };
406  short nW = nA[ ( ( aArc.fLeft & 1 ) << 1 ) + ( aArc.fUp & 1 ) ];
407  if( !aArc.fLeft ){
408  aP0.AdjustY( -static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dya )) );
409  aP1.AdjustY( -static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dya )) );
410  }
411  if( aArc.fUp ){
412  aP0.AdjustX( -static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dxa )) );
413  aP1.AdjustX( -static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dxa )) );
414  }
415 
416  SdrObject* pObj = new SdrCircObj(
417  *m_pDrawModel,
418  SdrCircKind::Section,
419  tools::Rectangle(aP0, aP1),
420  Degree100(nW * 9000),
421  Degree100(( ( nW + 1 ) & 3 ) * 9000));
422 
423  SetStdAttr( rSet, aArc.aLnt, aArc.aShd );
424  SetFill( rSet, aArc.aFill );
425 
426  return pObj;
427 }
428 
430 {
431  WW8_DP_POLYLINE aPoly;
432 
433  if( !ReadGrafStart( static_cast<void*>(&aPoly), sizeof( aPoly ), pHd, rSet ) )
434  return nullptr;
435 
436  sal_uInt16 nCount = SVBT16ToUInt16( aPoly.aBits1 ) >> 1 & 0x7fff;
437  std::unique_ptr<SVBT16[]> xP(new SVBT16[nCount * 2]);
438 
439  bool bCouldRead = checkRead(*m_pStrm, xP.get(), nCount * 4); // read points
440  OSL_ENSURE(bCouldRead, "Short PolyLine header");
441  if (!bCouldRead)
442  return nullptr;
443 
444  tools::Polygon aP( nCount );
445  Point aPt;
446  for (sal_uInt16 i=0; i<nCount; ++i)
447  {
448  aPt.setX( SVBT16ToUInt16( xP[i << 1] ) + m_nDrawXOfs2
449  + static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa )) );
450  aPt.setY( SVBT16ToUInt16( xP[( i << 1 ) + 1] ) + m_nDrawYOfs2
451  + static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya )) );
452  aP[i] = aPt;
453  }
454  xP.reset();
455 
456  SdrObject* pObj = new SdrPathObj(
457  *m_pDrawModel,
458  (SVBT16ToUInt16(aPoly.aBits1) & 0x1) ? SdrObjKind::Polygon : SdrObjKind::PolyLine,
460 
461  SetStdAttr( rSet, aPoly.aLnt, aPoly.aShd );
462  SetFill( rSet, aPoly.aFill );
463 
464  return pObj;
465 }
466 
467 static ESelection GetESelection(EditEngine const &rDrawEditEngine, tools::Long nCpStart, tools::Long nCpEnd)
468 {
469  sal_Int32 nPCnt = rDrawEditEngine.GetParagraphCount();
470  sal_Int32 nSP = 0;
471  sal_Int32 nEP = 0;
472  while( (nSP < nPCnt)
473  && (nCpStart >= rDrawEditEngine.GetTextLen( nSP ) + 1) )
474  {
475  nCpStart -= rDrawEditEngine.GetTextLen( nSP ) + 1;
476  nSP++;
477  }
478  // at the end, switch to the new line only 1 character later as
479  // otherwise line attributes reach one line too far
480  while( (nEP < nPCnt)
481  && (nCpEnd > rDrawEditEngine.GetTextLen( nEP ) + 1) )
482  {
483  nCpEnd -= rDrawEditEngine.GetTextLen( nEP ) + 1;
484  nEP++;
485  }
486  return ESelection( nSP, nCpStart, nEP, nCpEnd );
487 }
488 
489 // InsertTxbxStyAttrs() sets style attributes into the passed ItemSet.
490 // SW styles are used since import-WW-styles are already destroyed.
491 // SW styles are examined in depth first search order (with parent styles)
492 // for the attributes given in aSrcTab. They're cloned, and the clones'
493 // Which-IDs are changed according to the aDstTab table so that the
494 // EditEngine will not ignore them.
495 // Both Paragraph and character attributes are stuffed into the ItemSet.
496 void SwWW8ImplReader::InsertTxbxStyAttrs( SfxItemSet& rS, sal_uInt16 nColl )
497 {
498  SwWW8StyInf * pStyInf = GetStyle(nColl);
499  if( !(pStyInf != nullptr && pStyInf->m_pFormat && pStyInf->m_bColl) )
500  return;
501 
502  const SfxPoolItem* pItem;
503  for( sal_uInt16 i = POOLATTR_BEGIN; i < POOLATTR_END; i++ )
504  {
505  // If we are set in the source and not set in the destination
506  // then add it in.
507  if ( SfxItemState::SET == pStyInf->m_pFormat->GetItemState(
508  i, true, &pItem ) )
509  {
510  SfxItemPool *pEditPool = rS.GetPool();
511  sal_uInt16 nWhich = i;
512  sal_uInt16 nSlotId = m_rDoc.GetAttrPool().GetSlotId(nWhich);
513  if (
514  nSlotId && nWhich != nSlotId &&
515  0 != (nWhich = pEditPool->GetWhich(nSlotId)) &&
516  nWhich != nSlotId &&
517  ( SfxItemState::SET != rS.GetItemState(nWhich, false) )
518  )
519  {
520  rS.Put( pItem->CloneSetWhich(nWhich) );
521  }
522  }
523  }
524 
525 }
526 
527 static void lcl_StripFields(OUString &rString, WW8_CP &rNewStartCp)
528 {
529  sal_Int32 nStartPos = 0;
530  for (;;)
531  {
532  nStartPos = rString.indexOf(0x13, nStartPos);
533  if (nStartPos<0)
534  return;
535 
536  const sal_Unicode cStops[] = {0x14, 0x15, 0};
537  const sal_Int32 nStopPos = comphelper::string::indexOfAny(rString, cStops, nStartPos);
538  if (nStopPos<0)
539  {
540  rNewStartCp += rString.getLength()-nStartPos;
541  rString = rString.copy(0, nStartPos);
542  return;
543  }
544 
545  const bool was0x14 = rString[nStopPos]==0x14;
546  rString = rString.replaceAt(nStartPos, nStopPos+1-nStartPos, u"");
547  rNewStartCp += nStopPos-nStartPos;
548 
549  if (was0x14)
550  {
551  ++rNewStartCp;
552  nStartPos = rString.indexOf(0x15, nStartPos);
553  if (nStartPos<0)
554  return;
555  rString = rString.replaceAt(nStartPos, 1, u"");
556  }
557  }
558 }
559 
560 namespace {
561 
562 class Chunk
563 {
564 private:
565  OUString msURL;
566  tools::Long mnStartPos; // 0x13
567  tools::Long mnEndPos; // 0x15
568 public:
569  explicit Chunk(tools::Long nStart, const OUString &rURL)
570  : msURL(rURL), mnStartPos(nStart), mnEndPos(0) {}
571 
572  void SetEndPos(tools::Long nEnd) { mnEndPos = nEnd; }
573  tools::Long GetStartPos() const {return mnStartPos;}
574  tools::Long GetEndPos() const {return mnEndPos;}
575  const OUString &GetURL() const {return msURL;}
576  void Adjust(sal_Int32 nAdjust)
577  {
578  mnStartPos-=nAdjust;
579  mnEndPos-=nAdjust;
580  }
581 };
582 
583  bool IsValidSel(const EditEngine& rEngine, const ESelection& rSel)
584  {
585  const auto nParaCount = rEngine.GetParagraphCount();
586  if (rSel.nStartPara < nParaCount && rSel.nEndPara < nParaCount)
587  return rSel.nStartPos >= 0 && rSel.nEndPos >= 0;
588  return false;
589  }
590 }
591 
592 // InsertAttrsAsDrawingAttrs() sets attributes between StartCp and EndCp.
593 // Style attributes are set as hard, paragraph and character attributes.
595  ManTypes eType, bool bONLYnPicLocFc)
596 {
597  /*
598  Save and create new plcxman for this drawing object, of the type that
599  will include the para end mark inside a paragraph property range, as
600  drawing boxes have real paragraph marks as part of their text, while
601  normal writer has separate nodes for each paragraph and so has no actual
602  paragraph mark as part of the paragraph text.
603  */
604  WW8ReaderSave aSave(this);
605  m_xPlcxMan = std::make_shared<WW8PLCFMan>(m_xSBase.get(), eType, nStartCp, true);
606 
607  WW8_CP nStart = m_xPlcxMan->Where();
608  WW8_CP nNext, nStartReplace=0;
609 
610  bool bDoingSymbol = false;
611  sal_Unicode cReplaceSymbol = m_cSymbol;
612 
613  std::optional<SfxItemSet> pS(m_pDrawEditEngine->GetEmptyItemSet());
614  WW8PLCFManResult aRes;
615 
616  std::deque<Chunk> aChunks;
617 
618  // Here store stack location
619  size_t nCurrentCount = m_xCtrlStck->size();
620  while (nStart < nEndCp)
621  {
622  // nStart is the beginning of the attributes for this range, and
623  // may be before the text itself. So watch out for that
624  WW8_CP nTextStart = nStart;
625  if (nTextStart < nStartCp)
626  nTextStart = nStartCp;
627 
628  // get position of next SPRM
629  bool bStartAttr = m_xPlcxMan->Get(&aRes);
630  m_nCurrentColl = m_xPlcxMan->GetColl();
631  if (aRes.nSprmId)
632  {
633  if( bONLYnPicLocFc )
634  {
635  if ( (68 == aRes.nSprmId) || (0x6A03 == aRes.nSprmId) )
636  {
637  Read_PicLoc(aRes.nSprmId, aRes.pMemPos +
638  m_xSprmParser->DistanceToData(aRes.nSprmId), 4);
639  // Ok, that's what we were looking for. Now let's get
640  // out of here!
641  break;
642  }
643  }
644  else if ((eFTN > aRes.nSprmId) || (0x0800 <= aRes.nSprmId))
645  {
646  // Here place them onto our usual stack and we will pop them
647  // off and convert them later
648  if (bStartAttr)
649  {
650  ImportSprm(aRes.pMemPos, aRes.nMemLen, aRes.nSprmId);
651  if (!bDoingSymbol && m_bSymbol)
652  {
653  bDoingSymbol = true;
654  nStartReplace = nTextStart;
655  cReplaceSymbol = m_cSymbol;
656  }
657  }
658  else
659  {
660  EndSprm( aRes.nSprmId );
661  if (!m_bSymbol && bDoingSymbol)
662  {
663  bDoingSymbol = false;
664 
665  ESelection aReplaceSel(GetESelection(*m_pDrawEditEngine, nStartReplace - nStartCp,
666  nTextStart - nStartCp));
667 
668  sal_Int32 nParaCount = m_pDrawEditEngine->GetParagraphCount();
669  bool bBadSelection = aReplaceSel.nStartPara >= nParaCount || aReplaceSel.nEndPara >= nParaCount;
670 
671  SAL_WARN_IF(bBadSelection, "sw.ww8", "editengine has different amount of text than expected");
672 
673  if (!bBadSelection)
674  {
675  sal_Int32 nCount = nTextStart - nStartReplace;
676  OUStringBuffer sTemp(nCount);
677  comphelper::string::padToLength(sTemp, nCount, cReplaceSymbol);
678  m_pDrawEditEngine->QuickInsertText(sTemp.makeStringAndClear(), aReplaceSel);
679  }
680  }
681  }
682  }
683  else if (aRes.nSprmId == eFLD)
684  {
685  if (bStartAttr)
686  {
687  size_t nCount = m_xCtrlStck->size();
688  if (m_aFieldStack.empty() && Read_Field(&aRes))
689  {
690  OUString sURL;
691  for (size_t nI = m_xCtrlStck->size(); nI > nCount; --nI)
692  {
693  const SfxPoolItem *pItem = ((*m_xCtrlStck)[nI-1]).m_pAttr.get();
694  sal_uInt16 nWhich = pItem->Which();
695  if (nWhich == RES_TXTATR_INETFMT)
696  {
697  const SwFormatINetFormat *pURL =
698  static_cast<const SwFormatINetFormat *>(pItem);
699  sURL = pURL->GetValue();
700  }
701  m_xCtrlStck->DeleteAndDestroy(nI-1);
702  }
703  aChunks.emplace_back(nStart, sURL);
704  }
705  }
706  else
707  {
708  if (!m_aFieldStack.empty() && End_Field() && !aChunks.empty())
709  aChunks.back().SetEndPos(nStart+1);
710  }
711  }
712  }
713 
714  m_xPlcxMan->advance();
715  nNext = m_xPlcxMan->Where();
716 
717  const WW8_CP nEnd = ( nNext < nEndCp ) ? nNext : nEndCp;
718  if (!bONLYnPicLocFc && nNext != nStart && nEnd >= nStartCp)
719  {
720  SfxItemPool *pEditPool = pS->GetPool();
721 
722  // Here read current properties and convert them into pS
723  // and put those attrs into the draw box if they can be converted
724  // to draw attributes
725  if (m_xCtrlStck->size() - nCurrentCount)
726  {
727  for (size_t i = nCurrentCount; i < m_xCtrlStck->size(); ++i)
728  {
729  const SfxPoolItem *pItem = ((*m_xCtrlStck)[i]).m_pAttr.get();
730  sal_uInt16 nWhich = pItem->Which();
731  if( nWhich < RES_FLTRATTR_BEGIN ||
732  nWhich >= RES_FLTRATTR_END )
733  {
734  sal_uInt16 nSlotId = m_rDoc.GetAttrPool().GetSlotId(nWhich);
735  if (
736  nSlotId && nWhich != nSlotId &&
737  0 != (nWhich = pEditPool->GetWhich(nSlotId)) &&
738  nWhich != nSlotId
739  )
740  {
741  pS->Put( pItem->CloneSetWhich(nWhich) );
742  }
743  }
744  }
745  }
746  // Fill in the remainder from the style
747  InsertTxbxStyAttrs(*pS, m_nCurrentColl);
748 
749  if( pS->Count() )
750  {
751  m_pDrawEditEngine->QuickSetAttribs( *pS,
752  GetESelection(*m_pDrawEditEngine, nTextStart - nStartCp, nEnd - nStartCp ) );
753  pS.emplace(m_pDrawEditEngine->GetEmptyItemSet());
754  }
755  }
756  nStart = nNext;
757  }
758  pS.reset();
759 
760  // pop off as far as recorded location just in case there were some left
761  // unclosed
762  for (size_t nI = m_xCtrlStck->size(); nI > nCurrentCount; --nI)
763  m_xCtrlStck->DeleteAndDestroy(nI-1);
764 
765  auto aEnd = aChunks.end();
766  for (auto aIter = aChunks.begin(); aIter != aEnd; ++aIter)
767  {
768  ESelection aSel(GetESelection(*m_pDrawEditEngine, aIter->GetStartPos()-nStartCp,
769  aIter->GetEndPos()-nStartCp));
770  if (!IsValidSel(*m_pDrawEditEngine, aSel))
771  continue;
772  OUString aString(m_pDrawEditEngine->GetText(aSel));
773  const sal_Int32 nOrigLen = aString.getLength();
774  WW8_CP nDummy(0);
775  lcl_StripFields(aString, nDummy);
776 
777  sal_Int32 nChanged;
778  if (!aIter->GetURL().isEmpty())
779  {
780  SvxURLField aURL(aIter->GetURL(), aString, SvxURLFormat::AppDefault);
781  m_pDrawEditEngine->QuickInsertField(SvxFieldItem(aURL, EE_FEATURE_FIELD), aSel);
782  nChanged = nOrigLen - 1;
783  }
784  else
785  {
786  m_pDrawEditEngine->QuickInsertText(aString, aSel);
787  nChanged = nOrigLen - aString.getLength();
788  }
789  for (auto aIter2 = aIter+1; aIter2 != aEnd; ++aIter2)
790  aIter2->Adjust(nChanged);
791  }
792 
793  /*
794  Don't worry about the new pPlcxMan, the restore removes it when
795  replacing the current one with the old one.
796  */
797  aSave.Restore(this);
798 }
799 
801  sal_uInt16 nTxBxS, sal_uInt16 nSequence)
802 {
803  // grab the TextBox-PLCF quickly
804  WW8PLCFspecial* pT = m_xPlcxMan ? m_xPlcxMan->GetTxbx() : nullptr;
805  if( !pT )
806  {
807  OSL_ENSURE( false, "+where's the text graphic (1)?" );
808  return false;
809  }
810 
811  // if applicable first find the right TextBox-Story
812  bool bCheckTextBoxStory = ( nTxBxS && pT->GetIMax() >= nTxBxS );
813  if( bCheckTextBoxStory )
814  pT->SetIdx( nTxBxS-1 );
815 
816  // then determine start and end
817  void* pT0;
818  if (!pT->Get(rStartCp, pT0) || rStartCp < 0)
819  {
820  OSL_ENSURE( false, "+where's the text graphic (2)?" );
821  return false;
822  }
823 
824  if( bCheckTextBoxStory )
825  {
826  bool bReusable = (0 != SVBT16ToUInt16( static_cast<WW8_TXBXS*>(pT0)->fReusable ));
827  while( bReusable )
828  {
829  pT->advance();
830  if( !pT->Get( rStartCp, pT0 ) )
831  {
832  OSL_ENSURE( false, "+where's the text graphic (2a)?" );
833  return false;
834  }
835  bReusable = (0 != SVBT16ToUInt16( static_cast<WW8_TXBXS*>(pT0)->fReusable ));
836  }
837  }
838  pT->advance();
839  if (!pT->Get(rEndCp, pT0) || rEndCp < 0)
840  {
841  OSL_ENSURE( false, "+where's the text graphic (3)?" );
842  return false;
843  }
844 
845  // find the right page in the break table (if necessary)
846  if( bCheckTextBoxStory )
847  {
848  // special case: entire chain should be determined - done!
849  if( USHRT_MAX > nSequence )
850  {
851  tools::Long nMinStartCp = rStartCp;
852  tools::Long nMaxEndCp = rEndCp;
853  // quickly grab the TextBox-Break-Descriptor-PLCF
854  pT = m_xPlcxMan->GetTxbxBkd();
855  if (!pT) // It can occur on occasion, Caolan
856  return false;
857 
858  // find first entry for this TextBox story
859  if( !pT->SeekPos( rStartCp ) )
860  {
861  OSL_ENSURE( false, "+where's the text graphic (4)" );
862  return false;
863  }
864  // if needed skip the appropriate number of entries
865  for (sal_uInt16 iSequence = 0; iSequence < nSequence; ++iSequence)
866  pT->advance();
867  // and determine actual start and end
868  if( (!pT->Get( rStartCp, pT0 ))
869  || ( nMinStartCp > rStartCp ) )
870  {
871  OSL_ENSURE( false, "+where's the text graphic (5)?" );
872  return false;
873  }
874  if( rStartCp >= nMaxEndCp )
875  rEndCp = rStartCp; // not an error: empty string
876  else
877  {
878  pT->advance();
879  if ( (!pT->Get(rEndCp, pT0)) || (nMaxEndCp < rEndCp-1) )
880  {
881  OSL_ENSURE( false, "+where's the text graphic (6)?" );
882  return false;
883  }
884  rEndCp -= 1;
885  }
886  }
887  else
888  rEndCp -= 1;
889  }
890  else
891  rEndCp -= 1;
892  return true;
893 }
894 
895 // TxbxText() grabs the text from the WW file and returns that along with
896 // the StartCp and the corrected (by -2, or -1 for version 8) EndCp.
897 sal_Int32 SwWW8ImplReader::GetRangeAsDrawingString(OUString& rString, tools::Long nStartCp, tools::Long nEndCp, ManTypes eType)
898 {
899  WW8_CP nOffset = 0;
900  m_xWwFib->GetBaseCp(eType, &nOffset); //TODO: check return value
901 
902  OSL_ENSURE(nStartCp <= nEndCp, "+where's the graphic text (7)?");
903  if (nStartCp == nEndCp)
904  rString.clear(); // empty string: entirely possible
905  else if (nStartCp < nEndCp)
906  {
907  // read the text: can be split into multiple pieces
908  const sal_Int32 nLen = m_xSBase->WW8ReadString(*m_pStrm, rString,
909  nStartCp + nOffset, nEndCp - nStartCp, GetCurrentCharSet());
910  OSL_ENSURE(nLen, "+where's the text graphic (8)?");
911  if (nLen>0)
912  {
913  if( rString[nLen-1]==0x0d )
914  rString = rString.copy(0, nLen-1);
915 
916  rString = rString.replace( 0xb, 0xa );
917  return nLen;
918  }
919  }
920  return 0;
921 }
922 
923 //EditEngine::InsertText will replace dos lines resulting in a shorter
924 //string than is passed in, so inserting attributes based on the original
925 //string len can fail. So here replace the dos line ends similar to
926 //how EditEngine does it, but preserve the length and replace the extra
927 //chars with placeholders, record the position of the placeholders and
928 //remove those extra chars after attributes have been inserted
929 static std::vector<sal_Int32> replaceDosLineEndsButPreserveLength(OUString &rIn)
930 {
931  OUStringBuffer aNewData(rIn);
932  std::vector<sal_Int32> aDosLineEndDummies;
933  sal_Int32 i = 0;
934  sal_Int32 nStrLen = rIn.getLength();
935  while (i < nStrLen)
936  {
937  // \r or \n causes linebreak
938  if (rIn[i] == '\r' || rIn[i] == '\n')
939  {
940  // skip char if \r\n or \n\r
941  if ( (i+1) < nStrLen && ((rIn[i+1] == '\r') || (rIn[i+1] == '\n')) &&
942  (rIn[i] != rIn[i+1]) )
943  {
944  ++i;
945  aDosLineEndDummies.push_back(i);
946  aNewData[i] = 0;
947  }
948  }
949  ++i;
950  }
951  rIn = aNewData.makeStringAndClear();
952  return aDosLineEndDummies;
953 }
954 
955 static void removePositions(EditEngine &rDrawEditEngine, const std::vector<sal_Int32>& rDosLineEndDummies)
956 {
957  for (auto aIter = rDosLineEndDummies.rbegin(); aIter != rDosLineEndDummies.rend(); ++aIter)
958  {
959  sal_Int32 nCharPos(*aIter);
960  rDrawEditEngine.QuickDelete(GetESelection(rDrawEditEngine, nCharPos, nCharPos+1));
961  }
962 }
963 
965 {
967 
968  sal_Int32 nLen = GetRangeAsDrawingString(rString, nStartCp, nEndCp, eType);
969  if (nLen > 0)
970  {
971  if (m_bFuzzing && rString.getLength() > 1024)
972  {
973  SAL_WARN("sw.ww8", "Truncating long EditEngine strings when fuzzing for performance");
974  rString = rString.copy(0, 1024);
975  }
976 
977  if (!m_pDrawEditEngine)
978  {
979  m_pDrawEditEngine.reset(new EditEngine(nullptr));
980  }
981 
982  //replace dos line endings with editeng ones, replace any extra chars with
983  //placeholders to keep the inserted string len in sync with the attribute cps
984  //and record in aDosLineEnds the superfluous positions
985  OUString sEEString(rString);
986  std::vector<sal_Int32> aDosLineEnds(replaceDosLineEndsButPreserveLength(sEEString));
987  m_pDrawEditEngine->SetText(sEEString);
988  InsertAttrsAsDrawingAttrs(nStartCp, nStartCp+nLen, eType);
989  //remove any superfluous placeholders of replaceDosLineEndsButPreserveLength
990  //after attributes have been inserted
991  removePositions(*m_pDrawEditEngine, aDosLineEnds);
992 
993  // Annotations typically begin with a (useless) 0x5
994  if ((eType == MAN_AND) && m_pDrawEditEngine->GetTextLen())
995  {
996  ESelection aFirstChar(0, 0, 0, 1);
997  if (m_pDrawEditEngine->GetText( aFirstChar ) == "\x05")
998  m_pDrawEditEngine->QuickDelete(aFirstChar);
999  }
1000 
1001  std::unique_ptr<EditTextObject> pTemporaryText = m_pDrawEditEngine->CreateTextObject();
1002  pRet.emplace( std::move(pTemporaryText) );
1003  pRet->SetOutlinerMode( OutlinerMode::TextObject );
1004 
1005  m_pDrawEditEngine->SetText( OUString() );
1006  m_pDrawEditEngine->SetParaAttribs(0, m_pDrawEditEngine->GetEmptyItemSet());
1007 
1008  // Strip out fields, leaving the result
1009  WW8_CP nDummy(0);
1010  lcl_StripFields(rString, nDummy);
1011  // Strip out word's special characters for the simple string
1012  rString = rString.replaceAll("\x01", "");
1013  rString = rString.replaceAll("\x05", "");
1014  rString = rString.replaceAll("\x08", "");
1015  rString = rString.replaceAll("\007\007", "\007\012");
1016  rString = rString.replace(0x7, ' ');
1017  }
1018 
1019  return pRet;
1020 }
1021 
1022 // InsertTxbxText() adds the Text and the Attributes for TextBoxes and CaptionBoxes
1024  Size const * pObjSiz, sal_uInt16 nTxBxS, sal_uInt16 nSequence, tools::Long nPosCp,
1025  SwFrameFormat const * pOldFlyFormat, bool bMakeSdrGrafObj, bool& rbEraseTextObj,
1026  bool* pbTestTxbxContainsText, tools::Long* pnStartCp, tools::Long* pnEndCp,
1027  bool* pbContainsGraphics, SvxMSDffImportRec const * pRecord)
1028 {
1029  SwFrameFormat* pFlyFormat = nullptr;
1030  sal_uInt64 nOld = m_pStrm->Tell();
1031 
1032  ManTypes eType = m_xPlcxMan->GetManType() == MAN_HDFT ? MAN_TXBX_HDFT : MAN_TXBX;
1033 
1034  rbEraseTextObj = false;
1035 
1036  OUString aString;
1037  WW8_CP nStartCp, nEndCp;
1038  bool bContainsGraphics = false;
1039  bool bTextWasRead = GetTxbxTextSttEndCp(nStartCp, nEndCp, nTxBxS, nSequence) &&
1040  GetRangeAsDrawingString(aString, nStartCp, nEndCp, eType) > 0;
1041 
1042  if (!m_pDrawEditEngine)
1043  {
1044  m_pDrawEditEngine.reset(new EditEngine(nullptr));
1045  }
1046  if( pObjSiz )
1047  m_pDrawEditEngine->SetPaperSize( *pObjSiz );
1048 
1049  if (m_bFuzzing && aString.getLength() > 1024)
1050  {
1051  SAL_WARN("sw.ww8", "Truncating long EditEngine strings when fuzzing for performance");
1052  aString = aString.copy(0, 1024);
1053  }
1054 
1055  const OUString aOrigString(aString);
1056  if( bTextWasRead )
1057  {
1058  WW8_CP nNewStartCp = nStartCp;
1059  lcl_StripFields(aString, nNewStartCp);
1060 
1061  if (aString.getLength()!=1)
1062  {
1063  bContainsGraphics = aString.indexOf(0x1)<0 || aString.indexOf(0x8)<0;
1064  }
1065  else // May be a single graphic or object
1066  {
1067  bool bDone = true;
1068  switch( aString[0] )
1069  {
1070  case 0x1:
1071  if (!pbTestTxbxContainsText)
1072  {
1073  WW8ReaderSave aSave(this, nNewStartCp -1);
1074  bool bOldEmbeddObj = m_bEmbeddObj;
1075  // bEmbeddObj Ordinarily would have been set by field
1076  // parse, but this is impossible here so...
1077  m_bEmbeddObj = true;
1078 
1079  // 1st look for OLE- or Graph-Indicator Sprms
1080  WW8PLCFx_Cp_FKP* pChp = m_xPlcxMan->GetChpPLCF();
1081  WW8PLCFxDesc aDesc;
1082  pChp->GetSprms( &aDesc );
1083  WW8SprmIter aSprmIter(aDesc.pMemPos, aDesc.nSprmsLen, *m_xSprmParser);
1084 
1085  for( int nLoop = 0; nLoop < 2; ++nLoop )
1086  {
1087  while (aSprmIter.GetSprms())
1088  {
1089  const sal_uInt8 *const pParams(aSprmIter.GetCurrentParams());
1090  if (nullptr == pParams)
1091  break;
1092  sal_uInt16 nCurrentId = aSprmIter.GetCurrentId();
1093  switch( nCurrentId )
1094  {
1095  case 75:
1096  case 118:
1097  case 0x080A:
1098  case 0x0856:
1099  Read_Obj(nCurrentId, pParams, 1);
1100  break;
1101  case 68: // Read_Pic()
1102  case 0x6A03:
1104  Read_PicLoc(nCurrentId, pParams, 1);
1105  break;
1106  }
1107  aSprmIter.advance();
1108  }
1109 
1110  if( !nLoop )
1111  {
1112  pChp->GetPCDSprms( aDesc );
1113  aSprmIter.SetSprms( aDesc.pMemPos,
1114  aDesc.nSprmsLen );
1115  }
1116  }
1117  aSave.Restore(this);
1118  m_bEmbeddObj=bOldEmbeddObj;
1119 
1120  // then import either an OLE of a Graphic
1121  if( m_bObj )
1122  {
1123  if( bMakeSdrGrafObj && pTextObj &&
1124  pTextObj->getParentSdrObjectFromSdrObject() )
1125  {
1126  // use SdrOleObj/SdrGrafObj instead of
1127  // SdrTextObj in this Group
1128 
1129  Graphic aGraph;
1130  SdrObject* pNew = ImportOleBase(aGraph);
1131 
1132  if( !pNew )
1133  {
1134  pNew = new SdrGrafObj(*m_pDrawModel);
1135  static_cast<SdrGrafObj*>(pNew)->SetGraphic(aGraph);
1136  }
1137 
1138  GraphicCtor();
1139 
1140  pNew->SetLogicRect( pTextObj->GetCurrentBoundRect() );
1141  pNew->SetLayer( pTextObj->GetLayer() );
1142 
1144  ReplaceObject(pNew, pTextObj->GetOrdNum());
1145  }
1146  else
1147  pFlyFormat = ImportOle();
1148  m_bObj = false;
1149  }
1150  else
1151  {
1152  InsertAttrsAsDrawingAttrs(nNewStartCp, nNewStartCp+1,
1153  eType, true);
1154  pFlyFormat = ImportGraf(bMakeSdrGrafObj ? pTextObj : nullptr,
1155  pOldFlyFormat);
1156  }
1157  }
1158  break;
1159  case 0x8:
1160  if ( (!pbTestTxbxContainsText) && (!m_bObj) )
1161  pFlyFormat = Read_GrafLayer( nPosCp );
1162  break;
1163  default:
1164  bDone = false;
1165  break;
1166  }
1167 
1168  if( bDone )
1169  {
1170  if( pFlyFormat && pRecord )
1171  {
1173  aFlySet( m_rDoc.GetAttrPool() );
1174 
1175  tools::Rectangle aInnerDist( pRecord->nDxTextLeft,
1176  pRecord->nDyTextTop,
1177  pRecord->nDxTextRight,
1178  pRecord->nDyTextBottom );
1179  MatchSdrItemsIntoFlySet( pTextObj,
1180  aFlySet,
1181  pRecord->eLineStyle,
1182  pRecord->eLineDashing,
1183  pRecord->eShapeType,
1184  aInnerDist );
1185 
1186  pFlyFormat->SetFormatAttr( aFlySet );
1187 
1188  MapWrapIntoFlyFormat(*pRecord, *pFlyFormat);
1189  }
1190  aString.clear();
1191  rbEraseTextObj = (nullptr != pFlyFormat);
1192  }
1193  }
1194  }
1195 
1196  if( pnStartCp )
1197  *pnStartCp = nStartCp;
1198  if( pnEndCp )
1199  *pnEndCp = nEndCp;
1200 
1201  if( pbTestTxbxContainsText )
1202  *pbTestTxbxContainsText = bTextWasRead && ! rbEraseTextObj;
1203  else if( !rbEraseTextObj )
1204  {
1205  if( bTextWasRead )
1206  {
1207  m_pDrawEditEngine->SetText(aOrigString);
1208  InsertAttrsAsDrawingAttrs(nStartCp, nEndCp, eType);
1209  }
1210 
1211  bool bVertical = pTextObj->IsVerticalWriting();
1212  OutlinerParaObject aOp(m_pDrawEditEngine->CreateTextObject());
1213  aOp.SetOutlinerMode( OutlinerMode::TextObject );
1214  aOp.SetVertical( bVertical );
1215  pTextObj->NbcSetOutlinerParaObject( std::move(aOp) );
1216  pTextObj->SetVerticalWriting(bVertical);
1217 
1218  // For the next TextBox also remove the old paragraph attributes
1219  // and styles, otherwise the next box will start with the wrong
1220  // attributes.
1221  // Course of action: delete text = reduce to one paragraph
1222  // and on this one delete the paragraph attributes
1223  // and styles
1224  m_pDrawEditEngine->SetText( OUString() );
1225  m_pDrawEditEngine->SetParaAttribs(0, m_pDrawEditEngine->GetEmptyItemSet());
1226  }
1227 
1228  m_pStrm->Seek( nOld );
1229  if (pbContainsGraphics)
1230  *pbContainsGraphics = bContainsGraphics;
1231 }
1232 
1234  tools::Long& rEndCp)
1235 {
1236  bool bErase, bContainsText;
1237  InsertTxbxText( nullptr,nullptr,nTxBxS,USHRT_MAX,0,nullptr,false, bErase, &bContainsText,
1238  &rStartCp, &rEndCp );
1239  return bContainsText;
1240 }
1241 
1242 // TextBoxes only for Ver67 !!
1244 {
1245  bool bDummy;
1246  WW8_DP_TXTBOX aTextB;
1247 
1248  if( !ReadGrafStart( static_cast<void*>(&aTextB), sizeof( aTextB ), pHd, rSet ) )
1249  return nullptr;
1250 
1251  Point aP0( static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa )) + m_nDrawXOfs2,
1252  static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya )) + m_nDrawYOfs2 );
1253  Point aP1( aP0 );
1254  aP1.AdjustX(static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dxa )) );
1255  aP1.AdjustY(static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dya )) );
1256 
1257  SdrRectObj* pObj = new SdrRectObj(
1258  *m_pDrawModel,
1259  SdrObjKind::Text,
1260  tools::Rectangle(aP0, aP1));
1261 
1262  pObj->NbcSetSnapRect(tools::Rectangle(aP0, aP1));
1263  Size aSize( static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dxa )) ,
1264  static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dya )) );
1265 
1266  tools::Long nStartCpFly,nEndCpFly;
1267  bool bContainsGraphics;
1268  InsertTxbxText(pObj, &aSize, 0, 0, 0, nullptr, false,
1269  bDummy,nullptr,&nStartCpFly,&nEndCpFly,&bContainsGraphics);
1270 
1271  SetStdAttr( rSet, aTextB.aLnt, aTextB.aShd );
1272  SetFill( rSet, aTextB.aFill );
1273 
1274  rSet.Put( SdrTextFitToSizeTypeItem( drawing::TextFitToSizeType_NONE ) );
1275  rSet.Put( makeSdrTextAutoGrowWidthItem(false));
1276  rSet.Put( makeSdrTextAutoGrowHeightItem(false));
1281 
1282  return pObj;
1283 }
1284 
1286 {
1287  static const SdrCaptionType aCaptA[] = { SdrCaptionType::Type1, SdrCaptionType::Type2,
1288  SdrCaptionType::Type3, SdrCaptionType::Type4 };
1289 
1290  WW8_DP_CALLOUT_TXTBOX aCallB;
1291 
1292  if( !ReadGrafStart( static_cast<void*>(&aCallB), sizeof( aCallB ), pHd, rSet ) )
1293  return nullptr;
1294 
1295  sal_uInt16 nCount = SVBT16ToUInt16( aCallB.dpPolyLine.aBits1 ) >> 1 & 0x7fff;
1296  if (nCount < 1)
1297  {
1298  SAL_WARN("sw.ww8", "Short CaptionBox header");
1299  return nullptr;
1300  }
1301 
1302  std::unique_ptr<SVBT16[]> xP(new SVBT16[nCount * 2]);
1303 
1304  bool bCouldRead = checkRead(*m_pStrm, xP.get(), nCount * 4); // read points
1305  if (!bCouldRead)
1306  {
1307  SAL_WARN("sw.ww8", "Short CaptionBox header");
1308  return nullptr;
1309  }
1310 
1311  sal_uInt8 nTyp = static_cast<sal_uInt8>(nCount) - 1;
1312  if( nTyp == 1 && SVBT16ToUInt16( xP[0] ) == SVBT16ToUInt16( xP[2] ) )
1313  nTyp = 0;
1314 
1315  Point aP0( static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa )) +
1316  static_cast<sal_Int16>(SVBT16ToUInt16( aCallB.dpheadTxbx.xa )) + m_nDrawXOfs2,
1317  static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya ))
1318  + static_cast<sal_Int16>(SVBT16ToUInt16( aCallB.dpheadTxbx.ya )) + m_nDrawYOfs2 );
1319  Point aP1( aP0 );
1320  aP1.AdjustX(static_cast<sal_Int16>(SVBT16ToUInt16( aCallB.dpheadTxbx.dxa )) );
1321  aP1.AdjustY(static_cast<sal_Int16>(SVBT16ToUInt16( aCallB.dpheadTxbx.dya )) );
1322  Point aP2( static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa ))
1323  + static_cast<sal_Int16>(SVBT16ToUInt16( aCallB.dpheadPolyLine.xa ))
1324  + m_nDrawXOfs2 + static_cast<sal_Int16>(SVBT16ToUInt16( xP[0] )),
1325  static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya ))
1326  + static_cast<sal_Int16>(SVBT16ToUInt16( aCallB.dpheadPolyLine.ya ))
1327  + m_nDrawYOfs2 + static_cast<sal_Int16>(SVBT16ToUInt16( xP[1] )) );
1328  xP.reset();
1329 
1330  SdrCaptionObj* pObj = new SdrCaptionObj(
1331  *m_pDrawModel,
1332  tools::Rectangle(aP0, aP1),
1333  aP2);
1334 
1335  pObj->NbcSetSnapRect(tools::Rectangle(aP0, aP1));
1336  Size aSize( static_cast<sal_Int16>(SVBT16ToUInt16( aCallB.dpheadTxbx.dxa )),
1337  static_cast<sal_Int16>(SVBT16ToUInt16( aCallB.dpheadTxbx.dya )) );
1338  bool bEraseThisObject;
1339 
1340  InsertTxbxText(pObj, &aSize, 0, 0, 0, nullptr, false, bEraseThisObject );
1341 
1342  if( SVBT16ToUInt16( aCallB.dptxbx.aLnt.lnps ) != 5 ) // Is border visible ?
1343  SetStdAttr( rSet, aCallB.dptxbx.aLnt, aCallB.dptxbx.aShd );
1344  else // no -> take lines
1345  SetStdAttr( rSet, aCallB.dpPolyLine.aLnt, aCallB.dptxbx.aShd );
1346  SetFill( rSet, aCallB.dptxbx.aFill );
1347  rSet.Put(SdrCaptionTypeItem(aCaptA[nTyp % SAL_N_ELEMENTS(aCaptA)]));
1348 
1349  return pObj;
1350 }
1351 
1353 {
1354  sal_Int16 nGrouped;
1355 
1356  if( !ReadGrafStart( static_cast<void*>(&nGrouped), sizeof( nGrouped ), pHd, rSet ) )
1357  return nullptr;
1358 
1359 #ifdef OSL_BIGENDIAN
1360  nGrouped = (sal_Int16)OSL_SWAPWORD( nGrouped );
1361 #endif
1362 
1363  m_nDrawXOfs = m_nDrawXOfs + static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa ));
1364  m_nDrawYOfs = m_nDrawYOfs + static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya ));
1365 
1366  SdrObject* pObj = new SdrObjGroup(*m_pDrawModel);
1367 
1368  short nLeft = static_cast<sal_Int16>(SVBT16ToUInt16( pHd->cb )) - sizeof( WW8_DPHEAD );
1369  for (int i = 0; i < nGrouped && nLeft >= static_cast<short>(sizeof(WW8_DPHEAD)); ++i)
1370  {
1371  SfxAllItemSet aSet(m_pDrawModel->GetItemPool());
1372  if (SdrObject *pObject = ReadGrafPrimitive(nLeft, aSet))
1373  {
1374  // first add and then set ItemSet
1375  SdrObjList *pSubGroup = pObj->GetSubList();
1376  OSL_ENSURE(pSubGroup, "Why no sublist available?");
1377  if (pSubGroup)
1378  pSubGroup->InsertObject(pObject, 0);
1379  pObject->SetMergedItemSetAndBroadcast(aSet);
1380  }
1381  }
1382 
1383  m_nDrawXOfs = m_nDrawXOfs - static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa ));
1384  m_nDrawYOfs = m_nDrawYOfs - static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya ));
1385 
1386  return pObj;
1387 }
1388 
1390 {
1391  // This whole archaic word 6 graphic import can probably be refactored
1392  // into an object hierarchy with a little effort.
1393  SdrObject *pRet=nullptr;
1394  WW8_DPHEAD aHd; // Read Draw-Primitive-Header
1395  bool bCouldRead = checkRead(*m_pStrm, &aHd, sizeof(WW8_DPHEAD)) &&
1396  SVBT16ToUInt16(aHd.cb) >= sizeof(WW8_DPHEAD);
1397  OSL_ENSURE(bCouldRead, "Graphic Primitive header short read" );
1398  if (!bCouldRead)
1399  {
1400  rLeft=0;
1401  return pRet;
1402  }
1403 
1404  if( rLeft >= SVBT16ToUInt16(aHd.cb) ) // precautions
1405  {
1406  rSet.Put(SwFormatSurround(css::text::WrapTextMode_THROUGH));
1407  switch (SVBT16ToUInt16(aHd.dpk) & 0xff )
1408  {
1409  case 0:
1410  pRet = ReadGroup(&aHd, rSet);
1411  break;
1412  case 1:
1413  pRet = ReadLine(&aHd, rSet);
1414  break;
1415  case 2:
1416  pRet = ReadTextBox(&aHd, rSet);
1417  break;
1418  case 3:
1419  pRet = ReadRect(&aHd, rSet);
1420  break;
1421  case 4:
1422  pRet = ReadEllipse(&aHd, rSet);
1423  break;
1424  case 5:
1425  pRet = ReadArc(&aHd, rSet);
1426  break;
1427  case 6:
1428  pRet = ReadPolyLine(&aHd, rSet);
1429  break;
1430  case 7:
1431  pRet = ReadCaptionBox(&aHd, rSet);
1432  break;
1433  default: // unknown
1434  m_pStrm->SeekRel(SVBT16ToUInt16(aHd.cb) - sizeof(WW8_DPHEAD));
1435  break;
1436  }
1437  }
1438  else
1439  {
1440  OSL_ENSURE( false, "+Grafik-Overlap" );
1441  }
1442  rLeft = rLeft - SVBT16ToUInt16( aHd.cb );
1443  return pRet;
1444 }
1445 
1447 {
1448  rPF.SeekPos(nGrafAnchorCp);
1449  WW8_FC nStartFc;
1450  void* pF0;
1451  if (!rPF.Get(nStartFc, pF0))
1452  {
1453  OSL_ENSURE( false, "+Where is the graphic (2) ?" );
1454  return;
1455  }
1456  WW8_FDOA* pF = static_cast<WW8_FDOA*>(pF0);
1457  if( !SVBT32ToUInt32( pF->fc ) )
1458  {
1459  OSL_ENSURE( false, "+Where is the graphic (3) ?" );
1460  return;
1461  }
1462 
1463  sal_uInt32 nPosFc = SVBT32ToUInt32(pF->fc);
1464 
1465  //skip duplicate graphics when fuzzing
1466  if (m_bFuzzing)
1467  {
1468  if (!m_aGrafPosSet.insert(nPosFc).second)
1469  return;
1470  }
1471 
1472  bool bCouldSeek = checkSeek(*m_pStrm, nPosFc);
1473  OSL_ENSURE(bCouldSeek, "Invalid graphic offset");
1474  if (!bCouldSeek)
1475  return;
1476 
1477  // read Draw-Header
1478  WW8_DO aDo;
1479  bool bCouldRead = checkRead(*m_pStrm, &aDo, sizeof(WW8_DO));
1480  OSL_ENSURE(bCouldRead, "Short graphic header");
1481  if (!bCouldRead)
1482  return;
1483 
1484  short nLeft = SVBT16ToUInt16( aDo.cb ) - sizeof( WW8_DO );
1485  while (nLeft > static_cast<short>(sizeof(WW8_DPHEAD)))
1486  {
1487  SfxAllItemSet aSet( m_pDrawModel->GetItemPool() );
1488  if (SdrObject *pObject = ReadGrafPrimitive(nLeft, aSet))
1489  {
1490  m_xWWZOrder->InsertDrawingObject(pObject, SVBT16ToUInt16(aDo.dhgt));
1491 
1492  tools::Rectangle aRect(pObject->GetSnapRect());
1493 
1494  const sal_uInt32 nCntRelTo = 3;
1495 
1496  // Adjustment is horizontally relative to...
1497  static const sal_Int16 aHoriRelOriTab[nCntRelTo] =
1498  {
1499  text::RelOrientation::PAGE_PRINT_AREA, // 0 is page textarea margin
1500  text::RelOrientation::PAGE_FRAME, // 1 is page margin
1501  text::RelOrientation::FRAME, // 2 is relative to paragraph
1502  };
1503 
1504  // Adjustment is vertically relative to...
1505  static const sal_Int16 aVertRelOriTab[nCntRelTo] =
1506  {
1507  text::RelOrientation::PAGE_PRINT_AREA, // 0 is page textarea margin
1508  text::RelOrientation::PAGE_FRAME, // 1 is page margin
1509  text::RelOrientation::FRAME, // 2 is relative to paragraph
1510  };
1511 
1512  const int nXAlign = aDo.bx < nCntRelTo ? aDo.bx : 0;
1513  const int nYAlign = aDo.by < nCntRelTo ? aDo.by : 0;
1514 
1515  aSet.Put(SwFormatHoriOrient(aRect.Left(), text::HoriOrientation::NONE,
1516  aHoriRelOriTab[ nXAlign ]));
1517  aSet.Put(SwFormatVertOrient(aRect.Top(), text::VertOrientation::NONE,
1518  aVertRelOriTab[ nYAlign ]));
1519 
1521  pObject->SetMergedItemSet(aSet);
1522 
1523  if (SwDrawFrameFormat *pDrawFrame = dynamic_cast<SwDrawFrameFormat*>(pFrame))
1524  {
1525  pDrawFrame->PosAttrSet();
1526  }
1527 
1528  AddAutoAnchor(pFrame);
1529  }
1530  }
1531 }
1532 
1534  MSO_SPT eShapeType, sal_Int32 &rThick)
1535 {
1536  sal_Int32 nOutsideThick = 0;
1537  /*
1538  Note: In contrast to the regular WinWord table and frame border width,
1539  where the overall border width has to be calculated from the width of *one*
1540  line, the data from ESCHER already contains the overall width [twips]!
1541 
1542  The WinWord default is 15 tw. We take for this our 20 tw line.
1543  (0.75 pt and 1.0 pt looking more similar on hardcopy than 0.75 pt and our
1544  0.05 pt hairline.) The hairline we only set by WinWord width up to max.
1545  0.5 pt.
1546  */
1547  switch( eStyle )
1548  {
1549  case mso_lineTriple:
1550  case mso_lineSimple:
1551  nOutsideThick = eShapeType != mso_sptTextBox ? rThick : rThick/2;
1552  break;
1553  case mso_lineDouble:
1554  if (eShapeType == mso_sptTextBox)
1555  {
1556  nOutsideThick = rThick/6;
1557  rThick = rThick*2/3;
1558  }
1559  else
1560  nOutsideThick = rThick*2/3;
1561  break;
1562  case mso_lineThickThin:
1563  if (eShapeType == mso_sptTextBox)
1564  {
1565  nOutsideThick = rThick*3/10;
1566  rThick = rThick*4/5;
1567  }
1568  else
1569  nOutsideThick = rThick*4/5;
1570  break;
1571  case mso_lineThinThick:
1572  {
1573  if (eShapeType == mso_sptTextBox)
1574  {
1575  nOutsideThick = rThick/10;
1576  rThick = rThick*3/5;
1577  }
1578  else
1579  nOutsideThick = rThick*3/5;
1580  }
1581  break;
1582  default:
1583  break;
1584  }
1585  return nOutsideThick;
1586 }
1587 
1588 // Returns the thickness of the line outside the frame, the logic of
1589 // words positioning of borders around floating objects is that of a
1590 // disturbed mind.
1592  MSO_LineStyle eLineStyle, MSO_LineDashing eDashing, MSO_SPT eShapeType, sal_Int32 &rLineThick,
1593  SvxBoxItem& rBox )
1594 {
1595  sal_Int32 nOutsideThick = 0;
1596  if( !rLineThick )
1597  return nOutsideThick;
1598 
1599  SvxBorderLineStyle nIdx = SvxBorderLineStyle::NONE;
1600 
1601  sal_Int32 nLineThick=rLineThick;
1602  nOutsideThick = SwMSDffManager::GetEscherLineMatch(eLineStyle,
1603  eShapeType, rLineThick);
1604 
1605  /*
1606  Note: In contrast to the regular WinWord table and frame border width,
1607  where the overall border width has to be calculated from the width of *one*
1608  line, the data from ESCHER already contains the overall width [twips]!
1609 
1610  The WinWord default is 15 tw. We take for this our 20 tw line.
1611  (0.75 pt and 1.0 pt looking more similar on hardcopy than 0.75 pt and our
1612  0.05 pt hairline.) The hairline we only set by WinWord width up to max.
1613  0.5 pt.
1614  */
1615  switch( +eLineStyle )
1616  {
1617  // first the single lines
1618  case mso_lineSimple:
1619  nIdx = SvxBorderLineStyle::SOLID;
1620  break;
1621  // second the double lines
1622  case mso_lineDouble:
1623  nIdx = SvxBorderLineStyle::DOUBLE;
1624  break;
1625  case mso_lineThickThin:
1626  nIdx = SvxBorderLineStyle::THICKTHIN_SMALLGAP;
1627  break;
1628  case mso_lineThinThick:
1629  nIdx = SvxBorderLineStyle::THINTHICK_SMALLGAP;
1630  break;
1631  // We have no triple border, use double instead.
1632  case mso_lineTriple:
1633  nIdx = SvxBorderLineStyle::DOUBLE;
1634  break;
1635  // no line style is set
1636  case MSO_LineStyle(USHRT_MAX):
1637  break;
1638  // erroneously not implemented line style is set
1639  default:
1640  OSL_ENSURE(false, "eLineStyle is not (yet) implemented!");
1641  break;
1642  }
1643 
1644  switch( eDashing )
1645  {
1646  case mso_lineDashGEL:
1647  nIdx = SvxBorderLineStyle::DASHED;
1648  break;
1649  case mso_lineDotGEL:
1650  nIdx = SvxBorderLineStyle::DOTTED;
1651  break;
1652  default:
1653  break;
1654  }
1655 
1656  if (SvxBorderLineStyle::NONE != nIdx)
1657  {
1658  SvxBorderLine aLine;
1659  aLine.SetColor( rLineColor );
1660 
1661  aLine.SetWidth( nLineThick ); // No conversion here, nLineThick is already in twips
1662  aLine.SetBorderLineStyle(nIdx);
1663 
1665  {
1666  // aLine is cloned by SetLine
1667  rBox.SetLine(&aLine, nLine);
1668  }
1669  }
1670 
1671  return nOutsideThick;
1672 }
1673 
1674 #define WW8ITEMVALUE(ItemSet,Id,Cast) ItemSet.GetItem<Cast>(Id)->GetValue()
1675 
1677  SfxItemSet& rFlySet, MSO_LineStyle eLineStyle, MSO_LineDashing eDashing, MSO_SPT eShapeType,
1678  tools::Rectangle& rInnerDist )
1679 {
1680  /*
1681  attributes to be set on the frame
1682  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1683  SwFormatFrameSize if not set, set here
1684  SvxLRSpaceItem set here
1685  SvxULSpaceItem set here
1686  SvxOpaqueItem (Currently not possible for frames! khz 10.2.1999)
1687  SwFormatSurround already set
1688  SwFormatVertOrient already set
1689  SwFormatHoriOrient already set
1690  SwFormatAnchor already set
1691  SvxBoxItem set here
1692  SvxBrushItem set here
1693  SvxShadowItem set here
1694  */
1695 
1696  // 1. GraphicObject of documents?
1697  GraphicCtor();
1698 
1699  const SfxItemSet& rOldSet = pSdrObj->GetMergedItemSet();
1700 
1701  // some Items can be taken over directly
1702  static sal_uInt16 const aDirectMatch[]
1703  {
1704  RES_LR_SPACE, // outer spacing left/right: SvxLRSpaceItem
1705  RES_UL_SPACE // outer spacing top/bottom: SvxULSpaceItem
1706  };
1707  const SfxPoolItem* pPoolItem;
1708  for(sal_uInt16 i : aDirectMatch)
1709  if( SfxItemState::SET == rOldSet.GetItemState(i, false, &pPoolItem) )
1710  {
1711  rFlySet.Put( *pPoolItem );
1712  }
1713 
1714  // take new XATTR items directly. Skip old RES_BACKGROUND if new FILLSTYLE taken.
1715  bool bSkipResBackground = false;
1716  SfxItemPool* pPool = rFlySet.GetPool();
1717  if ( pPool )
1718  {
1719  for ( sal_uInt16 i = XATTR_START; i < XATTR_END; ++i )
1720  {
1721  // Not all Fly types support XATTRs - skip unsupported attributes
1722  SfxItemPool* pAttrPool = pPool->GetMasterPool();
1723  while ( pAttrPool && !pAttrPool->IsInRange(i) )
1724  pAttrPool = pAttrPool->GetSecondaryPool();
1725  if ( !pAttrPool )
1726  continue;
1727 
1728  if ( SfxItemState::SET == rOldSet.GetItemState(i, false, &pPoolItem) )
1729  {
1730  rFlySet.Put( *pPoolItem );
1731  if ( i == XATTR_FILLSTYLE )
1732  {
1733  const drawing::FillStyle eFill = static_cast<const XFillStyleItem*>(pPoolItem)->GetValue();
1734  // Transparency forced in certain situations when fillstyle is none - use old logic for that case still
1735  // which is especially needed for export purposes (tdf112618).
1736  if ( eFill != drawing::FillStyle_NONE )
1737  bSkipResBackground = true;
1738  }
1739  }
1740  }
1741  }
1742 
1743  // now calculate the borders and build the box: The unit is needed for the
1744  // frame SIZE!
1745  SvxBoxItem aBox(rFlySet.Get(RES_BOX));
1746  // dashed or solid becomes solid
1747  // WW-default: 0.75 pt = 15 twips
1748  sal_Int32 nLineThick = 15, nOutside=0;
1749 
1750  // check if LineStyle is *really* set!
1751 
1752  SfxItemState eState = rOldSet.GetItemState(XATTR_LINESTYLE);
1753  if( eState == SfxItemState::SET )
1754  {
1755  // Now, that we know there is a line style we will make use the
1756  // parameter given to us when calling the method... :-)
1757  const Color aLineColor = rOldSet.Get(XATTR_LINECOLOR).GetColorValue();
1758  nLineThick = WW8ITEMVALUE(rOldSet, XATTR_LINEWIDTH, XLineWidthItem);
1759 
1760  if( !nLineThick )
1761  nLineThick = 1; // for Writer, zero is "no border", so set a minimal value
1762 
1763  nOutside = MatchSdrBoxIntoFlyBoxItem(aLineColor, eLineStyle,
1764  eDashing, eShapeType, nLineThick, aBox);
1765  }
1766 
1767  rInnerDist.AdjustLeft(nLineThick );
1768  rInnerDist.AdjustTop(nLineThick );
1769  rInnerDist.AdjustRight(nLineThick );
1770  rInnerDist.AdjustBottom(nLineThick );
1771 
1772  rInnerDist.AdjustLeft( -(aBox.CalcLineWidth( SvxBoxItemLine::LEFT )) );
1773  rInnerDist.AdjustTop( -(aBox.CalcLineWidth( SvxBoxItemLine::TOP )) );
1774  rInnerDist.AdjustRight( -(aBox.CalcLineWidth( SvxBoxItemLine::RIGHT )) );
1775  rInnerDist.AdjustBottom( -(aBox.CalcLineWidth( SvxBoxItemLine::BOTTOM )) );
1776 
1777  // set distances from box's border to text contained within the box
1778  if( 0 < rInnerDist.Left() )
1779  aBox.SetDistance( o3tl::narrowing<sal_uInt16>(rInnerDist.Left()), SvxBoxItemLine::LEFT );
1780  if( 0 < rInnerDist.Top() )
1781  aBox.SetDistance( o3tl::narrowing<sal_uInt16>(rInnerDist.Top()), SvxBoxItemLine::TOP );
1782  if( 0 < rInnerDist.Right() )
1783  aBox.SetDistance( o3tl::narrowing<sal_uInt16>(rInnerDist.Right()), SvxBoxItemLine::RIGHT );
1784  if( 0 < rInnerDist.Bottom() )
1785  aBox.SetDistance( o3tl::narrowing<sal_uInt16>(rInnerDist.Bottom()), SvxBoxItemLine::BOTTOM );
1786 
1787  bool bFixSize = !(WW8ITEMVALUE(rOldSet, SDRATTR_TEXT_AUTOGROWHEIGHT,
1788  SdrOnOffItem));
1789 
1790  // Size: SwFormatFrameSize
1791  if( SfxItemState::SET != rFlySet.GetItemState(RES_FRM_SIZE, false) )
1792  {
1793  const tools::Rectangle& rSnapRect = pSdrObj->GetSnapRect();
1794  // if necessary adapt width and position of the framework: The
1795  // recorded interior is to remain equally large despite thick edges.
1797  rSnapRect.GetWidth() + 2*nOutside,
1798  rSnapRect.GetHeight() + 2*nOutside) );
1799  }
1800  else // If a size is set, adjust it to consider border thickness
1801  {
1802  SwFormatFrameSize aSize = rFlySet.Get(RES_FRM_SIZE);
1803 
1805  aSize.GetWidth() + 2*nOutside,
1806  aSize.GetHeight() + 2*nOutside);
1807  aNewSize.SetWidthSizeType(aSize.GetWidthSizeType());
1808  rFlySet.Put( aNewSize );
1809  }
1810 
1811  // Sadly word puts escher borders outside the graphic, but orients the
1812  // graphic in relation to the top left inside the border. We don't
1813  if (nOutside)
1814  {
1815  SwFormatHoriOrient aHori = rFlySet.Get(RES_HORI_ORIENT);
1816  aHori.SetPos(MakeSafePositioningValue(aHori.GetPos()-nOutside));
1817  rFlySet.Put(aHori);
1818 
1819  SwFormatVertOrient aVert = rFlySet.Get(RES_VERT_ORIENT);
1820  aVert.SetPos(aVert.GetPos()-nOutside);
1821  rFlySet.Put(aVert);
1822  }
1823 
1824  // now set the border
1825  rFlySet.Put( aBox );
1826 
1827  // shadow of the box: SvxShadowItem
1828  if( WW8ITEMVALUE(rOldSet, SDRATTR_SHADOW, SdrOnOffItem) )
1829  {
1830  SvxShadowItem aShadow( RES_SHADOW );
1831 
1832  const Color aShdColor = rOldSet.Get(SDRATTR_SHADOWCOLOR).GetColorValue();
1833  const sal_Int32 nShdDistX = WW8ITEMVALUE(rOldSet, SDRATTR_SHADOWXDIST,
1834  SdrMetricItem);
1835  const sal_Int32 nShdDistY = WW8ITEMVALUE(rOldSet, SDRATTR_SHADOWYDIST,
1836  SdrMetricItem);
1837 
1838  aShadow.SetColor( aShdColor );
1839 
1840  aShadow.SetWidth(writer_cast<sal_uInt16>((std::abs( nShdDistX) +
1841  std::abs( nShdDistY )) / 2 ));
1842 
1843  SvxShadowLocation eShdPosi;
1844  if( 0 <= nShdDistX )
1845  {
1846  if( 0 <= nShdDistY )
1847  eShdPosi = SvxShadowLocation::BottomRight;
1848  else
1849  eShdPosi = SvxShadowLocation::TopRight;
1850  }
1851  else
1852  {
1853  if( 0 <= nShdDistY )
1854  eShdPosi = SvxShadowLocation::BottomLeft;
1855  else
1856  eShdPosi = SvxShadowLocation::TopLeft;
1857  }
1858  aShadow.SetLocation( eShdPosi );
1859 
1860  rFlySet.Put( aShadow );
1861  }
1862  SvxBrushItem aBrushItem(COL_WHITE, RES_BACKGROUND);
1863  bool bBrushItemOk = false;
1864  sal_uInt8 nTrans = 0;
1865 
1866  // Separate transparency
1867  eState = rOldSet.GetItemState(XATTR_FILLTRANSPARENCE);
1868  if (!bSkipResBackground && eState == SfxItemState::SET)
1869  {
1870  sal_uInt16 nRes = WW8ITEMVALUE(rOldSet, XATTR_FILLTRANSPARENCE,
1872  nTrans = sal_uInt8((nRes * 0xFE) / 100);
1873  aBrushItem.GetColor().SetAlpha(255 - nTrans);
1874  bBrushItemOk = true;
1875  }
1876 
1877  // Background: SvxBrushItem
1878  const XFillStyleItem* pFillStyleItem = rOldSet.GetItemIfSet(XATTR_FILLSTYLE);
1879  if (!bSkipResBackground && pFillStyleItem)
1880  {
1881  const drawing::FillStyle eFill = pFillStyleItem->GetValue();
1882 
1883  switch (eFill)
1884  {
1885  default:
1886  case drawing::FillStyle_NONE:
1887  // Writer graphics don't have it yet
1888  if (eShapeType != mso_sptPictureFrame)
1889  {
1890  aBrushItem.GetColor().SetAlpha(1);
1891  bBrushItemOk = true;
1892  }
1893  break;
1894  case drawing::FillStyle_SOLID:
1895  case drawing::FillStyle_GRADIENT:
1896  {
1897  const Color aColor =
1898  rOldSet.Get(XATTR_FILLCOLOR).GetColorValue();
1899  aBrushItem.SetColor(aColor);
1900 
1901  if (bBrushItemOk) // has trans
1902  aBrushItem.GetColor().SetAlpha(255 - nTrans);
1903 
1904  bBrushItemOk = true;
1905  }
1906  break;
1907  case drawing::FillStyle_HATCH:
1908  break;
1909  case drawing::FillStyle_BITMAP:
1910  {
1911  GraphicObject aGrfObj(rOldSet.Get(XATTR_FILLBITMAP).GetGraphicObject());
1912  const bool bTile(WW8ITEMVALUE(rOldSet, XATTR_FILLBMP_TILE, XFillBmpTileItem));
1913 
1914  if(bBrushItemOk) // has trans
1915  {
1916  GraphicAttr aAttr(aGrfObj.GetAttr());
1917 
1918  aAttr.SetAlpha(255 - nTrans);
1919  aGrfObj.SetAttr(aAttr);
1920  }
1921 
1922  aBrushItem.SetGraphicObject(aGrfObj);
1923  aBrushItem.SetGraphicPos(bTile ? GPOS_TILED : GPOS_AREA);
1924  bBrushItemOk = true;
1925  }
1926  break;
1927  }
1928  }
1929 
1930  if (bBrushItemOk)
1931  rFlySet.Put(aBrushItem);
1932 }
1933 
1935  const SvxMSDffImportRec &rRecord, SvxLRSpaceItem &rLR)
1936 {
1937  sal_uInt32 nXRelTo = SvxMSDffImportRec::RELTO_DEFAULT;
1938  if ( rRecord.nXRelTo )
1939  {
1940  nXRelTo = *rRecord.nXRelTo;
1941  }
1942 
1943  // Left adjustments - if horizontally aligned to left of
1944  // margin or column then remove the left wrapping
1945  if (rRecord.nXAlign == 1)
1946  {
1947  if ((nXRelTo == 0) || (nXRelTo == 2))
1948  rLR.SetLeft(sal_uInt16(0));
1949  }
1950 
1951  // Right adjustments - if horizontally aligned to right of
1952  // margin or column then remove the right wrapping
1953  if (rRecord.nXAlign == 3)
1954  {
1955  if ((nXRelTo == 0) || (nXRelTo == 2))
1956  rLR.SetRight(sal_uInt16(0));
1957  }
1958 
1959  // Inside margin, remove left wrapping
1960  if ((rRecord.nXAlign == 4) && (nXRelTo == 0))
1961  {
1962  rLR.SetLeft(sal_uInt16(0));
1963  }
1964 
1965  // Outside margin, remove left wrapping
1966  if ((rRecord.nXAlign == 5) && (nXRelTo == 0))
1967  {
1968  rLR.SetRight(sal_uInt16(0));
1969  }
1970 }
1971 
1973  const SvxMSDffImportRec &rRecord, SvxULSpaceItem &rUL)
1974 {
1975  sal_uInt32 nYRelTo = SvxMSDffImportRec::RELTO_DEFAULT;
1976  if ( rRecord.nYRelTo )
1977  {
1978  nYRelTo = *rRecord.nYRelTo;
1979  }
1980 
1981  // Top adjustment - remove upper wrapping if aligned to page
1982  // printable area or to page
1983  if (rRecord.nYAlign == 1)
1984  {
1985  if ((nYRelTo == 0) || (nYRelTo == 1))
1986  rUL.SetUpper(sal_uInt16(0));
1987  }
1988 
1989  // Bottom adjustment - remove bottom wrapping if aligned to page or
1990  // printable area or to page
1991  if (rRecord.nYAlign == 3)
1992  {
1993  if ((nYRelTo == 0) || (nYRelTo == 1))
1994  rUL.SetLower(sal_uInt16(0));
1995  }
1996 
1997  // Remove top margin if aligned vertically inside margin
1998  if ((rRecord.nYAlign == 4) && (nYRelTo == 0))
1999  rUL.SetUpper(sal_uInt16(0));
2000 }
2001 
2003  SwFrameFormat& rFlyFormat)
2004 {
2005  if (rRecord.nDxWrapDistLeft || rRecord.nDxWrapDistRight)
2006  {
2007  SvxLRSpaceItem aLR(writer_cast<sal_uInt16>(rRecord.nDxWrapDistLeft),
2008  writer_cast<sal_uInt16>(rRecord.nDxWrapDistRight), 0, 0, RES_LR_SPACE);
2009  AdjustLRWrapForWordMargins(rRecord, aLR);
2010  rFlyFormat.SetFormatAttr(aLR);
2011  }
2012  if (rRecord.nDyWrapDistTop || rRecord.nDyWrapDistBottom)
2013  {
2014  SvxULSpaceItem aUL(writer_cast<sal_uInt16>(rRecord.nDyWrapDistTop),
2015  writer_cast<sal_uInt16>(rRecord.nDyWrapDistBottom), RES_UL_SPACE);
2016  AdjustULWrapForWordMargins(rRecord, aUL);
2017  rFlyFormat.SetFormatAttr(aUL);
2018  }
2019 
2020  // If we are contoured and have a custom polygon...
2021  if (rRecord.pWrapPolygon && rFlyFormat.GetSurround().IsContour())
2022  {
2023  if (SwNoTextNode* pNd = GetNoTextNodeFromSwFrameFormat(rFlyFormat))
2024  {
2025  /*
2026  Gather round children and hear of a tale that will raise the
2027  hairs on the back of your neck this dark halloween night.
2028 
2029  There is a polygon in word that describes the wrapping around
2030  the graphic.
2031 
2032  Here are some sample values for the simplest case of a square
2033  around some solid coloured graphics
2034 
2035  X Y Pixel size of graphic
2036  TopLeft -54 21600 400x400
2037  Bottom Right 0 21546
2038 
2039  TopLeft -108 21600 200x200
2040  Bottom Right 0 21492
2041 
2042  TopLeft -216 21600 100x100
2043  Bottom Right 0 21384
2044 
2045  TopLeft -432 21600 50x50
2046  Bottom Right 0 21168
2047 
2048  TopLeft -76 21600 283x212
2049  Bottom Right 0 21498
2050 
2051  So given that the size of the values remains pretty much the
2052  same despite the size of the graphic, we can tell that the
2053  polygon is measured in units that are independent of the
2054  graphic. But why does the left corner move a different value
2055  to the left each time, and why does the bottom move upwards
2056  each time, when the right and top remain at the same value ?
2057 
2058  I have no idea, but clearly once we calculate the values out
2059  we see that the left margin is always a fixed realworld
2060  distance from the true left and the polygon bottom is the same
2061  fixed value from the bottom. i.e. 15twips.
2062 
2063  So here we take our word provided polygon, shift it to the
2064  right by 15twips and rescale it widthwise to shrink the width
2065  a little to fit the now moved right margin back to where it
2066  was, and stretch the height a little to make the bottom move
2067  down the missing 15twips then we get a polygon that matches
2068  what I actually see in word
2069  */
2070 
2071  tools::PolyPolygon aPoly(*rRecord.pWrapPolygon);
2072  const Size &rSize = pNd->GetTwipSize();
2073  /*
2074  Move to the left by 15twips, and rescale to
2075  a) shrink right bound back to orig position
2076  b) stretch bottom bound to where I think it should have been
2077  in the first place
2078  */
2079  Fraction aMoveHack(ww::nWrap100Percent, rSize.Width());
2080  aMoveHack *= Fraction(15, 1);
2081  tools::Long nMove(aMoveHack);
2082  aPoly.Move(nMove, 0);
2083 
2086  aPoly.Scale(double(aHackX), double(aHackY));
2087 
2088  // Turn polygon back into units that match the graphic's
2089  const Size &rOrigSize = pNd->GetGraphic().GetPrefSize();
2090  Fraction aMapPolyX(rOrigSize.Width(), ww::nWrap100Percent);
2091  Fraction aMapPolyY(rOrigSize.Height(), ww::nWrap100Percent);
2092  aPoly.Scale(double(aMapPolyX), double(aMapPolyY));
2093 
2094  // #i47277# - contour is already in unit of the
2095  // graphic preferred unit. Thus, call method <SetContour(..)>
2096  pNd->SetContour(&aPoly);
2097  }
2098  }
2099  else if (rFlyFormat.GetSurround().IsContour())
2100  {
2101  // Contour is enabled, but no polygon is set: disable contour, because Word does not
2102  // Writer-style auto-contour in that case.
2103  SwFormatSurround aSurround(rFlyFormat.GetSurround());
2104  aSurround.SetContour(false);
2105  rFlyFormat.SetFormatAttr(aSurround);
2106  }
2107 }
2108 
2109 static sal_Int32 lcl_ConvertCrop(sal_uInt32 const nCrop, sal_Int32 const nSize)
2110 {
2111  // cast to sal_Int32 to handle negative crop properly
2112  sal_Int32 const nIntegral(static_cast<sal_Int32>(nCrop) >> 16);
2113  // fdo#77454: heuristic to detect mangled values written by old OOo/LO
2114  if (abs(nIntegral) >= 50) // FIXME: what's a good cut-off?
2115  {
2116  SAL_INFO("sw.ww8", "ignoring suspiciously large crop: " << nIntegral);
2117  return 0;
2118  }
2119  return (nIntegral * nSize) + (((nCrop & 0xffff) * nSize) >> 16);
2120 }
2121 
2123  const SwFrameFormat& rFlyFormat, WW8_FSPA const *pF)
2124 {
2125  const SwNodeIndex* pIdx = rFlyFormat.GetContent(false).GetContentIdx();
2126  SwGrfNode *const pGrfNd(
2127  pIdx ? m_rDoc.GetNodes()[pIdx->GetIndex() + 1]->GetGrfNode() : nullptr);
2128  if (!pGrfNd)
2129  return;
2130 
2131  Size aSz(pGrfNd->GetTwipSize());
2132  // use type <sal_uInt64> instead of sal_uLong to get correct results
2133  // in the following calculations.
2134  sal_uInt64 nHeight = aSz.Height();
2135  sal_uInt64 nWidth = aSz.Width();
2136  if (!nWidth && pF)
2137  nWidth = o3tl::saturating_sub(pF->nXaRight, pF->nXaLeft);
2138  else if (!nHeight && pF)
2139  nHeight = o3tl::saturating_sub(pF->nYaBottom, pF->nYaTop);
2140 
2141  if (rRecord.nCropFromTop || rRecord.nCropFromBottom ||
2142  rRecord.nCropFromLeft || rRecord.nCropFromRight)
2143  {
2144  SwCropGrf aCrop; // Cropping is stored in 'fixed floats'
2145  // 16.16 (fraction times total
2146  if (rRecord.nCropFromTop) // image width or height resp.)
2147  {
2148  aCrop.SetTop(lcl_ConvertCrop(rRecord.nCropFromTop, nHeight));
2149  }
2150  if (rRecord.nCropFromBottom)
2151  {
2152  aCrop.SetBottom(lcl_ConvertCrop(rRecord.nCropFromBottom, nHeight));
2153  }
2154  if (rRecord.nCropFromLeft)
2155  {
2156  aCrop.SetLeft(lcl_ConvertCrop(rRecord.nCropFromLeft, nWidth));
2157  }
2158  if (rRecord.nCropFromRight)
2159  {
2160  aCrop.SetRight(lcl_ConvertCrop(rRecord.nCropFromRight, nWidth));
2161  }
2162 
2163  pGrfNd->SetAttr( aCrop );
2164  }
2165 
2166  bool bFlipH(rRecord.nFlags & ShapeFlag::FlipH);
2167  bool bFlipV(rRecord.nFlags & ShapeFlag::FlipV);
2168  if ( bFlipH || bFlipV )
2169  {
2170  SwMirrorGrf aMirror = pGrfNd->GetSwAttrSet().GetMirrorGrf();
2171  if( bFlipH )
2172  {
2173  if( bFlipV )
2174  aMirror.SetValue(MirrorGraph::Both);
2175  else
2177  }
2178  else
2180 
2181  pGrfNd->SetAttr( aMirror );
2182  }
2183 
2184  if (!rRecord.pObj)
2185  return;
2186 
2187  const SfxItemSet& rOldSet = rRecord.pObj->GetMergedItemSet();
2188  // contrast
2189  if (WW8ITEMVALUE(rOldSet, SDRATTR_GRAFCONTRAST,
2191  {
2192  SwContrastGrf aContrast(
2193  WW8ITEMVALUE(rOldSet,
2195  pGrfNd->SetAttr( aContrast );
2196  }
2197 
2198  // luminance
2199  if (WW8ITEMVALUE(rOldSet, SDRATTR_GRAFLUMINANCE,
2201  {
2202  SwLuminanceGrf aLuminance(WW8ITEMVALUE(rOldSet,
2204  pGrfNd->SetAttr( aLuminance );
2205  }
2206  // gamma
2208  {
2209  double fVal = WW8ITEMVALUE(rOldSet, SDRATTR_GRAFGAMMA,
2211  pGrfNd->SetAttr(SwGammaGrf(fVal/100.));
2212  }
2213 
2214  // drawmode
2215  auto nGrafMode = rOldSet.GetItem<SdrGrafModeItem>(SDRATTR_GRAFMODE)->GetValue();
2216  if ( nGrafMode != GraphicDrawMode::Standard)
2217  {
2218  SwDrawModeGrf aDrawMode( nGrafMode );
2219  pGrfNd->SetAttr( aDrawMode );
2220  }
2221 }
2222 
2224 {
2225  if (pFlyFormat)
2226  {
2227  SdrObject* pNewObject = m_bNewDoc ? nullptr : pFlyFormat->FindRealSdrObject();
2228  if (!pNewObject)
2229  pNewObject = pFlyFormat->FindSdrObject();
2230  if (!pNewObject )
2231  if (auto pFlyFrameFormat = dynamic_cast<SwFlyFrameFormat *>( pFlyFormat ))
2232  {
2233  SwFlyDrawContact* pContactObject = pFlyFrameFormat->GetOrCreateContact();
2234  pNewObject = pContactObject->GetMaster();
2235  }
2236  return pNewObject;
2237  }
2238  return nullptr;
2239 }
2240 
2241 // Miserable miserable hack to fudge word's graphic layout in RTL mode to ours.
2243  sal_Int16 eHoriOri, sal_Int16 eHoriRel)
2244 {
2245  if (!IsRightToLeft())
2246  return false;
2247  return RTLGraphicsHack(rLeft, nWidth, eHoriOri, eHoriRel,
2248  m_aSectionManager.GetPageLeft(),
2249  m_aSectionManager.GetPageRight(),
2250  m_aSectionManager.GetPageWidth());
2251 }
2252 
2254  SfxItemSet &rFlySet)
2255 {
2256  bool bCurSectionVertical = m_aSectionManager.CurrentSectionIsVertical();
2257 
2258  if (!rRecord.nXRelTo)
2259  {
2260  rRecord.nXRelTo = sal_Int32(rFSPA.nbx);
2261  }
2262  if (!rRecord.nYRelTo)
2263  {
2264  rRecord.nYRelTo = sal_Int32(rFSPA.nby);
2265  }
2266 
2267  // nXAlign - abs. Position, Left, Centered, Right, Inside, Outside
2268  // nYAlign - abs. Position, Top, Centered, Bottom, Inside, Outside
2269 
2270  // nXRelTo - Page printable area, Page, Column, Character
2271  // nYRelTo - Page printable area, Page, Paragraph, Line
2272 
2273  const sal_uInt32 nCntXAlign = 6;
2274  const sal_uInt32 nCntYAlign = 6;
2275 
2276  const sal_uInt32 nCntRelTo = 4;
2277 
2278  sal_uInt32 nXAlign = nCntXAlign > rRecord.nXAlign ? rRecord.nXAlign : 1;
2279  sal_uInt32 nYAlign = nCntYAlign > rRecord.nYAlign ? rRecord.nYAlign : 1;
2280 
2281  // #i52565# - try to handle special case for objects in tables regarding its X Rel
2282 
2283  // if X and Y Rel values are on default take it as a hint, that they have not been set
2284  // by <SwMSDffManager::ProcessObj(..)>
2285  const bool bXYRelHaveDefaultValues = *rRecord.nXRelTo == 2 && *rRecord.nYRelTo == 2;
2286  if (bXYRelHaveDefaultValues && m_nInTable > 0 && !bCurSectionVertical)
2287  {
2288  if (sal_uInt32(rFSPA.nby) != rRecord.nYRelTo)
2289  rRecord.nYRelTo = sal_uInt32(rFSPA.nby);
2290  }
2291 
2292  sal_uInt32 nXRelTo = (rRecord.nXRelTo && nCntRelTo > rRecord.nXRelTo) ? *rRecord.nXRelTo : 1;
2293  sal_uInt32 nYRelTo = (rRecord.nYRelTo && nCntRelTo > rRecord.nYRelTo) ? *rRecord.nYRelTo : 1;
2294 
2295  RndStdIds eAnchor = IsInlineEscherHack() ? RndStdIds::FLY_AS_CHAR : RndStdIds::FLY_AT_CHAR; // #i43718#
2296 
2297  SwFormatAnchor aAnchor( eAnchor );
2298  aAnchor.SetAnchor( m_pPaM->GetPoint() );
2299  rFlySet.Put( aAnchor );
2300 
2301  // #i18732#
2302  // Given new layout where everything is changed to be anchored to
2303  // character the following 4 tables may need to be changed.
2304 
2305  // horizontal Adjustment
2306  static const sal_Int16 aHoriOriTab[ nCntXAlign ] =
2307  {
2308  text::HoriOrientation::NONE, // From left position
2309  text::HoriOrientation::LEFT, // left
2310  text::HoriOrientation::CENTER, // centered
2311  text::HoriOrientation::RIGHT, // right
2312  // #i36649#
2313  // - inside -> text::HoriOrientation::LEFT and outside -> text::HoriOrientation::RIGHT
2314  text::HoriOrientation::LEFT, // inside
2315  text::HoriOrientation::RIGHT // outside
2316  };
2317 
2318  // generic vertical Adjustment
2319  static const sal_Int16 aVertOriTab[ nCntYAlign ] =
2320  {
2321  text::VertOrientation::NONE, // From Top position
2322  text::VertOrientation::TOP, // top
2323  text::VertOrientation::CENTER, // centered
2324  text::VertOrientation::BOTTOM, // bottom
2325  text::VertOrientation::LINE_TOP, // inside (obscure)
2326  text::VertOrientation::LINE_BOTTOM // outside (obscure)
2327  };
2328 
2329  // #i22673# - to-line vertical alignment
2330  static const sal_Int16 aToLineVertOriTab[ nCntYAlign ] =
2331  {
2332  text::VertOrientation::NONE, // below
2333  text::VertOrientation::LINE_BOTTOM, // top
2334  text::VertOrientation::LINE_CENTER, // centered
2335  text::VertOrientation::LINE_TOP, // bottom
2336  text::VertOrientation::LINE_BOTTOM, // inside (obscure)
2337  text::VertOrientation::LINE_TOP // outside (obscure)
2338  };
2339 
2340  // Adjustment is horizontally relative to...
2341  static const sal_Int16 aHoriRelOriTab[nCntRelTo] =
2342  {
2343  text::RelOrientation::PAGE_PRINT_AREA, // 0 is page textarea margin
2344  text::RelOrientation::PAGE_FRAME, // 1 is page margin
2345  text::RelOrientation::FRAME, // 2 is relative to column
2346  text::RelOrientation::CHAR // 3 is relative to character
2347  };
2348 
2349  // Adjustment is vertically relative to...
2350  // #i22673# - adjustment for new vertical alignment at top of line.
2351  static const sal_Int16 aVertRelOriTab[nCntRelTo] =
2352  {
2353  text::RelOrientation::PAGE_PRINT_AREA, // 0 is page textarea margin
2354  text::RelOrientation::PAGE_FRAME, // 1 is page margin
2355  text::RelOrientation::FRAME, // 2 is relative to paragraph
2356  text::RelOrientation::TEXT_LINE // 3 is relative to line
2357  };
2358 
2359  sal_Int16 eHoriOri = aHoriOriTab[ nXAlign ];
2360  sal_Int16 eHoriRel = aHoriRelOriTab[ nXRelTo ];
2361 
2362  // #i36649# - adjustments for certain alignments
2363  if (eHoriOri == text::HoriOrientation::LEFT && eHoriRel == text::RelOrientation::PAGE_FRAME)
2364  {
2365  // convert 'left to page' to 'from left -<width> to page text area'
2366  eHoriOri = text::HoriOrientation::NONE;
2367  eHoriRel = text::RelOrientation::PAGE_PRINT_AREA;
2368  const tools::Long nWidth = rFSPA.nXaRight - rFSPA.nXaLeft;
2369  rFSPA.nXaLeft = -nWidth;
2370  rFSPA.nXaRight = 0;
2371  }
2372  else if (eHoriOri == text::HoriOrientation::RIGHT && eHoriRel == text::RelOrientation::PAGE_FRAME)
2373  {
2374  // convert 'right to page' to 'from left 0 to right page border'
2375  eHoriOri = text::HoriOrientation::NONE;
2376  eHoriRel = text::RelOrientation::PAGE_RIGHT;
2377  const tools::Long nWidth = rFSPA.nXaRight - rFSPA.nXaLeft;
2378  rFSPA.nXaLeft = 0;
2379  rFSPA.nXaRight = nWidth;
2380  }
2381 
2382  // #i24255# - position of floating screen objects in
2383  // R2L layout are given in L2R layout, thus convert them of all
2384  // floating screen objects, which are imported.
2385  {
2386  // Miserable miserable hack.
2387  SwTwips nWidth = o3tl::saturating_sub(rFSPA.nXaRight, rFSPA.nXaLeft);
2388  SwTwips nLeft = rFSPA.nXaLeft;
2389  if (MiserableRTLGraphicsHack(nLeft, nWidth, eHoriOri,
2390  eHoriRel))
2391  {
2392  rFSPA.nXaLeft = nLeft;
2393  rFSPA.nXaRight = rFSPA.nXaLeft + nWidth;
2394  }
2395  }
2396 
2397  // if the object is anchored inside a table cell, is horizontal aligned
2398  // at frame|character and has wrap through, but its attribute
2399  // 'layout in table cell' isn't set, convert its horizontal alignment to page text area.
2400  // #i84783# - use new method <IsObjectLayoutInTableCell()>
2401  if (m_nInTable &&
2402  (eHoriRel == text::RelOrientation::FRAME || eHoriRel == text::RelOrientation::CHAR) &&
2403  rFSPA.nwr == 3 &&
2404  !IsObjectLayoutInTableCell(rRecord.nGroupShapeBooleanProperties))
2405  {
2406  eHoriRel = text::RelOrientation::PAGE_PRINT_AREA;
2407  }
2408 
2409  // Writer honours this wrap distance when aligned as "left" or "right",
2410  // Word doesn't. Writer doesn't honour it when its "from left".
2411  if (eHoriOri == text::HoriOrientation::LEFT)
2412  rRecord.nDxWrapDistLeft = 0;
2413  else if (eHoriOri == text::HoriOrientation::RIGHT)
2414  rRecord.nDxWrapDistRight = 0;
2415 
2416  sal_Int16 eVertRel;
2417 
2418  eVertRel = aVertRelOriTab[ nYRelTo ]; // #i18732#
2419  if (bCurSectionVertical && nYRelTo == 2)
2420  eVertRel = text::RelOrientation::PAGE_PRINT_AREA;
2421  // #i22673# - fill <eVertOri> in dependence of <eVertRel>
2422  sal_Int16 eVertOri;
2423  if (eVertRel == text::RelOrientation::TEXT_LINE)
2424  {
2425  eVertOri = aToLineVertOriTab[ nYAlign ];
2426  }
2427  else
2428  {
2429  eVertOri = aVertOriTab[ nYAlign ];
2430  }
2431 
2432  // Below line in word is a positive value, while in writer its
2433  // negative
2434  tools::Long nYPos = rFSPA.nYaTop;
2435  // #i22673#
2436  if ((eVertRel == text::RelOrientation::TEXT_LINE) && (eVertOri == text::VertOrientation::NONE))
2437  nYPos = -nYPos;
2438 
2439  SwFormatHoriOrient aHoriOri(MakeSafePositioningValue(bCurSectionVertical ? nYPos : rFSPA.nXaLeft),
2440  bCurSectionVertical ? eVertOri : eHoriOri,
2441  bCurSectionVertical ? eVertRel : eHoriRel);
2442  if (4 <= nXAlign)
2443  aHoriOri.SetPosToggle(true);
2444  rFlySet.Put(aHoriOri);
2445 
2446  rFlySet.Put(SwFormatVertOrient(MakeSafePositioningValue(!bCurSectionVertical ? nYPos : -rFSPA.nXaRight),
2447  !bCurSectionVertical ? eVertOri : eHoriOri,
2448  !bCurSectionVertical ? eVertRel : eHoriRel));
2449 
2450  return eAnchor;
2451 }
2452 
2453 // #i84783#
2454 bool SwWW8ImplReader::IsObjectLayoutInTableCell(const sal_uInt32 nGroupShapeBooleanProperties) const
2455 {
2456  bool bIsObjectLayoutInTableCell = false;
2457 
2458  if ( m_bVer8 )
2459  {
2460  sal_uInt16 nWWVersion = m_xWwFib->m_nProduct & 0xE000;
2461  if (nWWVersion == 0)
2462  {
2463  // 0 nProduct can happen for Word >97 as well, check cswNew in this case instead.
2464  if (m_xWwFib->m_cswNew > 0)
2465  {
2466  // This is Word >=2000.
2467  nWWVersion = 0x2000;
2468  }
2469  }
2470 
2471  switch ( nWWVersion )
2472  {
2473  case 0x0000: // version 8 aka Microsoft Word 97
2474  {
2475  bIsObjectLayoutInTableCell = false;
2476  OSL_ENSURE(nGroupShapeBooleanProperties == 0,
2477  "no explicit object attribute layout in table cell expected." );
2478  }
2479  break;
2480  case 0x2000: // version 9 aka Microsoft Word 2000
2481  case 0x4000: // version 10 aka Microsoft Word 2002
2482  case 0x6000: // version 11 aka Microsoft Word 2003
2483  case 0x8000: // version 12 aka Microsoft Word 2007
2484  case 0xC000: // version 14 aka Microsoft Word 2010
2485  case 0xE000: // version 15 aka Microsoft Word 2013
2486  {
2487  // Documented in [MS-ODRAW], 2.3.4.44 "Group Shape Boolean Properties".
2488  bool fUsefLayoutInCell = (nGroupShapeBooleanProperties & 0x80000000) >> 31;
2489  bool fLayoutInCell = (nGroupShapeBooleanProperties & 0x8000) >> 15;
2490  // If unspecified, defaults to true
2491  bIsObjectLayoutInTableCell = !fUsefLayoutInCell || fLayoutInCell;
2492  }
2493  break;
2494  default:
2495  {
2496  OSL_FAIL( "unknown version." );
2497  }
2498  }
2499  }
2500 
2501  return bIsObjectLayoutInTableCell;
2502 }
2503 
2505 {
2506  if( m_nIniFlags & WW8FL_NO_GRAFLAYER )
2507  return nullptr;
2508 
2509  ::SetProgressState(m_nProgress, m_pDocShell); // Update
2510 
2511  m_nDrawCpO = 0;
2512  m_bDrawCpOValid = m_xWwFib->GetBaseCp(m_xPlcxMan->GetManType() == MAN_HDFT ? MAN_TXBX_HDFT : MAN_TXBX, &m_nDrawCpO);
2513 
2514  GraphicCtor();
2515 
2516  WW8PLCFspecial* pPF = m_xPlcxMan->GetFdoa();
2517  if( !pPF )
2518  {
2519  OSL_ENSURE( false, "Where is the graphic (1) ?" );
2520  return nullptr;
2521  }
2522 
2523  if( m_bVer67 )
2524  {
2525  sal_uInt64 nOldPos = m_pStrm->Tell();
2526 
2527  m_nDrawXOfs = m_nDrawYOfs = 0;
2528  ReadGrafLayer1(*pPF, nGrafAnchorCp);
2529 
2530  m_pStrm->Seek( nOldPos );
2531  return nullptr;
2532  }
2533 
2534  // Normal case of Word 8+ version stuff
2535  pPF->SeekPos( nGrafAnchorCp );
2536 
2537  WW8_FC nStartFc;
2538  void* pF0;
2539  if (!pPF->Get(nStartFc, pF0))
2540  {
2541  OSL_ENSURE( false, "+Where is the graphic (2) ?" );
2542  return nullptr;
2543  }
2544 
2545  WW8_FSPA_SHADOW& rFS = *static_cast<WW8_FSPA_SHADOW*>(pF0);
2546  WW8_FSPA aFSFA;
2547  WW8FSPAShadowToReal(rFS, aFSFA);
2548  if (!aFSFA.nSpId)
2549  {
2550  OSL_ENSURE( false, "+Where is the graphic (3) ?" );
2551  return nullptr;
2552  }
2553 
2554  if (!m_xMSDffManager->GetModel())
2555  m_xMSDffManager->SetModel(m_pDrawModel, 1440);
2556 
2557  tools::Rectangle aRect(aFSFA.nXaLeft, aFSFA.nYaTop, aFSFA.nXaRight, aFSFA.nYaBottom);
2558  SvxMSDffImportData aData( aRect );
2559 
2560  /*
2561  #i20540#
2562  The SdrOle2Obj will try and manage any ole objects it finds, causing all
2563  sorts of trouble later on
2564  */
2565  SwDocShell* pPersist = m_rDoc.GetDocShell();
2566  m_rDoc.SetDocShell(nullptr); // #i20540# Persist guard
2567 
2568  SdrObject* pObject = nullptr;
2569  bool bOk = (m_xMSDffManager->GetShape(aFSFA.nSpId, pObject, aData) && pObject);
2570 
2571  m_rDoc.SetDocShell(pPersist); // #i20540# Persist guard
2572 
2573  if (!bOk)
2574  {
2575  OSL_ENSURE( false, "Where is the Shape ?" );
2576  return nullptr;
2577  }
2578 
2579  // tdf#118375 Word relates position to the unrotated rectangle,
2580  // Writer uses the rotated one.
2581  if (pObject->GetRotateAngle())
2582  {
2583  tools::Rectangle aObjSnapRect(pObject->GetSnapRect()); // recalculates the SnapRect
2584  aFSFA.nXaLeft = aObjSnapRect.Left();
2585  aFSFA.nYaTop = aObjSnapRect.Top();
2586  aFSFA.nXaRight = aObjSnapRect.Right();
2587  aFSFA.nYaBottom = aObjSnapRect.Bottom();
2588  }
2589 
2590  bool bDone = false;
2591  SdrObject* pOurNewObject = nullptr;
2592  bool bReplaceable = false;
2593 
2594  switch (pObject->GetObjIdentifier())
2595  {
2596  case SdrObjKind::Graphic:
2597  bReplaceable = true;
2598  bDone = true;
2599  break;
2600  case SdrObjKind::OLE2:
2601  bReplaceable = true;
2602  break;
2603  default:
2604  break;
2605 
2606  }
2607 
2608  // when in a header or footer word appears to treat all elements as wrap through
2609 
2610  // determine wrapping mode
2612  Reader::ResetFrameFormatAttrs(aFlySet); // tdf#122425: Explicitly remove borders and spacing
2613  css::text::WrapTextMode eSurround = css::text::WrapTextMode_PARALLEL;
2614  bool bContour = false;
2615  switch (aFSFA.nwr)
2616  {
2617  case 0: // 0 like 2, but doesn't require absolute object
2618  case 2: // 2 wrap around absolute object
2619  eSurround = css::text::WrapTextMode_PARALLEL;
2620  break;
2621  case 1: // 1 no text next to shape
2622  eSurround = css::text::WrapTextMode_NONE;
2623  break;
2624  case 3: // 3 wrap as if no object present
2625  eSurround = css::text::WrapTextMode_THROUGH;
2626  break;
2627  case 4: // 4 wrap tightly around object
2628  case 5: // 5 wrap tightly, but allow holes
2629  eSurround = css::text::WrapTextMode_PARALLEL;
2630  bContour = true;
2631  break;
2632  }
2633 
2634  // if mode 2 or 4 also regard the additional parameters
2635  if ((2 == aFSFA.nwr) || (4 == aFSFA.nwr))
2636  {
2637  switch (aFSFA.nwrk)
2638  {
2639  // 0 wrap both sides
2640  case 0:
2641  eSurround = css::text::WrapTextMode_PARALLEL;
2642  break;
2643  // 1 wrap only on left
2644  case 1:
2645  eSurround = css::text::WrapTextMode_LEFT;
2646  break;
2647  // 2 wrap only on right
2648  case 2:
2649  eSurround = css::text::WrapTextMode_RIGHT;
2650  break;
2651  // 3 wrap only on largest side
2652  case 3:
2653  eSurround = css::text::WrapTextMode_DYNAMIC;
2654  break;
2655  }
2656  }
2657 
2658  SwFormatSurround aSur( eSurround );
2659  aSur.SetContour( bContour );
2660  aSur.SetOutside(true); // Winword can only do outside contours
2661  aFlySet.Put( aSur );
2662 
2663  // now position imported object correctly and so on (can be a whole group)
2664 
2665  OSL_ENSURE(!((aData.size() != 1) && bReplaceable),
2666  "Replaceable drawing with > 1 entries ?");
2667 
2668  if (aData.size() != 1)
2669  bReplaceable = false;
2670 
2671  /*
2672  Get the record for top level object, so we can get the word anchoring
2673  and wrapping information for it.
2674  */
2675  SvxMSDffImportRec* pRecord = aData.find(pObject);
2676  OSL_ENSURE(pRecord, "how did that happen?");
2677  if (!pRecord)
2678  {
2679  // remove old object from the Z-Order list
2680  m_xMSDffManager->RemoveFromShapeOrder(pObject);
2681  // and delete the object
2682  SdrObject::Free(pObject);
2683  return nullptr;
2684  }
2685  const bool bLayoutInTableCell =
2686  m_nInTable && IsObjectLayoutInTableCell(pRecord->nGroupShapeBooleanProperties);
2687 
2688  // #i18732# - Switch on 'follow text flow', if object is laid out
2689  // inside table cell
2690  if (bLayoutInTableCell)
2691  {
2692  SwFormatFollowTextFlow aFollowTextFlow( true );
2693  aFlySet.Put( aFollowTextFlow );
2694  }
2695 
2696  // #i21847#
2697  // Some shapes are set to *hidden*, don't import those ones.
2698  if (pRecord->bHidden)
2699  {
2700  // remove old object from the Z-Order list
2701  m_xMSDffManager->RemoveFromShapeOrder(pObject);
2702  // and delete the object
2703  SdrObject::Free(pObject);
2704  return nullptr;
2705  }
2706 
2707  sal_uInt16 nCount = pObject->GetUserDataCount();
2708  if(nCount)
2709  {
2710  OUString lnName, aObjName, aTarFrame;
2711  for (sal_uInt16 i = 0; i < nCount; i++ )
2712  {
2713  SdrObjUserData* pData = pObject->GetUserData( i );
2714  if( pData && pData->GetInventor() == SdrInventor::ScOrSwDraw
2715  && pData->GetId() == SW_UD_IMAPDATA)
2716  {
2717  SwMacroInfo* macInf = dynamic_cast<SwMacroInfo*>(pData);
2718  if (macInf && macInf->GetShapeId() == aFSFA.nSpId)
2719  {
2720  lnName = macInf->GetHlink();
2721  aObjName = macInf->GetName();
2722  aTarFrame = macInf->GetTarFrame();
2723  break;
2724  }
2725  }
2726  }
2727  std::unique_ptr<SwFormatURL> pFormatURL(new SwFormatURL());
2728  pFormatURL->SetURL( lnName, false );
2729  if (!aObjName.isEmpty())
2730  pFormatURL->SetName(aObjName);
2731  if (!aTarFrame.isEmpty())
2732  pFormatURL->SetTargetFrameName(aTarFrame);
2733  pFormatURL->SetMap(nullptr);
2734  aFlySet.Put(*pFormatURL);
2735  }
2736 
2737  // If we are to be "below text" then we are not to be opaque
2738  // #i14045# MM If we are in a header or footer then make the object transparent
2739  // Not exactly like word but close enough for now
2740 
2741  // both flags <bBelowText> and <bDrawHell> have to be set to move object into the background.
2742  // #i46794# - it reveals that value of flag <bBelowText> can be neglected.
2743  const bool bMoveToBackground = pRecord->bDrawHell ||
2744  ((m_bIsHeader || m_bIsFooter) && aFSFA.nwr == 3);
2745  if ( bMoveToBackground )
2746  aFlySet.Put(SvxOpaqueItem(RES_OPAQUE,false));
2747 
2748  OUString aObjName = pObject->GetName();
2749 
2750  bool bDrawObj = false;
2751  bool bFrame = false;
2752 
2753  SwFrameFormat* pRetFrameFormat = nullptr;
2754  if (bReplaceable)
2755  {
2756  // Single graphics or ole objects
2757  pRetFrameFormat = ImportReplaceableDrawables(pObject, pOurNewObject, *pRecord, aFSFA, aFlySet);
2758  }
2759  else
2760  {
2761  bDrawObj = true;
2762 
2763  // Drawing objects, (e.g. ovals or drawing groups)
2764  if (aFSFA.bRcaSimple)
2765  {
2766  aFSFA.nbx = WW8_FSPA::RelPageBorder;
2767  aFSFA.nby = WW8_FSPA::RelPageBorder;
2768  }
2769 
2770  RndStdIds eAnchor = ProcessEscherAlign(*pRecord, aFSFA, aFlySet);
2771 
2772  // Should we, and is it possible to make this into a writer textbox
2773  if ((!(m_nIniFlags1 & WW8FL_NO_FLY_FOR_TXBX)) && pRecord->bReplaceByFly)
2774  {
2775  pRetFrameFormat
2776  = ConvertDrawTextToFly(pObject, pOurNewObject, *pRecord, eAnchor, aFSFA, aFlySet);
2777  if (pRetFrameFormat)
2778  {
2779  bDone = true;
2780  bDrawObj = false;
2781  bFrame = true;
2782  }
2783  }
2784 
2785  if (!bDone)
2786  {
2787  sw::util::SetLayer aSetLayer(m_rDoc);
2788  if ( bMoveToBackground )
2789  aSetLayer.SendObjectToHell(*pObject);
2790  else
2791  aSetLayer.SendObjectToHeaven(*pObject);
2792 
2793  if (!IsInlineEscherHack())
2794  {
2795  /* Need to make sure that the correct layer ordering is applied. */
2796  // pass information, if object is in page header|footer to method.
2797  m_xWWZOrder->InsertEscherObject(pObject, aFSFA.nSpId, pRecord->bDrawHell,
2798  m_bIsHeader || m_bIsFooter);
2799  }
2800  else
2801  {
2802  m_xWWZOrder->InsertTextLayerObject(pObject);
2803  }
2804 
2805  pRetFrameFormat = m_rDoc.getIDocumentContentOperations().InsertDrawObj(*m_pPaM, *pObject, aFlySet );
2806 
2807  OSL_ENSURE(pRetFrameFormat->GetAnchor().GetAnchorId() ==
2808  eAnchor, "Not the anchor type requested!");
2809 
2810  /*
2811  Insert text if necessary into textboxes contained in groups.
2812  */
2813  for (const auto& it : aData)
2814  {
2815  pRecord = it.get();
2816  if (pRecord->pObj && pRecord->aTextId.nTxBxS)
2817  { // #i52825# pRetFrameFormat can be NULL
2818  pRetFrameFormat = MungeTextIntoDrawBox(
2819  *pRecord, nGrafAnchorCp, pRetFrameFormat);
2820  }
2821  }
2822  }
2823  }
2824 
2825  SwDrawFrameFormat* pDrawFrameFormat = dynamic_cast<SwDrawFrameFormat*>(pRetFrameFormat);
2826  // #i44344#, #i44681# - positioning attributes already set
2827  if (pDrawFrameFormat)
2828  pDrawFrameFormat->PosAttrSet();
2829  if (!IsInlineEscherHack() && pRetFrameFormat)
2830  MapWrapIntoFlyFormat(*pRecord, *pRetFrameFormat);
2831 
2832  // Set frame name with object name
2833  if (pRetFrameFormat /*#i52825# */)
2834  {
2835  if (!aObjName.isEmpty())
2836  pRetFrameFormat->SetName( aObjName );
2837  if (pRetFrameFormat->GetName().isEmpty())
2838  {
2839  if (bDrawObj)
2840  pRetFrameFormat->SetName(m_rDoc.GetUniqueDrawObjectName());
2841  else if (bFrame)
2842  pRetFrameFormat->SetName(m_rDoc.GetUniqueFrameName());
2843  }
2844  }
2845  return AddAutoAnchor(pRetFrameFormat);
2846 }
2847 
2849 {
2850  /*
2851  * anchored to character at the current position will move along the
2852  * paragraph as text is added because we are at the insertion point.
2853  *
2854  * Leave to later and set the correct location then.
2855  */
2856  if (pFormat && (pFormat->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR))
2857  {
2858  m_xAnchorStck->AddAnchor(*m_pPaM->GetPoint(), pFormat);
2859  }
2860  return pFormat;
2861 }
2862 
2864  tools::Long nGrafAnchorCp, SwFrameFormat* pRetFrameFormat)
2865 {
2866  SdrObject* pTrueObject = rRecord.pObj;
2867 
2868  SdrTextObj* pSdrTextObj;
2869 
2870  // check for group object (e.g. two parentheses)
2871  if (SdrObjGroup* pThisGroup = dynamic_cast<SdrObjGroup*>(rRecord.pObj))
2872  {
2873  // Group objects don't have text. Insert a text object into
2874  // the group for holding the text.
2875  pSdrTextObj = new SdrRectObj(
2876  *m_pDrawModel,
2877  SdrObjKind::Text,
2878  pThisGroup->GetCurrentBoundRect());
2879 
2880  SfxItemSet aSet(m_pDrawModel->GetItemPool());
2881  aSet.Put(XFillStyleItem(drawing::FillStyle_NONE));
2882  aSet.Put(XLineStyleItem(drawing::LineStyle_NONE));
2883  aSet.Put(SdrTextFitToSizeTypeItem( drawing::TextFitToSizeType_NONE ));
2884  aSet.Put(makeSdrTextAutoGrowHeightItem(false));
2885  aSet.Put(makeSdrTextAutoGrowWidthItem(false));
2886  pSdrTextObj->SetMergedItemSet(aSet);
2887  pSdrTextObj->NbcSetLayer( pThisGroup->GetLayer() );
2888  pThisGroup->GetSubList()->NbcInsertObject(pSdrTextObj);
2889  }
2890  else
2891  pSdrTextObj = dynamic_cast<SdrTextObj*>(rRecord.pObj);
2892 
2893  if( pSdrTextObj )
2894  {
2895  Size aObjSize(pSdrTextObj->GetSnapRect().GetWidth(),
2896  pSdrTextObj->GetSnapRect().GetHeight());
2897 
2898  // Object is part of a group?
2899  SdrObject* pGroupObject = pSdrTextObj->getParentSdrObjectFromSdrObject();
2900 
2901  const size_t nOrdNum = pSdrTextObj->GetOrdNum();
2902  bool bEraseThisObject;
2903  InsertTxbxText(pSdrTextObj, &aObjSize, rRecord.aTextId.nTxBxS, rRecord.aTextId.nSequence,
2904  nGrafAnchorCp, pRetFrameFormat,
2905  (pSdrTextObj != pTrueObject) || (nullptr != pGroupObject), bEraseThisObject,
2906  nullptr, nullptr, nullptr, nullptr, &rRecord);
2907 
2908  // was this object replaced ??
2909  if (bEraseThisObject)
2910  {
2911  if( pGroupObject || (pSdrTextObj != pTrueObject) )
2912  {
2913  // Object is already replaced by a new SdrGrafObj (in the group
2914  // and) the Drawing-Page.
2915 
2916  SdrObject* pNewObj = pGroupObject ?
2917  pGroupObject->GetSubList()->GetObj(nOrdNum) : pTrueObject;
2918  if (pSdrTextObj != pNewObj)
2919  {
2920  // Replace object in the Z-Order-List
2921  m_xMSDffManager->ExchangeInShapeOrder(pSdrTextObj, 0, pNewObj);
2922  // now delete object
2923  SdrObject::Free(rRecord.pObj);
2924  // and save the new object.
2925  rRecord.pObj = pNewObj;
2926  }
2927  }
2928  else
2929  {
2930  // remove the object from Z-Order list
2931  m_xMSDffManager->RemoveFromShapeOrder( pSdrTextObj );
2932  // take the object from the drawing page
2933  if( pSdrTextObj->getSdrPageFromSdrObject() )
2934  m_pDrawPg->RemoveObject( pSdrTextObj->GetOrdNum() );
2935  // and delete FrameFormat, because replaced by graphic
2936  // (this also deletes the object)
2937  m_rDoc.DelFrameFormat( pRetFrameFormat );
2938  pRetFrameFormat = nullptr;
2939  // also delete the object record
2940  rRecord.pObj = nullptr;
2941  }
2942  }
2943  else
2944  {
2945  // use ww8-default border distance
2947  aItemSet(m_pDrawModel->GetItemPool());
2948  aItemSet.Put(makeSdrTextLeftDistItem(rRecord.nDxTextLeft));
2949  aItemSet.Put(makeSdrTextRightDistItem(rRecord.nDxTextRight));
2950  aItemSet.Put(makeSdrTextUpperDistItem(rRecord.nDyTextTop));
2951  aItemSet.Put(makeSdrTextLowerDistItem(rRecord.nDyTextBottom));
2952  pSdrTextObj->SetMergedItemSetAndBroadcast(aItemSet);
2953  }
2954  }
2955  return pRetFrameFormat;
2956 }
2957 
2959  SdrObject*& rpOurNewObject,
2960  const SvxMSDffImportRec& rRecord,
2961  RndStdIds eAnchor, const WW8_FSPA& rF,
2962  SfxItemSet &rFlySet)
2963 {
2964  SwFlyFrameFormat* pRetFrameFormat = nullptr;
2965  tools::Long nStartCp;
2966  tools::Long nEndCp;
2967 
2968  // Check if this textbox chain contains text as conversion of an empty
2969  // chain would not make sense.
2970  if (TxbxChainContainsRealText(rRecord.aTextId.nTxBxS, nStartCp, nEndCp))
2971  {
2972  // The Text is not read into SdrTextObj! Rather insert a frame and
2973  // insert the text from nStartCp to nEndCp.
2974 
2975  // More attributes can be used in a frame compared to the
2976  // Edit-Engine, and it can contain field, OLEs or graphics...
2977  tools::Rectangle aInnerDist(rRecord.nDxTextLeft, rRecord.nDyTextTop, rRecord.nDxTextRight,
2978  rRecord.nDyTextBottom);
2979 
2981  rF.nYaBottom - rF.nYaTop);
2983  : SwFrameSize::Fixed);
2984  rFlySet.Put(aFrameSize);
2985 
2986  MatchSdrItemsIntoFlySet(rpObject, rFlySet, rRecord.eLineStyle, rRecord.eLineDashing,
2987  rRecord.eShapeType, aInnerDist);
2988 
2989  SdrTextObj *pSdrTextObj = dynamic_cast<SdrTextObj*>(rpObject);
2990  if (pSdrTextObj && pSdrTextObj->IsVerticalWriting())
2991  rFlySet.Put(SvxFrameDirectionItem(SvxFrameDirection::Vertical_RL_TB, RES_FRAMEDIR));
2992 
2993  pRetFrameFormat = m_rDoc.MakeFlySection(eAnchor, m_pPaM->GetPoint(), &rFlySet);
2994  OSL_ENSURE(pRetFrameFormat->GetAnchor().GetAnchorId() == eAnchor,
2995  "Not the anchor type requested!");
2996 
2997  // if everything is OK, find pointer on new object and correct
2998  // Z-order list (or delete entry)
2999  rpOurNewObject = CreateContactObject(pRetFrameFormat);
3000 
3001  // remove old object from the Z-Order list
3002  m_xMSDffManager->RemoveFromShapeOrder( rpObject );
3003 
3004  // and delete the object
3005  SdrObject::Free( rpObject );
3006  /*
3007  NB: only query pOrgShapeObject starting here!
3008  */
3009 
3010  if (rpOurNewObject)
3011  {
3012  /*
3013  We do not store our rpOutNewObject in the ShapeOrder because we
3014  have a FrameFormat from which we can regenerate the contact object when
3015  we need it. Because, we can have frames anchored to paragraphs in
3016  header/footers and we can copy header/footers, if we do copy a
3017  header/footer with a nonpage anchored frame in it then the contact
3018  objects are invalidated. Under this condition the FrameFormat will be
3019  updated to reflect this change and can be used to get a new
3020  contact object, while a raw rpOutNewObject stored here becomes
3021  deleted and useless.
3022  */
3023  m_xMSDffManager->StoreShapeOrder(rF.nSpId,
3024  (static_cast<sal_uLong>(rRecord.aTextId.nTxBxS) << 16) +
3025  rRecord.aTextId.nSequence, nullptr, pRetFrameFormat);
3026 
3027  // The Contact object has to be inserted into the draw page, so
3028  // SwWW8ImplReader::LoadDoc1() can determine the z-order.
3029  if (!rpOurNewObject->IsInserted())
3030  {
3031  // pass information, if object is in page header|footer to method.
3032  m_xWWZOrder->InsertEscherObject(rpOurNewObject, rF.nSpId, rRecord.bDrawHell,
3033  m_bIsHeader || m_bIsFooter);
3034  }
3035  }
3036 
3037  // Box-0 receives the text for the whole chain!
3038  if (!rRecord.aTextId.nSequence)
3039  {
3040  // save flags etc and reset them
3041  WW8ReaderSave aSave( this );
3042 
3043  MoveInsideFly(pRetFrameFormat);
3044 
3045  m_xWWZOrder->InsideEscher(rF.nSpId);
3046 
3047  // read in the text
3048  m_bTxbxFlySection = true;
3049  bool bJoined = ReadText(nStartCp, (nEndCp-nStartCp),
3050  MAN_MAINTEXT == m_xPlcxMan->GetManType() ?
3052 
3053  m_xWWZOrder->OutsideEscher();
3054 
3055  MoveOutsideFly(pRetFrameFormat, aSave.GetStartPos(),!bJoined);
3056 
3057  aSave.Restore( this );
3058 
3059  StripNegativeAfterIndent(pRetFrameFormat);
3060  }
3061 
3062  }
3063  return pRetFrameFormat;
3064 }
3065 
3067 {
3068  if (rRecord.bVFlip || rRecord.bHFlip)
3069  {
3071  if (rRecord.bVFlip && rRecord.bHFlip)
3072  eType = MirrorGraph::Both;
3073  else if (rRecord.bVFlip)
3074  eType = MirrorGraph::Horizontal;
3075  else
3076  eType = MirrorGraph::Vertical;
3077  rFlySet.Put( SwMirrorGrf(eType) );
3078  }
3079 }
3080 
3082  SdrObject* &rpOurNewObject,
3083  SvxMSDffImportRec& rRecord,
3084  WW8_FSPA& rF,
3085  SfxItemSet &rFlySet )
3086 {
3087  SwFlyFrameFormat* pRetFrameFormat = nullptr;
3088  sal_Int32 nWidthTw = o3tl::saturating_sub(rF.nXaRight, rF.nXaLeft);
3089  if (0 > nWidthTw)
3090  nWidthTw = 0;
3091  sal_Int32 nHeightTw = o3tl::saturating_sub(rF.nYaBottom, rF.nYaTop);
3092  if (0 > nHeightTw)
3093  nHeightTw = 0;
3094 
3095  ProcessEscherAlign(rRecord, rF, rFlySet);
3096 
3097  rFlySet.Put(SwFormatFrameSize(SwFrameSize::Fixed, nWidthTw, nHeightTw));
3098 
3100 
3101  // Note that the escher inner distance only seems to be honoured in
3102  // word for textboxes, not for graphics and ole objects.
3103  tools::Rectangle aInnerDist(0, 0, 0, 0);
3104 
3105  MatchSdrItemsIntoFlySet(rpObject, rFlySet, rRecord.eLineStyle, rRecord.eLineDashing,
3106  rRecord.eShapeType, aInnerDist);
3107 
3108  MatchEscherMirrorIntoFlySet(rRecord, aGrSet);
3109 
3110  OUString aObjectName(rpObject->GetName());
3111  if (SdrObjKind::OLE2 == rpObject->GetObjIdentifier())
3112  pRetFrameFormat = InsertOle(*static_cast<SdrOle2Obj*>(rpObject), rFlySet, &aGrSet);
3113  else
3114  {
3115  const SdrGrafObj *pGrf = static_cast<const SdrGrafObj*>(rpObject);
3116  bool bDone = false;
3117  if (pGrf->IsLinkedGraphic() && !pGrf->GetFileName().isEmpty())
3118  {
3119  GraphicType eType = pGrf->GetGraphicType();
3120  OUString aGrfName(
3122  INetURLObject(m_sBaseURL), pGrf->GetFileName(),
3124  // correction of fix for issue #i10939#:
3125  // One of the two conditions have to be true to insert the graphic
3126  // as a linked graphic -
3127  if (GraphicType::NONE == eType || CanUseRemoteLink(aGrfName))
3128  {
3130  *m_pPaM, aGrfName, OUString(), nullptr,
3131  &rFlySet, &aGrSet, nullptr);
3132  bDone = true;
3133  }
3134  }
3135  if (!bDone)
3136  {
3137  const Graphic& rGraph = pGrf->GetGraphic();
3139  *m_pPaM, OUString(), OUString(), &rGraph,
3140  &rFlySet, &aGrSet, nullptr);
3141  }
3142  }
3143 
3144  if (pRetFrameFormat)
3145  {
3146  if (SdrObjKind::OLE2 != rpObject->GetObjIdentifier())
3147  SetAttributesAtGrfNode(rRecord, *pRetFrameFormat, &rF);
3148  // avoid multiple occurrences of the same graphic name
3149  m_aGrfNameGenerator.SetUniqueGraphName(pRetFrameFormat, aObjectName);
3150  }
3151  // if everything is OK, determine pointer to new object and correct
3152  // Z-Order-List accordingly (or delete entry)
3153  rpOurNewObject = CreateContactObject(pRetFrameFormat);
3154 
3155  // remove old object from Z-Order-List
3156  m_xMSDffManager->RemoveFromShapeOrder( rpObject );
3157  // remove from Drawing-Page
3158  if( rpObject->getSdrPageFromSdrObject() )
3159  m_pDrawPg->RemoveObject( rpObject->GetOrdNum() );
3160 
3161  // and delete the object
3162  SdrObject::Free( rpObject );
3163  /*
3164  Warning: from now on query only pOrgShapeObject!
3165  */
3166 
3167  // add Contact-Object to the Z-Order-List and the page
3168  if (rpOurNewObject)
3169  {
3170  if (!m_bHdFtFootnoteEdn)
3171  m_xMSDffManager->StoreShapeOrder(rF.nSpId, 0, rpOurNewObject);
3172 
3173  // The Contact-Object MUST be set in the Draw-Page, so that in
3174  // SwWW8ImplReader::LoadDoc1() the Z-Order can be defined !!!
3175  if (!rpOurNewObject->IsInserted())
3176  {
3177  // pass information, if object is in page header|footer to method.
3178  m_xWWZOrder->InsertEscherObject(rpOurNewObject, rF.nSpId, rRecord.bDrawHell,
3179  m_bIsHeader || m_bIsFooter);
3180  }
3181  }
3182  return pRetFrameFormat;
3183 }
3184 
3185 void SwWW8ImplReader::GraphicCtor() // For SVDraw and VCControls and Escher
3186 {
3187  if (m_pDrawModel)
3188  return;
3189 
3190  m_rDoc.getIDocumentDrawModelAccess().GetOrCreateDrawModel(); // #i52858# - method name changed
3191  m_pDrawModel = m_rDoc.getIDocumentDrawModelAccess().GetDrawModel();
3192  OSL_ENSURE(m_pDrawModel, "Cannot create DrawModel");
3193  m_pDrawPg = m_pDrawModel->GetPage(0);
3194 
3195  m_xMSDffManager.reset(new SwMSDffManager(*this, m_bSkipImages));
3196  m_xMSDffManager->SetModel(m_pDrawModel, 1440);
3197  /*
3198  Now the dff manager always needs a controls converter as well, but a
3199  control converter may still exist without a dffmanager.
3200  */
3201  m_xFormImpl.reset(new SwMSConvertControls(m_pDocShell, m_pPaM));
3202 
3203  m_xWWZOrder.reset(new wwZOrderer(sw::util::SetLayer(m_rDoc), m_pDrawPg,
3204  m_xMSDffManager->GetShapeOrders()));
3205 }
3206 
3208 {
3209  m_pDrawEditEngine.reset(); // maybe created by graphic
3210  m_xWWZOrder.reset(); // same
3211 }
3212 
3214 {
3215  OSL_ENSURE(pFormat->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR,
3216  "Don't use fltanchors with inline frames, slap!");
3217  NewAttr(rPos, SwFltAnchor(pFormat));
3218 }
3219 
3221 {
3222  size_t nCnt = size();
3223  for (size_t i=0; i < nCnt; ++i)
3224  {
3225  SwFltStackEntry &rEntry = (*this)[i];
3226  SwPosition aDummy(rEntry.m_aMkPos.m_nNode);
3227  SetAttrInDoc(aDummy, rEntry);
3228  DeleteAndDestroy(i--);
3229  --nCnt;
3230  }
3231 }
3232 
3233 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static ESelection GetESelection(EditEngine const &rDrawEditEngine, tools::Long nCpStart, tools::Long nCpEnd)
Definition: ww8graf.cxx:467
constexpr TypedWhichId< SdrOnOffItem > SDRATTR_TEXT_AUTOGROWHEIGHT(SDRATTR_MISC_FIRST+2)
sal_Int32 nXaRight
Definition: ww8struc.hxx:909
bool IsContour() const
Definition: fmtsrnd.hxx:53
sal_Int32 nDyTextBottom
simple Iterator for SPRMs
Definition: ww8scan.hxx:262
virtual void NbcSetOutlinerParaObject(std::optional< OutlinerParaObject > pTextObject) override
constexpr TypedWhichId< SvxFrameDirectionItem > RES_FRAMEDIR(120)
std::optional< OutlinerParaObject > ImportAsOutliner(OUString &rString, WW8_CP nStartCp, WW8_CP nEndCp, ManTypes eType)
Definition: ww8graf.cxx:964
tools::Long GetWidth() const
SdrMetricItem makeSdrTextUpperDistItem(tools::Long mnHeight)
sal_uInt16 nby
Definition: ww8struc.hxx:919
constexpr TypedWhichId< SdrGrafGamma100Item > SDRATTR_GRAFGAMMA(SDRATTR_GRAF_FIRST+5)
URL aURL
tools::Long GetIMax() const
Definition: ww8scan.hxx:237
bool checkRead(SvStream &rSt, void *pDest, sal_uInt32 nLength)
Definition: ww8scan.cxx:8544
sal_Int32 nStartPara
SwNoTextNode * GetNoTextNodeFromSwFrameFormat(const SwFrameFormat &rFormat)
Get the SwNoTextNode associated with a SwFrameFormat if here is one.
SdrMetricItem makeSdrShadowYDistItem(tools::Long nDist)
constexpr SwTwips MIN_BORDER_DIST
Definition: swtypes.hxx:70
SdrObject * ReadPolyLine(WW8_DPHEAD const *pHd, SfxAllItemSet &rSet)
Definition: ww8graf.cxx:429
void append(const basegfx::B2DPoint &rPoint, sal_uInt32 nCount)
static sal_Int32 MatchSdrBoxIntoFlyBoxItem(const Color &rLineColor, MSO_LineStyle eLineStyle, MSO_LineDashing eDashing, MSO_SPT eShapeType, sal_Int32 &rLineWidth, SvxBoxItem &rBox)
Definition: ww8graf.cxx:1591
void SetRight(const tools::Long nR, const sal_uInt16 nProp=100)
sal_Int32 nDxWrapDistRight
const T * GetItemIfSet(TypedWhichId< T > nWhich, bool bSrchInParent=true) const
void SetAlpha(sal_uInt8 nAlpha)
Marks a position in the document model.
Definition: pam.hxx:36
bool RTLGraphicsHack(SwTwips &rLeft, SwTwips nWidth, sal_Int16 eHoriOri, sal_Int16 eHoriRel, SwTwips nPageLeft, SwTwips nPageRight, SwTwips nPageSize)
Definition: wrtw8esh.cxx:524
virtual const tools::Rectangle & GetCurrentBoundRect() const
sal_uInt8 GetRed() const
WW8_DP_POLYLINE dpPolyLine
Definition: ww8struc.hxx:833
SVBT16 cb
Definition: ww8struc.hxx:713
void SetSprms(const sal_uInt8 *pSprms_, sal_Int32 nLen_)
Definition: ww8scan.cxx:882
constexpr sal_uInt16 RES_FLTRATTR_BEGIN(RES_MSG_END)
sal_Int32 GetRangeAsDrawingString(OUString &rString, tools::Long StartCp, tools::Long nEndCp, ManTypes eType)
Definition: ww8graf.cxx:897
void SetBlue(sal_uInt8 nBlue)
static void SetFill(SfxItemSet &rSet, WW8_DP_FILL &rFill)
Definition: ww8graf.cxx:240
OUString GetUniqueDrawObjectName() const
Definition: doclay.cxx:1387
SdrObject * ReadCaptionBox(WW8_DPHEAD const *pHd, SfxAllItemSet &rSet)
Definition: ww8graf.cxx:1285
mso_lineDouble
void SetLeft(sal_Int32 nVal)
sal_uInt8 SVBT16[2]
void SetPosToggle(bool bNew)
Definition: fmtornt.hxx:96
WW8_DPHEAD dpheadPolyLine
Definition: ww8struc.hxx:832
WW8_DP_SHADOW aShd
Definition: ww8struc.hxx:773
tools::Long AdjustRight(tools::Long nHorzMoveDelta)
sal_uInt32 nXAlign
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_LIGHTMAGENTA
sal_uInt8 fUp
Definition: ww8struc.hxx:796
const OUString & GetFileName() const
virtual SwFlyFrameFormat * InsertGraphic(const SwPaM &rRg, const OUString &rGrfName, const OUString &rFltName, const Graphic *pGraphic, const SfxItemSet *pFlyAttrSet, const SfxItemSet *pGrfAttrSet, SwFrameFormat *)=0
Insert graphic or formula.
SwDocShell * GetDocShell()
Definition: doc.hxx:1351
SvxMSDffImportRec * find(const SdrObject *pObj)
sal_Int32 nDxTextLeft
std::string GetValue
SwNodeIndex m_nNode
Definition: fltshell.hxx:50
constexpr tools::Long Left() const
static sal_Int32 lcl_ConvertCrop(sal_uInt32 const nCrop, sal_Int32 const nSize)
Definition: ww8graf.cxx:2109
constexpr TypedWhichId< SwFormatFrameSize > RES_FRM_SIZE(89)
sal_uInt16 nbx
Definition: ww8struc.hxx:913
sal_Int32 nCropFromRight
sal_Int32 nDxWrapDistLeft
constexpr::Color COL_RED(0x80, 0x00, 0x00)
std::unique_ptr< sal_Int32[]> pData
void MatchSdrItemsIntoFlySet(SdrObject const *pSdrObj, SfxItemSet &aFlySet, MSO_LineStyle eLineStyle, MSO_LineDashing eDashing, MSO_SPT eShapeType, tools::Rectangle &rInnerDist)
Definition: ww8graf.cxx:1676
void SetDots(sal_uInt16 nNewDots)
SwTwips GetPos() const
Definition: fmtornt.hxx:92
sal_uIntPtr sal_uLong
long Long
void SetColor(const Color &rNew)
constexpr TypedWhichId< XFillStyleItem > XATTR_FILLSTYLE(XATTR_FILL_FIRST)
sal_uInt16 GetCurrentId() const
Definition: ww8scan.hxx:285
static void AdjustLRWrapForWordMargins(const SvxMSDffImportRec &rRecord, SvxLRSpaceItem &rLR)
Definition: ww8graf.cxx:1934
constexpr TypedWhichId< XLineWidthItem > XATTR_LINEWIDTH(XATTR_LINE_FIRST+2)
#define WW8FL_NO_GRAFLAYER
Definition: ww8par.hxx:126
GraphicType
static sal_Int32 GetEscherLineMatch(MSO_LineStyle eStyle, MSO_SPT eShapeType, sal_Int32 &rThick)
Definition: ww8graf.cxx:1533
bool IsInserted() const
constexpr sal_uInt16 RES_FRMATR_END(133)
const OUString & GetTarFrame() const
Definition: ww8par.hxx:514
void WW8FSPAShadowToReal(const WW8_FSPA_SHADOW &rFSPAS, WW8_FSPA &rPic)
Definition: ww8graf2.cxx:760
OUString GetUniqueFrameName() const
Definition: doclay.cxx:1377
void Scale(double fScaleX, double fScaleY)
void PosAttrSet()
Definition: frmfmt.hxx:407
sal_uInt8 by
Definition: ww8struc.hxx:686
MirrorGraph
Definition: grfatr.hxx:31
sal_uInt16 nTxBxS
sal_uInt32 nYAlign
WW8_DP_LINETYPE aLnt
Definition: ww8struc.hxx:810
constexpr TypedWhichId< XLineStyleItem > XATTR_LINESTYLE(XATTR_LINE_FIRST)
bool CanUseRemoteLink(const OUString &rGrfName)
Definition: ww8par5.cxx:2418
constexpr TypedWhichId< SvxOpaqueItem > RES_OPAQUE(99)
sal_Int32 nCropFromLeft
static void MapWrapIntoFlyFormat(const SvxMSDffImportRec &rRecord, SwFrameFormat &rFlyFormat)
Definition: ww8graf.cxx:2002
constexpr::Color COL_LIGHTGRAY(0xC0, 0xC0, 0xC0)
SdrMetricItem makeSdrTextRightDistItem(tools::Long mnHeight)
SdrMetricItem makeSdrTextLowerDistItem(tools::Long mnHeight)
sal_Int32 nXaLeft
Definition: ww8struc.hxx:907
static void Free(SdrObject *&_rpObject)
virtual SdrObjKind GetObjIdentifier() const
SwNodeOffset abs(const SwNodeOffset &a)
Definition: nodeoffset.hxx:34
sal_Int32 nSpId
Definition: ww8struc.hxx:906
T saturating_sub(T a, T b)
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:315
virtual void InsertObject(SdrObject *pObj, size_t nPos=SAL_MAX_SIZE)
virtual const tools::Rectangle & GetSnapRect() const override
SVBT32 dlpcBg
Definition: ww8struc.hxx:738
GraphicType GetGraphicType() const
EmbeddedObjectRef * pObject
void SetOutside(bool bNew)
Definition: fmtsrnd.hxx:58
void SetContour(bool bNew)
Definition: fmtsrnd.hxx:57
SVBT16 xa
Definition: ww8struc.hxx:714
sal_Int32 nCropFromTop
virtual SdrObjList * GetSubList() const
const OUString & GetName() const
Definition: ww8par.hxx:518
WW8_DP_LINEEND aEpp
Definition: ww8struc.hxx:765
Make setting a drawing object's layer in a Writer document easy.
SdrOnOffItem makeSdrTextAutoGrowHeightItem(bool bAuto)
void SetRight(sal_Int32 nVal)
const int nWrap100Percent
For custom wrapping.
Definition: types.hxx:40
IDocumentDrawModelAccess const & getIDocumentDrawModelAccess() const
Definition: doc.cxx:155
const OUString & GetHlink() const
Definition: ww8par.hxx:512
virtual const tools::Rectangle & GetSnapRect() const
void GraphicDtor()
Definition: ww8graf.cxx:3207
void GraphicCtor()
Definition: ww8graf.cxx:3185
SdrObject * ReadEllipse(WW8_DPHEAD const *pHd, SfxAllItemSet &rSet)
Definition: ww8graf.cxx:368
void SetGraphicObject(const GraphicObject &rNewObj)
constexpr::Color COL_MAGENTA(0x80, 0x00, 0x80)
mso_lineThickThin
constexpr tools::Long Width() const
mso_sptPictureFrame
SvxBorderLineStyle
SwDoc & m_rDoc
Definition: docbm.cxx:1201
constexpr TypedWhichId< SwFormatVertOrient > RES_VERT_ORIENT(102)
GPOS_TILED
WW8_DP_FILL aFill
Definition: ww8struc.hxx:811
SVBT16 dpk
Definition: ww8struc.hxx:709
sal_uInt16 sal_Unicode
const OUString & GetValue() const
Definition: fmtinfmt.hxx:75
static void ResetFrameFormatAttrs(SfxItemSet &rFrameSet)
Definition: shellio.cxx:613
SwFlyFrameFormat * MakeFlySection(RndStdIds eAnchorType, const SwPosition *pAnchorPos, const SfxItemSet *pSet=nullptr, SwFrameFormat *pParent=nullptr, bool bCalledFromShell=false)
Definition: doclay.cxx:289
MSO_LineDashing
constexpr TypedWhichId< SvxFieldItem > EE_FEATURE_FIELD(EE_FEATURE_NOTCONV+1)
constexpr sal_uInt16 RES_GRFATR_END(150)
constexpr TypedWhichId< SwFormatHoriOrient > RES_HORI_ORIENT(103)
MSO_SPT
SdrPage * getSdrPageFromSdrObject() const
#define WW8FL_NO_FLY_FOR_TXBX
Definition: ww8par.hxx:129
void advance()
Definition: ww8scan.hxx:254
constexpr::Color COL_CYAN(0x00, 0x80, 0x80)
const OUString & GetName() const
Definition: format.hxx:131
int nCount
constexpr sal_uInt16 POOLATTR_BEGIN(HINT_BEGIN)
static void lcl_StripFields(OUString &rString, WW8_CP &rNewStartCp)
Definition: ww8graf.cxx:527
static void SetStdAttr(SfxItemSet &rSet, WW8_DP_LINETYPE &rL, WW8_DP_SHADOW const &rSh)
Definition: ww8graf.cxx:199
virtual void SetName(const OUString &rNewName, bool bBroadcast=false) override
Definition: atrfrm.cxx:2560
constexpr TypedWhichId< XColorItem > SDRATTR_SHADOWCOLOR(SDRATTR_SHADOW_FIRST+1)
constexpr tools::Long GetWidth() const
SdrCaptionType
WW8_DP_LINETYPE aLnt
Definition: ww8struc.hxx:792
void SetMergedItemSet(const SfxItemSet &rSet, bool bClearAllItems=false)
const SwFormatSurround & GetSurround(bool=true) const
Definition: fmtsrnd.hxx:66
void InsertTxbxText(SdrTextObj *pTextObj, Size const *pObjSiz, sal_uInt16 nTxBxS, sal_uInt16 nSequence, tools::Long nPosCp, SwFrameFormat const *pFlyFormat, bool bMakeSdrGrafObj, bool &rbEraseTextObj, bool *pbTestTxbxContainsText=nullptr, tools::Long *pnStartCp=nullptr, tools::Long *pnEndCp=nullptr, bool *pbContainsGraphics=nullptr, SvxMSDffImportRec const *pRecord=nullptr)
Definition: ww8graf.cxx:1023
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:161
SdrOnOffItem makeSdrTextAutoGrowWidthItem(bool bAuto)
void InsertTxbxStyAttrs(SfxItemSet &rS, sal_uInt16 nColl)
Definition: ww8graf.cxx:496
sal_Int32 nEndPos
constexpr TypedWhichId< SdrOnOffItem > SDRATTR_SHADOW(SDRATTR_SHADOW_FIRST+0)
tools::Long AdjustBottom(tools::Long nVertMoveDelta)
sal_uInt8 GetBlue() const
sal_Int32 GetTextLen() const
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_LIGHTRED
void SetColor(const Color &rCol)
void SetLower(const sal_uInt16 nL, const sal_uInt16 nProp=100)
constexpr TypedWhichId< SwFormatINetFormat > RES_TXTATR_INETFMT(51)
mso_lineTriple
SVBT16 ya
Definition: ww8struc.hxx:715
constexpr OUStringLiteral aData
Definition: ww8scan.hxx:48
#define SAL_N_ELEMENTS(arr)
void SetOutlinerMode(OutlinerMode nNew)
virtual void GetSprms(WW8PLCFxDesc *p) override
Definition: ww8scan.cxx:3413
DocumentType eType
SVBT16 dhgt
Definition: ww8struc.hxx:701
ContactObject for connection between frames (or their formats respectively) in SwClient and the drawo...
Definition: dcontact.hxx:175
SwFrameFormat * Read_GrafLayer(tools::Long nGrafAnchorCp)
Definition: ww8graf.cxx:2504
void SendObjectToHeaven(SdrObject &rObject) const
Make Object lives in the top layer.
const Color & GetColor() const
sal_Int32 nDxTextRight
MSO_LineDashing eLineDashing
bool IsInRange(sal_uInt16 nWhich) const
void SetAttributesAtGrfNode(const SvxMSDffImportRec &rRecord, const SwFrameFormat &rFlyFormat, WW8_FSPA const *pF)
Definition: ww8graf.cxx:2122
virtual void SetLayer(SdrLayerID nLayer)
sal_Int32 nEndPara
Style of a layout element.
Definition: frmfmt.hxx:59
WW8_DP_LINETYPE aLnt
Definition: ww8struc.hxx:782
SVBT16 cb
Definition: ww8struc.hxx:684
bool checkSeek(SvStream &rSt, sal_uInt64 nOffset)
void SetUniqueGraphName(SwFrameFormat *pFrameFormat, std::u16string_view rFixedPart)
Definition: ww8graf.cxx:164
constexpr TypedWhichId< XFillTransparenceItem > XATTR_FILLTRANSPARENCE(XATTR_FILL_FIRST+5)
SwFrameFormat * MungeTextIntoDrawBox(SvxMSDffImportRec &rRecord, tools::Long nGrafAnchorCp, SwFrameFormat *pRetFrameFormat)
Definition: ww8graf.cxx:2863
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
constexpr TypedWhichId< SdrGrafLuminanceItem > SDRATTR_GRAFLUMINANCE(SDRATTR_GRAF_FIRST+3)
int i
void SetAlpha(sal_uInt8 cAlpha)
void SetDistance(double nNewDistance)
constexpr TypedWhichId< XFillBitmapItem > XATTR_FILLBITMAP(XATTR_FILL_FIRST+4)
mso_lineDashGEL
among others for fields, that is, the same number of attr as positions, if Ctor-Param bNoEnd = false ...
Definition: ww8scan.hxx:220
SVBT16 flpp
Definition: ww8struc.hxx:739
SwTwips MakeSafePositioningValue(SwTwips nIn)
Clips a value to MAX/MIN 16bit value to make it safe for use as a position value to give to writer...
void SetValue(EnumT nTheValue)
bool TxbxChainContainsRealText(sal_uInt16 nTxBxS, tools::Long &rStartCp, tools::Long &rEndCp)
Definition: ww8graf.cxx:1233
bool GetTxbxTextSttEndCp(WW8_CP &rStartCp, WW8_CP &rEndCp, sal_uInt16 nTxBxS, sal_uInt16 nSequence)
Definition: ww8graf.cxx:800
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
SVL_DLLPUBLIC Link< OUString *, bool > const & GetMaybeFileHdl()
SwFormat * m_pFormat
Definition: ww8par.hxx:232
const Graphic & GetGraphic() const
SwFrameFormat * AddAutoAnchor(SwFrameFormat *pFormat)
Definition: ww8graf.cxx:2848
constexpr sal_uInt16 XATTR_START
WW8_DP_LINETYPE aLnt
Definition: ww8struc.hxx:764
void SetPos(SwTwips nNew)
Definition: fmtornt.hxx:60
static void SetLineEndAttr(SfxItemSet &rSet, WW8_DP_LINEEND const &rLe, WW8_DP_LINETYPE const &rLt)
Definition: ww8graf.cxx:274
SdrObject * ReadRect(WW8_DPHEAD const *pHd, SfxAllItemSet &rSet)
Definition: ww8graf.cxx:345
FlyAnchors.
Definition: fmtanchr.hxx:34
void SetWidthSizeType(SwFrameSize eSize)
Definition: fmtfsize.hxx:84
SVBT16 xaOffset
Definition: ww8struc.hxx:731
virtual const SwDrawModel * GetDrawModel() const =0
Draw Model and id accessors.
constexpr tools::Long Right() const
void SetMergedItemSetAndBroadcast(const SfxItemSet &rSet, bool bClearAllItems=false)
void SetRed(sal_uInt8 nRed)
float u
void MatchEscherMirrorIntoFlySet(const SvxMSDffImportRec &rRecord, SfxItemSet &rFlySet)
Definition: ww8graf.cxx:3066
static const int RELTO_DEFAULT
constexpr TypedWhichId< SdrGrafModeItem > SDRATTR_GRAFMODE(SDRATTR_GRAF_FIRST+8)
void Move(tools::Long nHorzMove, tools::Long nVertMove)
SwFrameSize GetWidthSizeType() const
Definition: fmtfsize.hxx:83
void SetTop(sal_Int32 nVal)
sal_uInt32 GetOrdNum() const
WW8_DP_SHADOW aShd
Definition: ww8struc.hxx:766
constexpr TypedWhichId< SdrMetricItem > SDRATTR_SHADOWYDIST(SDRATTR_SHADOW_FIRST+3)
void Restore(SwWW8ImplReader *pRdr)
Definition: ww8par.cxx:2037
constexpr tools::Long Top() const
mso_lineThinThick
size
Layout frame for SwNoTextNode, i.e. graphics and OLE nodes (including charts).
Definition: ndnotxt.hxx:29
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
Definition: format.cxx:386
virtual void SetLogicRect(const tools::Rectangle &rRect)
static Color WW8TransCol(SVBT32 nWC)
Definition: ww8graf.cxx:112
WW8_DP_SHADOW aShd
Definition: ww8struc.hxx:784
Marks a node in the document model.
Definition: ndindex.hxx:30
const sal_uInt16 LN_CObjLocation
Definition: sprmids.hxx:45
sal_Int32 indexOfAny(std::u16string_view rIn, sal_Unicode const *const pChars, sal_Int32 const nPos)
bool SeekPos(tools::Long nPos)
Definition: ww8scan.cxx:2178
sal_uInt16 GetSlotId(sal_uInt16 nWhich) const
ManTypes
Definition: ww8scan.hxx:870
::basegfx::B2DPolygon getB2DPolygon() const
sal_Int32 nDyTextTop
constexpr sal_uInt16 XATTR_END
void SetDocShell(SwDocShell *pDSh)
Definition: docnew.cxx:606
tools::Long GetHeight() const
GPOS_AREA
std::unique_ptr< SfxPoolItem > CloneSetWhich(sal_uInt16 nNewWhich) const
SfxItemPool * GetPool() const
SVBT32 dlpcFg
Definition: ww8struc.hxx:737
WW8_DP_LINETYPE aLnt
Definition: ww8struc.hxx:803
const char * pS
Frame cannot be moved in Var-direction.
tools::Long SwTwips
Definition: swtypes.hxx:51
SwFltPosition m_aMkPos
Definition: fltshell.hxx:87
#define Y
bool ReadGrafStart(void *pData, short nDataSiz, WW8_DPHEAD const *pHd, SfxAllItemSet &rSet)
Definition: ww8graf.cxx:173
size_t size() const
sal_Int32 GetParagraphCount() const
constexpr sal_uInt16 POOLATTR_END(RES_UNKNOWNATR_END)
static void removePositions(EditEngine &rDrawEditEngine, const std::vector< sal_Int32 > &rDosLineEndDummies)
Definition: ww8graf.cxx:955
WW8_DP_FILL aFill
Definition: ww8struc.hxx:793
SdrMetricItem makeSdrTextLeftDistItem(tools::Long mnHeight)
sal_Int32 WW8_CP
Definition: ww8struc.hxx:153
virtual SdrLayerID GetLayer() const
tools::Long AdjustTop(tools::Long nVertMoveDelta)
bool Get(WW8_CP &rStart, void *&rpValue) const
Definition: ww8scan.cxx:2244
const SwNodeIndex * GetContentIdx() const
Definition: fmtcntnt.hxx:46
SVBT16 dxa
Definition: ww8struc.hxx:716
constexpr tools::Long Bottom() const
sal_uInt16 nwrk
Definition: ww8struc.hxx:933
static void AdjustULWrapForWordMargins(const SvxMSDffImportRec &rRecord, SvxULSpaceItem &rUL)
Definition: ww8graf.cxx:1972
sal_Int32 nSprmsLen
Definition: ww8scan.hxx:902
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:448
void SetGraphicPos(SvxGraphicPosition eNew)
SVBT16 yaEnd
Definition: ww8struc.hxx:763
SfxItemPool * GetSecondaryPool() const
SVBT16 aEndBits
Definition: ww8struc.hxx:750
sal_uInt8 GetGreen() const
bool IsLinkedGraphic() const
void GetPCDSprms(WW8PLCFxDesc &rDesc)
Definition: ww8scan.cxx:3264
SdrObject * ReadTextBox(WW8_DPHEAD const *pHd, SfxAllItemSet &rSet)
Definition: ww8graf.cxx:1243
sal_uInt8 bx
Definition: ww8struc.hxx:685
WW8_DP_SHADOW aShd
Definition: ww8struc.hxx:794
virtual OUString GetURL() const override
constexpr TypedWhichId< XFillColorItem > XATTR_FILLCOLOR(XATTR_FILL_FIRST+1)
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
SVBT32 fc
Definition: ww8struc.hxx:677
constexpr TypedWhichId< SdrMetricItem > SDRATTR_SHADOWXDIST(SDRATTR_SHADOW_FIRST+2)
void setClosed(bool bNew)
void SetDashes(sal_uInt16 nNewDashes)
sal_uInt16 bRcaSimple
Definition: ww8struc.hxx:939
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_LIGHTCYAN
std::optional< sal_uInt32 > nYRelTo
#define SW_UD_IMAPDATA
Definition: ww8par.hxx:59
virtual SwDrawFrameFormat * InsertDrawObj(const SwPaM &rRg, SdrObject &rDrawObj, const SfxItemSet &rFlyAttrSet)=0
Insert a DrawObject.
virtual bool IsVerticalWriting() const
mso_sptTextBox
constexpr sal_uInt16 RES_FLTRATTR_END(197)
sal_Int32 nDyWrapDistBottom
SfxItemState
constexpr TypedWhichId< SvxBrushItem > RES_BACKGROUND(105)
MSO_LineStyle eLineStyle
SVBT16 yaStart
Definition: ww8struc.hxx:761
void SetLeft(const tools::Long nL, const sal_uInt16 nProp=100)
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
sal_uInt16 GetWhich(sal_uInt16 nSlot, bool bDeep=true) const
#define SAL_WARN_IF(condition, area, stream)
#define WW8ITEMVALUE(ItemSet, Id, Cast)
Definition: ww8graf.cxx:1674
constexpr tools::Long Height() const
void advance()
Definition: ww8scan.cxx:889
unsigned char sal_uInt8
void SetWidth(sal_uInt16 nNew)
constexpr::Color COL_GREEN(0x00, 0x80, 0x00)
SVBT16 shdwpi
Definition: ww8struc.hxx:730
SdrMetricItem makeSdrShadowXDistItem(tools::Long nDist)
constexpr sal_uInt16 RES_GRFATR_BEGIN(RES_FRMATR_END)
SwTwips GetPos() const
Definition: fmtornt.hxx:59
sal_uInt16 GetId() const
void SetIdx(tools::Long nI)
Definition: ww8scan.hxx:236
void SetGreen(sal_uInt8 nGreen)
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_WHITE
#define SAL_INFO(area, stream)
RndStdIds ProcessEscherAlign(SvxMSDffImportRec &rRecord, WW8_FSPA &rFSPA, SfxItemSet &rFlySet)
Definition: ww8graf.cxx:2253
const SfxItemSet & GetMergedItemSet() const
void SetLocation(SvxShadowLocation eNew)
void SetProgressState(tools::Long nPosition, SwDocShell const *pDocShell)
Definition: mainwn.cxx:82
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BROWN
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_LIGHTGREEN
SfxItemPool * GetMasterPool() const
SdrObjUserData * GetUserData(sal_uInt16 nNum) const
virtual SwDrawModel * GetOrCreateDrawModel()=0
WW8_DP_SHADOW aShd
Definition: ww8struc.hxx:805
SwNodes & GetNodes()
Definition: doc.hxx:408
SvxBoxItemLine
iterator for Piece Table Exceptions of Fkps works on CPs (high-level)
Definition: ww8scan.hxx:633
bool IsObjectLayoutInTableCell(const sal_uInt32 nGroupShapeBooleanProperties) const
Definition: ww8graf.cxx:2454
MSO_LineStyle
WW8_DP_FILL aFill
Definition: ww8struc.hxx:772
void InsertAttrsAsDrawingAttrs(WW8_CP nStartCp, WW8_CP nEndCp, ManTypes eType, bool bONLYnPicLocFc=false)
Definition: ww8graf.cxx:594
const sal_uInt8 * GetCurrentParams() const
Definition: ww8scan.hxx:284
sal_Int32 nCropFromBottom
void QuickDelete(const ESelection &rSel)
constexpr TypedWhichId< XFillBmpTileItem > XATTR_FILLBMP_TILE(XATTR_FILL_FIRST+7)
SdrObject * CreateContactObject(SwFrameFormat *pFlyFormat)
Definition: ww8graf.cxx:2223
SwFlyFrameFormat * ImportReplaceableDrawables(SdrObject *&rpObject, SdrObject *&rpOurNewObject, SvxMSDffImportRec &rRecord, WW8_FSPA &rF, SfxItemSet &rFlySet)
Definition: ww8graf.cxx:3081
WW8_DP_TXTBOX dptxbx
Definition: ww8struc.hxx:831
SdrObject * ReadGrafPrimitive(short &rLeft, SfxAllItemSet &rSet)
Definition: ww8graf.cxx:1389
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_YELLOW
constexpr TypedWhichId< SvxLRSpaceItem > RES_LR_SPACE(91)
SdrOnOffItem makeSdrShadowItem(bool bShadow)
SVBT16 xaStart
Definition: ww8struc.hxx:760
sal_uInt16 GetUserDataCount() const
constexpr TypedWhichId< SvxBoxItem > RES_BOX(106)
SdrObject * getParentSdrObjectFromSdrObject() const
const SwFormatContent & GetContent(bool=true) const
Definition: fmtcntnt.hxx:55
void SetPos(SwTwips nNew)
Definition: fmtornt.hxx:93
SVBT16 xaEnd
Definition: ww8struc.hxx:762
void SetDashLen(double nNewDashLen)
const sal_Int32 & GetShapeId() const
Definition: ww8par.hxx:516
WW8_DP_FILL aFill
Definition: ww8struc.hxx:783
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_LIGHTBLUE
void DelFrameFormat(SwFrameFormat *pFormat, bool bBroadcast=false)
Definition: docfmt.cxx:697
SVBT16 dya
Definition: ww8struc.hxx:717
SdrObject * ReadArc(WW8_DPHEAD const *pHd, SfxAllItemSet &rSet)
Definition: ww8graf.cxx:392
sal_Int32 nDyWrapDistTop
tools::Long AdjustLeft(tools::Long nHorzMoveDelta)
constexpr TypedWhichId< SdrGrafContrastItem > SDRATTR_GRAFCONTRAST(SDRATTR_GRAF_FIRST+4)
#define SAL_WARN(area, stream)
SdrObject * ReadLine(WW8_DPHEAD const *pHd, SfxAllItemSet &rSet)
Definition: ww8graf.cxx:310
RndStdIds
void SendObjectToHell(SdrObject &rObject) const
Make Object live in the bottom drawing layer.
virtual Degree100 GetRotateAngle() const
constexpr::Color COL_BLUE(0x00, 0x00, 0x80)
SdrObject * pObj
void ReadGrafLayer1(WW8PLCFspecial &rPF, tools::Long nGrafAnchorCp)
Definition: ww8graf.cxx:1446
std::optional< sal_uInt32 > nXRelTo
virtual void NbcSetSnapRect(const tools::Rectangle &rRect) override
sal_uInt16 nwr
Definition: ww8struc.hxx:924
std::optional< tools::Polygon > pWrapPolygon
SwFlyFrameFormat * ConvertDrawTextToFly(SdrObject *&rpObject, SdrObject *&rpOurNewObject, const SvxMSDffImportRec &rRecord, RndStdIds eAnchor, const WW8_FSPA &rF, SfxItemSet &rFlySet)
Definition: ww8graf.cxx:2958
bool m_bColl
Definition: ww8par.hxx:254
const SwPosition & GetStartPos() const
Definition: ww8par.hxx:615
Frame is variable in Var-direction.
SVBT16 yaOffset
Definition: ww8struc.hxx:732
SVBT16 aStartBits
Definition: ww8struc.hxx:744
WW8_DPHEAD dpheadTxbx
Definition: ww8struc.hxx:830
sal_Int32 nYaBottom
Definition: ww8struc.hxx:910
sal_uInt32 nGroupShapeBooleanProperties
sal_Int32 WW8_FC
Definition: ww8struc.hxx:152
SdrObject * ReadGroup(WW8_DPHEAD const *pHd, SfxAllItemSet &rSet)
Definition: ww8graf.cxx:1352
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
sal_uInt16 nSequence
SdrInventor GetInventor() const
void SetUpper(const sal_uInt16 nU, const sal_uInt16 nProp=100)
constexpr TypedWhichId< XLineColorItem > XATTR_LINECOLOR(XATTR_LINE_FIRST+3)
mso_lineSimple
void AddAnchor(const SwPosition &rPos, SwFrameFormat *pFormat)
Definition: ww8graf.cxx:3213
static std::vector< sal_Int32 > replaceDosLineEndsButPreserveLength(OUString &rIn)
Definition: ww8graf.cxx:929
const sal_uInt8 * pMemPos
Definition: ww8scan.hxx:883
constexpr sal_uInt16 RES_FRMATR_BEGIN(RES_PARATR_LIST_END)
const OUString & GetName() const
sal_Int32 nYaTop
Definition: ww8struc.hxx:908
WW8_DP_FILL aFill
Definition: ww8struc.hxx:804
SdrObject * FindSdrObject()
Definition: frmfmt.hxx:140
constexpr TypedWhichId< SvxULSpaceItem > RES_UL_SPACE(92)
WW8_DP_LINETYPE aLnt
Definition: ww8struc.hxx:771
virtual void SetVerticalWriting(bool bVertical)
sal_uInt16 Which() const
SdrObject * FindRealSdrObject()
Definition: atrfrm.cxx:2763
constexpr TypedWhichId< SvxShadowItem > RES_SHADOW(107)
void SetBottom(sal_Int32 nVal)
WW8_DP_SHADOW aShd
Definition: ww8struc.hxx:813
mso_lineDotGEL
const sal_uInt8 * GetSprms() const
Definition: ww8scan.hxx:282
const SwAttrPool & GetAttrPool() const
Definition: doc.hxx:1318
void SetAnchor(const SwPosition *pPos)
Definition: atrfrm.cxx:1585
constexpr tools::Long GetHeight() const
void SetLine(const editeng::SvxBorderLine *pNew, SvxBoxItemLine nLine)
SVL_DLLPUBLIC OUString SmartRel2Abs(INetURLObject const &rTheBaseURIRef, OUString const &rTheRelURIRef, Link< OUString *, bool > const &rMaybeFileHdl=Link< OUString *, bool >(), bool bCheckFileExists=true, bool bIgnoreFragment=false, INetURLObject::EncodeMechanism eEncodeMechanism=INetURLObject::EncodeMechanism::WasEncoded, INetURLObject::DecodeMechanism eDecodeMechanism=INetURLObject::DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8, FSysStyle eStyle=FSysStyle::Detect)
virtual const SdrObject * GetMaster() const override
Definition: dcontact.hxx:194
SvxShadowLocation
virtual void NbcSetLayer(SdrLayerID nLayer)
sal_Int32 nStartPos
sal_uInt8 fLeft
Definition: ww8struc.hxx:795
OStringBuffer & padToLength(OStringBuffer &rBuffer, sal_Int32 nLength, char cFill= '\0')
bool MiserableRTLGraphicsHack(SwTwips &rLeft, SwTwips nWidth, sal_Int16 eHoriOri, sal_Int16 eHoriRel)
Definition: ww8graf.cxx:2242