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/xfillit0.hxx>
27 #include <svx/xlineit0.hxx>
28 #include <svx/xlnclit.hxx>
29 #include <svx/xlnwtit.hxx>
30 #include <svx/xlndsit.hxx>
31 #include <svx/xlnstit.hxx>
32 #include <svx/xlnedit.hxx>
33 #include <svx/xlnstwit.hxx>
34 #include <svx/xlnedwit.hxx>
35 #include <svx/xlnstcit.hxx>
36 #include <svx/xlnedcit.hxx>
37 #include <svx/xflclit.hxx>
38 #include <svx/xbtmpit.hxx>
39 #include <svx/svdmodel.hxx>
40 #include <svx/svdocapt.hxx>
41 #include <svx/sxctitm.hxx>
42 #include <svx/sdggaitm.hxx>
43 #include <svx/sdgluitm.hxx>
44 #include <svx/sdgmoitm.hxx>
45 #include <svx/sdmetitm.hxx>
46 #include <svx/sdooitm.hxx>
47 #include <svx/sdshitm.hxx>
48 #include <svx/sdsxyitm.hxx>
49 #include <svx/sdtagitm.hxx>
50 #include <svx/sdtditm.hxx>
51 #include <svx/sdtfsitm.hxx>
52 #include <editeng/editeng.hxx>
53 #include <svx/svdpage.hxx>
54 #include <svx/svdopath.hxx>
55 #include <svx/svdocirc.hxx>
56 #include <editeng/outlobj.hxx>
57 #include <svx/svdogrp.hxx>
58 #include <svx/svdograf.hxx>
59 #include <svx/svdoole2.hxx>
60 #include <editeng/ulspitem.hxx>
61 #include <editeng/brushitem.hxx>
62 #include <editeng/opaqitem.hxx>
63 #include <editeng/shaditem.hxx>
64 #include <editeng/boxitem.hxx>
65 #include <editeng/outliner.hxx>
66 #include <editeng/frmdiritem.hxx>
67 #include <svx/xfltrit.hxx>
69 #include <grfatr.hxx>
70 #include <fmtornt.hxx>
71 #include <fmtcntnt.hxx>
72 #include <frmfmt.hxx>
73 #include <fmtanchr.hxx>
74 #include <pam.hxx>
75 #include <doc.hxx>
76 #include <drawdoc.hxx>
78 #include <ndgrf.hxx>
79 #include <dcontact.hxx>
80 #include <docsh.hxx>
81 #include <mdiexp.hxx>
82 #include "ww8struc.hxx"
83 #include "ww8scan.hxx"
84 #include "ww8par.hxx"
85 #include "ww8par2.hxx"
86 #include "ww8graf.hxx"
87 #include <fmtinfmt.hxx>
88 #include <editeng/eeitem.hxx>
89 #include <editeng/flditem.hxx>
90 #include <fmtfollowtextflow.hxx>
91 #include "writerhelper.hxx"
92 #include "writerwordglue.hxx"
95 #include <editeng/editobj.hxx>
96 #include <math.h>
97 #include <fmturl.hxx>
98 #include <o3tl/enumrange.hxx>
99 #include <o3tl/safeint.hxx>
100 #include <memory>
101 #include <optional>
103 #include "sprmids.hxx"
104 
105 using ::editeng::SvxBorderLine;
106 using namespace ::com::sun::star;
107 using namespace sw::types;
108 using namespace sw::util;
109 
110 // helper methods
111 static Color WW8TransCol(SVBT32 nWC)
112 {
113 #if 1 // 1 = use predefined color, 0 = ignore
114 
115  // color table to convert RGB values to pre-defined colors
116  // (to make the writer UI show the right color names)
117  // the table is split in base 3, the greys are missing as
118  // they don't fit into that system (4 values: bw, wb, 2 * grey)
119  static const Color eColA[] = { // B G R B G R B G R
120  COL_BLACK, COL_RED, COL_LIGHTRED, // 0 0 0, 0 0 1, 0 0 2
121  COL_GREEN, COL_BROWN, COL_BLACK, // 0 1 0, 0 1 1, 0 1 2
122  COL_LIGHTGREEN, COL_BLACK, COL_YELLOW, // 0 2 0, 0 2 1, 0 2 2
123  COL_BLUE, COL_MAGENTA, COL_BLACK, // 1 0 0, 1 0 1, 1 0 2
124  COL_CYAN, COL_LIGHTGRAY, COL_BLACK, // 1 1 0, 1 1 1, 1 1 2
125  COL_BLACK, COL_BLACK, COL_BLACK, // 1 2 0, 1 2 1, 1 2 2
126  COL_LIGHTBLUE, COL_BLACK, COL_LIGHTMAGENTA, // 2 0 0, 2 0 1, 2 0 2
127  COL_BLACK, COL_BLACK, COL_BLACK, // 2 1 0, 2 1 1, 2 1 2
128  COL_LIGHTCYAN, COL_BLACK, COL_WHITE }; // 2 2 0, 2 2 1, 2 2 2
129 
130  // In nWC[3] is a byte that's not described in the WW documentation.
131  // Its meaning appears to be the following: For 0, it's a normal color
132  // whose RGB values are in nWC[0..2]. If nWC[3] is 0x1, 0x7d or 0x83,
133  // it's a grey value whose black portion is given in 0.5% in nWC[0].
134  // I guess that BIT(0) in nWC[3] is relevant for distinguishing RGB/Grey.
135 
136  if( !( nWC[3] & 0x1 ) && // not special (grey)
137  ( ( nWC[0] == 0 || nWC[0]== 0x80 || nWC[0] == 0xff ) // R
138  && ( nWC[1] == 0 || nWC[1]== 0x80 || nWC[1] == 0xff ) // G
139  && ( nWC[2] == 0 || nWC[2]== 0x80 || nWC[2] == 0xff ) ) ){// B
140  int nIdx = 0; // and now: Idx-calculation in base 3
141  for (int i = 2; i >= 0; i--)
142  {
143  nIdx *= 3;
144  if (nWC[i])
145  nIdx += ((nWC[i] == 0xff) ? 2 : 1);
146  }
147  if (eColA[nIdx] != COL_BLACK)
148  return eColA[nIdx]; // default color
149  }
150 #endif
151 
152  if (nWC[3] & 0x1)
153  {
154  // Special color gray
155  sal_uInt8 u = static_cast<sal_uInt8>( static_cast<sal_uLong>( 200 - nWC[0] ) * 256 / 200 );
156  return Color(u, u, u);
157  }
158 
159  // User-Color
160  return Color(nWC[0], nWC[1], nWC[2]);
161 }
162 
163 void wwFrameNamer::SetUniqueGraphName(SwFrameFormat *pFrameFormat, std::u16string_view rFixed)
164 {
165  if (mbIsDisabled || rFixed.empty())
166  return;
167 
168  pFrameFormat->SetName(msSeed+OUString::number(++mnImportedGraphicsCount) + ": " + rFixed);
169 }
170 
171 // ReadGrafStart reads object data and if necessary creates an anchor
172 bool SwWW8ImplReader::ReadGrafStart(void* pData, short nDataSiz,
173  WW8_DPHEAD const * pHd, SfxAllItemSet &rSet)
174 {
175  if (SVBT16ToUInt16(pHd->cb) < sizeof(WW8_DPHEAD) + nDataSiz)
176  {
177  OSL_ENSURE( false, "+graphic element: too short?" );
178  m_pStrm->SeekRel(SVBT16ToUInt16(pHd->cb) - sizeof(WW8_DPHEAD));
179  return false;
180  }
181 
182  bool bCouldRead = checkRead(*m_pStrm, pData, nDataSiz);
183  OSL_ENSURE(bCouldRead, "Short Graphic header");
184  if (!bCouldRead)
185  return false;
186 
187  SwFormatAnchor aAnchor( RndStdIds::FLY_AT_CHAR );
188  aAnchor.SetAnchor( m_pPaM->GetPoint() );
189  rSet.Put( aAnchor );
190 
191  m_nDrawXOfs2 = m_nDrawXOfs;
192  m_nDrawYOfs2 = m_nDrawYOfs;
193 
194  return true;
195 }
196 
197 // SetStdAttr() sets standard attributes
198 static void SetStdAttr( SfxItemSet& rSet, WW8_DP_LINETYPE& rL,
199  WW8_DP_SHADOW const & rSh )
200 {
201  if( SVBT16ToUInt16( rL.lnps ) == 5 ){ // invisible
202  rSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
203  }else{ // visible
204  Color aCol( WW8TransCol( rL.lnpc ) ); // line color
205  rSet.Put( XLineColorItem( OUString(), aCol ) );
206  rSet.Put( XLineWidthItem( SVBT16ToUInt16( rL.lnpw ) ) );
207  // line thickness
208  if( SVBT16ToUInt16( rL.lnps ) >= 1
209  && SVBT16ToUInt16(rL.lnps ) <= 4 ){ // line style
210  rSet.Put( XLineStyleItem( drawing::LineStyle_DASH ) );
211  sal_Int16 nLen = SVBT16ToUInt16( rL.lnpw );
212  XDash aD( css::drawing::DashStyle_RECT, 1, 2 * nLen, 1, 5 * nLen, 5 * nLen );
213  switch( SVBT16ToUInt16( rL.lnps ) ){
214  case 1: aD.SetDots( 0 ); // Dash
215  aD.SetDashLen( 6 * nLen );
216  aD.SetDistance( 4 * nLen );
217  break;
218  case 2: aD.SetDashes( 0 ); break; // Dot
219  case 3: break; // Dash Dot
220  case 4: aD.SetDots( 2 ); break; // Dash Dot Dot
221  }
222  rSet.Put( XLineDashItem( OUString(), aD ) );
223  }else{
224  rSet.Put( XLineStyleItem( drawing::LineStyle_SOLID ) ); // needed for TextBox
225  }
226  }
227  if( SVBT16ToUInt16( rSh.shdwpi ) ){ // shadow
228  rSet.Put(makeSdrShadowItem(true));
229  rSet.Put( makeSdrShadowXDistItem( SVBT16ToUInt16( rSh.xaOffset ) ) );
230  rSet.Put( makeSdrShadowYDistItem( SVBT16ToUInt16( rSh.yaOffset ) ) );
231  }
232 }
233 
234 // SetFill() sets fill attributes such as fore- and background color and
235 // pattern by reducing to a color
236 // SetFill() doesn't yet set a pattern, because Sdr can't easily do that
237 // and the Sdr hatching (XDash) isn't finished yet.
238 // Instead, a mixed color will be picked that's between the selected ones.
239 static void SetFill( SfxItemSet& rSet, WW8_DP_FILL& rFill )
240 {
241  static const sal_uInt8 nPatA[] =
242  {
243  0, 0, 5, 10, 20, 25, 30, 40, 50, 60, 70, 75, 80,
244  90, 50, 50, 50, 50, 50, 50, 33, 33, 33, 33, 33, 33
245  };
246  sal_uInt16 nPat = SVBT16ToUInt16(rFill.flpp);
247 
248  if (nPat == 0) // transparent
249  rSet.Put(XFillStyleItem(drawing::FillStyle_NONE));
250  else
251  {
252  rSet.Put(XFillStyleItem(drawing::FillStyle_SOLID)); // necessary for textbox
253  if (nPat <= 1 || (SAL_N_ELEMENTS(nPatA) <= nPat))
254  {
255  // Solid background or unknown
256  rSet.Put(XFillColorItem(OUString(), WW8TransCol(rFill.dlpcBg)));
257  }
258  else
259  { // Brush -> color mix
260  Color aB( WW8TransCol( rFill.dlpcBg ) );
261  Color aF( WW8TransCol( rFill.dlpcFg ) );
262  aB.SetRed( static_cast<sal_uInt8>( ( static_cast<sal_uLong>(aF.GetRed()) * nPatA[nPat]
263  + static_cast<sal_uLong>(aB.GetRed()) * ( 100 - nPatA[nPat] ) ) / 100 ) );
264  aB.SetGreen( static_cast<sal_uInt8>( ( static_cast<sal_uLong>(aF.GetGreen()) * nPatA[nPat]
265  + static_cast<sal_uLong>(aB.GetGreen()) * ( 100 - nPatA[nPat] ) ) / 100 ) );
266  aB.SetBlue( static_cast<sal_uInt8>( ( static_cast<sal_uLong>(aF.GetBlue()) * nPatA[nPat]
267  + static_cast<sal_uLong>(aB.GetBlue()) * ( 100 - nPatA[nPat] ) ) / 100 ) );
268  rSet.Put( XFillColorItem( OUString(), aB ) );
269  }
270  }
271 }
272 
273 static void SetLineEndAttr( SfxItemSet& rSet, WW8_DP_LINEEND const & rLe,
274  WW8_DP_LINETYPE const & rLt )
275 {
276  sal_uInt16 aSB = SVBT16ToUInt16( rLe.aStartBits );
277  if( aSB & 0x3 )
278  {
279  ::basegfx::B2DPolygon aPolygon;
280  aPolygon.append(::basegfx::B2DPoint(0.0, 330.0));
281  aPolygon.append(::basegfx::B2DPoint(100.0, 0.0));
282  aPolygon.append(::basegfx::B2DPoint(200.0, 330.0));
283  aPolygon.setClosed(true);
284  rSet.Put( XLineEndItem( OUString(), ::basegfx::B2DPolyPolygon(aPolygon) ) );
285  sal_uInt16 nSiz = SVBT16ToUInt16( rLt.lnpw )
286  * ( ( aSB >> 2 & 0x3 ) + ( aSB >> 4 & 0x3 ) );
287  if( nSiz < 220 ) nSiz = 220;
288  rSet.Put(XLineEndWidthItem(nSiz));
289  rSet.Put(XLineEndCenterItem(false));
290  }
291 
292  sal_uInt16 aEB = SVBT16ToUInt16( rLe.aEndBits );
293  if( !(aEB & 0x3) ) return;
294 
295  ::basegfx::B2DPolygon aPolygon;
296  aPolygon.append(::basegfx::B2DPoint(0.0, 330.0));
297  aPolygon.append(::basegfx::B2DPoint(100.0, 0.0));
298  aPolygon.append(::basegfx::B2DPoint(200.0, 330.0));
299  aPolygon.setClosed(true);
300  rSet.Put( XLineStartItem( OUString(), ::basegfx::B2DPolyPolygon(aPolygon) ) );
301  sal_uInt16 nSiz = SVBT16ToUInt16( rLt.lnpw )
302  * ( ( aEB >> 2 & 0x3 ) + ( aEB >> 4 & 0x3 ) );
303  if( nSiz < 220 ) nSiz = 220;
304  rSet.Put(XLineStartWidthItem(nSiz));
305  rSet.Put(XLineStartCenterItem(false));
306 }
307 
308 // start of routines for the different objects
310 {
311  WW8_DP_LINE aLine;
312 
313  if( !ReadGrafStart( static_cast<void*>(&aLine), sizeof( aLine ), pHd, rSet ) )
314  return nullptr;
315 
316  Point aP[2];
317  {
318  Point& rP0 = aP[0];
319  Point& rP1 = aP[1];
320 
321  rP0.setX( static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa )) + m_nDrawXOfs2 );
322  rP0.setY( static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya )) + m_nDrawYOfs2 );
323  rP1 = rP0;
324  rP0.AdjustX(static_cast<sal_Int16>(SVBT16ToUInt16( aLine.xaStart )) );
325  rP0.AdjustY(static_cast<sal_Int16>(SVBT16ToUInt16( aLine.yaStart )) );
326  rP1.AdjustX(static_cast<sal_Int16>(SVBT16ToUInt16( aLine.xaEnd )) );
327  rP1.AdjustY(static_cast<sal_Int16>(SVBT16ToUInt16( aLine.yaEnd )) );
328  }
329 
330  ::basegfx::B2DPolygon aPolygon;
331  aPolygon.append(::basegfx::B2DPoint(aP[0].X(), aP[0].Y()));
332  aPolygon.append(::basegfx::B2DPoint(aP[1].X(), aP[1].Y()));
333  SdrObject* pObj = new SdrPathObj(
334  *m_pDrawModel,
335  OBJ_LINE,
336  ::basegfx::B2DPolyPolygon(aPolygon));
337 
338  SetStdAttr( rSet, aLine.aLnt, aLine.aShd );
339  SetLineEndAttr( rSet, aLine.aEpp, aLine.aLnt );
340 
341  return pObj;
342 }
343 
345 {
346  WW8_DP_RECT aRect;
347 
348  if( !ReadGrafStart( static_cast<void*>(&aRect), sizeof( aRect ), pHd, rSet ) )
349  return nullptr;
350 
351  Point aP0( static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa )) + m_nDrawXOfs2,
352  static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya )) + m_nDrawYOfs2 );
353  Point aP1( aP0 );
354  aP1.AdjustX(static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dxa )) );
355  aP1.AdjustY(static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dya )) );
356 
357  SdrObject* pObj = new SdrRectObj(
358  *m_pDrawModel,
359  tools::Rectangle(aP0, aP1));
360 
361  SetStdAttr( rSet, aRect.aLnt, aRect.aShd );
362  SetFill( rSet, aRect.aFill );
363 
364  return pObj;
365 }
366 
368 {
369  WW8_DP_ELLIPSE aEllipse;
370 
371  if( !ReadGrafStart( static_cast<void*>(&aEllipse), sizeof( aEllipse ), pHd, rSet ) )
372  return nullptr;
373 
374  Point aP0( static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa )) + m_nDrawXOfs2,
375  static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya )) + m_nDrawYOfs2 );
376  Point aP1( aP0 );
377  aP1.AdjustX(static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dxa )) );
378  aP1.AdjustY(static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dya )) );
379 
380  SdrObject* pObj = new SdrCircObj(
381  *m_pDrawModel,
382  SdrCircKind::Full,
383  tools::Rectangle(aP0, aP1));
384 
385  SetStdAttr( rSet, aEllipse.aLnt, aEllipse.aShd );
386  SetFill( rSet, aEllipse.aFill );
387 
388  return pObj;
389 }
390 
392 {
393  WW8_DP_ARC aArc;
394 
395  if( !ReadGrafStart( static_cast<void*>(&aArc), sizeof( aArc ), pHd, rSet ) )
396  return nullptr;
397 
398  Point aP0( static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa )) + m_nDrawXOfs2,
399  static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya )) + m_nDrawYOfs2 );
400  Point aP1( aP0 );
401  aP1.AdjustX(static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dxa )) * 2 );
402  aP1.AdjustY(static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dya )) * 2 );
403 
404  short nA[] = { 2, 3, 1, 0 };
405  short nW = nA[ ( ( aArc.fLeft & 1 ) << 1 ) + ( aArc.fUp & 1 ) ];
406  if( !aArc.fLeft ){
407  aP0.AdjustY( -static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dya )) );
408  aP1.AdjustY( -static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dya )) );
409  }
410  if( aArc.fUp ){
411  aP0.AdjustX( -static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dxa )) );
412  aP1.AdjustX( -static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dxa )) );
413  }
414 
415  SdrObject* pObj = new SdrCircObj(
416  *m_pDrawModel,
417  SdrCircKind::Section,
418  tools::Rectangle(aP0, aP1),
419  Degree100(nW * 9000),
420  Degree100(( ( nW + 1 ) & 3 ) * 9000));
421 
422  SetStdAttr( rSet, aArc.aLnt, aArc.aShd );
423  SetFill( rSet, aArc.aFill );
424 
425  return pObj;
426 }
427 
429 {
430  WW8_DP_POLYLINE aPoly;
431 
432  if( !ReadGrafStart( static_cast<void*>(&aPoly), sizeof( aPoly ), pHd, rSet ) )
433  return nullptr;
434 
435  sal_uInt16 nCount = SVBT16ToUInt16( aPoly.aBits1 ) >> 1 & 0x7fff;
436  std::unique_ptr<SVBT16[]> xP(new SVBT16[nCount * 2]);
437 
438  bool bCouldRead = checkRead(*m_pStrm, xP.get(), nCount * 4); // read points
439  OSL_ENSURE(bCouldRead, "Short PolyLine header");
440  if (!bCouldRead)
441  return nullptr;
442 
443  tools::Polygon aP( nCount );
444  Point aPt;
445  for (sal_uInt16 i=0; i<nCount; ++i)
446  {
447  aPt.setX( SVBT16ToUInt16( xP[i << 1] ) + m_nDrawXOfs2
448  + static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa )) );
449  aPt.setY( SVBT16ToUInt16( xP[( i << 1 ) + 1] ) + m_nDrawYOfs2
450  + static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya )) );
451  aP[i] = aPt;
452  }
453  xP.reset();
454 
455  SdrObject* pObj = new SdrPathObj(
456  *m_pDrawModel,
457  (SVBT16ToUInt16(aPoly.aBits1) & 0x1) ? OBJ_POLY : OBJ_PLIN,
459 
460  SetStdAttr( rSet, aPoly.aLnt, aPoly.aShd );
461  SetFill( rSet, aPoly.aFill );
462 
463  return pObj;
464 }
465 
466 static ESelection GetESelection(EditEngine const &rDrawEditEngine, tools::Long nCpStart, tools::Long nCpEnd)
467 {
468  sal_Int32 nPCnt = rDrawEditEngine.GetParagraphCount();
469  sal_Int32 nSP = 0;
470  sal_Int32 nEP = 0;
471  while( (nSP < nPCnt)
472  && (nCpStart >= rDrawEditEngine.GetTextLen( nSP ) + 1) )
473  {
474  nCpStart -= rDrawEditEngine.GetTextLen( nSP ) + 1;
475  nSP++;
476  }
477  // at the end, switch to the new line only 1 character later as
478  // otherwise line attributes reach one line too far
479  while( (nEP < nPCnt)
480  && (nCpEnd > rDrawEditEngine.GetTextLen( nEP ) + 1) )
481  {
482  nCpEnd -= rDrawEditEngine.GetTextLen( nEP ) + 1;
483  nEP++;
484  }
485  return ESelection( nSP, nCpStart, nEP, nCpEnd );
486 }
487 
488 // InsertTxbxStyAttrs() sets style attributes into the passed ItemSet.
489 // SW styles are used since import-WW-styles are already destroyed.
490 // SW styles are examined in depth first search order (with parent styles)
491 // for the attributes given in aSrcTab. They're cloned, and the clones'
492 // Which-IDs are changed according to the aDstTab table so that the
493 // EditEngine will not ignore them.
494 // Both Paragraph and character attributes are stuffed into the ItemSet.
495 void SwWW8ImplReader::InsertTxbxStyAttrs( SfxItemSet& rS, sal_uInt16 nColl )
496 {
497  SwWW8StyInf * pStyInf = GetStyle(nColl);
498  if( !(pStyInf != nullptr && pStyInf->m_pFormat && pStyInf->m_bColl) )
499  return;
500 
501  const SfxPoolItem* pItem;
502  for( sal_uInt16 i = POOLATTR_BEGIN; i < POOLATTR_END; i++ )
503  {
504  // If we are set in the source and not set in the destination
505  // then add it in.
506  if ( SfxItemState::SET == pStyInf->m_pFormat->GetItemState(
507  i, true, &pItem ) )
508  {
509  SfxItemPool *pEditPool = rS.GetPool();
510  sal_uInt16 nWhich = i;
511  sal_uInt16 nSlotId = m_rDoc.GetAttrPool().GetSlotId(nWhich);
512  if (
513  nSlotId && nWhich != nSlotId &&
514  0 != (nWhich = pEditPool->GetWhich(nSlotId)) &&
515  nWhich != nSlotId &&
516  ( SfxItemState::SET != rS.GetItemState(nWhich, false) )
517  )
518  {
519  rS.Put( pItem->CloneSetWhich(nWhich) );
520  }
521  }
522  }
523 
524 }
525 
526 static void lcl_StripFields(OUString &rString, WW8_CP &rNewStartCp)
527 {
528  sal_Int32 nStartPos = 0;
529  for (;;)
530  {
531  nStartPos = rString.indexOf(0x13, nStartPos);
532  if (nStartPos<0)
533  return;
534 
535  const sal_Unicode cStops[] = {0x14, 0x15, 0};
536  const sal_Int32 nStopPos = comphelper::string::indexOfAny(rString, cStops, nStartPos);
537  if (nStopPos<0)
538  {
539  rNewStartCp += rString.getLength()-nStartPos;
540  rString = rString.copy(0, nStartPos);
541  return;
542  }
543 
544  const bool was0x14 = rString[nStopPos]==0x14;
545  rString = rString.replaceAt(nStartPos, nStopPos+1-nStartPos, "");
546  rNewStartCp += nStopPos-nStartPos;
547 
548  if (was0x14)
549  {
550  ++rNewStartCp;
551  nStartPos = rString.indexOf(0x15, nStartPos);
552  if (nStartPos<0)
553  return;
554  rString = rString.replaceAt(nStartPos, 1, "");
555  }
556  }
557 }
558 
559 namespace {
560 
561 class Chunk
562 {
563 private:
564  OUString msURL;
565  tools::Long mnStartPos; // 0x13
566  tools::Long mnEndPos; // 0x15
567 public:
568  explicit Chunk(tools::Long nStart, const OUString &rURL)
569  : msURL(rURL), mnStartPos(nStart), mnEndPos(0) {}
570 
571  void SetEndPos(tools::Long nEnd) { mnEndPos = nEnd; }
572  tools::Long GetStartPos() const {return mnStartPos;}
573  tools::Long GetEndPos() const {return mnEndPos;}
574  const OUString &GetURL() const {return msURL;}
575  void Adjust(sal_Int32 nAdjust)
576  {
577  mnStartPos-=nAdjust;
578  mnEndPos-=nAdjust;
579  }
580 };
581 
582  bool IsValidSel(const EditEngine& rEngine, const ESelection& rSel)
583  {
584  const auto nParaCount = rEngine.GetParagraphCount();
585  if (rSel.nStartPara < nParaCount && rSel.nEndPara < nParaCount)
586  return rSel.nStartPos >= 0 && rSel.nEndPos >= 0;
587  return false;
588  }
589 }
590 
591 // InsertAttrsAsDrawingAttrs() sets attributes between StartCp and EndCp.
592 // Style attributes are set as hard, paragraph and character attributes.
594  ManTypes eType, bool bONLYnPicLocFc)
595 {
596  /*
597  Save and create new plcxman for this drawing object, of the type that
598  will include the para end mark inside a paragraph property range, as
599  drawing boxes have real paragraph marks as part of their text, while
600  normal writer has separate nodes for each paragraph and so has no actual
601  paragraph mark as part of the paragraph text.
602  */
603  WW8ReaderSave aSave(this);
604  m_xPlcxMan = std::make_shared<WW8PLCFMan>(m_xSBase.get(), eType, nStartCp, true);
605 
606  WW8_CP nStart = m_xPlcxMan->Where();
607  WW8_CP nNext, nStartReplace=0;
608 
609  bool bDoingSymbol = false;
610  sal_Unicode cReplaceSymbol = m_cSymbol;
611 
612  std::optional<SfxItemSet> pS(m_pDrawEditEngine->GetEmptyItemSet());
613  WW8PLCFManResult aRes;
614 
615  std::deque<Chunk> aChunks;
616 
617  // Here store stack location
618  size_t nCurrentCount = m_xCtrlStck->size();
619  while (nStart < nEndCp)
620  {
621  // nStart is the beginning of the attributes for this range, and
622  // may be before the text itself. So watch out for that
623  WW8_CP nTextStart = nStart;
624  if (nTextStart < nStartCp)
625  nTextStart = nStartCp;
626 
627  // get position of next SPRM
628  bool bStartAttr = m_xPlcxMan->Get(&aRes);
629  m_nCurrentColl = m_xPlcxMan->GetColl();
630  if (aRes.nSprmId)
631  {
632  if( bONLYnPicLocFc )
633  {
634  if ( (68 == aRes.nSprmId) || (0x6A03 == aRes.nSprmId) )
635  {
636  Read_PicLoc(aRes.nSprmId, aRes.pMemPos +
637  m_xSprmParser->DistanceToData(aRes.nSprmId), 4);
638  // Ok, that's what we were looking for. Now let's get
639  // out of here!
640  break;
641  }
642  }
643  else if ((eFTN > aRes.nSprmId) || (0x0800 <= aRes.nSprmId))
644  {
645  // Here place them onto our usual stack and we will pop them
646  // off and convert them later
647  if (bStartAttr)
648  {
649  ImportSprm(aRes.pMemPos, aRes.nMemLen, aRes.nSprmId);
650  if (!bDoingSymbol && m_bSymbol)
651  {
652  bDoingSymbol = true;
653  nStartReplace = nTextStart;
654  cReplaceSymbol = m_cSymbol;
655  }
656  }
657  else
658  {
659  EndSprm( aRes.nSprmId );
660  if (!m_bSymbol && bDoingSymbol)
661  {
662  bDoingSymbol = false;
663 
664  ESelection aReplaceSel(GetESelection(*m_pDrawEditEngine, nStartReplace - nStartCp,
665  nTextStart - nStartCp));
666 
667  sal_Int32 nParaCount = m_pDrawEditEngine->GetParagraphCount();
668  bool bBadSelection = aReplaceSel.nStartPara >= nParaCount || aReplaceSel.nEndPara >= nParaCount;
669 
670  SAL_WARN_IF(bBadSelection, "sw.ww8", "editengine has different amount of text than expected");
671 
672  if (!bBadSelection)
673  {
674  OUStringBuffer sTemp;
676  nTextStart - nStartReplace, cReplaceSymbol);
677  m_pDrawEditEngine->QuickInsertText(sTemp.makeStringAndClear(), aReplaceSel);
678  }
679  }
680  }
681  }
682  else if (aRes.nSprmId == eFLD)
683  {
684  if (bStartAttr)
685  {
686  size_t nCount = m_xCtrlStck->size();
687  if (m_aFieldStack.empty() && Read_Field(&aRes))
688  {
689  OUString sURL;
690  for (size_t nI = m_xCtrlStck->size(); nI > nCount; --nI)
691  {
692  const SfxPoolItem *pItem = ((*m_xCtrlStck)[nI-1]).m_pAttr.get();
693  sal_uInt16 nWhich = pItem->Which();
694  if (nWhich == RES_TXTATR_INETFMT)
695  {
696  const SwFormatINetFormat *pURL =
697  static_cast<const SwFormatINetFormat *>(pItem);
698  sURL = pURL->GetValue();
699  }
700  m_xCtrlStck->DeleteAndDestroy(nI-1);
701  }
702  aChunks.emplace_back(nStart, sURL);
703  }
704  }
705  else
706  {
707  if (!m_aFieldStack.empty() && End_Field() && !aChunks.empty())
708  aChunks.back().SetEndPos(nStart+1);
709  }
710  }
711  }
712 
713  m_xPlcxMan->advance();
714  nNext = m_xPlcxMan->Where();
715 
716  const WW8_CP nEnd = ( nNext < nEndCp ) ? nNext : nEndCp;
717  if (!bONLYnPicLocFc && nNext != nStart && nEnd >= nStartCp)
718  {
719  SfxItemPool *pEditPool = pS->GetPool();
720 
721  // Here read current properties and convert them into pS
722  // and put those attrs into the draw box if they can be converted
723  // to draw attributes
724  if (m_xCtrlStck->size() - nCurrentCount)
725  {
726  for (size_t i = nCurrentCount; i < m_xCtrlStck->size(); ++i)
727  {
728  const SfxPoolItem *pItem = ((*m_xCtrlStck)[i]).m_pAttr.get();
729  sal_uInt16 nWhich = pItem->Which();
730  if( nWhich < RES_FLTRATTR_BEGIN ||
731  nWhich >= RES_FLTRATTR_END )
732  {
733  sal_uInt16 nSlotId = m_rDoc.GetAttrPool().GetSlotId(nWhich);
734  if (
735  nSlotId && nWhich != nSlotId &&
736  0 != (nWhich = pEditPool->GetWhich(nSlotId)) &&
737  nWhich != nSlotId
738  )
739  {
740  pS->Put( pItem->CloneSetWhich(nWhich) );
741  }
742  }
743  }
744  }
745  // Fill in the remainder from the style
746  InsertTxbxStyAttrs(*pS, m_nCurrentColl);
747 
748  if( pS->Count() )
749  {
750  m_pDrawEditEngine->QuickSetAttribs( *pS,
751  GetESelection(*m_pDrawEditEngine, nTextStart - nStartCp, nEnd - nStartCp ) );
752  pS.emplace(m_pDrawEditEngine->GetEmptyItemSet());
753  }
754  }
755  nStart = nNext;
756  }
757  pS.reset();
758 
759  // pop off as far as recorded location just in case there were some left
760  // unclosed
761  for (size_t nI = m_xCtrlStck->size(); nI > nCurrentCount; --nI)
762  m_xCtrlStck->DeleteAndDestroy(nI-1);
763 
764  auto aEnd = aChunks.end();
765  for (auto aIter = aChunks.begin(); aIter != aEnd; ++aIter)
766  {
767  ESelection aSel(GetESelection(*m_pDrawEditEngine, aIter->GetStartPos()-nStartCp,
768  aIter->GetEndPos()-nStartCp));
769  if (!IsValidSel(*m_pDrawEditEngine, aSel))
770  continue;
771  OUString aString(m_pDrawEditEngine->GetText(aSel));
772  const sal_Int32 nOrigLen = aString.getLength();
773  WW8_CP nDummy(0);
774  lcl_StripFields(aString, nDummy);
775 
776  sal_Int32 nChanged;
777  if (!aIter->GetURL().isEmpty())
778  {
779  SvxURLField aURL(aIter->GetURL(), aString, SvxURLFormat::AppDefault);
780  m_pDrawEditEngine->QuickInsertField(SvxFieldItem(aURL, EE_FEATURE_FIELD), aSel);
781  nChanged = nOrigLen - 1;
782  }
783  else
784  {
785  m_pDrawEditEngine->QuickInsertText(aString, aSel);
786  nChanged = nOrigLen - aString.getLength();
787  }
788  for (auto aIter2 = aIter+1; aIter2 != aEnd; ++aIter2)
789  aIter2->Adjust(nChanged);
790  }
791 
792  /*
793  Don't worry about the new pPlcxMan, the restore removes it when
794  replacing the current one with the old one.
795  */
796  aSave.Restore(this);
797 }
798 
800  sal_uInt16 nTxBxS, sal_uInt16 nSequence)
801 {
802  // grab the TextBox-PLCF quickly
803  WW8PLCFspecial* pT = m_xPlcxMan ? m_xPlcxMan->GetTxbx() : nullptr;
804  if( !pT )
805  {
806  OSL_ENSURE( false, "+where's the text graphic (1)?" );
807  return false;
808  }
809 
810  // if applicable first find the right TextBox-Story
811  bool bCheckTextBoxStory = ( nTxBxS && pT->GetIMax() >= nTxBxS );
812  if( bCheckTextBoxStory )
813  pT->SetIdx( nTxBxS-1 );
814 
815  // then determine start and end
816  void* pT0;
817  if (!pT->Get(rStartCp, pT0) || rStartCp < 0)
818  {
819  OSL_ENSURE( false, "+where's the text graphic (2)?" );
820  return false;
821  }
822 
823  if( bCheckTextBoxStory )
824  {
825  bool bReusable = (0 != SVBT16ToUInt16( static_cast<WW8_TXBXS*>(pT0)->fReusable ));
826  while( bReusable )
827  {
828  pT->advance();
829  if( !pT->Get( rStartCp, pT0 ) )
830  {
831  OSL_ENSURE( false, "+where's the text graphic (2a)?" );
832  return false;
833  }
834  bReusable = (0 != SVBT16ToUInt16( static_cast<WW8_TXBXS*>(pT0)->fReusable ));
835  }
836  }
837  pT->advance();
838  if (!pT->Get(rEndCp, pT0) || rEndCp < 0)
839  {
840  OSL_ENSURE( false, "+where's the text graphic (3)?" );
841  return false;
842  }
843 
844  // find the right page in the break table (if necessary)
845  if( bCheckTextBoxStory )
846  {
847  // special case: entire chain should be determined - done!
848  if( USHRT_MAX > nSequence )
849  {
850  tools::Long nMinStartCp = rStartCp;
851  tools::Long nMaxEndCp = rEndCp;
852  // quickly grab the TextBox-Break-Descriptor-PLCF
853  pT = m_xPlcxMan->GetTxbxBkd();
854  if (!pT) // It can occur on occasion, Caolan
855  return false;
856 
857  // find first entry for this TextBox story
858  if( !pT->SeekPos( rStartCp ) )
859  {
860  OSL_ENSURE( false, "+where's the text graphic (4)" );
861  return false;
862  }
863  // if needed skip the appropriate number of entries
864  for (sal_uInt16 iSequence = 0; iSequence < nSequence; ++iSequence)
865  pT->advance();
866  // and determine actual start and end
867  if( (!pT->Get( rStartCp, pT0 ))
868  || ( nMinStartCp > rStartCp ) )
869  {
870  OSL_ENSURE( false, "+where's the text graphic (5)?" );
871  return false;
872  }
873  if( rStartCp >= nMaxEndCp )
874  rEndCp = rStartCp; // not an error: empty string
875  else
876  {
877  pT->advance();
878  if ( (!pT->Get(rEndCp, pT0)) || (nMaxEndCp < rEndCp-1) )
879  {
880  OSL_ENSURE( false, "+where's the text graphic (6)?" );
881  return false;
882  }
883  rEndCp -= 1;
884  }
885  }
886  else
887  rEndCp -= 1;
888  }
889  else
890  rEndCp -= 1;
891  return true;
892 }
893 
894 // TxbxText() grabs the text from the WW file and returns that along with
895 // the StartCp and the corrected (by -2, or -1 for version 8) EndCp.
896 sal_Int32 SwWW8ImplReader::GetRangeAsDrawingString(OUString& rString, tools::Long nStartCp, tools::Long nEndCp, ManTypes eType)
897 {
898  WW8_CP nOffset = 0;
899  m_xWwFib->GetBaseCp(eType, &nOffset); //TODO: check return value
900 
901  OSL_ENSURE(nStartCp <= nEndCp, "+where's the graphic text (7)?");
902  if (nStartCp == nEndCp)
903  rString.clear(); // empty string: entirely possible
904  else if (nStartCp < nEndCp)
905  {
906  // read the text: can be split into multiple pieces
907  const sal_Int32 nLen = m_xSBase->WW8ReadString(*m_pStrm, rString,
908  nStartCp + nOffset, nEndCp - nStartCp, GetCurrentCharSet());
909  OSL_ENSURE(nLen, "+where's the text graphic (8)?");
910  if (nLen>0)
911  {
912  if( rString[nLen-1]==0x0d )
913  rString = rString.copy(0, nLen-1);
914 
915  rString = rString.replace( 0xb, 0xa );
916  return nLen;
917  }
918  }
919  return 0;
920 }
921 
922 //EditEngine::InsertText will replace dos lines resulting in a shorter
923 //string than is passed in, so inserting attributes based on the original
924 //string len can fail. So here replace the dos line ends similar to
925 //how EditEngine does it, but preserve the length and replace the extra
926 //chars with placeholders, record the position of the placeholders and
927 //remove those extra chars after attributes have been inserted
928 static std::vector<sal_Int32> replaceDosLineEndsButPreserveLength(OUString &rIn)
929 {
930  OUStringBuffer aNewData(rIn);
931  std::vector<sal_Int32> aDosLineEndDummies;
932  sal_Int32 i = 0;
933  sal_Int32 nStrLen = rIn.getLength();
934  while (i < nStrLen)
935  {
936  // \r or \n causes linebreak
937  if (rIn[i] == '\r' || rIn[i] == '\n')
938  {
939  // skip char if \r\n or \n\r
940  if ( (i+1) < nStrLen && ((rIn[i+1] == '\r') || (rIn[i+1] == '\n')) &&
941  (rIn[i] != rIn[i+1]) )
942  {
943  ++i;
944  aDosLineEndDummies.push_back(i);
945  aNewData[i] = 0;
946  }
947  }
948  ++i;
949  }
950  rIn = aNewData.makeStringAndClear();
951  return aDosLineEndDummies;
952 }
953 
954 static void removePositions(EditEngine &rDrawEditEngine, const std::vector<sal_Int32>& rDosLineEndDummies)
955 {
956  for (auto aIter = rDosLineEndDummies.rbegin(); aIter != rDosLineEndDummies.rend(); ++aIter)
957  {
958  sal_Int32 nCharPos(*aIter);
959  rDrawEditEngine.QuickDelete(GetESelection(rDrawEditEngine, nCharPos, nCharPos+1));
960  }
961 }
962 
964 {
966 
967  sal_Int32 nLen = GetRangeAsDrawingString(rString, nStartCp, nEndCp, eType);
968  if (nLen > 0)
969  {
970  if (m_bFuzzing && rString.getLength() > 1024)
971  {
972  SAL_WARN("sw.ww8", "Truncating long EditEngine strings when fuzzing for performance");
973  rString = rString.copy(0, 1024);
974  }
975 
976  if (!m_pDrawEditEngine)
977  {
978  m_pDrawEditEngine.reset(new EditEngine(nullptr));
979  }
980 
981  //replace dos line endings with editeng ones, replace any extra chars with
982  //placeholders to keep the inserted string len in sync with the attribute cps
983  //and record in aDosLineEnds the superfluous positions
984  OUString sEEString(rString);
985  std::vector<sal_Int32> aDosLineEnds(replaceDosLineEndsButPreserveLength(sEEString));
986  m_pDrawEditEngine->SetText(sEEString);
987  InsertAttrsAsDrawingAttrs(nStartCp, nStartCp+nLen, eType);
988  //remove any superfluous placeholders of replaceDosLineEndsButPreserveLength
989  //after attributes have been inserted
990  removePositions(*m_pDrawEditEngine, aDosLineEnds);
991 
992  // Annotations typically begin with a (useless) 0x5
993  if ((eType == MAN_AND) && m_pDrawEditEngine->GetTextLen())
994  {
995  ESelection aFirstChar(0, 0, 0, 1);
996  if (m_pDrawEditEngine->GetText( aFirstChar ) == "\x05")
997  m_pDrawEditEngine->QuickDelete(aFirstChar);
998  }
999 
1000  std::unique_ptr<EditTextObject> pTemporaryText = m_pDrawEditEngine->CreateTextObject();
1001  pRet.emplace( std::move(pTemporaryText) );
1002  pRet->SetOutlinerMode( OutlinerMode::TextObject );
1003 
1004  m_pDrawEditEngine->SetText( OUString() );
1005  m_pDrawEditEngine->SetParaAttribs(0, m_pDrawEditEngine->GetEmptyItemSet());
1006 
1007  // Strip out fields, leaving the result
1008  WW8_CP nDummy(0);
1009  lcl_StripFields(rString, nDummy);
1010  // Strip out word's special characters for the simple string
1011  rString = rString.replaceAll("\x01", "");
1012  rString = rString.replaceAll("\x05", "");
1013  rString = rString.replaceAll("\x08", "");
1014  rString = rString.replaceAll("\007\007", "\007\012");
1015  rString = rString.replace(0x7, ' ');
1016  }
1017 
1018  return pRet;
1019 }
1020 
1021 // InsertTxbxText() adds the Text and the Attributes for TextBoxes and CaptionBoxes
1023  Size const * pObjSiz, sal_uInt16 nTxBxS, sal_uInt16 nSequence, tools::Long nPosCp,
1024  SwFrameFormat const * pOldFlyFormat, bool bMakeSdrGrafObj, bool& rbEraseTextObj,
1025  bool* pbTestTxbxContainsText, tools::Long* pnStartCp, tools::Long* pnEndCp,
1026  bool* pbContainsGraphics, SvxMSDffImportRec const * pRecord)
1027 {
1028  SwFrameFormat* pFlyFormat = nullptr;
1029  sal_uLong nOld = m_pStrm->Tell();
1030 
1031  ManTypes eType = m_xPlcxMan->GetManType() == MAN_HDFT ? MAN_TXBX_HDFT : MAN_TXBX;
1032 
1033  rbEraseTextObj = false;
1034 
1035  OUString aString;
1036  WW8_CP nStartCp, nEndCp;
1037  bool bContainsGraphics = false;
1038  bool bTextWasRead = GetTxbxTextSttEndCp(nStartCp, nEndCp, nTxBxS, nSequence) &&
1039  GetRangeAsDrawingString(aString, nStartCp, nEndCp, eType) > 0;
1040 
1041  if (!m_pDrawEditEngine)
1042  {
1043  m_pDrawEditEngine.reset(new EditEngine(nullptr));
1044  }
1045  if( pObjSiz )
1046  m_pDrawEditEngine->SetPaperSize( *pObjSiz );
1047 
1048  if (m_bFuzzing && aString.getLength() > 1024)
1049  {
1050  SAL_WARN("sw.ww8", "Truncating long EditEngine strings when fuzzing for performance");
1051  aString = aString.copy(0, 1024);
1052  }
1053 
1054  const OUString aOrigString(aString);
1055  if( bTextWasRead )
1056  {
1057  WW8_CP nNewStartCp = nStartCp;
1058  lcl_StripFields(aString, nNewStartCp);
1059 
1060  if (aString.getLength()!=1)
1061  {
1062  bContainsGraphics = aString.indexOf(0x1)<0 || aString.indexOf(0x8)<0;
1063  }
1064  else // May be a single graphic or object
1065  {
1066  bool bDone = true;
1067  switch( aString[0] )
1068  {
1069  case 0x1:
1070  if (!pbTestTxbxContainsText)
1071  {
1072  WW8ReaderSave aSave(this, nNewStartCp -1);
1073  bool bOldEmbeddObj = m_bEmbeddObj;
1074  // bEmbeddObj Ordinarily would have been set by field
1075  // parse, but this is impossible here so...
1076  m_bEmbeddObj = true;
1077 
1078  // 1st look for OLE- or Graph-Indicator Sprms
1079  WW8PLCFx_Cp_FKP* pChp = m_xPlcxMan->GetChpPLCF();
1080  WW8PLCFxDesc aDesc;
1081  pChp->GetSprms( &aDesc );
1082  WW8SprmIter aSprmIter(aDesc.pMemPos, aDesc.nSprmsLen, *m_xSprmParser);
1083 
1084  for( int nLoop = 0; nLoop < 2; ++nLoop )
1085  {
1086  while (aSprmIter.GetSprms())
1087  {
1088  const sal_uInt8 *const pParams(aSprmIter.GetCurrentParams());
1089  if (nullptr == pParams)
1090  break;
1091  sal_uInt16 nCurrentId = aSprmIter.GetCurrentId();
1092  switch( nCurrentId )
1093  {
1094  case 75:
1095  case 118:
1096  case 0x080A:
1097  case 0x0856:
1098  Read_Obj(nCurrentId, pParams, 1);
1099  break;
1100  case 68: // Read_Pic()
1101  case 0x6A03:
1103  Read_PicLoc(nCurrentId, pParams, 1);
1104  break;
1105  }
1106  aSprmIter.advance();
1107  }
1108 
1109  if( !nLoop )
1110  {
1111  pChp->GetPCDSprms( aDesc );
1112  aSprmIter.SetSprms( aDesc.pMemPos,
1113  aDesc.nSprmsLen );
1114  }
1115  }
1116  aSave.Restore(this);
1117  m_bEmbeddObj=bOldEmbeddObj;
1118 
1119  // then import either an OLE of a Graphic
1120  if( m_bObj )
1121  {
1122  if( bMakeSdrGrafObj && pTextObj &&
1123  pTextObj->getParentSdrObjectFromSdrObject() )
1124  {
1125  // use SdrOleObj/SdrGrafObj instead of
1126  // SdrTextObj in this Group
1127 
1128  Graphic aGraph;
1129  SdrObject* pNew = ImportOleBase(aGraph);
1130 
1131  if( !pNew )
1132  {
1133  pNew = new SdrGrafObj(*m_pDrawModel);
1134  static_cast<SdrGrafObj*>(pNew)->SetGraphic(aGraph);
1135  }
1136 
1137  GraphicCtor();
1138 
1139  pNew->SetLogicRect( pTextObj->GetCurrentBoundRect() );
1140  pNew->SetLayer( pTextObj->GetLayer() );
1141 
1143  ReplaceObject(pNew, pTextObj->GetOrdNum());
1144  }
1145  else
1146  pFlyFormat = ImportOle();
1147  m_bObj = false;
1148  }
1149  else
1150  {
1151  InsertAttrsAsDrawingAttrs(nNewStartCp, nNewStartCp+1,
1152  eType, true);
1153  pFlyFormat = ImportGraf(bMakeSdrGrafObj ? pTextObj : nullptr,
1154  pOldFlyFormat);
1155  }
1156  }
1157  break;
1158  case 0x8:
1159  if ( (!pbTestTxbxContainsText) && (!m_bObj) )
1160  pFlyFormat = Read_GrafLayer( nPosCp );
1161  break;
1162  default:
1163  bDone = false;
1164  break;
1165  }
1166 
1167  if( bDone )
1168  {
1169  if( pFlyFormat && pRecord )
1170  {
1172  aFlySet( m_rDoc.GetAttrPool() );
1173 
1174  tools::Rectangle aInnerDist( pRecord->nDxTextLeft,
1175  pRecord->nDyTextTop,
1176  pRecord->nDxTextRight,
1177  pRecord->nDyTextBottom );
1178  MatchSdrItemsIntoFlySet( pTextObj,
1179  aFlySet,
1180  pRecord->eLineStyle,
1181  pRecord->eLineDashing,
1182  pRecord->eShapeType,
1183  aInnerDist );
1184 
1185  pFlyFormat->SetFormatAttr( aFlySet );
1186 
1187  MapWrapIntoFlyFormat(*pRecord, *pFlyFormat);
1188  }
1189  aString.clear();
1190  rbEraseTextObj = (nullptr != pFlyFormat);
1191  }
1192  }
1193  }
1194 
1195  if( pnStartCp )
1196  *pnStartCp = nStartCp;
1197  if( pnEndCp )
1198  *pnEndCp = nEndCp;
1199 
1200  if( pbTestTxbxContainsText )
1201  *pbTestTxbxContainsText = bTextWasRead && ! rbEraseTextObj;
1202  else if( !rbEraseTextObj )
1203  {
1204  if( bTextWasRead )
1205  {
1206  m_pDrawEditEngine->SetText(aOrigString);
1207  InsertAttrsAsDrawingAttrs(nStartCp, nEndCp, eType);
1208  }
1209 
1210  bool bVertical = pTextObj->IsVerticalWriting();
1211  OutlinerParaObject aOp(m_pDrawEditEngine->CreateTextObject());
1212  aOp.SetOutlinerMode( OutlinerMode::TextObject );
1213  aOp.SetVertical( bVertical );
1214  pTextObj->NbcSetOutlinerParaObject( std::move(aOp) );
1215  pTextObj->SetVerticalWriting(bVertical);
1216 
1217  // For the next TextBox also remove the old paragraph attributes
1218  // and styles, otherwise the next box will start with the wrong
1219  // attributes.
1220  // Course of action: delete text = reduce to one paragraph
1221  // and on this one delete the paragraph attributes
1222  // and styles
1223  m_pDrawEditEngine->SetText( OUString() );
1224  m_pDrawEditEngine->SetParaAttribs(0, m_pDrawEditEngine->GetEmptyItemSet());
1225  }
1226 
1227  m_pStrm->Seek( nOld );
1228  if (pbContainsGraphics)
1229  *pbContainsGraphics = bContainsGraphics;
1230 }
1231 
1233  tools::Long& rEndCp)
1234 {
1235  bool bErase, bContainsText;
1236  InsertTxbxText( nullptr,nullptr,nTxBxS,USHRT_MAX,0,nullptr,false, bErase, &bContainsText,
1237  &rStartCp, &rEndCp );
1238  return bContainsText;
1239 }
1240 
1241 // TextBoxes only for Ver67 !!
1243 {
1244  bool bDummy;
1245  WW8_DP_TXTBOX aTextB;
1246 
1247  if( !ReadGrafStart( static_cast<void*>(&aTextB), sizeof( aTextB ), pHd, rSet ) )
1248  return nullptr;
1249 
1250  Point aP0( static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa )) + m_nDrawXOfs2,
1251  static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya )) + m_nDrawYOfs2 );
1252  Point aP1( aP0 );
1253  aP1.AdjustX(static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dxa )) );
1254  aP1.AdjustY(static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dya )) );
1255 
1256  SdrRectObj* pObj = new SdrRectObj(
1257  *m_pDrawModel,
1258  OBJ_TEXT,
1259  tools::Rectangle(aP0, aP1));
1260 
1261  pObj->NbcSetSnapRect(tools::Rectangle(aP0, aP1));
1262  Size aSize( static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dxa )) ,
1263  static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dya )) );
1264 
1265  tools::Long nStartCpFly,nEndCpFly;
1266  bool bContainsGraphics;
1267  InsertTxbxText(pObj, &aSize, 0, 0, 0, nullptr, false,
1268  bDummy,nullptr,&nStartCpFly,&nEndCpFly,&bContainsGraphics);
1269 
1270  SetStdAttr( rSet, aTextB.aLnt, aTextB.aShd );
1271  SetFill( rSet, aTextB.aFill );
1272 
1273  rSet.Put( SdrTextFitToSizeTypeItem( drawing::TextFitToSizeType_NONE ) );
1274  rSet.Put( makeSdrTextAutoGrowWidthItem(false));
1275  rSet.Put( makeSdrTextAutoGrowHeightItem(false));
1280 
1281  return pObj;
1282 }
1283 
1285 {
1286  static const SdrCaptionType aCaptA[] = { SdrCaptionType::Type1, SdrCaptionType::Type2,
1287  SdrCaptionType::Type3, SdrCaptionType::Type4 };
1288 
1289  WW8_DP_CALLOUT_TXTBOX aCallB;
1290 
1291  if( !ReadGrafStart( static_cast<void*>(&aCallB), sizeof( aCallB ), pHd, rSet ) )
1292  return nullptr;
1293 
1294  sal_uInt16 nCount = SVBT16ToUInt16( aCallB.dpPolyLine.aBits1 ) >> 1 & 0x7fff;
1295  if (nCount < 1)
1296  {
1297  SAL_WARN("sw.ww8", "Short CaptionBox header");
1298  return nullptr;
1299  }
1300 
1301  std::unique_ptr<SVBT16[]> xP(new SVBT16[nCount * 2]);
1302 
1303  bool bCouldRead = checkRead(*m_pStrm, xP.get(), nCount * 4); // read points
1304  if (!bCouldRead)
1305  {
1306  SAL_WARN("sw.ww8", "Short CaptionBox header");
1307  return nullptr;
1308  }
1309 
1310  sal_uInt8 nTyp = static_cast<sal_uInt8>(nCount) - 1;
1311  if( nTyp == 1 && SVBT16ToUInt16( xP[0] ) == SVBT16ToUInt16( xP[2] ) )
1312  nTyp = 0;
1313 
1314  Point aP0( static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa )) +
1315  static_cast<sal_Int16>(SVBT16ToUInt16( aCallB.dpheadTxbx.xa )) + m_nDrawXOfs2,
1316  static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya ))
1317  + static_cast<sal_Int16>(SVBT16ToUInt16( aCallB.dpheadTxbx.ya )) + m_nDrawYOfs2 );
1318  Point aP1( aP0 );
1319  aP1.AdjustX(static_cast<sal_Int16>(SVBT16ToUInt16( aCallB.dpheadTxbx.dxa )) );
1320  aP1.AdjustY(static_cast<sal_Int16>(SVBT16ToUInt16( aCallB.dpheadTxbx.dya )) );
1321  Point aP2( static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa ))
1322  + static_cast<sal_Int16>(SVBT16ToUInt16( aCallB.dpheadPolyLine.xa ))
1323  + m_nDrawXOfs2 + static_cast<sal_Int16>(SVBT16ToUInt16( xP[0] )),
1324  static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya ))
1325  + static_cast<sal_Int16>(SVBT16ToUInt16( aCallB.dpheadPolyLine.ya ))
1326  + m_nDrawYOfs2 + static_cast<sal_Int16>(SVBT16ToUInt16( xP[1] )) );
1327  xP.reset();
1328 
1329  SdrCaptionObj* pObj = new SdrCaptionObj(
1330  *m_pDrawModel,
1331  tools::Rectangle(aP0, aP1),
1332  aP2);
1333 
1334  pObj->NbcSetSnapRect(tools::Rectangle(aP0, aP1));
1335  Size aSize( static_cast<sal_Int16>(SVBT16ToUInt16( aCallB.dpheadTxbx.dxa )),
1336  static_cast<sal_Int16>(SVBT16ToUInt16( aCallB.dpheadTxbx.dya )) );
1337  bool bEraseThisObject;
1338 
1339  InsertTxbxText(pObj, &aSize, 0, 0, 0, nullptr, false, bEraseThisObject );
1340 
1341  if( SVBT16ToUInt16( aCallB.dptxbx.aLnt.lnps ) != 5 ) // Is border visible ?
1342  SetStdAttr( rSet, aCallB.dptxbx.aLnt, aCallB.dptxbx.aShd );
1343  else // no -> take lines
1344  SetStdAttr( rSet, aCallB.dpPolyLine.aLnt, aCallB.dptxbx.aShd );
1345  SetFill( rSet, aCallB.dptxbx.aFill );
1346  rSet.Put(SdrCaptionTypeItem(aCaptA[nTyp % SAL_N_ELEMENTS(aCaptA)]));
1347 
1348  return pObj;
1349 }
1350 
1352 {
1353  sal_Int16 nGrouped;
1354 
1355  if( !ReadGrafStart( static_cast<void*>(&nGrouped), sizeof( nGrouped ), pHd, rSet ) )
1356  return nullptr;
1357 
1358 #ifdef OSL_BIGENDIAN
1359  nGrouped = (sal_Int16)OSL_SWAPWORD( nGrouped );
1360 #endif
1361 
1362  m_nDrawXOfs = m_nDrawXOfs + static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa ));
1363  m_nDrawYOfs = m_nDrawYOfs + static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya ));
1364 
1365  SdrObject* pObj = new SdrObjGroup(*m_pDrawModel);
1366 
1367  short nLeft = static_cast<sal_Int16>(SVBT16ToUInt16( pHd->cb )) - sizeof( WW8_DPHEAD );
1368  for (int i = 0; i < nGrouped && nLeft >= static_cast<short>(sizeof(WW8_DPHEAD)); ++i)
1369  {
1370  SfxAllItemSet aSet(m_pDrawModel->GetItemPool());
1371  if (SdrObject *pObject = ReadGrafPrimitive(nLeft, aSet))
1372  {
1373  // first add and then set ItemSet
1374  SdrObjList *pSubGroup = pObj->GetSubList();
1375  OSL_ENSURE(pSubGroup, "Why no sublist available?");
1376  if (pSubGroup)
1377  pSubGroup->InsertObject(pObject, 0);
1378  pObject->SetMergedItemSetAndBroadcast(aSet);
1379  }
1380  }
1381 
1382  m_nDrawXOfs = m_nDrawXOfs - static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa ));
1383  m_nDrawYOfs = m_nDrawYOfs - static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya ));
1384 
1385  return pObj;
1386 }
1387 
1389 {
1390  // This whole archaic word 6 graphic import can probably be refactored
1391  // into an object hierarchy with a little effort.
1392  SdrObject *pRet=nullptr;
1393  WW8_DPHEAD aHd; // Read Draw-Primitive-Header
1394  bool bCouldRead = checkRead(*m_pStrm, &aHd, sizeof(WW8_DPHEAD)) &&
1395  SVBT16ToUInt16(aHd.cb) >= sizeof(WW8_DPHEAD);
1396  OSL_ENSURE(bCouldRead, "Graphic Primitive header short read" );
1397  if (!bCouldRead)
1398  {
1399  rLeft=0;
1400  return pRet;
1401  }
1402 
1403  if( rLeft >= SVBT16ToUInt16(aHd.cb) ) // precautions
1404  {
1405  rSet.Put(SwFormatSurround(css::text::WrapTextMode_THROUGH));
1406  switch (SVBT16ToUInt16(aHd.dpk) & 0xff )
1407  {
1408  case 0:
1409  pRet = ReadGroup(&aHd, rSet);
1410  break;
1411  case 1:
1412  pRet = ReadLine(&aHd, rSet);
1413  break;
1414  case 2:
1415  pRet = ReadTextBox(&aHd, rSet);
1416  break;
1417  case 3:
1418  pRet = ReadRect(&aHd, rSet);
1419  break;
1420  case 4:
1421  pRet = ReadEllipse(&aHd, rSet);
1422  break;
1423  case 5:
1424  pRet = ReadArc(&aHd, rSet);
1425  break;
1426  case 6:
1427  pRet = ReadPolyLine(&aHd, rSet);
1428  break;
1429  case 7:
1430  pRet = ReadCaptionBox(&aHd, rSet);
1431  break;
1432  default: // unknown
1433  m_pStrm->SeekRel(SVBT16ToUInt16(aHd.cb) - sizeof(WW8_DPHEAD));
1434  break;
1435  }
1436  }
1437  else
1438  {
1439  OSL_ENSURE( false, "+Grafik-Overlap" );
1440  }
1441  rLeft = rLeft - SVBT16ToUInt16( aHd.cb );
1442  return pRet;
1443 }
1444 
1446 {
1447  rPF.SeekPos(nGrafAnchorCp);
1448  WW8_FC nStartFc;
1449  void* pF0;
1450  if (!rPF.Get(nStartFc, pF0))
1451  {
1452  OSL_ENSURE( false, "+Where is the graphic (2) ?" );
1453  return;
1454  }
1455  WW8_FDOA* pF = static_cast<WW8_FDOA*>(pF0);
1456  if( !SVBT32ToUInt32( pF->fc ) )
1457  {
1458  OSL_ENSURE( false, "+Where is the graphic (3) ?" );
1459  return;
1460  }
1461 
1462  sal_uInt32 nPosFc = SVBT32ToUInt32(pF->fc);
1463 
1464  //skip duplicate graphics when fuzzing
1465  if (m_bFuzzing)
1466  {
1467  if (!m_aGrafPosSet.insert(nPosFc).second)
1468  return;
1469  }
1470 
1471  bool bCouldSeek = checkSeek(*m_pStrm, nPosFc);
1472  OSL_ENSURE(bCouldSeek, "Invalid graphic offset");
1473  if (!bCouldSeek)
1474  return;
1475 
1476  // read Draw-Header
1477  WW8_DO aDo;
1478  bool bCouldRead = checkRead(*m_pStrm, &aDo, sizeof(WW8_DO));
1479  OSL_ENSURE(bCouldRead, "Short graphic header");
1480  if (!bCouldRead)
1481  return;
1482 
1483  short nLeft = SVBT16ToUInt16( aDo.cb ) - sizeof( WW8_DO );
1484  while (nLeft > static_cast<short>(sizeof(WW8_DPHEAD)))
1485  {
1486  SfxAllItemSet aSet( m_pDrawModel->GetItemPool() );
1487  if (SdrObject *pObject = ReadGrafPrimitive(nLeft, aSet))
1488  {
1489  m_xWWZOrder->InsertDrawingObject(pObject, SVBT16ToUInt16(aDo.dhgt));
1490 
1491  tools::Rectangle aRect(pObject->GetSnapRect());
1492 
1493  const sal_uInt32 nCntRelTo = 3;
1494 
1495  // Adjustment is horizontally relative to...
1496  static const sal_Int16 aHoriRelOriTab[nCntRelTo] =
1497  {
1498  text::RelOrientation::PAGE_PRINT_AREA, // 0 is page textarea margin
1499  text::RelOrientation::PAGE_FRAME, // 1 is page margin
1500  text::RelOrientation::FRAME, // 2 is relative to paragraph
1501  };
1502 
1503  // Adjustment is vertically relative to...
1504  static const sal_Int16 aVertRelOriTab[nCntRelTo] =
1505  {
1506  text::RelOrientation::PAGE_PRINT_AREA, // 0 is page textarea margin
1507  text::RelOrientation::PAGE_FRAME, // 1 is page margin
1508  text::RelOrientation::FRAME, // 2 is relative to paragraph
1509  };
1510 
1511  const int nXAlign = aDo.bx < nCntRelTo ? aDo.bx : 0;
1512  const int nYAlign = aDo.by < nCntRelTo ? aDo.by : 0;
1513 
1514  aSet.Put(SwFormatHoriOrient(aRect.Left(), text::HoriOrientation::NONE,
1515  aHoriRelOriTab[ nXAlign ]));
1516  aSet.Put(SwFormatVertOrient(aRect.Top(), text::VertOrientation::NONE,
1517  aVertRelOriTab[ nYAlign ]));
1518 
1520  pObject->SetMergedItemSet(aSet);
1521 
1522  if (SwDrawFrameFormat *pDrawFrame = dynamic_cast<SwDrawFrameFormat*>(pFrame))
1523  {
1524  pDrawFrame->PosAttrSet();
1525  }
1526 
1527  AddAutoAnchor(pFrame);
1528  }
1529  }
1530 }
1531 
1533  MSO_SPT eShapeType, sal_Int32 &rThick)
1534 {
1535  sal_Int32 nOutsideThick = 0;
1536  /*
1537  Note: In contrast to the regular WinWord table and frame border width,
1538  where the overall border width has to be calculated from the width of *one*
1539  line, the data from ESCHER already contains the overall width [twips]!
1540 
1541  The WinWord default is 15 tw. We take for this our 20 tw line.
1542  (0.75 pt and 1.0 pt looking more similar on hardcopy than 0.75 pt and our
1543  0.05 pt hairline.) The hairline we only set by WinWord width up to max.
1544  0.5 pt.
1545  */
1546  switch( eStyle )
1547  {
1548  case mso_lineTriple:
1549  case mso_lineSimple:
1550  nOutsideThick = eShapeType != mso_sptTextBox ? rThick : rThick/2;
1551  break;
1552  case mso_lineDouble:
1553  if (eShapeType == mso_sptTextBox)
1554  {
1555  nOutsideThick = rThick/6;
1556  rThick = rThick*2/3;
1557  }
1558  else
1559  nOutsideThick = rThick*2/3;
1560  break;
1561  case mso_lineThickThin:
1562  if (eShapeType == mso_sptTextBox)
1563  {
1564  nOutsideThick = rThick*3/10;
1565  rThick = rThick*4/5;
1566  }
1567  else
1568  nOutsideThick = rThick*4/5;
1569  break;
1570  case mso_lineThinThick:
1571  {
1572  if (eShapeType == mso_sptTextBox)
1573  {
1574  nOutsideThick = rThick/10;
1575  rThick = rThick*3/5;
1576  }
1577  else
1578  nOutsideThick = rThick*3/5;
1579  }
1580  break;
1581  default:
1582  break;
1583  }
1584  return nOutsideThick;
1585 }
1586 
1587 // Returns the thickness of the line outside the frame, the logic of
1588 // words positioning of borders around floating objects is that of a
1589 // disturbed mind.
1591  MSO_LineStyle eLineStyle, MSO_LineDashing eDashing, MSO_SPT eShapeType, sal_Int32 &rLineThick,
1592  SvxBoxItem& rBox )
1593 {
1594  sal_Int32 nOutsideThick = 0;
1595  if( !rLineThick )
1596  return nOutsideThick;
1597 
1598  SvxBorderLineStyle nIdx = SvxBorderLineStyle::NONE;
1599 
1600  sal_Int32 nLineThick=rLineThick;
1601  nOutsideThick = SwMSDffManager::GetEscherLineMatch(eLineStyle,
1602  eShapeType, rLineThick);
1603 
1604  /*
1605  Note: In contrast to the regular WinWord table and frame border width,
1606  where the overall border width has to be calculated from the width of *one*
1607  line, the data from ESCHER already contains the overall width [twips]!
1608 
1609  The WinWord default is 15 tw. We take for this our 20 tw line.
1610  (0.75 pt and 1.0 pt looking more similar on hardcopy than 0.75 pt and our
1611  0.05 pt hairline.) The hairline we only set by WinWord width up to max.
1612  0.5 pt.
1613  */
1614  switch( +eLineStyle )
1615  {
1616  // first the single lines
1617  case mso_lineSimple:
1618  nIdx = SvxBorderLineStyle::SOLID;
1619  break;
1620  // second the double lines
1621  case mso_lineDouble:
1622  nIdx = SvxBorderLineStyle::DOUBLE;
1623  break;
1624  case mso_lineThickThin:
1625  nIdx = SvxBorderLineStyle::THICKTHIN_SMALLGAP;
1626  break;
1627  case mso_lineThinThick:
1628  nIdx = SvxBorderLineStyle::THINTHICK_SMALLGAP;
1629  break;
1630  // We have no triple border, use double instead.
1631  case mso_lineTriple:
1632  nIdx = SvxBorderLineStyle::DOUBLE;
1633  break;
1634  // no line style is set
1635  case MSO_LineStyle(USHRT_MAX):
1636  break;
1637  // erroneously not implemented line style is set
1638  default:
1639  OSL_ENSURE(false, "eLineStyle is not (yet) implemented!");
1640  break;
1641  }
1642 
1643  switch( eDashing )
1644  {
1645  case mso_lineDashGEL:
1646  nIdx = SvxBorderLineStyle::DASHED;
1647  break;
1648  case mso_lineDotGEL:
1649  nIdx = SvxBorderLineStyle::DOTTED;
1650  break;
1651  default:
1652  break;
1653  }
1654 
1655  if (SvxBorderLineStyle::NONE != nIdx)
1656  {
1657  SvxBorderLine aLine;
1658  aLine.SetColor( rLineColor );
1659 
1660  aLine.SetWidth( nLineThick ); // No conversion here, nLineThick is already in twips
1661  aLine.SetBorderLineStyle(nIdx);
1662 
1664  {
1665  // aLine is cloned by SetLine
1666  rBox.SetLine(&aLine, nLine);
1667  }
1668  }
1669 
1670  return nOutsideThick;
1671 }
1672 
1673 #define WW8ITEMVALUE(ItemSet,Id,Cast) ItemSet.GetItem<Cast>(Id)->GetValue()
1674 
1676  SfxItemSet& rFlySet, MSO_LineStyle eLineStyle, MSO_LineDashing eDashing, MSO_SPT eShapeType,
1677  tools::Rectangle& rInnerDist )
1678 {
1679  /*
1680  attributes to be set on the frame
1681  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1682  SwFormatFrameSize if not set, set here
1683  SvxLRSpaceItem set here
1684  SvxULSpaceItem set here
1685  SvxOpaqueItem (Currently not possible for frames! khz 10.2.1999)
1686  SwFormatSurround already set
1687  SwFormatVertOrient already set
1688  SwFormatHoriOrient already set
1689  SwFormatAnchor already set
1690  SvxBoxItem set here
1691  SvxBrushItem set here
1692  SvxShadowItem set here
1693  */
1694 
1695  // 1. GraphicObject of documents?
1696  GraphicCtor();
1697 
1698  const SfxItemSet& rOldSet = pSdrObj->GetMergedItemSet();
1699 
1700  // some Items can be taken over directly
1701  static sal_uInt16 const aDirectMatch[]
1702  {
1703  RES_LR_SPACE, // outer spacing left/right: SvxLRSpaceItem
1704  RES_UL_SPACE // outer spacing top/bottom: SvxULSpaceItem
1705  };
1706  const SfxPoolItem* pPoolItem;
1707  for(sal_uInt16 i : aDirectMatch)
1708  if( SfxItemState::SET == rOldSet.GetItemState(i, false, &pPoolItem) )
1709  {
1710  rFlySet.Put( *pPoolItem );
1711  }
1712 
1713  // take new XATTR items directly. Skip old RES_BACKGROUND if new FILLSTYLE taken.
1714  bool bSkipResBackground = false;
1715  SfxItemPool* pPool = rFlySet.GetPool();
1716  if ( pPool )
1717  {
1718  for ( sal_uInt16 i = XATTR_START; i < XATTR_END; ++i )
1719  {
1720  // Not all Fly types support XATTRs - skip unsupported attributes
1721  SfxItemPool* pAttrPool = pPool->GetMasterPool();
1722  while ( pAttrPool && !pAttrPool->IsInRange(i) )
1723  pAttrPool = pAttrPool->GetSecondaryPool();
1724  if ( !pAttrPool )
1725  continue;
1726 
1727  if ( SfxItemState::SET == rOldSet.GetItemState(i, false, &pPoolItem) )
1728  {
1729  rFlySet.Put( *pPoolItem );
1730  if ( i == XATTR_FILLSTYLE )
1731  {
1732  const drawing::FillStyle eFill = static_cast<const XFillStyleItem*>(pPoolItem)->GetValue();
1733  // Transparency forced in certain situations when fillstyle is none - use old logic for that case still
1734  // which is especially needed for export purposes (tdf112618).
1735  if ( eFill != drawing::FillStyle_NONE )
1736  bSkipResBackground = true;
1737  }
1738  }
1739  }
1740  }
1741 
1742  // now calculate the borders and build the box: The unit is needed for the
1743  // frame SIZE!
1744  SvxBoxItem aBox(sw::util::ItemGet<SvxBoxItem>(rFlySet, RES_BOX));
1745  // dashed or solid becomes solid
1746  // WW-default: 0.75 pt = 15 twips
1747  sal_Int32 nLineThick = 15, nOutside=0;
1748 
1749  // check if LineStyle is *really* set!
1750  const SfxPoolItem* pItem;
1751 
1752  SfxItemState eState = rOldSet.GetItemState(XATTR_LINESTYLE,true,&pItem);
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, true, &pItem);
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  eState = rOldSet.GetItemState(XATTR_FILLSTYLE, true, &pItem);
1879  if (!bSkipResBackground && eState == SfxItemState::SET)
1880  {
1881  const drawing::FillStyle eFill = static_cast<const XFillStyleItem*>(pItem)->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, SfxBoolItem));
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.nLayoutInTableCell))
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 nLayoutInTableCell ) 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( nLayoutInTableCell == 0xFFFFFFFF,
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  // #i98037#
2488  // adjustment of conditions needed after deeper analysis of
2489  // certain test cases.
2490  if ( nLayoutInTableCell == 0xFFFFFFFF || // no explicit attribute value given
2491  nLayoutInTableCell == 0x80008000 ||
2492  ( nLayoutInTableCell & 0x02000000 &&
2493  !(nLayoutInTableCell & 0x80000000 ) ) )
2494  {
2495  bIsObjectLayoutInTableCell = true;
2496  }
2497  else
2498  {
2499  // Documented in [MS-ODRAW], 2.3.4.44 "Group Shape Boolean Properties".
2500  bool fUsefLayoutInCell = (nLayoutInTableCell & 0x80000000) >> 31;
2501  bool fLayoutInCell = (nLayoutInTableCell & 0x8000) >> 15;
2502  bIsObjectLayoutInTableCell = fUsefLayoutInCell && fLayoutInCell;
2503  }
2504  }
2505  break;
2506  default:
2507  {
2508  OSL_FAIL( "unknown version." );
2509  }
2510  }
2511  }
2512 
2513  return bIsObjectLayoutInTableCell;
2514 }
2515 
2517 {
2518  if( m_nIniFlags & WW8FL_NO_GRAFLAYER )
2519  return nullptr;
2520 
2521  ::SetProgressState(m_nProgress, m_pDocShell); // Update
2522 
2523  m_nDrawCpO = 0;
2524  m_bDrawCpOValid = m_xWwFib->GetBaseCp(m_xPlcxMan->GetManType() == MAN_HDFT ? MAN_TXBX_HDFT : MAN_TXBX, &m_nDrawCpO);
2525 
2526  GraphicCtor();
2527 
2528  WW8PLCFspecial* pPF = m_xPlcxMan->GetFdoa();
2529  if( !pPF )
2530  {
2531  OSL_ENSURE( false, "Where is the graphic (1) ?" );
2532  return nullptr;
2533  }
2534 
2535  if( m_bVer67 )
2536  {
2537  tools::Long nOldPos = m_pStrm->Tell();
2538 
2539  m_nDrawXOfs = m_nDrawYOfs = 0;
2540  ReadGrafLayer1(*pPF, nGrafAnchorCp);
2541 
2542  m_pStrm->Seek( nOldPos );
2543  return nullptr;
2544  }
2545 
2546  // Normal case of Word 8+ version stuff
2547  pPF->SeekPos( nGrafAnchorCp );
2548 
2549  WW8_FC nStartFc;
2550  void* pF0;
2551  if (!pPF->Get(nStartFc, pF0))
2552  {
2553  OSL_ENSURE( false, "+Where is the graphic (2) ?" );
2554  return nullptr;
2555  }
2556 
2557  WW8_FSPA_SHADOW& rFS = *static_cast<WW8_FSPA_SHADOW*>(pF0);
2558  WW8_FSPA aFSFA;
2559  WW8FSPAShadowToReal(rFS, aFSFA);
2560  if (!aFSFA.nSpId)
2561  {
2562  OSL_ENSURE( false, "+Where is the graphic (3) ?" );
2563  return nullptr;
2564  }
2565 
2566  if (!m_xMSDffManager->GetModel())
2567  m_xMSDffManager->SetModel(m_pDrawModel, 1440);
2568 
2569  tools::Rectangle aRect(aFSFA.nXaLeft, aFSFA.nYaTop, aFSFA.nXaRight, aFSFA.nYaBottom);
2570  SvxMSDffImportData aData( aRect );
2571 
2572  /*
2573  #i20540#
2574  The SdrOle2Obj will try and manage any ole objects it finds, causing all
2575  sorts of trouble later on
2576  */
2577  SwDocShell* pPersist = m_rDoc.GetDocShell();
2578  m_rDoc.SetDocShell(nullptr); // #i20540# Persist guard
2579 
2580  SdrObject* pObject = nullptr;
2581  bool bOk = (m_xMSDffManager->GetShape(aFSFA.nSpId, pObject, aData) && pObject);
2582 
2583  m_rDoc.SetDocShell(pPersist); // #i20540# Persist guard
2584 
2585  if (!bOk)
2586  {
2587  OSL_ENSURE( false, "Where is the Shape ?" );
2588  return nullptr;
2589  }
2590 
2591  // tdf#118375 Word relates position to the unrotated rectangle,
2592  // Writer uses the rotated one.
2593  if (pObject->GetRotateAngle())
2594  {
2595  tools::Rectangle aObjSnapRect(pObject->GetSnapRect()); // recalculates the SnapRect
2596  aFSFA.nXaLeft = aObjSnapRect.Left();
2597  aFSFA.nYaTop = aObjSnapRect.Top();
2598  aFSFA.nXaRight = aObjSnapRect.Right();
2599  aFSFA.nYaBottom = aObjSnapRect.Bottom();
2600  }
2601 
2602  bool bDone = false;
2603  SdrObject* pOurNewObject = nullptr;
2604  bool bReplaceable = false;
2605 
2606  switch (pObject->GetObjIdentifier())
2607  {
2608  case OBJ_GRAF:
2609  bReplaceable = true;
2610  bDone = true;
2611  break;
2612  case OBJ_OLE2:
2613  bReplaceable = true;
2614  break;
2615  default:
2616  break;
2617 
2618  }
2619 
2620  // when in a header or footer word appears to treat all elements as wrap through
2621 
2622  // determine wrapping mode
2624  Reader::ResetFrameFormatAttrs(aFlySet); // tdf#122425: Explicitly remove borders and spacing
2625  css::text::WrapTextMode eSurround = css::text::WrapTextMode_PARALLEL;
2626  bool bContour = false;
2627  switch (aFSFA.nwr)
2628  {
2629  case 0: // 0 like 2, but doesn't require absolute object
2630  case 2: // 2 wrap around absolute object
2631  eSurround = css::text::WrapTextMode_PARALLEL;
2632  break;
2633  case 1: // 1 no text next to shape
2634  eSurround = css::text::WrapTextMode_NONE;
2635  break;
2636  case 3: // 3 wrap as if no object present
2637  eSurround = css::text::WrapTextMode_THROUGH;
2638  break;
2639  case 4: // 4 wrap tightly around object
2640  case 5: // 5 wrap tightly, but allow holes
2641  eSurround = css::text::WrapTextMode_PARALLEL;
2642  bContour = true;
2643  break;
2644  }
2645 
2646  // if mode 2 or 4 also regard the additional parameters
2647  if ((2 == aFSFA.nwr) || (4 == aFSFA.nwr))
2648  {
2649  switch (aFSFA.nwrk)
2650  {
2651  // 0 wrap both sides
2652  case 0:
2653  eSurround = css::text::WrapTextMode_PARALLEL;
2654  break;
2655  // 1 wrap only on left
2656  case 1:
2657  eSurround = css::text::WrapTextMode_LEFT;
2658  break;
2659  // 2 wrap only on right
2660  case 2:
2661  eSurround = css::text::WrapTextMode_RIGHT;
2662  break;
2663  // 3 wrap only on largest side
2664  case 3:
2665  eSurround = css::text::WrapTextMode_DYNAMIC;
2666  break;
2667  }
2668  }
2669 
2670  SwFormatSurround aSur( eSurround );
2671  aSur.SetContour( bContour );
2672  aSur.SetOutside(true); // Winword can only do outside contours
2673  aFlySet.Put( aSur );
2674 
2675  // now position imported object correctly and so on (can be a whole group)
2676 
2677  OSL_ENSURE(!((aData.size() != 1) && bReplaceable),
2678  "Replaceable drawing with > 1 entries ?");
2679 
2680  if (aData.size() != 1)
2681  bReplaceable = false;
2682 
2683  /*
2684  Get the record for top level object, so we can get the word anchoring
2685  and wrapping information for it.
2686  */
2687  SvxMSDffImportRec* pRecord = aData.find(pObject);
2688  OSL_ENSURE(pRecord, "how did that happen?");
2689  if (!pRecord)
2690  {
2691  // remove old object from the Z-Order list
2692  m_xMSDffManager->RemoveFromShapeOrder(pObject);
2693  // and delete the object
2694  SdrObject::Free(pObject);
2695  return nullptr;
2696  }
2697  const bool bLayoutInTableCell =
2698  m_nInTable && IsObjectLayoutInTableCell( pRecord->nLayoutInTableCell );
2699 
2700  // #i18732# - Switch on 'follow text flow', if object is laid out
2701  // inside table cell
2702  if (bLayoutInTableCell)
2703  {
2704  SwFormatFollowTextFlow aFollowTextFlow( true );
2705  aFlySet.Put( aFollowTextFlow );
2706  }
2707 
2708  // #i21847#
2709  // Some shapes are set to *hidden*, don't import those ones.
2710  if (pRecord->bHidden)
2711  {
2712  // remove old object from the Z-Order list
2713  m_xMSDffManager->RemoveFromShapeOrder(pObject);
2714  // and delete the object
2715  SdrObject::Free(pObject);
2716  return nullptr;
2717  }
2718 
2719  sal_uInt16 nCount = pObject->GetUserDataCount();
2720  if(nCount)
2721  {
2722  OUString lnName, aObjName, aTarFrame;
2723  for (sal_uInt16 i = 0; i < nCount; i++ )
2724  {
2725  SdrObjUserData* pData = pObject->GetUserData( i );
2726  if( pData && pData->GetInventor() == SdrInventor::ScOrSwDraw
2727  && pData->GetId() == SW_UD_IMAPDATA)
2728  {
2729  SwMacroInfo* macInf = dynamic_cast<SwMacroInfo*>(pData);
2730  if (macInf && macInf->GetShapeId() == aFSFA.nSpId)
2731  {
2732  lnName = macInf->GetHlink();
2733  aObjName = macInf->GetName();
2734  aTarFrame = macInf->GetTarFrame();
2735  break;
2736  }
2737  }
2738  }
2739  std::unique_ptr<SwFormatURL> pFormatURL(new SwFormatURL());
2740  pFormatURL->SetURL( lnName, false );
2741  if (!aObjName.isEmpty())
2742  pFormatURL->SetName(aObjName);
2743  if (!aTarFrame.isEmpty())
2744  pFormatURL->SetTargetFrameName(aTarFrame);
2745  pFormatURL->SetMap(nullptr);
2746  aFlySet.Put(*pFormatURL);
2747  }
2748 
2749  // If we are to be "below text" then we are not to be opaque
2750  // #i14045# MM If we are in a header or footer then make the object transparent
2751  // Not exactly like word but close enough for now
2752 
2753  // both flags <bBelowText> and <bDrawHell> have to be set to move object into the background.
2754  // #i46794# - it reveals that value of flag <bBelowText> can be neglected.
2755  const bool bMoveToBackground = pRecord->bDrawHell ||
2756  ((m_bIsHeader || m_bIsFooter) && aFSFA.nwr == 3);
2757  if ( bMoveToBackground )
2758  aFlySet.Put(SvxOpaqueItem(RES_OPAQUE,false));
2759 
2760  OUString aObjName = pObject->GetName();
2761 
2762  bool bDrawObj = false;
2763  bool bFrame = false;
2764 
2765  SwFrameFormat* pRetFrameFormat = nullptr;
2766  if (bReplaceable)
2767  {
2768  // Single graphics or ole objects
2769  pRetFrameFormat = ImportReplaceableDrawables(pObject, pOurNewObject, *pRecord, aFSFA, aFlySet);
2770  }
2771  else
2772  {
2773  bDrawObj = true;
2774 
2775  // Drawing objects, (e.g. ovals or drawing groups)
2776  if (aFSFA.bRcaSimple)
2777  {
2778  aFSFA.nbx = WW8_FSPA::RelPageBorder;
2779  aFSFA.nby = WW8_FSPA::RelPageBorder;
2780  }
2781 
2782  RndStdIds eAnchor = ProcessEscherAlign(*pRecord, aFSFA, aFlySet);
2783 
2784  // Should we, and is it possible to make this into a writer textbox
2785  if ((!(m_nIniFlags1 & WW8FL_NO_FLY_FOR_TXBX)) && pRecord->bReplaceByFly)
2786  {
2787  pRetFrameFormat
2788  = ConvertDrawTextToFly(pObject, pOurNewObject, *pRecord, eAnchor, aFSFA, aFlySet);
2789  if (pRetFrameFormat)
2790  {
2791  bDone = true;
2792  bDrawObj = false;
2793  bFrame = true;
2794  }
2795  }
2796 
2797  if (!bDone)
2798  {
2799  sw::util::SetLayer aSetLayer(m_rDoc);
2800  if ( bMoveToBackground )
2801  aSetLayer.SendObjectToHell(*pObject);
2802  else
2803  aSetLayer.SendObjectToHeaven(*pObject);
2804 
2805  if (!IsInlineEscherHack())
2806  {
2807  /* Need to make sure that the correct layer ordering is applied. */
2808  // pass information, if object is in page header|footer to method.
2809  m_xWWZOrder->InsertEscherObject(pObject, aFSFA.nSpId, pRecord->bDrawHell,
2810  m_bIsHeader || m_bIsFooter);
2811  }
2812  else
2813  {
2814  m_xWWZOrder->InsertTextLayerObject(pObject);
2815  }
2816 
2817  pRetFrameFormat = m_rDoc.getIDocumentContentOperations().InsertDrawObj(*m_pPaM, *pObject, aFlySet );
2818 
2819  OSL_ENSURE(pRetFrameFormat->GetAnchor().GetAnchorId() ==
2820  eAnchor, "Not the anchor type requested!");
2821 
2822  /*
2823  Insert text if necessary into textboxes contained in groups.
2824  */
2825  for (const auto& it : aData)
2826  {
2827  pRecord = it.get();
2828  if (pRecord->pObj && pRecord->aTextId.nTxBxS)
2829  { // #i52825# pRetFrameFormat can be NULL
2830  pRetFrameFormat = MungeTextIntoDrawBox(
2831  *pRecord, nGrafAnchorCp, pRetFrameFormat);
2832  }
2833  }
2834  }
2835  }
2836 
2837  SwDrawFrameFormat* pDrawFrameFormat = dynamic_cast<SwDrawFrameFormat*>(pRetFrameFormat);
2838  // #i44344#, #i44681# - positioning attributes already set
2839  if (pDrawFrameFormat)
2840  pDrawFrameFormat->PosAttrSet();
2841  if (!IsInlineEscherHack() && pRetFrameFormat)
2842  MapWrapIntoFlyFormat(*pRecord, *pRetFrameFormat);
2843 
2844  // Set frame name with object name
2845  if (pRetFrameFormat /*#i52825# */)
2846  {
2847  if (!aObjName.isEmpty())
2848  pRetFrameFormat->SetName( aObjName );
2849  if (pRetFrameFormat->GetName().isEmpty())
2850  {
2851  if (bDrawObj)
2852  pRetFrameFormat->SetName(m_rDoc.GetUniqueDrawObjectName());
2853  else if (bFrame)
2854  pRetFrameFormat->SetName(m_rDoc.GetUniqueFrameName());
2855  }
2856  }
2857  return AddAutoAnchor(pRetFrameFormat);
2858 }
2859 
2861 {
2862  /*
2863  * anchored to character at the current position will move along the
2864  * paragraph as text is added because we are at the insertion point.
2865  *
2866  * Leave to later and set the correct location then.
2867  */
2868  if (pFormat && (pFormat->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR))
2869  {
2870  m_xAnchorStck->AddAnchor(*m_pPaM->GetPoint(), pFormat);
2871  }
2872  return pFormat;
2873 }
2874 
2876  tools::Long nGrafAnchorCp, SwFrameFormat* pRetFrameFormat)
2877 {
2878  SdrObject* pTrueObject = rRecord.pObj;
2879 
2880  SdrTextObj* pSdrTextObj;
2881 
2882  // check for group object (e.g. two parentheses)
2883  if (SdrObjGroup* pThisGroup = dynamic_cast<SdrObjGroup*>(rRecord.pObj))
2884  {
2885  // Group objects don't have text. Insert a text object into
2886  // the group for holding the text.
2887  pSdrTextObj = new SdrRectObj(
2888  *m_pDrawModel,
2889  OBJ_TEXT,
2890  pThisGroup->GetCurrentBoundRect());
2891 
2892  SfxItemSet aSet(m_pDrawModel->GetItemPool());
2893  aSet.Put(XFillStyleItem(drawing::FillStyle_NONE));
2894  aSet.Put(XLineStyleItem(drawing::LineStyle_NONE));
2895  aSet.Put(SdrTextFitToSizeTypeItem( drawing::TextFitToSizeType_NONE ));
2896  aSet.Put(makeSdrTextAutoGrowHeightItem(false));
2897  aSet.Put(makeSdrTextAutoGrowWidthItem(false));
2898  pSdrTextObj->SetMergedItemSet(aSet);
2899  pSdrTextObj->NbcSetLayer( pThisGroup->GetLayer() );
2900  pThisGroup->GetSubList()->NbcInsertObject(pSdrTextObj);
2901  }
2902  else
2903  pSdrTextObj = dynamic_cast<SdrTextObj*>(rRecord.pObj);
2904 
2905  if( pSdrTextObj )
2906  {
2907  Size aObjSize(pSdrTextObj->GetSnapRect().GetWidth(),
2908  pSdrTextObj->GetSnapRect().GetHeight());
2909 
2910  // Object is part of a group?
2911  SdrObject* pGroupObject = pSdrTextObj->getParentSdrObjectFromSdrObject();
2912 
2913  const size_t nOrdNum = pSdrTextObj->GetOrdNum();
2914  bool bEraseThisObject;
2915  InsertTxbxText(pSdrTextObj, &aObjSize, rRecord.aTextId.nTxBxS, rRecord.aTextId.nSequence,
2916  nGrafAnchorCp, pRetFrameFormat,
2917  (pSdrTextObj != pTrueObject) || (nullptr != pGroupObject), bEraseThisObject,
2918  nullptr, nullptr, nullptr, nullptr, &rRecord);
2919 
2920  // was this object replaced ??
2921  if (bEraseThisObject)
2922  {
2923  if( pGroupObject || (pSdrTextObj != pTrueObject) )
2924  {
2925  // Object is already replaced by a new SdrGrafObj (in the group
2926  // and) the Drawing-Page.
2927 
2928  SdrObject* pNewObj = pGroupObject ?
2929  pGroupObject->GetSubList()->GetObj(nOrdNum) : pTrueObject;
2930  if (pSdrTextObj != pNewObj)
2931  {
2932  // Replace object in the Z-Order-List
2933  m_xMSDffManager->ExchangeInShapeOrder(pSdrTextObj, 0, pNewObj);
2934  // now delete object
2935  SdrObject::Free(rRecord.pObj);
2936  // and save the new object.
2937  rRecord.pObj = pNewObj;
2938  }
2939  }
2940  else
2941  {
2942  // remove the object from Z-Order list
2943  m_xMSDffManager->RemoveFromShapeOrder( pSdrTextObj );
2944  // take the object from the drawing page
2945  if( pSdrTextObj->getSdrPageFromSdrObject() )
2946  m_pDrawPg->RemoveObject( pSdrTextObj->GetOrdNum() );
2947  // and delete FrameFormat, because replaced by graphic
2948  // (this also deletes the object)
2949  m_rDoc.DelFrameFormat( pRetFrameFormat );
2950  pRetFrameFormat = nullptr;
2951  // also delete the object record
2952  rRecord.pObj = nullptr;
2953  }
2954  }
2955  else
2956  {
2957  // use ww8-default border distance
2959  aItemSet(m_pDrawModel->GetItemPool());
2960  aItemSet.Put(makeSdrTextLeftDistItem(rRecord.nDxTextLeft));
2961  aItemSet.Put(makeSdrTextRightDistItem(rRecord.nDxTextRight));
2962  aItemSet.Put(makeSdrTextUpperDistItem(rRecord.nDyTextTop));
2963  aItemSet.Put(makeSdrTextLowerDistItem(rRecord.nDyTextBottom));
2964  pSdrTextObj->SetMergedItemSetAndBroadcast(aItemSet);
2965  }
2966  }
2967  return pRetFrameFormat;
2968 }
2969 
2971  SdrObject*& rpOurNewObject,
2972  const SvxMSDffImportRec& rRecord,
2973  RndStdIds eAnchor, const WW8_FSPA& rF,
2974  SfxItemSet &rFlySet)
2975 {
2976  SwFlyFrameFormat* pRetFrameFormat = nullptr;
2977  tools::Long nStartCp;
2978  tools::Long nEndCp;
2979 
2980  // Check if this textbox chain contains text as conversion of an empty
2981  // chain would not make sense.
2982  if (TxbxChainContainsRealText(rRecord.aTextId.nTxBxS, nStartCp, nEndCp))
2983  {
2984  // The Text is not read into SdrTextObj! Rather insert a frame and
2985  // insert the text from nStartCp to nEndCp.
2986 
2987  // More attributes can be used in a frame compared to the
2988  // Edit-Engine, and it can contain field, OLEs or graphics...
2989  tools::Rectangle aInnerDist(rRecord.nDxTextLeft, rRecord.nDyTextTop, rRecord.nDxTextRight,
2990  rRecord.nDyTextBottom);
2991 
2993  rF.nYaBottom - rF.nYaTop);
2995  : SwFrameSize::Fixed);
2996  rFlySet.Put(aFrameSize);
2997 
2998  MatchSdrItemsIntoFlySet(rpObject, rFlySet, rRecord.eLineStyle, rRecord.eLineDashing,
2999  rRecord.eShapeType, aInnerDist);
3000 
3001  SdrTextObj *pSdrTextObj = dynamic_cast<SdrTextObj*>(rpObject);
3002  if (pSdrTextObj && pSdrTextObj->IsVerticalWriting())
3003  rFlySet.Put(SvxFrameDirectionItem(SvxFrameDirection::Vertical_RL_TB, RES_FRAMEDIR));
3004 
3005  pRetFrameFormat = m_rDoc.MakeFlySection(eAnchor, m_pPaM->GetPoint(), &rFlySet);
3006  OSL_ENSURE(pRetFrameFormat->GetAnchor().GetAnchorId() == eAnchor,
3007  "Not the anchor type requested!");
3008 
3009  // if everything is OK, find pointer on new object and correct
3010  // Z-order list (or delete entry)
3011  rpOurNewObject = CreateContactObject(pRetFrameFormat);
3012 
3013  // remove old object from the Z-Order list
3014  m_xMSDffManager->RemoveFromShapeOrder( rpObject );
3015 
3016  // and delete the object
3017  SdrObject::Free( rpObject );
3018  /*
3019  NB: only query pOrgShapeObject starting here!
3020  */
3021 
3022  if (rpOurNewObject)
3023  {
3024  /*
3025  We do not store our rpOutNewObject in the ShapeOrder because we
3026  have a FrameFormat from which we can regenerate the contact object when
3027  we need it. Because, we can have frames anchored to paragraphs in
3028  header/footers and we can copy header/footers, if we do copy a
3029  header/footer with a nonpage anchored frame in it then the contact
3030  objects are invalidated. Under this condition the FrameFormat will be
3031  updated to reflect this change and can be used to get a new
3032  contact object, while a raw rpOutNewObject stored here becomes
3033  deleted and useless.
3034  */
3035  m_xMSDffManager->StoreShapeOrder(rF.nSpId,
3036  (static_cast<sal_uLong>(rRecord.aTextId.nTxBxS) << 16) +
3037  rRecord.aTextId.nSequence, nullptr, pRetFrameFormat);
3038 
3039  // The Contact object has to be inserted into the draw page, so
3040  // SwWW8ImplReader::LoadDoc1() can determine the z-order.
3041  if (!rpOurNewObject->IsInserted())
3042  {
3043  // pass information, if object is in page header|footer to method.
3044  m_xWWZOrder->InsertEscherObject(rpOurNewObject, rF.nSpId, rRecord.bDrawHell,
3045  m_bIsHeader || m_bIsFooter);
3046  }
3047  }
3048 
3049  // Box-0 receives the text for the whole chain!
3050  if (!rRecord.aTextId.nSequence)
3051  {
3052  // save flags etc and reset them
3053  WW8ReaderSave aSave( this );
3054 
3055  MoveInsideFly(pRetFrameFormat);
3056 
3057  m_xWWZOrder->InsideEscher(rF.nSpId);
3058 
3059  // read in the text
3060  m_bTxbxFlySection = true;
3061  bool bJoined = ReadText(nStartCp, (nEndCp-nStartCp),
3062  MAN_MAINTEXT == m_xPlcxMan->GetManType() ?
3064 
3065  m_xWWZOrder->OutsideEscher();
3066 
3067  MoveOutsideFly(pRetFrameFormat, aSave.GetStartPos(),!bJoined);
3068 
3069  aSave.Restore( this );
3070 
3071  StripNegativeAfterIndent(pRetFrameFormat);
3072  }
3073 
3074  }
3075  return pRetFrameFormat;
3076 }
3077 
3079 {
3080  if (rRecord.bVFlip || rRecord.bHFlip)
3081  {
3083  if (rRecord.bVFlip && rRecord.bHFlip)
3084  eType = MirrorGraph::Both;
3085  else if (rRecord.bVFlip)
3086  eType = MirrorGraph::Horizontal;
3087  else
3088  eType = MirrorGraph::Vertical;
3089  rFlySet.Put( SwMirrorGrf(eType) );
3090  }
3091 }
3092 
3094  SdrObject* &rpOurNewObject,
3095  SvxMSDffImportRec& rRecord,
3096  WW8_FSPA& rF,
3097  SfxItemSet &rFlySet )
3098 {
3099  SwFlyFrameFormat* pRetFrameFormat = nullptr;
3100  sal_Int32 nWidthTw = o3tl::saturating_sub(rF.nXaRight, rF.nXaLeft);
3101  if (0 > nWidthTw)
3102  nWidthTw = 0;
3103  sal_Int32 nHeightTw = o3tl::saturating_sub(rF.nYaBottom, rF.nYaTop);
3104  if (0 > nHeightTw)
3105  nHeightTw = 0;
3106 
3107  ProcessEscherAlign(rRecord, rF, rFlySet);
3108 
3109  rFlySet.Put(SwFormatFrameSize(SwFrameSize::Fixed, nWidthTw, nHeightTw));
3110 
3112 
3113  // Note that the escher inner distance only seems to be honoured in
3114  // word for textboxes, not for graphics and ole objects.
3115  tools::Rectangle aInnerDist(0, 0, 0, 0);
3116 
3117  MatchSdrItemsIntoFlySet(rpObject, rFlySet, rRecord.eLineStyle, rRecord.eLineDashing,
3118  rRecord.eShapeType, aInnerDist);
3119 
3120  MatchEscherMirrorIntoFlySet(rRecord, aGrSet);
3121 
3122  OUString aObjectName(rpObject->GetName());
3123  if (OBJ_OLE2 == rpObject->GetObjIdentifier())
3124  pRetFrameFormat = InsertOle(*static_cast<SdrOle2Obj*>(rpObject), rFlySet, &aGrSet);
3125  else
3126  {
3127  const SdrGrafObj *pGrf = static_cast<const SdrGrafObj*>(rpObject);
3128  bool bDone = false;
3129  if (pGrf->IsLinkedGraphic() && !pGrf->GetFileName().isEmpty())
3130  {
3131  GraphicType eType = pGrf->GetGraphicType();
3132  OUString aGrfName(
3134  INetURLObject(m_sBaseURL), pGrf->GetFileName(),
3136  // correction of fix for issue #i10939#:
3137  // One of the two conditions have to be true to insert the graphic
3138  // as a linked graphic -
3139  if (GraphicType::NONE == eType || CanUseRemoteLink(aGrfName))
3140  {
3142  *m_pPaM, aGrfName, OUString(), nullptr,
3143  &rFlySet, &aGrSet, nullptr);
3144  bDone = true;
3145  }
3146  }
3147  if (!bDone)
3148  {
3149  const Graphic& rGraph = pGrf->GetGraphic();
3151  *m_pPaM, OUString(), OUString(), &rGraph,
3152  &rFlySet, &aGrSet, nullptr);
3153  }
3154  }
3155 
3156  if (pRetFrameFormat)
3157  {
3158  if (OBJ_OLE2 != rpObject->GetObjIdentifier())
3159  SetAttributesAtGrfNode(rRecord, *pRetFrameFormat, &rF);
3160  // avoid multiple occurrences of the same graphic name
3161  m_aGrfNameGenerator.SetUniqueGraphName(pRetFrameFormat, aObjectName);
3162  }
3163  // if everything is OK, determine pointer to new object and correct
3164  // Z-Order-List accordingly (or delete entry)
3165  rpOurNewObject = CreateContactObject(pRetFrameFormat);
3166 
3167  // remove old object from Z-Order-List
3168  m_xMSDffManager->RemoveFromShapeOrder( rpObject );
3169  // remove from Drawing-Page
3170  if( rpObject->getSdrPageFromSdrObject() )
3171  m_pDrawPg->RemoveObject( rpObject->GetOrdNum() );
3172 
3173  // and delete the object
3174  SdrObject::Free( rpObject );
3175  /*
3176  Warning: from now on query only pOrgShapeObject!
3177  */
3178 
3179  // add Contact-Object to the Z-Order-List and the page
3180  if (rpOurNewObject)
3181  {
3182  if (!m_bHdFtFootnoteEdn)
3183  m_xMSDffManager->StoreShapeOrder(rF.nSpId, 0, rpOurNewObject);
3184 
3185  // The Contact-Object MUST be set in the Draw-Page, so that in
3186  // SwWW8ImplReader::LoadDoc1() the Z-Order can be defined !!!
3187  if (!rpOurNewObject->IsInserted())
3188  {
3189  // pass information, if object is in page header|footer to method.
3190  m_xWWZOrder->InsertEscherObject(rpOurNewObject, rF.nSpId, rRecord.bDrawHell,
3191  m_bIsHeader || m_bIsFooter);
3192  }
3193  }
3194  return pRetFrameFormat;
3195 }
3196 
3197 void SwWW8ImplReader::GraphicCtor() // For SVDraw and VCControls and Escher
3198 {
3199  if (m_pDrawModel)
3200  return;
3201 
3202  m_rDoc.getIDocumentDrawModelAccess().GetOrCreateDrawModel(); // #i52858# - method name changed
3203  m_pDrawModel = m_rDoc.getIDocumentDrawModelAccess().GetDrawModel();
3204  OSL_ENSURE(m_pDrawModel, "Cannot create DrawModel");
3205  m_pDrawPg = m_pDrawModel->GetPage(0);
3206 
3207  m_xMSDffManager.reset(new SwMSDffManager(*this, m_bSkipImages));
3208  m_xMSDffManager->SetModel(m_pDrawModel, 1440);
3209  /*
3210  Now the dff manager always needs a controls converter as well, but a
3211  control converter may still exist without a dffmanager.
3212  */
3213  m_xFormImpl.reset(new SwMSConvertControls(m_pDocShell, m_pPaM));
3214 
3215  m_xWWZOrder.reset(new wwZOrderer(sw::util::SetLayer(m_rDoc), m_pDrawPg,
3216  m_xMSDffManager->GetShapeOrders()));
3217 }
3218 
3220 {
3221  m_pDrawEditEngine.reset(); // maybe created by graphic
3222  m_xWWZOrder.reset(); // same
3223 }
3224 
3226 {
3227  OSL_ENSURE(pFormat->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR,
3228  "Don't use fltanchors with inline frames, slap!");
3229  NewAttr(rPos, SwFltAnchor(pFormat));
3230 }
3231 
3233 {
3234  size_t nCnt = size();
3235  for (size_t i=0; i < nCnt; ++i)
3236  {
3237  SwFltStackEntry &rEntry = (*this)[i];
3238  SwPosition aDummy(rEntry.m_aMkPos.m_nNode);
3239  SetAttrInDoc(aDummy, rEntry);
3240  DeleteAndDestroy(i--);
3241  --nCnt;
3242  }
3243 }
3244 
3245 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static ESelection GetESelection(EditEngine const &rDrawEditEngine, tools::Long nCpStart, tools::Long nCpEnd)
Definition: ww8graf.cxx:466
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:963
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:8550
sal_Int32 nStartPara
SwNoTextNode * GetNoTextNodeFromSwFrameFormat(const SwFrameFormat &rFormat)
Get the SwNoTextNode associated with a SwFrameFormat if here is one.
sal_uInt16 CalcLineWidth(SvxBoxItemLine nLine) const
SdrMetricItem makeSdrShadowYDistItem(tools::Long nDist)
constexpr SwTwips MIN_BORDER_DIST
Definition: swtypes.hxx:71
SdrObject * ReadPolyLine(WW8_DPHEAD const *pHd, SfxAllItemSet &rSet)
Definition: ww8graf.cxx:428
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:1590
void SetRight(const tools::Long nR, const sal_uInt16 nProp=100)
sal_Int32 nDxWrapDistRight
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:531
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:896
void SetBlue(sal_uInt8 nBlue)
static void SetFill(SfxItemSet &rSet, WW8_DP_FILL &rFill)
Definition: ww8graf.cxx:239
OUString GetUniqueDrawObjectName() const
Definition: doclay.cxx:1389
SdrObject * ReadCaptionBox(WW8_DPHEAD const *pHd, SfxAllItemSet &rSet)
Definition: ww8graf.cxx:1284
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:1352
SvxMSDffImportRec * find(const SdrObject *pObj)
sal_Int32 nDxTextLeft
std::unique_ptr< ContentProperties > pData
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)
void MatchSdrItemsIntoFlySet(SdrObject const *pSdrObj, SfxItemSet &aFlySet, MSO_LineStyle eLineStyle, MSO_LineDashing eDashing, MSO_SPT eShapeType, tools::Rectangle &rInnerDist)
Definition: ww8graf.cxx:1675
void SetDots(sal_uInt16 nNewDots)
SwTwips GetPos() const
Definition: fmtornt.hxx:92
sal_uIntPtr sal_uLong
bool IsObjectLayoutInTableCell(const sal_uInt32 nLayoutInTableCell) const
Definition: ww8graf.cxx:2454
long Long
void SetColor(const Color &rNew)
OBJ_LINE
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:125
GraphicType
static sal_Int32 GetEscherLineMatch(MSO_LineStyle eStyle, MSO_SPT eShapeType, sal_Int32 &rThick)
Definition: ww8graf.cxx:1532
bool IsInserted() const
constexpr sal_uInt16 RES_FRMATR_END(133)
const OUString & GetTarFrame() const
Definition: ww8par.hxx:519
OBJ_POLY
void WW8FSPAShadowToReal(const WW8_FSPA_SHADOW &rFSPAS, WW8_FSPA &rPic)
Definition: ww8graf2.cxx:761
OUString GetUniqueFrameName() const
Definition: doclay.cxx:1379
void Scale(double fScaleX, double fScaleY)
void PosAttrSet()
Definition: frmfmt.hxx:401
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:2376
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:32
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:523
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:517
virtual const tools::Rectangle & GetSnapRect() const
void GraphicDtor()
Definition: ww8graf.cxx:3219
void GraphicCtor()
Definition: ww8graf.cxx:3197
SdrObject * ReadEllipse(WW8_DPHEAD const *pHd, SfxAllItemSet &rSet)
Definition: ww8graf.cxx:367
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:1204
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:288
MSO_LineDashing
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:128
void advance()
Definition: ww8scan.hxx:254
constexpr::Color COL_CYAN(0x00, 0x80, 0x80)
const OUString & GetName() const
Definition: format.hxx:115
int nCount
constexpr sal_uInt16 POOLATTR_BEGIN(HINT_BEGIN)
static void lcl_StripFields(OUString &rString, WW8_CP &rNewStartCp)
Definition: ww8graf.cxx:526
static void SetStdAttr(SfxItemSet &rSet, WW8_DP_LINETYPE &rL, WW8_DP_SHADOW const &rSh)
Definition: ww8graf.cxx:198
virtual void SetName(const OUString &rNewName, bool bBroadcast=false) override
Definition: atrfrm.cxx:2570
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:1022
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:154
SdrOnOffItem makeSdrTextAutoGrowWidthItem(bool bAuto)
void InsertTxbxStyAttrs(SfxItemSet &rS, sal_uInt16 nColl)
Definition: ww8graf.cxx:495
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:2516
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:163
constexpr TypedWhichId< XFillTransparenceItem > XATTR_FILLTRANSPARENCE(XATTR_FILL_FIRST+5)
SwFrameFormat * MungeTextIntoDrawBox(SvxMSDffImportRec &rRecord, tools::Long nGrafAnchorCp, SwFrameFormat *pRetFrameFormat)
Definition: ww8graf.cxx:2875
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:1232
bool GetTxbxTextSttEndCp(WW8_CP &rStartCp, WW8_CP &rEndCp, sal_uInt16 nTxBxS, sal_uInt16 nSequence)
Definition: ww8graf.cxx:799
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:65
SVL_DLLPUBLIC Link< OUString *, bool > const & GetMaybeFileHdl()
SwFormat * m_pFormat
Definition: ww8par.hxx:229
const Graphic & GetGraphic() const
SwFrameFormat * AddAutoAnchor(SwFrameFormat *pFormat)
Definition: ww8graf.cxx:2860
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:273
SdrObject * ReadRect(WW8_DPHEAD const *pHd, SfxAllItemSet &rSet)
Definition: ww8graf.cxx:344
FlyAnchors.
Definition: fmtanchr.hxx:34
void SetWidthSizeType(SwFrameSize eSize)
Definition: fmtfsize.hxx:84
SVBT16 xaOffset
Definition: ww8struc.hxx:731
OBJ_GRAF
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:3078
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
OBJ_PLIN
WW8_DP_SHADOW aShd
Definition: ww8struc.hxx:766
constexpr TypedWhichId< SdrMetricItem > SDRATTR_SHADOWYDIST(SDRATTR_SHADOW_FIRST+3)
void Restore(SwWW8ImplReader *pRdr)
Definition: ww8par.cxx:2044
constexpr tools::Long Top() const
mso_lineThinThick
size
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
Definition: format.cxx:388
virtual void SetLogicRect(const tools::Rectangle &rRect)
static Color WW8TransCol(SVBT32 nWC)
Definition: ww8graf.cxx:111
WW8_DP_SHADOW aShd
Definition: ww8struc.hxx:784
Marks a node in the document model.
Definition: ndindex.hxx:32
const sal_uInt16 LN_CObjLocation
Definition: sprmids.hxx:45
sal_uInt32 nLayoutInTableCell
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
void SetDistance(sal_uInt16 nNew, SvxBoxItemLine nLine)
::basegfx::B2DPolygon getB2DPolygon() const
sal_Int32 nDyTextTop
constexpr sal_uInt16 XATTR_END
void SetDocShell(SwDocShell *pDSh)
Definition: docnew.cxx:605
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:52
SwFltPosition m_aMkPos
Definition: fltshell.hxx:87
OUString GetName() const
#define Y
bool ReadGrafStart(void *pData, short nDataSiz, WW8_DPHEAD const *pHd, SfxAllItemSet &rSet)
Definition: ww8graf.cxx:172
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:954
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:450
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:1242
sal_uInt8 bx
Definition: ww8struc.hxx:685
WW8_DP_SHADOW aShd
Definition: ww8struc.hxx:794
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:1673
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:409
SvxBoxItemLine
iterator for Piece Table Exceptions of Fkps works on CPs (high-level)
Definition: ww8scan.hxx:633
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:593
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:3093
WW8_DP_TXTBOX dptxbx
Definition: ww8struc.hxx:831
SdrObject * ReadGrafPrimitive(short &rLeft, SfxAllItemSet &rSet)
Definition: ww8graf.cxx:1388
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:521
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:699
SVBT16 dya
Definition: ww8struc.hxx:717
SdrObject * ReadArc(WW8_DPHEAD const *pHd, SfxAllItemSet &rSet)
Definition: ww8graf.cxx:391
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:309
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)
constexpr sal_uInt16 EE_FEATURE_FIELD(EE_FEATURE_NOTCONV+1)
SdrObject * pObj
void ReadGrafLayer1(WW8PLCFspecial &rPF, tools::Long nGrafAnchorCp)
Definition: ww8graf.cxx:1445
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:2970
bool m_bColl
Definition: ww8par.hxx:251
const SwPosition & GetStartPos() const
Definition: ww8par.hxx:620
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_Int32 WW8_FC
Definition: ww8struc.hxx:152
SdrObject * ReadGroup(WW8_DPHEAD const *pHd, SfxAllItemSet &rSet)
Definition: ww8graf.cxx:1351
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)
OBJ_TEXT
constexpr TypedWhichId< XLineColorItem > XATTR_LINECOLOR(XATTR_LINE_FIRST+3)
mso_lineSimple
OBJ_OLE2
void AddAnchor(const SwPosition &rPos, SwFrameFormat *pFormat)
Definition: ww8graf.cxx:3225
static std::vector< sal_Int32 > replaceDosLineEndsButPreserveLength(OUString &rIn)
Definition: ww8graf.cxx:928
const sal_uInt8 * pMemPos
Definition: ww8scan.hxx:883
constexpr sal_uInt16 RES_FRMATR_BEGIN(RES_PARATR_LIST_END)
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:2773
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:1319
void SetAnchor(const SwPosition *pPos)
Definition: atrfrm.cxx:1584
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