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 
963 std::unique_ptr<OutlinerParaObject> SwWW8ImplReader::ImportAsOutliner(OUString &rString, WW8_CP nStartCp, WW8_CP nEndCp, ManTypes eType)
964 {
965  std::unique_ptr<OutlinerParaObject> pRet;
966 
967  sal_Int32 nLen = GetRangeAsDrawingString(rString, nStartCp, nEndCp, eType);
968  if (nLen > 0)
969  {
970  if (!m_pDrawEditEngine)
971  {
972  m_pDrawEditEngine.reset(new EditEngine(nullptr));
973  }
974 
975  //replace dos line endings with editeng ones, replace any extra chars with
976  //placeholders to keep the inserted string len in sync with the attribute cps
977  //and record in aDosLineEnds the superfluous positions
978  OUString sEEString(rString);
979  std::vector<sal_Int32> aDosLineEnds(replaceDosLineEndsButPreserveLength(sEEString));
980  m_pDrawEditEngine->SetText(sEEString);
981  InsertAttrsAsDrawingAttrs(nStartCp, nStartCp+nLen, eType);
982  //remove any superfluous placeholders of replaceDosLineEndsButPreserveLength
983  //after attributes have been inserted
984  removePositions(*m_pDrawEditEngine, aDosLineEnds);
985 
986  // Annotations typically begin with a (useless) 0x5
987  if ((eType == MAN_AND) && m_pDrawEditEngine->GetTextLen())
988  {
989  ESelection aFirstChar(0, 0, 0, 1);
990  if (m_pDrawEditEngine->GetText( aFirstChar ) == "\x05")
991  m_pDrawEditEngine->QuickDelete(aFirstChar);
992  }
993 
994  std::unique_ptr<EditTextObject> pTemporaryText = m_pDrawEditEngine->CreateTextObject();
995  pRet.reset( new OutlinerParaObject( std::move(pTemporaryText) ) );
996  pRet->SetOutlinerMode( OutlinerMode::TextObject );
997 
998  m_pDrawEditEngine->SetText( OUString() );
999  m_pDrawEditEngine->SetParaAttribs(0, m_pDrawEditEngine->GetEmptyItemSet());
1000 
1001  // Strip out fields, leaving the result
1002  WW8_CP nDummy(0);
1003  lcl_StripFields(rString, nDummy);
1004  // Strip out word's special characters for the simple string
1005  rString = rString.replaceAll("\x01", "");
1006  rString = rString.replaceAll("\x05", "");
1007  rString = rString.replaceAll("\x08", "");
1008  rString = rString.replaceAll("\007\007", "\007\012");
1009  rString = rString.replace(0x7, ' ');
1010  }
1011 
1012  return pRet;
1013 }
1014 
1015 // InsertTxbxText() adds the Text and the Attributes for TextBoxes and CaptionBoxes
1017  Size const * pObjSiz, sal_uInt16 nTxBxS, sal_uInt16 nSequence, tools::Long nPosCp,
1018  SwFrameFormat const * pOldFlyFormat, bool bMakeSdrGrafObj, bool& rbEraseTextObj,
1019  bool* pbTestTxbxContainsText, tools::Long* pnStartCp, tools::Long* pnEndCp,
1020  bool* pbContainsGraphics, SvxMSDffImportRec const * pRecord)
1021 {
1022  SwFrameFormat* pFlyFormat = nullptr;
1023  sal_uLong nOld = m_pStrm->Tell();
1024 
1025  ManTypes eType = m_xPlcxMan->GetManType() == MAN_HDFT ? MAN_TXBX_HDFT : MAN_TXBX;
1026 
1027  rbEraseTextObj = false;
1028 
1029  OUString aString;
1030  WW8_CP nStartCp, nEndCp;
1031  bool bContainsGraphics = false;
1032  bool bTextWasRead = GetTxbxTextSttEndCp(nStartCp, nEndCp, nTxBxS, nSequence) &&
1033  GetRangeAsDrawingString(aString, nStartCp, nEndCp, eType) > 0;
1034 
1035  if (!m_pDrawEditEngine)
1036  {
1037  m_pDrawEditEngine.reset(new EditEngine(nullptr));
1038  }
1039  if( pObjSiz )
1040  m_pDrawEditEngine->SetPaperSize( *pObjSiz );
1041 
1042  const OUString aOrigString(aString);
1043  if( bTextWasRead )
1044  {
1045  WW8_CP nNewStartCp = nStartCp;
1046  lcl_StripFields(aString, nNewStartCp);
1047 
1048  if (aString.getLength()!=1)
1049  {
1050  bContainsGraphics = aString.indexOf(0x1)<0 || aString.indexOf(0x8)<0;
1051  }
1052  else // May be a single graphic or object
1053  {
1054  bool bDone = true;
1055  switch( aString[0] )
1056  {
1057  case 0x1:
1058  if (!pbTestTxbxContainsText)
1059  {
1060  WW8ReaderSave aSave(this, nNewStartCp -1);
1061  bool bOldEmbeddObj = m_bEmbeddObj;
1062  // bEmbeddObj Ordinarily would have been set by field
1063  // parse, but this is impossible here so...
1064  m_bEmbeddObj = true;
1065 
1066  // 1st look for OLE- or Graph-Indicator Sprms
1067  WW8PLCFx_Cp_FKP* pChp = m_xPlcxMan->GetChpPLCF();
1068  WW8PLCFxDesc aDesc;
1069  pChp->GetSprms( &aDesc );
1070  WW8SprmIter aSprmIter(aDesc.pMemPos, aDesc.nSprmsLen, *m_xSprmParser);
1071 
1072  for( int nLoop = 0; nLoop < 2; ++nLoop )
1073  {
1074  while (aSprmIter.GetSprms())
1075  {
1076  const sal_uInt8 *const pParams(aSprmIter.GetCurrentParams());
1077  if (nullptr == pParams)
1078  break;
1079  sal_uInt16 nCurrentId = aSprmIter.GetCurrentId();
1080  switch( nCurrentId )
1081  {
1082  case 75:
1083  case 118:
1084  case 0x080A:
1085  case 0x0856:
1086  Read_Obj(nCurrentId, pParams, 1);
1087  break;
1088  case 68: // Read_Pic()
1089  case 0x6A03:
1091  Read_PicLoc(nCurrentId, pParams, 1);
1092  break;
1093  }
1094  aSprmIter.advance();
1095  }
1096 
1097  if( !nLoop )
1098  {
1099  pChp->GetPCDSprms( aDesc );
1100  aSprmIter.SetSprms( aDesc.pMemPos,
1101  aDesc.nSprmsLen );
1102  }
1103  }
1104  aSave.Restore(this);
1105  m_bEmbeddObj=bOldEmbeddObj;
1106 
1107  // then import either an OLE of a Graphic
1108  if( m_bObj )
1109  {
1110  if( bMakeSdrGrafObj && pTextObj &&
1111  pTextObj->getParentSdrObjectFromSdrObject() )
1112  {
1113  // use SdrOleObj/SdrGrafObj instead of
1114  // SdrTextObj in this Group
1115 
1116  Graphic aGraph;
1117  SdrObject* pNew = ImportOleBase(aGraph);
1118 
1119  if( !pNew )
1120  {
1121  pNew = new SdrGrafObj(*m_pDrawModel);
1122  static_cast<SdrGrafObj*>(pNew)->SetGraphic(aGraph);
1123  }
1124 
1125  GraphicCtor();
1126 
1127  pNew->SetLogicRect( pTextObj->GetCurrentBoundRect() );
1128  pNew->SetLayer( pTextObj->GetLayer() );
1129 
1131  ReplaceObject(pNew, pTextObj->GetOrdNum());
1132  }
1133  else
1134  pFlyFormat = ImportOle();
1135  m_bObj = false;
1136  }
1137  else
1138  {
1139  InsertAttrsAsDrawingAttrs(nNewStartCp, nNewStartCp+1,
1140  eType, true);
1141  pFlyFormat = ImportGraf(bMakeSdrGrafObj ? pTextObj : nullptr,
1142  pOldFlyFormat);
1143  }
1144  }
1145  break;
1146  case 0x8:
1147  if ( (!pbTestTxbxContainsText) && (!m_bObj) )
1148  pFlyFormat = Read_GrafLayer( nPosCp );
1149  break;
1150  default:
1151  bDone = false;
1152  break;
1153  }
1154 
1155  if( bDone )
1156  {
1157  if( pFlyFormat && pRecord )
1158  {
1159  SfxItemSet aFlySet( m_rDoc.GetAttrPool(),
1161 
1162  tools::Rectangle aInnerDist( pRecord->nDxTextLeft,
1163  pRecord->nDyTextTop,
1164  pRecord->nDxTextRight,
1165  pRecord->nDyTextBottom );
1166  MatchSdrItemsIntoFlySet( pTextObj,
1167  aFlySet,
1168  pRecord->eLineStyle,
1169  pRecord->eLineDashing,
1170  pRecord->eShapeType,
1171  aInnerDist );
1172 
1173  pFlyFormat->SetFormatAttr( aFlySet );
1174 
1175  MapWrapIntoFlyFormat(*pRecord, *pFlyFormat);
1176  }
1177  aString.clear();
1178  rbEraseTextObj = (nullptr != pFlyFormat);
1179  }
1180  }
1181  }
1182 
1183  if( pnStartCp )
1184  *pnStartCp = nStartCp;
1185  if( pnEndCp )
1186  *pnEndCp = nEndCp;
1187 
1188  if( pbTestTxbxContainsText )
1189  *pbTestTxbxContainsText = bTextWasRead && ! rbEraseTextObj;
1190  else if( !rbEraseTextObj )
1191  {
1192  if( bTextWasRead )
1193  {
1194  m_pDrawEditEngine->SetText(aOrigString);
1195  InsertAttrsAsDrawingAttrs(nStartCp, nEndCp, eType);
1196  }
1197 
1198  bool bVertical = pTextObj->IsVerticalWriting();
1199  std::unique_ptr<OutlinerParaObject> pOp(new OutlinerParaObject(m_pDrawEditEngine->CreateTextObject()));
1200  pOp->SetOutlinerMode( OutlinerMode::TextObject );
1201  pOp->SetVertical( bVertical );
1202  pTextObj->NbcSetOutlinerParaObject( std::move(pOp) );
1203  pTextObj->SetVerticalWriting(bVertical);
1204 
1205  // For the next TextBox also remove the old paragraph attributes
1206  // and styles, otherwise the next box will start with the wrong
1207  // attributes.
1208  // Course of action: delete text = reduce to one paragraph
1209  // and on this one delete the paragraph attributes
1210  // and styles
1211  m_pDrawEditEngine->SetText( OUString() );
1212  m_pDrawEditEngine->SetParaAttribs(0, m_pDrawEditEngine->GetEmptyItemSet());
1213  }
1214 
1215  m_pStrm->Seek( nOld );
1216  if (pbContainsGraphics)
1217  *pbContainsGraphics = bContainsGraphics;
1218 }
1219 
1221  tools::Long& rEndCp)
1222 {
1223  bool bErase, bContainsText;
1224  InsertTxbxText( nullptr,nullptr,nTxBxS,USHRT_MAX,0,nullptr,false, bErase, &bContainsText,
1225  &rStartCp, &rEndCp );
1226  return bContainsText;
1227 }
1228 
1229 // TextBoxes only for Ver67 !!
1231 {
1232  bool bDummy;
1233  WW8_DP_TXTBOX aTextB;
1234 
1235  if( !ReadGrafStart( static_cast<void*>(&aTextB), sizeof( aTextB ), pHd, rSet ) )
1236  return nullptr;
1237 
1238  Point aP0( static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa )) + m_nDrawXOfs2,
1239  static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya )) + m_nDrawYOfs2 );
1240  Point aP1( aP0 );
1241  aP1.AdjustX(static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dxa )) );
1242  aP1.AdjustY(static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dya )) );
1243 
1244  SdrRectObj* pObj = new SdrRectObj(
1245  *m_pDrawModel,
1246  OBJ_TEXT,
1247  tools::Rectangle(aP0, aP1));
1248 
1249  pObj->NbcSetSnapRect(tools::Rectangle(aP0, aP1));
1250  Size aSize( static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dxa )) ,
1251  static_cast<sal_Int16>(SVBT16ToUInt16( pHd->dya )) );
1252 
1253  tools::Long nStartCpFly,nEndCpFly;
1254  bool bContainsGraphics;
1255  InsertTxbxText(pObj, &aSize, 0, 0, 0, nullptr, false,
1256  bDummy,nullptr,&nStartCpFly,&nEndCpFly,&bContainsGraphics);
1257 
1258  SetStdAttr( rSet, aTextB.aLnt, aTextB.aShd );
1259  SetFill( rSet, aTextB.aFill );
1260 
1261  rSet.Put( SdrTextFitToSizeTypeItem( drawing::TextFitToSizeType_NONE ) );
1262  rSet.Put( makeSdrTextAutoGrowWidthItem(false));
1263  rSet.Put( makeSdrTextAutoGrowHeightItem(false));
1268 
1269  return pObj;
1270 }
1271 
1273 {
1274  static const SdrCaptionType aCaptA[] = { SdrCaptionType::Type1, SdrCaptionType::Type2,
1275  SdrCaptionType::Type3, SdrCaptionType::Type4 };
1276 
1277  WW8_DP_CALLOUT_TXTBOX aCallB;
1278 
1279  if( !ReadGrafStart( static_cast<void*>(&aCallB), sizeof( aCallB ), pHd, rSet ) )
1280  return nullptr;
1281 
1282  sal_uInt16 nCount = SVBT16ToUInt16( aCallB.dpPolyLine.aBits1 ) >> 1 & 0x7fff;
1283  if (nCount < 1)
1284  {
1285  SAL_WARN("sw.ww8", "Short CaptionBox header");
1286  return nullptr;
1287  }
1288 
1289  std::unique_ptr<SVBT16[]> xP(new SVBT16[nCount * 2]);
1290 
1291  bool bCouldRead = checkRead(*m_pStrm, xP.get(), nCount * 4); // read points
1292  if (!bCouldRead)
1293  {
1294  SAL_WARN("sw.ww8", "Short CaptionBox header");
1295  return nullptr;
1296  }
1297 
1298  sal_uInt8 nTyp = static_cast<sal_uInt8>(nCount) - 1;
1299  if( nTyp == 1 && SVBT16ToUInt16( xP[0] ) == SVBT16ToUInt16( xP[2] ) )
1300  nTyp = 0;
1301 
1302  Point aP0( static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa )) +
1303  static_cast<sal_Int16>(SVBT16ToUInt16( aCallB.dpheadTxbx.xa )) + m_nDrawXOfs2,
1304  static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya ))
1305  + static_cast<sal_Int16>(SVBT16ToUInt16( aCallB.dpheadTxbx.ya )) + m_nDrawYOfs2 );
1306  Point aP1( aP0 );
1307  aP1.AdjustX(static_cast<sal_Int16>(SVBT16ToUInt16( aCallB.dpheadTxbx.dxa )) );
1308  aP1.AdjustY(static_cast<sal_Int16>(SVBT16ToUInt16( aCallB.dpheadTxbx.dya )) );
1309  Point aP2( static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa ))
1310  + static_cast<sal_Int16>(SVBT16ToUInt16( aCallB.dpheadPolyLine.xa ))
1311  + m_nDrawXOfs2 + static_cast<sal_Int16>(SVBT16ToUInt16( xP[0] )),
1312  static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya ))
1313  + static_cast<sal_Int16>(SVBT16ToUInt16( aCallB.dpheadPolyLine.ya ))
1314  + m_nDrawYOfs2 + static_cast<sal_Int16>(SVBT16ToUInt16( xP[1] )) );
1315  xP.reset();
1316 
1317  SdrCaptionObj* pObj = new SdrCaptionObj(
1318  *m_pDrawModel,
1319  tools::Rectangle(aP0, aP1),
1320  aP2);
1321 
1322  pObj->NbcSetSnapRect(tools::Rectangle(aP0, aP1));
1323  Size aSize( static_cast<sal_Int16>(SVBT16ToUInt16( aCallB.dpheadTxbx.dxa )),
1324  static_cast<sal_Int16>(SVBT16ToUInt16( aCallB.dpheadTxbx.dya )) );
1325  bool bEraseThisObject;
1326 
1327  InsertTxbxText(pObj, &aSize, 0, 0, 0, nullptr, false, bEraseThisObject );
1328 
1329  if( SVBT16ToUInt16( aCallB.dptxbx.aLnt.lnps ) != 5 ) // Is border visible ?
1330  SetStdAttr( rSet, aCallB.dptxbx.aLnt, aCallB.dptxbx.aShd );
1331  else // no -> take lines
1332  SetStdAttr( rSet, aCallB.dpPolyLine.aLnt, aCallB.dptxbx.aShd );
1333  SetFill( rSet, aCallB.dptxbx.aFill );
1334  rSet.Put(SdrCaptionTypeItem(aCaptA[nTyp % SAL_N_ELEMENTS(aCaptA)]));
1335 
1336  return pObj;
1337 }
1338 
1340 {
1341  sal_Int16 nGrouped;
1342 
1343  if( !ReadGrafStart( static_cast<void*>(&nGrouped), sizeof( nGrouped ), pHd, rSet ) )
1344  return nullptr;
1345 
1346 #ifdef OSL_BIGENDIAN
1347  nGrouped = (sal_Int16)OSL_SWAPWORD( nGrouped );
1348 #endif
1349 
1350  m_nDrawXOfs = m_nDrawXOfs + static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa ));
1351  m_nDrawYOfs = m_nDrawYOfs + static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya ));
1352 
1353  SdrObject* pObj = new SdrObjGroup(*m_pDrawModel);
1354 
1355  short nLeft = static_cast<sal_Int16>(SVBT16ToUInt16( pHd->cb )) - sizeof( WW8_DPHEAD );
1356  for (int i = 0; i < nGrouped && nLeft >= static_cast<short>(sizeof(WW8_DPHEAD)); ++i)
1357  {
1358  SfxAllItemSet aSet(m_pDrawModel->GetItemPool());
1359  if (SdrObject *pObject = ReadGrafPrimitive(nLeft, aSet))
1360  {
1361  // first add and then set ItemSet
1362  SdrObjList *pSubGroup = pObj->GetSubList();
1363  OSL_ENSURE(pSubGroup, "Why no sublist available?");
1364  if (pSubGroup)
1365  pSubGroup->InsertObject(pObject, 0);
1366  pObject->SetMergedItemSetAndBroadcast(aSet);
1367  }
1368  }
1369 
1370  m_nDrawXOfs = m_nDrawXOfs - static_cast<sal_Int16>(SVBT16ToUInt16( pHd->xa ));
1371  m_nDrawYOfs = m_nDrawYOfs - static_cast<sal_Int16>(SVBT16ToUInt16( pHd->ya ));
1372 
1373  return pObj;
1374 }
1375 
1377 {
1378  // This whole archaic word 6 graphic import can probably be refactored
1379  // into an object hierarchy with a little effort.
1380  SdrObject *pRet=nullptr;
1381  WW8_DPHEAD aHd; // Read Draw-Primitive-Header
1382  bool bCouldRead = checkRead(*m_pStrm, &aHd, sizeof(WW8_DPHEAD)) &&
1383  SVBT16ToUInt16(aHd.cb) >= sizeof(WW8_DPHEAD);
1384  OSL_ENSURE(bCouldRead, "Graphic Primitive header short read" );
1385  if (!bCouldRead)
1386  {
1387  rLeft=0;
1388  return pRet;
1389  }
1390 
1391  if( rLeft >= SVBT16ToUInt16(aHd.cb) ) // precautions
1392  {
1393  rSet.Put(SwFormatSurround(css::text::WrapTextMode_THROUGH));
1394  switch (SVBT16ToUInt16(aHd.dpk) & 0xff )
1395  {
1396  case 0:
1397  pRet = ReadGroup(&aHd, rSet);
1398  break;
1399  case 1:
1400  pRet = ReadLine(&aHd, rSet);
1401  break;
1402  case 2:
1403  pRet = ReadTextBox(&aHd, rSet);
1404  break;
1405  case 3:
1406  pRet = ReadRect(&aHd, rSet);
1407  break;
1408  case 4:
1409  pRet = ReadEllipse(&aHd, rSet);
1410  break;
1411  case 5:
1412  pRet = ReadArc(&aHd, rSet);
1413  break;
1414  case 6:
1415  pRet = ReadPolyLine(&aHd, rSet);
1416  break;
1417  case 7:
1418  pRet = ReadCaptionBox(&aHd, rSet);
1419  break;
1420  default: // unknown
1421  m_pStrm->SeekRel(SVBT16ToUInt16(aHd.cb) - sizeof(WW8_DPHEAD));
1422  break;
1423  }
1424  }
1425  else
1426  {
1427  OSL_ENSURE( false, "+Grafik-Overlap" );
1428  }
1429  rLeft = rLeft - SVBT16ToUInt16( aHd.cb );
1430  return pRet;
1431 }
1432 
1434 {
1435  rPF.SeekPos(nGrafAnchorCp);
1436  WW8_FC nStartFc;
1437  void* pF0;
1438  if (!rPF.Get(nStartFc, pF0))
1439  {
1440  OSL_ENSURE( false, "+Where is the graphic (2) ?" );
1441  return;
1442  }
1443  WW8_FDOA* pF = static_cast<WW8_FDOA*>(pF0);
1444  if( !SVBT32ToUInt32( pF->fc ) )
1445  {
1446  OSL_ENSURE( false, "+Where is the graphic (3) ?" );
1447  return;
1448  }
1449 
1450  sal_uInt32 nPosFc = SVBT32ToUInt32(pF->fc);
1451 
1452  //skip duplicate graphics when fuzzing
1453  if (m_bFuzzing)
1454  {
1455  if (!m_aGrafPosSet.insert(nPosFc).second)
1456  return;
1457  }
1458 
1459  bool bCouldSeek = checkSeek(*m_pStrm, nPosFc);
1460  OSL_ENSURE(bCouldSeek, "Invalid graphic offset");
1461  if (!bCouldSeek)
1462  return;
1463 
1464  // read Draw-Header
1465  WW8_DO aDo;
1466  bool bCouldRead = checkRead(*m_pStrm, &aDo, sizeof(WW8_DO));
1467  OSL_ENSURE(bCouldRead, "Short graphic header");
1468  if (!bCouldRead)
1469  return;
1470 
1471  short nLeft = SVBT16ToUInt16( aDo.cb ) - sizeof( WW8_DO );
1472  while (nLeft > static_cast<short>(sizeof(WW8_DPHEAD)))
1473  {
1474  SfxAllItemSet aSet( m_pDrawModel->GetItemPool() );
1475  if (SdrObject *pObject = ReadGrafPrimitive(nLeft, aSet))
1476  {
1477  m_xWWZOrder->InsertDrawingObject(pObject, SVBT16ToUInt16(aDo.dhgt));
1478 
1479  tools::Rectangle aRect(pObject->GetSnapRect());
1480 
1481  const sal_uInt32 nCntRelTo = 3;
1482 
1483  // Adjustment is horizontally relative to...
1484  static const sal_Int16 aHoriRelOriTab[nCntRelTo] =
1485  {
1486  text::RelOrientation::PAGE_PRINT_AREA, // 0 is page textarea margin
1487  text::RelOrientation::PAGE_FRAME, // 1 is page margin
1488  text::RelOrientation::FRAME, // 2 is relative to paragraph
1489  };
1490 
1491  // Adjustment is vertically relative to...
1492  static const sal_Int16 aVertRelOriTab[nCntRelTo] =
1493  {
1494  text::RelOrientation::PAGE_PRINT_AREA, // 0 is page textarea margin
1495  text::RelOrientation::PAGE_FRAME, // 1 is page margin
1496  text::RelOrientation::FRAME, // 2 is relative to paragraph
1497  };
1498 
1499  const int nXAlign = aDo.bx < nCntRelTo ? aDo.bx : 0;
1500  const int nYAlign = aDo.by < nCntRelTo ? aDo.by : 0;
1501 
1502  aSet.Put(SwFormatHoriOrient(aRect.Left(), text::HoriOrientation::NONE,
1503  aHoriRelOriTab[ nXAlign ]));
1504  aSet.Put(SwFormatVertOrient(aRect.Top(), text::VertOrientation::NONE,
1505  aVertRelOriTab[ nYAlign ]));
1506 
1508  pObject->SetMergedItemSet(aSet);
1509 
1510  if (SwDrawFrameFormat *pDrawFrame = dynamic_cast<SwDrawFrameFormat*>(pFrame))
1511  {
1512  pDrawFrame->PosAttrSet();
1513  }
1514 
1515  AddAutoAnchor(pFrame);
1516  }
1517  }
1518 }
1519 
1521  MSO_SPT eShapeType, sal_Int32 &rThick)
1522 {
1523  sal_Int32 nOutsideThick = 0;
1524  /*
1525  Note: In contrast to the regular WinWord table and frame border width,
1526  where the overall border width has to be calculated from the width of *one*
1527  line, the data from ESCHER already contains the overall width [twips]!
1528 
1529  The WinWord default is 15 tw. We take for this our 20 tw line.
1530  (0.75 pt and 1.0 pt looking more similar on hardcopy than 0.75 pt and our
1531  0.05 pt hairline.) The hairline we only set by WinWord width up to max.
1532  0.5 pt.
1533  */
1534  switch( eStyle )
1535  {
1536  case mso_lineTriple:
1537  case mso_lineSimple:
1538  nOutsideThick = eShapeType != mso_sptTextBox ? rThick : rThick/2;
1539  break;
1540  case mso_lineDouble:
1541  if (eShapeType == mso_sptTextBox)
1542  {
1543  nOutsideThick = rThick/6;
1544  rThick = rThick*2/3;
1545  }
1546  else
1547  nOutsideThick = rThick*2/3;
1548  break;
1549  case mso_lineThickThin:
1550  if (eShapeType == mso_sptTextBox)
1551  {
1552  nOutsideThick = rThick*3/10;
1553  rThick = rThick*4/5;
1554  }
1555  else
1556  nOutsideThick = rThick*4/5;
1557  break;
1558  case mso_lineThinThick:
1559  {
1560  if (eShapeType == mso_sptTextBox)
1561  {
1562  nOutsideThick = rThick/10;
1563  rThick = rThick*3/5;
1564  }
1565  else
1566  nOutsideThick = rThick*3/5;
1567  }
1568  break;
1569  default:
1570  break;
1571  }
1572  return nOutsideThick;
1573 }
1574 
1575 // Returns the thickness of the line outside the frame, the logic of
1576 // words positioning of borders around floating objects is that of a
1577 // disturbed mind.
1579  MSO_LineStyle eLineStyle, MSO_LineDashing eDashing, MSO_SPT eShapeType, sal_Int32 &rLineThick,
1580  SvxBoxItem& rBox )
1581 {
1582  sal_Int32 nOutsideThick = 0;
1583  if( !rLineThick )
1584  return nOutsideThick;
1585 
1586  SvxBorderLineStyle nIdx = SvxBorderLineStyle::NONE;
1587 
1588  sal_Int32 nLineThick=rLineThick;
1589  nOutsideThick = SwMSDffManager::GetEscherLineMatch(eLineStyle,
1590  eShapeType, rLineThick);
1591 
1592  /*
1593  Note: In contrast to the regular WinWord table and frame border width,
1594  where the overall border width has to be calculated from the width of *one*
1595  line, the data from ESCHER already contains the overall width [twips]!
1596 
1597  The WinWord default is 15 tw. We take for this our 20 tw line.
1598  (0.75 pt and 1.0 pt looking more similar on hardcopy than 0.75 pt and our
1599  0.05 pt hairline.) The hairline we only set by WinWord width up to max.
1600  0.5 pt.
1601  */
1602  switch( +eLineStyle )
1603  {
1604  // first the single lines
1605  case mso_lineSimple:
1606  nIdx = SvxBorderLineStyle::SOLID;
1607  break;
1608  // second the double lines
1609  case mso_lineDouble:
1610  nIdx = SvxBorderLineStyle::DOUBLE;
1611  break;
1612  case mso_lineThickThin:
1613  nIdx = SvxBorderLineStyle::THICKTHIN_SMALLGAP;
1614  break;
1615  case mso_lineThinThick:
1616  nIdx = SvxBorderLineStyle::THINTHICK_SMALLGAP;
1617  break;
1618  // We have no triple border, use double instead.
1619  case mso_lineTriple:
1620  nIdx = SvxBorderLineStyle::DOUBLE;
1621  break;
1622  // no line style is set
1623  case MSO_LineStyle(USHRT_MAX):
1624  break;
1625  // erroneously not implemented line style is set
1626  default:
1627  OSL_ENSURE(false, "eLineStyle is not (yet) implemented!");
1628  break;
1629  }
1630 
1631  switch( eDashing )
1632  {
1633  case mso_lineDashGEL:
1634  nIdx = SvxBorderLineStyle::DASHED;
1635  break;
1636  case mso_lineDotGEL:
1637  nIdx = SvxBorderLineStyle::DOTTED;
1638  break;
1639  default:
1640  break;
1641  }
1642 
1643  if (SvxBorderLineStyle::NONE != nIdx)
1644  {
1645  SvxBorderLine aLine;
1646  aLine.SetColor( rLineColor );
1647 
1648  aLine.SetWidth( nLineThick ); // No conversion here, nLineThick is already in twips
1649  aLine.SetBorderLineStyle(nIdx);
1650 
1652  {
1653  // aLine is cloned by SetLine
1654  rBox.SetLine(&aLine, nLine);
1655  }
1656  }
1657 
1658  return nOutsideThick;
1659 }
1660 
1661 #define WW8ITEMVALUE(ItemSet,Id,Cast) ItemSet.GetItem<Cast>(Id)->GetValue()
1662 
1664  SfxItemSet& rFlySet, MSO_LineStyle eLineStyle, MSO_LineDashing eDashing, MSO_SPT eShapeType,
1665  tools::Rectangle& rInnerDist )
1666 {
1667  /*
1668  attributes to be set on the frame
1669  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1670  SwFormatFrameSize if not set, set here
1671  SvxLRSpaceItem set here
1672  SvxULSpaceItem set here
1673  SvxOpaqueItem (Currently not possible for frames! khz 10.2.1999)
1674  SwFormatSurround already set
1675  SwFormatVertOrient already set
1676  SwFormatHoriOrient already set
1677  SwFormatAnchor already set
1678  SvxBoxItem set here
1679  SvxBrushItem set here
1680  SvxShadowItem set here
1681  */
1682 
1683  // 1. GraphicObject of documents?
1684  GraphicCtor();
1685 
1686  const SfxItemSet& rOldSet = pSdrObj->GetMergedItemSet();
1687 
1688  // some Items can be taken over directly
1689  static sal_uInt16 const aDirectMatch[]
1690  {
1691  RES_LR_SPACE, // outer spacing left/right: SvxLRSpaceItem
1692  RES_UL_SPACE // outer spacing top/bottom: SvxULSpaceItem
1693  };
1694  const SfxPoolItem* pPoolItem;
1695  for(sal_uInt16 i : aDirectMatch)
1696  if( SfxItemState::SET == rOldSet.GetItemState(i, false, &pPoolItem) )
1697  {
1698  rFlySet.Put( *pPoolItem );
1699  }
1700 
1701  // take new XATTR items directly. Skip old RES_BACKGROUND if new FILLSTYLE taken.
1702  bool bSkipResBackground = false;
1703  SfxItemPool* pPool = rFlySet.GetPool();
1704  if ( pPool )
1705  {
1706  for ( sal_uInt16 i = XATTR_START; i < XATTR_END; ++i )
1707  {
1708  // Not all Fly types support XATTRs - skip unsupported attributes
1709  SfxItemPool* pAttrPool = pPool->GetMasterPool();
1710  while ( pAttrPool && !pAttrPool->IsInRange(i) )
1711  pAttrPool = pAttrPool->GetSecondaryPool();
1712  if ( !pAttrPool )
1713  continue;
1714 
1715  if ( SfxItemState::SET == rOldSet.GetItemState(i, false, &pPoolItem) )
1716  {
1717  rFlySet.Put( *pPoolItem );
1718  if ( i == XATTR_FILLSTYLE )
1719  {
1720  const drawing::FillStyle eFill = static_cast<const XFillStyleItem*>(pPoolItem)->GetValue();
1721  // Transparency forced in certain situations when fillstyle is none - use old logic for that case still
1722  // which is especially needed for export purposes (tdf112618).
1723  if ( eFill != drawing::FillStyle_NONE )
1724  bSkipResBackground = true;
1725  }
1726  }
1727  }
1728  }
1729 
1730  // now calculate the borders and build the box: The unit is needed for the
1731  // frame SIZE!
1732  SvxBoxItem aBox(sw::util::ItemGet<SvxBoxItem>(rFlySet, RES_BOX));
1733  // dashed or solid becomes solid
1734  // WW-default: 0.75 pt = 15 twips
1735  sal_Int32 nLineThick = 15, nOutside=0;
1736 
1737  // check if LineStyle is *really* set!
1738  const SfxPoolItem* pItem;
1739 
1740  SfxItemState eState = rOldSet.GetItemState(XATTR_LINESTYLE,true,&pItem);
1741  if( eState == SfxItemState::SET )
1742  {
1743  // Now, that we know there is a line style we will make use the
1744  // parameter given to us when calling the method... :-)
1745  const Color aLineColor = rOldSet.Get(XATTR_LINECOLOR).GetColorValue();
1746  nLineThick = WW8ITEMVALUE(rOldSet, XATTR_LINEWIDTH, XLineWidthItem);
1747 
1748  if( !nLineThick )
1749  nLineThick = 1; // for Writer, zero is "no border", so set a minimal value
1750 
1751  nOutside = MatchSdrBoxIntoFlyBoxItem(aLineColor, eLineStyle,
1752  eDashing, eShapeType, nLineThick, aBox);
1753  }
1754 
1755  rInnerDist.AdjustLeft(nLineThick );
1756  rInnerDist.AdjustTop(nLineThick );
1757  rInnerDist.AdjustRight(nLineThick );
1758  rInnerDist.AdjustBottom(nLineThick );
1759 
1760  rInnerDist.AdjustLeft( -(aBox.CalcLineWidth( SvxBoxItemLine::LEFT )) );
1761  rInnerDist.AdjustTop( -(aBox.CalcLineWidth( SvxBoxItemLine::TOP )) );
1762  rInnerDist.AdjustRight( -(aBox.CalcLineWidth( SvxBoxItemLine::RIGHT )) );
1763  rInnerDist.AdjustBottom( -(aBox.CalcLineWidth( SvxBoxItemLine::BOTTOM )) );
1764 
1765  // set distances from box's border to text contained within the box
1766  if( 0 < rInnerDist.Left() )
1767  aBox.SetDistance( o3tl::narrowing<sal_uInt16>(rInnerDist.Left()), SvxBoxItemLine::LEFT );
1768  if( 0 < rInnerDist.Top() )
1769  aBox.SetDistance( o3tl::narrowing<sal_uInt16>(rInnerDist.Top()), SvxBoxItemLine::TOP );
1770  if( 0 < rInnerDist.Right() )
1771  aBox.SetDistance( o3tl::narrowing<sal_uInt16>(rInnerDist.Right()), SvxBoxItemLine::RIGHT );
1772  if( 0 < rInnerDist.Bottom() )
1773  aBox.SetDistance( o3tl::narrowing<sal_uInt16>(rInnerDist.Bottom()), SvxBoxItemLine::BOTTOM );
1774 
1775  bool bFixSize = !(WW8ITEMVALUE(rOldSet, SDRATTR_TEXT_AUTOGROWHEIGHT,
1776  SdrOnOffItem));
1777 
1778  // Size: SwFormatFrameSize
1779  if( SfxItemState::SET != rFlySet.GetItemState(RES_FRM_SIZE, false) )
1780  {
1781  const tools::Rectangle& rSnapRect = pSdrObj->GetSnapRect();
1782  // if necessary adapt width and position of the framework: The
1783  // recorded interior is to remain equally large despite thick edges.
1785  rSnapRect.GetWidth() + 2*nOutside,
1786  rSnapRect.GetHeight() + 2*nOutside) );
1787  }
1788  else // If a size is set, adjust it to consider border thickness
1789  {
1790  SwFormatFrameSize aSize = rFlySet.Get(RES_FRM_SIZE);
1791 
1793  aSize.GetWidth() + 2*nOutside,
1794  aSize.GetHeight() + 2*nOutside);
1795  aNewSize.SetWidthSizeType(aSize.GetWidthSizeType());
1796  rFlySet.Put( aNewSize );
1797  }
1798 
1799  // Sadly word puts escher borders outside the graphic, but orients the
1800  // graphic in relation to the top left inside the border. We don't
1801  if (nOutside)
1802  {
1803  SwFormatHoriOrient aHori = rFlySet.Get(RES_HORI_ORIENT);
1804  aHori.SetPos(MakeSafePositioningValue(aHori.GetPos()-nOutside));
1805  rFlySet.Put(aHori);
1806 
1807  SwFormatVertOrient aVert = rFlySet.Get(RES_VERT_ORIENT);
1808  aVert.SetPos(aVert.GetPos()-nOutside);
1809  rFlySet.Put(aVert);
1810  }
1811 
1812  // now set the border
1813  rFlySet.Put( aBox );
1814 
1815  // shadow of the box: SvxShadowItem
1816  if( WW8ITEMVALUE(rOldSet, SDRATTR_SHADOW, SdrOnOffItem) )
1817  {
1818  SvxShadowItem aShadow( RES_SHADOW );
1819 
1820  const Color aShdColor = rOldSet.Get(SDRATTR_SHADOWCOLOR).GetColorValue();
1821  const sal_Int32 nShdDistX = WW8ITEMVALUE(rOldSet, SDRATTR_SHADOWXDIST,
1822  SdrMetricItem);
1823  const sal_Int32 nShdDistY = WW8ITEMVALUE(rOldSet, SDRATTR_SHADOWYDIST,
1824  SdrMetricItem);
1825 
1826  aShadow.SetColor( aShdColor );
1827 
1828  aShadow.SetWidth(writer_cast<sal_uInt16>((std::abs( nShdDistX) +
1829  std::abs( nShdDistY )) / 2 ));
1830 
1831  SvxShadowLocation eShdPosi;
1832  if( 0 <= nShdDistX )
1833  {
1834  if( 0 <= nShdDistY )
1835  eShdPosi = SvxShadowLocation::BottomRight;
1836  else
1837  eShdPosi = SvxShadowLocation::TopRight;
1838  }
1839  else
1840  {
1841  if( 0 <= nShdDistY )
1842  eShdPosi = SvxShadowLocation::BottomLeft;
1843  else
1844  eShdPosi = SvxShadowLocation::TopLeft;
1845  }
1846  aShadow.SetLocation( eShdPosi );
1847 
1848  rFlySet.Put( aShadow );
1849  }
1850  SvxBrushItem aBrushItem(COL_WHITE, RES_BACKGROUND);
1851  bool bBrushItemOk = false;
1852  sal_uInt8 nTrans = 0;
1853 
1854  // Separate transparency
1855  eState = rOldSet.GetItemState(XATTR_FILLTRANSPARENCE, true, &pItem);
1856  if (!bSkipResBackground && eState == SfxItemState::SET)
1857  {
1858  sal_uInt16 nRes = WW8ITEMVALUE(rOldSet, XATTR_FILLTRANSPARENCE,
1860  nTrans = sal_uInt8((nRes * 0xFE) / 100);
1861  aBrushItem.GetColor().SetAlpha(255 - nTrans);
1862  bBrushItemOk = true;
1863  }
1864 
1865  // Background: SvxBrushItem
1866  eState = rOldSet.GetItemState(XATTR_FILLSTYLE, true, &pItem);
1867  if (!bSkipResBackground && eState == SfxItemState::SET)
1868  {
1869  const drawing::FillStyle eFill = static_cast<const XFillStyleItem*>(pItem)->GetValue();
1870 
1871  switch (eFill)
1872  {
1873  default:
1874  case drawing::FillStyle_NONE:
1875  // Writer graphics don't have it yet
1876  if (eShapeType != mso_sptPictureFrame)
1877  {
1878  aBrushItem.GetColor().SetAlpha(1);
1879  bBrushItemOk = true;
1880  }
1881  break;
1882  case drawing::FillStyle_SOLID:
1883  case drawing::FillStyle_GRADIENT:
1884  {
1885  const Color aColor =
1886  rOldSet.Get(XATTR_FILLCOLOR).GetColorValue();
1887  aBrushItem.SetColor(aColor);
1888 
1889  if (bBrushItemOk) // has trans
1890  aBrushItem.GetColor().SetAlpha(255 - nTrans);
1891 
1892  bBrushItemOk = true;
1893  }
1894  break;
1895  case drawing::FillStyle_HATCH:
1896  break;
1897  case drawing::FillStyle_BITMAP:
1898  {
1899  GraphicObject aGrfObj(rOldSet.Get(XATTR_FILLBITMAP).GetGraphicObject());
1900  const bool bTile(WW8ITEMVALUE(rOldSet, XATTR_FILLBMP_TILE, SfxBoolItem));
1901 
1902  if(bBrushItemOk) // has trans
1903  {
1904  GraphicAttr aAttr(aGrfObj.GetAttr());
1905 
1906  aAttr.SetAlpha(255 - nTrans);
1907  aGrfObj.SetAttr(aAttr);
1908  }
1909 
1910  aBrushItem.SetGraphicObject(aGrfObj);
1911  aBrushItem.SetGraphicPos(bTile ? GPOS_TILED : GPOS_AREA);
1912  bBrushItemOk = true;
1913  }
1914  break;
1915  }
1916  }
1917 
1918  if (bBrushItemOk)
1919  rFlySet.Put(aBrushItem);
1920 }
1921 
1923  const SvxMSDffImportRec &rRecord, SvxLRSpaceItem &rLR)
1924 {
1925  sal_uInt32 nXRelTo = SvxMSDffImportRec::RELTO_DEFAULT;
1926  if ( rRecord.nXRelTo )
1927  {
1928  nXRelTo = *rRecord.nXRelTo;
1929  }
1930 
1931  // Left adjustments - if horizontally aligned to left of
1932  // margin or column then remove the left wrapping
1933  if (rRecord.nXAlign == 1)
1934  {
1935  if ((nXRelTo == 0) || (nXRelTo == 2))
1936  rLR.SetLeft(sal_uInt16(0));
1937  }
1938 
1939  // Right adjustments - if horizontally aligned to right of
1940  // margin or column then remove the right wrapping
1941  if (rRecord.nXAlign == 3)
1942  {
1943  if ((nXRelTo == 0) || (nXRelTo == 2))
1944  rLR.SetRight(sal_uInt16(0));
1945  }
1946 
1947  // Inside margin, remove left wrapping
1948  if ((rRecord.nXAlign == 4) && (nXRelTo == 0))
1949  {
1950  rLR.SetLeft(sal_uInt16(0));
1951  }
1952 
1953  // Outside margin, remove left wrapping
1954  if ((rRecord.nXAlign == 5) && (nXRelTo == 0))
1955  {
1956  rLR.SetRight(sal_uInt16(0));
1957  }
1958 }
1959 
1961  const SvxMSDffImportRec &rRecord, SvxULSpaceItem &rUL)
1962 {
1963  sal_uInt32 nYRelTo = SvxMSDffImportRec::RELTO_DEFAULT;
1964  if ( rRecord.nYRelTo )
1965  {
1966  nYRelTo = *rRecord.nYRelTo;
1967  }
1968 
1969  // Top adjustment - remove upper wrapping if aligned to page
1970  // printable area or to page
1971  if (rRecord.nYAlign == 1)
1972  {
1973  if ((nYRelTo == 0) || (nYRelTo == 1))
1974  rUL.SetUpper(sal_uInt16(0));
1975  }
1976 
1977  // Bottom adjustment - remove bottom wrapping if aligned to page or
1978  // printable area or to page
1979  if (rRecord.nYAlign == 3)
1980  {
1981  if ((nYRelTo == 0) || (nYRelTo == 1))
1982  rUL.SetLower(sal_uInt16(0));
1983  }
1984 
1985  // Remove top margin if aligned vertically inside margin
1986  if ((rRecord.nYAlign == 4) && (nYRelTo == 0))
1987  rUL.SetUpper(sal_uInt16(0));
1988 }
1989 
1991  SwFrameFormat& rFlyFormat)
1992 {
1993  if (rRecord.nDxWrapDistLeft || rRecord.nDxWrapDistRight)
1994  {
1995  SvxLRSpaceItem aLR(writer_cast<sal_uInt16>(rRecord.nDxWrapDistLeft),
1996  writer_cast<sal_uInt16>(rRecord.nDxWrapDistRight), 0, 0, RES_LR_SPACE);
1997  AdjustLRWrapForWordMargins(rRecord, aLR);
1998  rFlyFormat.SetFormatAttr(aLR);
1999  }
2000  if (rRecord.nDyWrapDistTop || rRecord.nDyWrapDistBottom)
2001  {
2002  SvxULSpaceItem aUL(writer_cast<sal_uInt16>(rRecord.nDyWrapDistTop),
2003  writer_cast<sal_uInt16>(rRecord.nDyWrapDistBottom), RES_UL_SPACE);
2004  AdjustULWrapForWordMargins(rRecord, aUL);
2005  rFlyFormat.SetFormatAttr(aUL);
2006  }
2007 
2008  // If we are contoured and have a custom polygon...
2009  if (rRecord.pWrapPolygon && rFlyFormat.GetSurround().IsContour())
2010  {
2011  if (SwNoTextNode* pNd = GetNoTextNodeFromSwFrameFormat(rFlyFormat))
2012  {
2013  /*
2014  Gather round children and hear of a tale that will raise the
2015  hairs on the back of your neck this dark halloween night.
2016 
2017  There is a polygon in word that describes the wrapping around
2018  the graphic.
2019 
2020  Here are some sample values for the simplest case of a square
2021  around some solid coloured graphics
2022 
2023  X Y Pixel size of graphic
2024  TopLeft -54 21600 400x400
2025  Bottom Right 0 21546
2026 
2027  TopLeft -108 21600 200x200
2028  Bottom Right 0 21492
2029 
2030  TopLeft -216 21600 100x100
2031  Bottom Right 0 21384
2032 
2033  TopLeft -432 21600 50x50
2034  Bottom Right 0 21168
2035 
2036  TopLeft -76 21600 283x212
2037  Bottom Right 0 21498
2038 
2039  So given that the size of the values remains pretty much the
2040  same despite the size of the graphic, we can tell that the
2041  polygon is measured in units that are independent of the
2042  graphic. But why does the left corner move a different value
2043  to the left each time, and why does the bottom move upwards
2044  each time, when the right and top remain at the same value ?
2045 
2046  I have no idea, but clearly once we calculate the values out
2047  we see that the left margin is always a fixed realworld
2048  distance from the true left and the polygon bottom is the same
2049  fixed value from the bottom. i.e. 15twips.
2050 
2051  So here we take our word provided polygon, shift it to the
2052  right by 15twips and rescale it widthwise to shrink the width
2053  a little to fit the now moved right margin back to where it
2054  was, and stretch the height a little to make the bottom move
2055  down the missing 15twips then we get a polygon that matches
2056  what I actually see in word
2057  */
2058 
2059  tools::PolyPolygon aPoly(*rRecord.pWrapPolygon);
2060  const Size &rSize = pNd->GetTwipSize();
2061  /*
2062  Move to the left by 15twips, and rescale to
2063  a) shrink right bound back to orig position
2064  b) stretch bottom bound to where I think it should have been
2065  in the first place
2066  */
2067  Fraction aMoveHack(ww::nWrap100Percent, rSize.Width());
2068  aMoveHack *= Fraction(15, 1);
2069  tools::Long nMove(aMoveHack);
2070  aPoly.Move(nMove, 0);
2071 
2074  aPoly.Scale(double(aHackX), double(aHackY));
2075 
2076  // Turn polygon back into units that match the graphic's
2077  const Size &rOrigSize = pNd->GetGraphic().GetPrefSize();
2078  Fraction aMapPolyX(rOrigSize.Width(), ww::nWrap100Percent);
2079  Fraction aMapPolyY(rOrigSize.Height(), ww::nWrap100Percent);
2080  aPoly.Scale(double(aMapPolyX), double(aMapPolyY));
2081 
2082  // #i47277# - contour is already in unit of the
2083  // graphic preferred unit. Thus, call method <SetContour(..)>
2084  pNd->SetContour(&aPoly);
2085  }
2086  }
2087  else if (rFlyFormat.GetSurround().IsContour())
2088  {
2089  // Contour is enabled, but no polygon is set: disable contour, because Word does not
2090  // Writer-style auto-contour in that case.
2091  SwFormatSurround aSurround(rFlyFormat.GetSurround());
2092  aSurround.SetContour(false);
2093  rFlyFormat.SetFormatAttr(aSurround);
2094  }
2095 }
2096 
2097 static sal_Int32 lcl_ConvertCrop(sal_uInt32 const nCrop, sal_Int32 const nSize)
2098 {
2099  // cast to sal_Int32 to handle negative crop properly
2100  sal_Int32 const nIntegral(static_cast<sal_Int32>(nCrop) >> 16);
2101  // fdo#77454: heuristic to detect mangled values written by old OOo/LO
2102  if (abs(nIntegral) >= 50) // FIXME: what's a good cut-off?
2103  {
2104  SAL_INFO("sw.ww8", "ignoring suspiciously large crop: " << nIntegral);
2105  return 0;
2106  }
2107  return (nIntegral * nSize) + (((nCrop & 0xffff) * nSize) >> 16);
2108 }
2109 
2111  const SwFrameFormat& rFlyFormat, WW8_FSPA const *pF)
2112 {
2113  const SwNodeIndex* pIdx = rFlyFormat.GetContent(false).GetContentIdx();
2114  SwGrfNode *const pGrfNd(
2115  pIdx ? m_rDoc.GetNodes()[pIdx->GetIndex() + 1]->GetGrfNode() : nullptr);
2116  if (!pGrfNd)
2117  return;
2118 
2119  Size aSz(pGrfNd->GetTwipSize());
2120  // use type <sal_uInt64> instead of sal_uLong to get correct results
2121  // in the following calculations.
2122  sal_uInt64 nHeight = aSz.Height();
2123  sal_uInt64 nWidth = aSz.Width();
2124  if (!nWidth && pF)
2125  nWidth = o3tl::saturating_sub(pF->nXaRight, pF->nXaLeft);
2126  else if (!nHeight && pF)
2127  nHeight = o3tl::saturating_sub(pF->nYaBottom, pF->nYaTop);
2128 
2129  if (rRecord.nCropFromTop || rRecord.nCropFromBottom ||
2130  rRecord.nCropFromLeft || rRecord.nCropFromRight)
2131  {
2132  SwCropGrf aCrop; // Cropping is stored in 'fixed floats'
2133  // 16.16 (fraction times total
2134  if (rRecord.nCropFromTop) // image width or height resp.)
2135  {
2136  aCrop.SetTop(lcl_ConvertCrop(rRecord.nCropFromTop, nHeight));
2137  }
2138  if (rRecord.nCropFromBottom)
2139  {
2140  aCrop.SetBottom(lcl_ConvertCrop(rRecord.nCropFromBottom, nHeight));
2141  }
2142  if (rRecord.nCropFromLeft)
2143  {
2144  aCrop.SetLeft(lcl_ConvertCrop(rRecord.nCropFromLeft, nWidth));
2145  }
2146  if (rRecord.nCropFromRight)
2147  {
2148  aCrop.SetRight(lcl_ConvertCrop(rRecord.nCropFromRight, nWidth));
2149  }
2150 
2151  pGrfNd->SetAttr( aCrop );
2152  }
2153 
2154  bool bFlipH(rRecord.nFlags & ShapeFlag::FlipH);
2155  bool bFlipV(rRecord.nFlags & ShapeFlag::FlipV);
2156  if ( bFlipH || bFlipV )
2157  {
2158  SwMirrorGrf aMirror = pGrfNd->GetSwAttrSet().GetMirrorGrf();
2159  if( bFlipH )
2160  {
2161  if( bFlipV )
2162  aMirror.SetValue(MirrorGraph::Both);
2163  else
2165  }
2166  else
2168 
2169  pGrfNd->SetAttr( aMirror );
2170  }
2171 
2172  if (!rRecord.pObj)
2173  return;
2174 
2175  const SfxItemSet& rOldSet = rRecord.pObj->GetMergedItemSet();
2176  // contrast
2177  if (WW8ITEMVALUE(rOldSet, SDRATTR_GRAFCONTRAST,
2179  {
2180  SwContrastGrf aContrast(
2181  WW8ITEMVALUE(rOldSet,
2183  pGrfNd->SetAttr( aContrast );
2184  }
2185 
2186  // luminance
2187  if (WW8ITEMVALUE(rOldSet, SDRATTR_GRAFLUMINANCE,
2189  {
2190  SwLuminanceGrf aLuminance(WW8ITEMVALUE(rOldSet,
2192  pGrfNd->SetAttr( aLuminance );
2193  }
2194  // gamma
2196  {
2197  double fVal = WW8ITEMVALUE(rOldSet, SDRATTR_GRAFGAMMA,
2199  pGrfNd->SetAttr(SwGammaGrf(fVal/100.));
2200  }
2201 
2202  // drawmode
2203  auto nGrafMode = rOldSet.GetItem<SdrGrafModeItem>(SDRATTR_GRAFMODE)->GetValue();
2204  if ( nGrafMode != GraphicDrawMode::Standard)
2205  {
2206  SwDrawModeGrf aDrawMode( nGrafMode );
2207  pGrfNd->SetAttr( aDrawMode );
2208  }
2209 }
2210 
2212 {
2213  if (pFlyFormat)
2214  {
2215  SdrObject* pNewObject = m_bNewDoc ? nullptr : pFlyFormat->FindRealSdrObject();
2216  if (!pNewObject)
2217  pNewObject = pFlyFormat->FindSdrObject();
2218  if (!pNewObject )
2219  if (auto pFlyFrameFormat = dynamic_cast<SwFlyFrameFormat *>( pFlyFormat ))
2220  {
2221  SwFlyDrawContact* pContactObject = pFlyFrameFormat->GetOrCreateContact();
2222  pNewObject = pContactObject->GetMaster();
2223  }
2224  return pNewObject;
2225  }
2226  return nullptr;
2227 }
2228 
2229 // Miserable miserable hack to fudge word's graphic layout in RTL mode to ours.
2231  sal_Int16 eHoriOri, sal_Int16 eHoriRel)
2232 {
2233  if (!IsRightToLeft())
2234  return false;
2235  return RTLGraphicsHack(rLeft, nWidth, eHoriOri, eHoriRel,
2236  m_aSectionManager.GetPageLeft(),
2237  m_aSectionManager.GetPageRight(),
2238  m_aSectionManager.GetPageWidth());
2239 }
2240 
2242  SfxItemSet &rFlySet)
2243 {
2244  bool bCurSectionVertical = m_aSectionManager.CurrentSectionIsVertical();
2245 
2246  if (!rRecord.nXRelTo)
2247  {
2248  rRecord.nXRelTo = sal_Int32(rFSPA.nbx);
2249  }
2250  if (!rRecord.nYRelTo)
2251  {
2252  rRecord.nYRelTo = sal_Int32(rFSPA.nby);
2253  }
2254 
2255  // nXAlign - abs. Position, Left, Centered, Right, Inside, Outside
2256  // nYAlign - abs. Position, Top, Centered, Bottom, Inside, Outside
2257 
2258  // nXRelTo - Page printable area, Page, Column, Character
2259  // nYRelTo - Page printable area, Page, Paragraph, Line
2260 
2261  const sal_uInt32 nCntXAlign = 6;
2262  const sal_uInt32 nCntYAlign = 6;
2263 
2264  const sal_uInt32 nCntRelTo = 4;
2265 
2266  sal_uInt32 nXAlign = nCntXAlign > rRecord.nXAlign ? rRecord.nXAlign : 1;
2267  sal_uInt32 nYAlign = nCntYAlign > rRecord.nYAlign ? rRecord.nYAlign : 1;
2268 
2269  // #i52565# - try to handle special case for objects in tables regarding its X Rel
2270 
2271  // if X and Y Rel values are on default take it as a hint, that they have not been set
2272  // by <SwMSDffManager::ProcessObj(..)>
2273  const bool bXYRelHaveDefaultValues = *rRecord.nXRelTo == 2 && *rRecord.nYRelTo == 2;
2274  if (bXYRelHaveDefaultValues && m_nInTable > 0 && !bCurSectionVertical)
2275  {
2276  if (sal_uInt32(rFSPA.nby) != rRecord.nYRelTo)
2277  rRecord.nYRelTo = sal_uInt32(rFSPA.nby);
2278  }
2279 
2280  sal_uInt32 nXRelTo = (rRecord.nXRelTo && nCntRelTo > rRecord.nXRelTo) ? *rRecord.nXRelTo : 1;
2281  sal_uInt32 nYRelTo = (rRecord.nYRelTo && nCntRelTo > rRecord.nYRelTo) ? *rRecord.nYRelTo : 1;
2282 
2283  RndStdIds eAnchor = IsInlineEscherHack() ? RndStdIds::FLY_AS_CHAR : RndStdIds::FLY_AT_CHAR; // #i43718#
2284 
2285  SwFormatAnchor aAnchor( eAnchor );
2286  aAnchor.SetAnchor( m_pPaM->GetPoint() );
2287  rFlySet.Put( aAnchor );
2288 
2289  // #i18732#
2290  // Given new layout where everything is changed to be anchored to
2291  // character the following 4 tables may need to be changed.
2292 
2293  // horizontal Adjustment
2294  static const sal_Int16 aHoriOriTab[ nCntXAlign ] =
2295  {
2296  text::HoriOrientation::NONE, // From left position
2297  text::HoriOrientation::LEFT, // left
2298  text::HoriOrientation::CENTER, // centered
2299  text::HoriOrientation::RIGHT, // right
2300  // #i36649#
2301  // - inside -> text::HoriOrientation::LEFT and outside -> text::HoriOrientation::RIGHT
2302  text::HoriOrientation::LEFT, // inside
2303  text::HoriOrientation::RIGHT // outside
2304  };
2305 
2306  // generic vertical Adjustment
2307  static const sal_Int16 aVertOriTab[ nCntYAlign ] =
2308  {
2309  text::VertOrientation::NONE, // From Top position
2310  text::VertOrientation::TOP, // top
2311  text::VertOrientation::CENTER, // centered
2312  text::VertOrientation::BOTTOM, // bottom
2313  text::VertOrientation::LINE_TOP, // inside (obscure)
2314  text::VertOrientation::LINE_BOTTOM // outside (obscure)
2315  };
2316 
2317  // #i22673# - to-line vertical alignment
2318  static const sal_Int16 aToLineVertOriTab[ nCntYAlign ] =
2319  {
2320  text::VertOrientation::NONE, // below
2321  text::VertOrientation::LINE_BOTTOM, // top
2322  text::VertOrientation::LINE_CENTER, // centered
2323  text::VertOrientation::LINE_TOP, // bottom
2324  text::VertOrientation::LINE_BOTTOM, // inside (obscure)
2325  text::VertOrientation::LINE_TOP // outside (obscure)
2326  };
2327 
2328  // Adjustment is horizontally relative to...
2329  static const sal_Int16 aHoriRelOriTab[nCntRelTo] =
2330  {
2331  text::RelOrientation::PAGE_PRINT_AREA, // 0 is page textarea margin
2332  text::RelOrientation::PAGE_FRAME, // 1 is page margin
2333  text::RelOrientation::FRAME, // 2 is relative to column
2334  text::RelOrientation::CHAR // 3 is relative to character
2335  };
2336 
2337  // Adjustment is vertically relative to...
2338  // #i22673# - adjustment for new vertical alignment at top of line.
2339  static const sal_Int16 aVertRelOriTab[nCntRelTo] =
2340  {
2341  text::RelOrientation::PAGE_PRINT_AREA, // 0 is page textarea margin
2342  text::RelOrientation::PAGE_FRAME, // 1 is page margin
2343  text::RelOrientation::FRAME, // 2 is relative to paragraph
2344  text::RelOrientation::TEXT_LINE // 3 is relative to line
2345  };
2346 
2347  sal_Int16 eHoriOri = aHoriOriTab[ nXAlign ];
2348  sal_Int16 eHoriRel = aHoriRelOriTab[ nXRelTo ];
2349 
2350  // #i36649# - adjustments for certain alignments
2351  if (eHoriOri == text::HoriOrientation::LEFT && eHoriRel == text::RelOrientation::PAGE_FRAME)
2352  {
2353  // convert 'left to page' to 'from left -<width> to page text area'
2354  eHoriOri = text::HoriOrientation::NONE;
2355  eHoriRel = text::RelOrientation::PAGE_PRINT_AREA;
2356  const tools::Long nWidth = rFSPA.nXaRight - rFSPA.nXaLeft;
2357  rFSPA.nXaLeft = -nWidth;
2358  rFSPA.nXaRight = 0;
2359  }
2360  else if (eHoriOri == text::HoriOrientation::RIGHT && eHoriRel == text::RelOrientation::PAGE_FRAME)
2361  {
2362  // convert 'right to page' to 'from left 0 to right page border'
2363  eHoriOri = text::HoriOrientation::NONE;
2364  eHoriRel = text::RelOrientation::PAGE_RIGHT;
2365  const tools::Long nWidth = rFSPA.nXaRight - rFSPA.nXaLeft;
2366  rFSPA.nXaLeft = 0;
2367  rFSPA.nXaRight = nWidth;
2368  }
2369 
2370  // #i24255# - position of floating screen objects in
2371  // R2L layout are given in L2R layout, thus convert them of all
2372  // floating screen objects, which are imported.
2373  {
2374  // Miserable miserable hack.
2375  SwTwips nWidth = o3tl::saturating_sub(rFSPA.nXaRight, rFSPA.nXaLeft);
2376  SwTwips nLeft = rFSPA.nXaLeft;
2377  if (MiserableRTLGraphicsHack(nLeft, nWidth, eHoriOri,
2378  eHoriRel))
2379  {
2380  rFSPA.nXaLeft = nLeft;
2381  rFSPA.nXaRight = rFSPA.nXaLeft + nWidth;
2382  }
2383  }
2384 
2385  // if the object is anchored inside a table cell, is horizontal aligned
2386  // at frame|character and has wrap through, but its attribute
2387  // 'layout in table cell' isn't set, convert its horizontal alignment to page text area.
2388  // #i84783# - use new method <IsObjectLayoutInTableCell()>
2389  if (m_nInTable &&
2390  (eHoriRel == text::RelOrientation::FRAME || eHoriRel == text::RelOrientation::CHAR) &&
2391  rFSPA.nwr == 3 &&
2392  !IsObjectLayoutInTableCell(rRecord.nLayoutInTableCell))
2393  {
2394  eHoriRel = text::RelOrientation::PAGE_PRINT_AREA;
2395  }
2396 
2397  // Writer honours this wrap distance when aligned as "left" or "right",
2398  // Word doesn't. Writer doesn't honour it when its "from left".
2399  if (eHoriOri == text::HoriOrientation::LEFT)
2400  rRecord.nDxWrapDistLeft = 0;
2401  else if (eHoriOri == text::HoriOrientation::RIGHT)
2402  rRecord.nDxWrapDistRight = 0;
2403 
2404  sal_Int16 eVertRel;
2405 
2406  eVertRel = aVertRelOriTab[ nYRelTo ]; // #i18732#
2407  if (bCurSectionVertical && nYRelTo == 2)
2408  eVertRel = text::RelOrientation::PAGE_PRINT_AREA;
2409  // #i22673# - fill <eVertOri> in dependence of <eVertRel>
2410  sal_Int16 eVertOri;
2411  if (eVertRel == text::RelOrientation::TEXT_LINE)
2412  {
2413  eVertOri = aToLineVertOriTab[ nYAlign ];
2414  }
2415  else
2416  {
2417  eVertOri = aVertOriTab[ nYAlign ];
2418  }
2419 
2420  // Below line in word is a positive value, while in writer its
2421  // negative
2422  tools::Long nYPos = rFSPA.nYaTop;
2423  // #i22673#
2424  if ((eVertRel == text::RelOrientation::TEXT_LINE) && (eVertOri == text::VertOrientation::NONE))
2425  nYPos = -nYPos;
2426 
2427  SwFormatHoriOrient aHoriOri(MakeSafePositioningValue(bCurSectionVertical ? nYPos : rFSPA.nXaLeft),
2428  bCurSectionVertical ? eVertOri : eHoriOri,
2429  bCurSectionVertical ? eVertRel : eHoriRel);
2430  if (4 <= nXAlign)
2431  aHoriOri.SetPosToggle(true);
2432  rFlySet.Put(aHoriOri);
2433 
2434  rFlySet.Put(SwFormatVertOrient(MakeSafePositioningValue(!bCurSectionVertical ? nYPos : -rFSPA.nXaRight),
2435  !bCurSectionVertical ? eVertOri : eHoriOri,
2436  !bCurSectionVertical ? eVertRel : eHoriRel));
2437 
2438  return eAnchor;
2439 }
2440 
2441 // #i84783#
2442 bool SwWW8ImplReader::IsObjectLayoutInTableCell( const sal_uInt32 nLayoutInTableCell ) const
2443 {
2444  bool bIsObjectLayoutInTableCell = false;
2445 
2446  if ( m_bVer8 )
2447  {
2448  sal_uInt16 nWWVersion = m_xWwFib->m_nProduct & 0xE000;
2449  if (nWWVersion == 0)
2450  {
2451  // 0 nProduct can happen for Word >97 as well, check cswNew in this case instead.
2452  if (m_xWwFib->m_cswNew > 0)
2453  {
2454  // This is Word >=2000.
2455  nWWVersion = 0x2000;
2456  }
2457  }
2458 
2459  switch ( nWWVersion )
2460  {
2461  case 0x0000: // version 8 aka Microsoft Word 97
2462  {
2463  bIsObjectLayoutInTableCell = false;
2464  OSL_ENSURE( nLayoutInTableCell == 0xFFFFFFFF,
2465  "no explicit object attribute layout in table cell expected." );
2466  }
2467  break;
2468  case 0x2000: // version 9 aka Microsoft Word 2000
2469  case 0x4000: // version 10 aka Microsoft Word 2002
2470  case 0x6000: // version 11 aka Microsoft Word 2003
2471  case 0x8000: // version 12 aka Microsoft Word 2007
2472  case 0xC000: // version 14 aka Microsoft Word 2010
2473  case 0xE000: // version 15 aka Microsoft Word 2013
2474  {
2475  // #i98037#
2476  // adjustment of conditions needed after deeper analysis of
2477  // certain test cases.
2478  if ( nLayoutInTableCell == 0xFFFFFFFF || // no explicit attribute value given
2479  nLayoutInTableCell == 0x80008000 ||
2480  ( nLayoutInTableCell & 0x02000000 &&
2481  !(nLayoutInTableCell & 0x80000000 ) ) )
2482  {
2483  bIsObjectLayoutInTableCell = true;
2484  }
2485  else
2486  {
2487  // Documented in [MS-ODRAW], 2.3.4.44 "Group Shape Boolean Properties".
2488  bool fUsefLayoutInCell = (nLayoutInTableCell & 0x80000000) >> 31;
2489  bool fLayoutInCell = (nLayoutInTableCell & 0x8000) >> 15;
2490  bIsObjectLayoutInTableCell = fUsefLayoutInCell && fLayoutInCell;
2491  }
2492  }
2493  break;
2494  default:
2495  {
2496  OSL_FAIL( "unknown version." );
2497  }
2498  }
2499  }
2500 
2501  return bIsObjectLayoutInTableCell;
2502 }
2503 
2505 {
2506  if( m_nIniFlags & WW8FL_NO_GRAFLAYER )
2507  return nullptr;
2508 
2509  ::SetProgressState(m_nProgress, m_pDocShell); // Update
2510 
2511  m_nDrawCpO = 0;
2512  m_bDrawCpOValid = m_xWwFib->GetBaseCp(m_xPlcxMan->GetManType() == MAN_HDFT ? MAN_TXBX_HDFT : MAN_TXBX, &m_nDrawCpO);
2513 
2514  GraphicCtor();
2515 
2516  WW8PLCFspecial* pPF = m_xPlcxMan->GetFdoa();
2517  if( !pPF )
2518  {
2519  OSL_ENSURE( false, "Where is the graphic (1) ?" );
2520  return nullptr;
2521  }
2522 
2523  if( m_bVer67 )
2524  {
2525  tools::Long nOldPos = m_pStrm->Tell();
2526 
2527  m_nDrawXOfs = m_nDrawYOfs = 0;
2528  ReadGrafLayer1(*pPF, nGrafAnchorCp);
2529 
2530  m_pStrm->Seek( nOldPos );
2531  return nullptr;
2532  }
2533 
2534  // Normal case of Word 8+ version stuff
2535  pPF->SeekPos( nGrafAnchorCp );
2536 
2537  WW8_FC nStartFc;
2538  void* pF0;
2539  if (!pPF->Get(nStartFc, pF0))
2540  {
2541  OSL_ENSURE( false, "+Where is the graphic (2) ?" );
2542  return nullptr;
2543  }
2544 
2545  WW8_FSPA_SHADOW& rFS = *static_cast<WW8_FSPA_SHADOW*>(pF0);
2546  WW8_FSPA aFSFA;
2547  WW8FSPAShadowToReal(rFS, aFSFA);
2548  if (!aFSFA.nSpId)
2549  {
2550  OSL_ENSURE( false, "+Where is the graphic (3) ?" );
2551  return nullptr;
2552  }
2553 
2554  if (!m_xMSDffManager->GetModel())
2555  m_xMSDffManager->SetModel(m_pDrawModel, 1440);
2556 
2557  tools::Rectangle aRect(aFSFA.nXaLeft, aFSFA.nYaTop, aFSFA.nXaRight, aFSFA.nYaBottom);
2558  SvxMSDffImportData aData( aRect );
2559 
2560  /*
2561  #i20540#
2562  The SdrOle2Obj will try and manage any ole objects it finds, causing all
2563  sorts of trouble later on
2564  */
2565  SwDocShell* pPersist = m_rDoc.GetDocShell();
2566  m_rDoc.SetDocShell(nullptr); // #i20540# Persist guard
2567 
2568  SdrObject* pObject = nullptr;
2569  bool bOk = (m_xMSDffManager->GetShape(aFSFA.nSpId, pObject, aData) && pObject);
2570 
2571  m_rDoc.SetDocShell(pPersist); // #i20540# Persist guard
2572 
2573  if (!bOk)
2574  {
2575  OSL_ENSURE( false, "Where is the Shape ?" );
2576  return nullptr;
2577  }
2578 
2579  // tdf#118375 Word relates position to the unrotated rectangle,
2580  // Writer uses the rotated one.
2581  if (pObject->GetRotateAngle())
2582  {
2583  tools::Rectangle aObjSnapRect(pObject->GetSnapRect()); // recalculates the SnapRect
2584  aFSFA.nXaLeft = aObjSnapRect.Left();
2585  aFSFA.nYaTop = aObjSnapRect.Top();
2586  aFSFA.nXaRight = aObjSnapRect.Right();
2587  aFSFA.nYaBottom = aObjSnapRect.Bottom();
2588  }
2589 
2590  bool bDone = false;
2591  SdrObject* pOurNewObject = nullptr;
2592  bool bReplaceable = false;
2593 
2594  switch (pObject->GetObjIdentifier())
2595  {
2596  case OBJ_GRAF:
2597  bReplaceable = true;
2598  bDone = true;
2599  break;
2600  case OBJ_OLE2:
2601  bReplaceable = true;
2602  break;
2603  default:
2604  break;
2605 
2606  }
2607 
2608  // when in a header or footer word appears to treat all elements as wrap through
2609 
2610  // determine wrapping mode
2612  Reader::ResetFrameFormatAttrs(aFlySet); // tdf#122425: Explicitly remove borders and spacing
2613  css::text::WrapTextMode eSurround = css::text::WrapTextMode_PARALLEL;
2614  bool bContour = false;
2615  switch (aFSFA.nwr)
2616  {
2617  case 0: // 0 like 2, but doesn't require absolute object
2618  case 2: // 2 wrap around absolute object
2619  eSurround = css::text::WrapTextMode_PARALLEL;
2620  break;
2621  case 1: // 1 no text next to shape
2622  eSurround = css::text::WrapTextMode_NONE;
2623  break;
2624  case 3: // 3 wrap as if no object present
2625  eSurround = css::text::WrapTextMode_THROUGH;
2626  break;
2627  case 4: // 4 wrap tightly around object
2628  case 5: // 5 wrap tightly, but allow holes
2629  eSurround = css::text::WrapTextMode_PARALLEL;
2630  bContour = true;
2631  break;
2632  }
2633 
2634  // if mode 2 or 4 also regard the additional parameters
2635  if ((2 == aFSFA.nwr) || (4 == aFSFA.nwr))
2636  {
2637  switch (aFSFA.nwrk)
2638  {
2639  // 0 wrap both sides
2640  case 0:
2641  eSurround = css::text::WrapTextMode_PARALLEL;
2642  break;
2643  // 1 wrap only on left
2644  case 1:
2645  eSurround = css::text::WrapTextMode_LEFT;
2646  break;
2647  // 2 wrap only on right
2648  case 2:
2649  eSurround = css::text::WrapTextMode_RIGHT;
2650  break;
2651  // 3 wrap only on largest side
2652  case 3:
2653  eSurround = css::text::WrapTextMode_DYNAMIC;
2654  break;
2655  }
2656  }
2657 
2658  SwFormatSurround aSur( eSurround );
2659  aSur.SetContour( bContour );
2660  aSur.SetOutside(true); // Winword can only do outside contours
2661  aFlySet.Put( aSur );
2662 
2663  // now position imported object correctly and so on (can be a whole group)
2664 
2665  OSL_ENSURE(!((aData.size() != 1) && bReplaceable),
2666  "Replaceable drawing with > 1 entries ?");
2667 
2668  if (aData.size() != 1)
2669  bReplaceable = false;
2670 
2671  /*
2672  Get the record for top level object, so we can get the word anchoring
2673  and wrapping information for it.
2674  */
2675  SvxMSDffImportRec* pRecord = aData.find(pObject);
2676  OSL_ENSURE(pRecord, "how did that happen?");
2677  if (!pRecord)
2678  {
2679  // remove old object from the Z-Order list
2680  m_xMSDffManager->RemoveFromShapeOrder(pObject);
2681  // and delete the object
2682  SdrObject::Free(pObject);
2683  return nullptr;
2684  }
2685  const bool bLayoutInTableCell =
2686  m_nInTable && IsObjectLayoutInTableCell( pRecord->nLayoutInTableCell );
2687 
2688  // #i18732# - Switch on 'follow text flow', if object is laid out
2689  // inside table cell
2690  if (bLayoutInTableCell)
2691  {
2692  SwFormatFollowTextFlow aFollowTextFlow( true );
2693  aFlySet.Put( aFollowTextFlow );
2694  }
2695 
2696  // #i21847#
2697  // Some shapes are set to *hidden*, don't import those ones.
2698  if (pRecord->bHidden)
2699  {
2700  // remove old object from the Z-Order list
2701  m_xMSDffManager->RemoveFromShapeOrder(pObject);
2702  // and delete the object
2703  SdrObject::Free(pObject);
2704  return nullptr;
2705  }
2706 
2707  sal_uInt16 nCount = pObject->GetUserDataCount();
2708  if(nCount)
2709  {
2710  OUString lnName, aObjName, aTarFrame;
2711  for (sal_uInt16 i = 0; i < nCount; i++ )
2712  {
2713  SdrObjUserData* pData = pObject->GetUserData( i );
2714  if( pData && pData->GetInventor() == SdrInventor::ScOrSwDraw
2715  && pData->GetId() == SW_UD_IMAPDATA)
2716  {
2717  SwMacroInfo* macInf = dynamic_cast<SwMacroInfo*>(pData);
2718  if (macInf && macInf->GetShapeId() == aFSFA.nSpId)
2719  {
2720  lnName = macInf->GetHlink();
2721  aObjName = macInf->GetName();
2722  aTarFrame = macInf->GetTarFrame();
2723  break;
2724  }
2725  }
2726  }
2727  std::unique_ptr<SwFormatURL> pFormatURL(new SwFormatURL());
2728  pFormatURL->SetURL( lnName, false );
2729  if (!aObjName.isEmpty())
2730  pFormatURL->SetName(aObjName);
2731  if (!aTarFrame.isEmpty())
2732  pFormatURL->SetTargetFrameName(aTarFrame);
2733  pFormatURL->SetMap(nullptr);
2734  aFlySet.Put(*pFormatURL);
2735  }
2736 
2737  // If we are to be "below text" then we are not to be opaque
2738  // #i14045# MM If we are in a header or footer then make the object transparent
2739  // Not exactly like word but close enough for now
2740 
2741  // both flags <bBelowText> and <bDrawHell> have to be set to move object into the background.
2742  // #i46794# - it reveals that value of flag <bBelowText> can be neglected.
2743  const bool bMoveToBackground = pRecord->bDrawHell ||
2744  ((m_bIsHeader || m_bIsFooter) && aFSFA.nwr == 3);
2745  if ( bMoveToBackground )
2746  aFlySet.Put(SvxOpaqueItem(RES_OPAQUE,false));
2747 
2748  OUString aObjName = pObject->GetName();
2749 
2750  bool bDrawObj = false;
2751  bool bFrame = false;
2752 
2753  SwFrameFormat* pRetFrameFormat = nullptr;
2754  if (bReplaceable)
2755  {
2756  // Single graphics or ole objects
2757  pRetFrameFormat = ImportReplaceableDrawables(pObject, pOurNewObject, *pRecord, aFSFA, aFlySet);
2758  }
2759  else
2760  {
2761  bDrawObj = true;
2762 
2763  // Drawing objects, (e.g. ovals or drawing groups)
2764  if (aFSFA.bRcaSimple)
2765  {
2766  aFSFA.nbx = WW8_FSPA::RelPageBorder;
2767  aFSFA.nby = WW8_FSPA::RelPageBorder;
2768  }
2769 
2770  RndStdIds eAnchor = ProcessEscherAlign(*pRecord, aFSFA, aFlySet);
2771 
2772  // Should we, and is it possible to make this into a writer textbox
2773  if ((!(m_nIniFlags1 & WW8FL_NO_FLY_FOR_TXBX)) && pRecord->bReplaceByFly)
2774  {
2775  pRetFrameFormat
2776  = ConvertDrawTextToFly(pObject, pOurNewObject, *pRecord, eAnchor, aFSFA, aFlySet);
2777  if (pRetFrameFormat)
2778  {
2779  bDone = true;
2780  bDrawObj = false;
2781  bFrame = true;
2782  }
2783  }
2784 
2785  if (!bDone)
2786  {
2787  sw::util::SetLayer aSetLayer(m_rDoc);
2788  if ( bMoveToBackground )
2789  aSetLayer.SendObjectToHell(*pObject);
2790  else
2791  aSetLayer.SendObjectToHeaven(*pObject);
2792 
2793  if (!IsInlineEscherHack())
2794  {
2795  /* Need to make sure that the correct layer ordering is applied. */
2796  // pass information, if object is in page header|footer to method.
2797  m_xWWZOrder->InsertEscherObject(pObject, aFSFA.nSpId, pRecord->bDrawHell,
2798  m_bIsHeader || m_bIsFooter);
2799  }
2800  else
2801  {
2802  m_xWWZOrder->InsertTextLayerObject(pObject);
2803  }
2804 
2805  pRetFrameFormat = m_rDoc.getIDocumentContentOperations().InsertDrawObj(*m_pPaM, *pObject, aFlySet );
2806 
2807  OSL_ENSURE(pRetFrameFormat->GetAnchor().GetAnchorId() ==
2808  eAnchor, "Not the anchor type requested!");
2809 
2810  /*
2811  Insert text if necessary into textboxes contained in groups.
2812  */
2813  for (const auto& it : aData)
2814  {
2815  pRecord = it.get();
2816  if (pRecord->pObj && pRecord->aTextId.nTxBxS)
2817  { // #i52825# pRetFrameFormat can be NULL
2818  pRetFrameFormat = MungeTextIntoDrawBox(
2819  *pRecord, nGrafAnchorCp, pRetFrameFormat);
2820  }
2821  }
2822  }
2823  }
2824 
2825  SwDrawFrameFormat* pDrawFrameFormat = dynamic_cast<SwDrawFrameFormat*>(pRetFrameFormat);
2826  // #i44344#, #i44681# - positioning attributes already set
2827  if (pDrawFrameFormat)
2828  pDrawFrameFormat->PosAttrSet();
2829  if (!IsInlineEscherHack() && pRetFrameFormat)
2830  MapWrapIntoFlyFormat(*pRecord, *pRetFrameFormat);
2831 
2832  // Set frame name with object name
2833  if (pRetFrameFormat /*#i52825# */)
2834  {
2835  if (!aObjName.isEmpty())
2836  pRetFrameFormat->SetName( aObjName );
2837  if (pRetFrameFormat->GetName().isEmpty())
2838  {
2839  if (bDrawObj)
2840  pRetFrameFormat->SetName(m_rDoc.GetUniqueDrawObjectName());
2841  else if (bFrame)
2842  pRetFrameFormat->SetName(m_rDoc.GetUniqueFrameName());
2843  }
2844  }
2845  return AddAutoAnchor(pRetFrameFormat);
2846 }
2847 
2849 {
2850  /*
2851  * anchored to character at the current position will move along the
2852  * paragraph as text is added because we are at the insertion point.
2853  *
2854  * Leave to later and set the correct location then.
2855  */
2856  if (pFormat && (pFormat->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR))
2857  {
2858  m_xAnchorStck->AddAnchor(*m_pPaM->GetPoint(), pFormat);
2859  }
2860  return pFormat;
2861 }
2862 
2864  tools::Long nGrafAnchorCp, SwFrameFormat* pRetFrameFormat)
2865 {
2866  SdrObject* pTrueObject = rRecord.pObj;
2867 
2868  SdrTextObj* pSdrTextObj;
2869 
2870  // check for group object (e.g. two parentheses)
2871  if (SdrObjGroup* pThisGroup = dynamic_cast<SdrObjGroup*>(rRecord.pObj))
2872  {
2873  // Group objects don't have text. Insert a text object into
2874  // the group for holding the text.
2875  pSdrTextObj = new SdrRectObj(
2876  *m_pDrawModel,
2877  OBJ_TEXT,
2878  pThisGroup->GetCurrentBoundRect());
2879 
2880  SfxItemSet aSet(m_pDrawModel->GetItemPool());
2881  aSet.Put(XFillStyleItem(drawing::FillStyle_NONE));
2882  aSet.Put(XLineStyleItem(drawing::LineStyle_NONE));
2883  aSet.Put(SdrTextFitToSizeTypeItem( drawing::TextFitToSizeType_NONE ));
2884  aSet.Put(makeSdrTextAutoGrowHeightItem(false));
2885  aSet.Put(makeSdrTextAutoGrowWidthItem(false));
2886  pSdrTextObj->SetMergedItemSet(aSet);
2887  pSdrTextObj->NbcSetLayer( pThisGroup->GetLayer() );
2888  pThisGroup->GetSubList()->NbcInsertObject(pSdrTextObj);
2889  }
2890  else
2891  pSdrTextObj = dynamic_cast<SdrTextObj*>(rRecord.pObj);
2892 
2893  if( pSdrTextObj )
2894  {
2895  Size aObjSize(pSdrTextObj->GetSnapRect().GetWidth(),
2896  pSdrTextObj->GetSnapRect().GetHeight());
2897 
2898  // Object is part of a group?
2899  SdrObject* pGroupObject = pSdrTextObj->getParentSdrObjectFromSdrObject();
2900 
2901  const size_t nOrdNum = pSdrTextObj->GetOrdNum();
2902  bool bEraseThisObject;
2903  InsertTxbxText(pSdrTextObj, &aObjSize, rRecord.aTextId.nTxBxS, rRecord.aTextId.nSequence,
2904  nGrafAnchorCp, pRetFrameFormat,
2905  (pSdrTextObj != pTrueObject) || (nullptr != pGroupObject), bEraseThisObject,
2906  nullptr, nullptr, nullptr, nullptr, &rRecord);
2907 
2908  // was this object replaced ??
2909  if (bEraseThisObject)
2910  {
2911  if( pGroupObject || (pSdrTextObj != pTrueObject) )
2912  {
2913  // Object is already replaced by a new SdrGrafObj (in the group
2914  // and) the Drawing-Page.
2915 
2916  SdrObject* pNewObj = pGroupObject ?
2917  pGroupObject->GetSubList()->GetObj(nOrdNum) : pTrueObject;
2918  if (pSdrTextObj != pNewObj)
2919  {
2920  // Replace object in the Z-Order-List
2921  m_xMSDffManager->ExchangeInShapeOrder(pSdrTextObj, 0, pNewObj);
2922  // now delete object
2923  SdrObject::Free(rRecord.pObj);
2924  // and save the new object.
2925  rRecord.pObj = pNewObj;
2926  }
2927  }
2928  else
2929  {
2930  // remove the object from Z-Order list
2931  m_xMSDffManager->RemoveFromShapeOrder( pSdrTextObj );
2932  // take the object from the drawing page
2933  if( pSdrTextObj->getSdrPageFromSdrObject() )
2934  m_pDrawPg->RemoveObject( pSdrTextObj->GetOrdNum() );
2935  // and delete FrameFormat, because replaced by graphic
2936  // (this also deletes the object)
2937  m_rDoc.DelFrameFormat( pRetFrameFormat );
2938  pRetFrameFormat = nullptr;
2939  // also delete the object record
2940  rRecord.pObj = nullptr;
2941  }
2942  }
2943  else
2944  {
2945  // use ww8-default border distance
2946  SfxItemSet aItemSet(m_pDrawModel->GetItemPool(),
2947  svl::Items<SDRATTR_TEXT_LEFTDIST, SDRATTR_TEXT_LOWERDIST>);
2948  aItemSet.Put(makeSdrTextLeftDistItem(rRecord.nDxTextLeft));
2949  aItemSet.Put(makeSdrTextRightDistItem(rRecord.nDxTextRight));
2950  aItemSet.Put(makeSdrTextUpperDistItem(rRecord.nDyTextTop));
2951  aItemSet.Put(makeSdrTextLowerDistItem(rRecord.nDyTextBottom));
2952  pSdrTextObj->SetMergedItemSetAndBroadcast(aItemSet);
2953  }
2954  }
2955  return pRetFrameFormat;
2956 }
2957 
2959  SdrObject*& rpOurNewObject,
2960  const SvxMSDffImportRec& rRecord,
2961  RndStdIds eAnchor, const WW8_FSPA& rF,
2962  SfxItemSet &rFlySet)
2963 {
2964  SwFlyFrameFormat* pRetFrameFormat = nullptr;
2965  tools::Long nStartCp;
2966  tools::Long nEndCp;
2967 
2968  // Check if this textbox chain contains text as conversion of an empty
2969  // chain would not make sense.
2970  if (TxbxChainContainsRealText(rRecord.aTextId.nTxBxS, nStartCp, nEndCp))
2971  {
2972  // The Text is not read into SdrTextObj! Rather insert a frame and
2973  // insert the text from nStartCp to nEndCp.
2974 
2975  // More attributes can be used in a frame compared to the
2976  // Edit-Engine, and it can contain field, OLEs or graphics...
2977  tools::Rectangle aInnerDist(rRecord.nDxTextLeft, rRecord.nDyTextTop, rRecord.nDxTextRight,
2978  rRecord.nDyTextBottom);
2979 
2981  rF.nYaBottom - rF.nYaTop);
2983  : SwFrameSize::Fixed);
2984  rFlySet.Put(aFrameSize);
2985 
2986  MatchSdrItemsIntoFlySet(rpObject, rFlySet, rRecord.eLineStyle, rRecord.eLineDashing,
2987  rRecord.eShapeType, aInnerDist);
2988 
2989  SdrTextObj *pSdrTextObj = dynamic_cast<SdrTextObj*>(rpObject);
2990  if (pSdrTextObj && pSdrTextObj->IsVerticalWriting())
2991  rFlySet.Put(SvxFrameDirectionItem(SvxFrameDirection::Vertical_RL_TB, RES_FRAMEDIR));
2992 
2993  pRetFrameFormat = m_rDoc.MakeFlySection(eAnchor, m_pPaM->GetPoint(), &rFlySet);
2994  OSL_ENSURE(pRetFrameFormat->GetAnchor().GetAnchorId() == eAnchor,
2995  "Not the anchor type requested!");
2996 
2997  // if everything is OK, find pointer on new object and correct
2998  // Z-order list (or delete entry)
2999  rpOurNewObject = CreateContactObject(pRetFrameFormat);
3000 
3001  // remove old object from the Z-Order list
3002  m_xMSDffManager->RemoveFromShapeOrder( rpObject );
3003 
3004  // and delete the object
3005  SdrObject::Free( rpObject );
3006  /*
3007  NB: only query pOrgShapeObject starting here!
3008  */
3009 
3010  if (rpOurNewObject)
3011  {
3012  /*
3013  We do not store our rpOutNewObject in the ShapeOrder because we
3014  have a FrameFormat from which we can regenerate the contact object when
3015  we need it. Because, we can have frames anchored to paragraphs in
3016  header/footers and we can copy header/footers, if we do copy a
3017  header/footer with a nonpage anchored frame in it then the contact
3018  objects are invalidated. Under this condition the FrameFormat will be
3019  updated to reflect this change and can be used to get a new
3020  contact object, while a raw rpOutNewObject stored here becomes
3021  deleted and useless.
3022  */
3023  m_xMSDffManager->StoreShapeOrder(rF.nSpId,
3024  (static_cast<sal_uLong>(rRecord.aTextId.nTxBxS) << 16) +
3025  rRecord.aTextId.nSequence, nullptr, pRetFrameFormat);
3026 
3027  // The Contact object has to be inserted into the draw page, so
3028  // SwWW8ImplReader::LoadDoc1() can determine the z-order.
3029  if (!rpOurNewObject->IsInserted())
3030  {
3031  // pass information, if object is in page header|footer to method.
3032  m_xWWZOrder->InsertEscherObject(rpOurNewObject, rF.nSpId, rRecord.bDrawHell,
3033  m_bIsHeader || m_bIsFooter);
3034  }
3035  }
3036 
3037  // Box-0 receives the text for the whole chain!
3038  if (!rRecord.aTextId.nSequence)
3039  {
3040  // save flags etc and reset them
3041  WW8ReaderSave aSave( this );
3042 
3043  MoveInsideFly(pRetFrameFormat);
3044 
3045  m_xWWZOrder->InsideEscher(rF.nSpId);
3046 
3047  // read in the text
3048  m_bTxbxFlySection = true;
3049  bool bJoined = ReadText(nStartCp, (nEndCp-nStartCp),
3050  MAN_MAINTEXT == m_xPlcxMan->GetManType() ?
3052 
3053  m_xWWZOrder->OutsideEscher();
3054 
3055  MoveOutsideFly(pRetFrameFormat, aSave.GetStartPos(),!bJoined);
3056 
3057  aSave.Restore( this );
3058 
3059  StripNegativeAfterIndent(pRetFrameFormat);
3060  }
3061 
3062  }
3063  return pRetFrameFormat;
3064 }
3065 
3067 {
3068  if (rRecord.bVFlip || rRecord.bHFlip)
3069  {
3071  if (rRecord.bVFlip && rRecord.bHFlip)
3072  eType = MirrorGraph::Both;
3073  else if (rRecord.bVFlip)
3074  eType = MirrorGraph::Horizontal;
3075  else
3076  eType = MirrorGraph::Vertical;
3077  rFlySet.Put( SwMirrorGrf(eType) );
3078  }
3079 }
3080 
3082  SdrObject* &rpOurNewObject,
3083  SvxMSDffImportRec& rRecord,
3084  WW8_FSPA& rF,
3085  SfxItemSet &rFlySet )
3086 {
3087  SwFlyFrameFormat* pRetFrameFormat = nullptr;
3088  sal_Int32 nWidthTw = o3tl::saturating_sub(rF.nXaRight, rF.nXaLeft);
3089  if (0 > nWidthTw)
3090  nWidthTw = 0;
3091  sal_Int32 nHeightTw = o3tl::saturating_sub(rF.nYaBottom, rF.nYaTop);
3092  if (0 > nHeightTw)
3093  nHeightTw = 0;
3094 
3095  ProcessEscherAlign(rRecord, rF, rFlySet);
3096 
3097  rFlySet.Put(SwFormatFrameSize(SwFrameSize::Fixed, nWidthTw, nHeightTw));
3098 
3100 
3101  // Note that the escher inner distance only seems to be honoured in
3102  // word for textboxes, not for graphics and ole objects.
3103  tools::Rectangle aInnerDist(0, 0, 0, 0);
3104 
3105  MatchSdrItemsIntoFlySet(rpObject, rFlySet, rRecord.eLineStyle, rRecord.eLineDashing,
3106  rRecord.eShapeType, aInnerDist);
3107 
3108  MatchEscherMirrorIntoFlySet(rRecord, aGrSet);
3109 
3110  OUString aObjectName(rpObject->GetName());
3111  if (OBJ_OLE2 == rpObject->GetObjIdentifier())
3112  pRetFrameFormat = InsertOle(*static_cast<SdrOle2Obj*>(rpObject), rFlySet, &aGrSet);
3113  else
3114  {
3115  const SdrGrafObj *pGrf = static_cast<const SdrGrafObj*>(rpObject);
3116  bool bDone = false;
3117  if (pGrf->IsLinkedGraphic() && !pGrf->GetFileName().isEmpty())
3118  {
3119  GraphicType eType = pGrf->GetGraphicType();
3120  OUString aGrfName(
3122  INetURLObject(m_sBaseURL), pGrf->GetFileName(),
3124  // correction of fix for issue #i10939#:
3125  // One of the two conditions have to be true to insert the graphic
3126  // as a linked graphic -
3127  if (GraphicType::NONE == eType || CanUseRemoteLink(aGrfName))
3128  {
3130  *m_pPaM, aGrfName, OUString(), nullptr,
3131  &rFlySet, &aGrSet, nullptr);
3132  bDone = true;
3133  }
3134  }
3135  if (!bDone)
3136  {
3137  const Graphic& rGraph = pGrf->GetGraphic();
3139  *m_pPaM, OUString(), OUString(), &rGraph,
3140  &rFlySet, &aGrSet, nullptr);
3141  }
3142  }
3143 
3144  if (pRetFrameFormat)
3145  {
3146  if (OBJ_OLE2 != rpObject->GetObjIdentifier())
3147  SetAttributesAtGrfNode(rRecord, *pRetFrameFormat, &rF);
3148  // avoid multiple occurrences of the same graphic name
3149  m_aGrfNameGenerator.SetUniqueGraphName(pRetFrameFormat, aObjectName);
3150  }
3151  // if everything is OK, determine pointer to new object and correct
3152  // Z-Order-List accordingly (or delete entry)
3153  rpOurNewObject = CreateContactObject(pRetFrameFormat);
3154 
3155  // remove old object from Z-Order-List
3156  m_xMSDffManager->RemoveFromShapeOrder( rpObject );
3157  // remove from Drawing-Page
3158  if( rpObject->getSdrPageFromSdrObject() )
3159  m_pDrawPg->RemoveObject( rpObject->GetOrdNum() );
3160 
3161  // and delete the object
3162  SdrObject::Free( rpObject );
3163  /*
3164  Warning: from now on query only pOrgShapeObject!
3165  */
3166 
3167  // add Contact-Object to the Z-Order-List and the page
3168  if (rpOurNewObject)
3169  {
3170  if (!m_bHdFtFootnoteEdn)
3171  m_xMSDffManager->StoreShapeOrder(rF.nSpId, 0, rpOurNewObject);
3172 
3173  // The Contact-Object MUST be set in the Draw-Page, so that in
3174  // SwWW8ImplReader::LoadDoc1() the Z-Order can be defined !!!
3175  if (!rpOurNewObject->IsInserted())
3176  {
3177  // pass information, if object is in page header|footer to method.
3178  m_xWWZOrder->InsertEscherObject(rpOurNewObject, rF.nSpId, rRecord.bDrawHell,
3179  m_bIsHeader || m_bIsFooter);
3180  }
3181  }
3182  return pRetFrameFormat;
3183 }
3184 
3185 void SwWW8ImplReader::GraphicCtor() // For SVDraw and VCControls and Escher
3186 {
3187  if (m_pDrawModel)
3188  return;
3189 
3190  m_rDoc.getIDocumentDrawModelAccess().GetOrCreateDrawModel(); // #i52858# - method name changed
3191  m_pDrawModel = m_rDoc.getIDocumentDrawModelAccess().GetDrawModel();
3192  OSL_ENSURE(m_pDrawModel, "Cannot create DrawModel");
3193  m_pDrawPg = m_pDrawModel->GetPage(0);
3194 
3195  m_xMSDffManager.reset(new SwMSDffManager(*this, m_bSkipImages));
3196  m_xMSDffManager->SetModel(m_pDrawModel, 1440);
3197  /*
3198  Now the dff manager always needs a controls converter as well, but a
3199  control converter may still exist without a dffmanager.
3200  */
3201  m_xFormImpl.reset(new SwMSConvertControls(m_pDocShell, m_pPaM));
3202 
3203  m_xWWZOrder.reset(new wwZOrderer(sw::util::SetLayer(m_rDoc), m_pDrawPg,
3204  m_xMSDffManager->GetShapeOrders()));
3205 }
3206 
3208 {
3209  m_pDrawEditEngine.reset(); // maybe created by graphic
3210  m_xWWZOrder.reset(); // same
3211 }
3212 
3214 {
3215  OSL_ENSURE(pFormat->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR,
3216  "Don't use fltanchors with inline frames, slap!");
3217  NewAttr(rPos, SwFltAnchor(pFormat));
3218 }
3219 
3221 {
3222  size_t nCnt = size();
3223  for (size_t i=0; i < nCnt; ++i)
3224  {
3225  SwFltStackEntry &rEntry = (*this)[i];
3226  SwPosition aDummy(rEntry.m_aMkPos.m_nNode);
3227  SetAttrInDoc(aDummy, rEntry);
3228  DeleteAndDestroy(i--);
3229  --nCnt;
3230  }
3231 }
3232 
3233 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static ESelection GetESelection(EditEngine const &rDrawEditEngine, tools::Long nCpStart, tools::Long nCpEnd)
Definition: ww8graf.cxx: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
constexpr TypedWhichId< SvxFrameDirectionItem > RES_FRAMEDIR(120)
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:8540
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:69
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:1578
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:35
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:1272
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
static constexpr auto Items
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
static sal_Int32 lcl_ConvertCrop(sal_uInt32 const nCrop, sal_Int32 const nSize)
Definition: ww8graf.cxx:2097
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:1663
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:2442
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:1922
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:1520
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:763
OUString GetUniqueFrameName() const
Definition: doclay.cxx:1379
void Scale(double fScaleX, double fScaleY)
void PosAttrSet()
Definition: frmfmt.hxx:399
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:2373
constexpr TypedWhichId< SvxOpaqueItem > RES_OPAQUE(99)
sal_Int32 nCropFromLeft
static void MapWrapIntoFlyFormat(const SvxMSDffImportRec &rRecord, SwFrameFormat &rFlyFormat)
Definition: ww8graf.cxx:1990
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
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:3207
void GraphicCtor()
Definition: ww8graf.cxx:3185
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:1208
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)
tools::Long Left() const
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)
sal_uLong GetIndex() const
Definition: ndindex.hxx:152
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
tools::Long Bottom() const
virtual void SetName(const OUString &rNewName, bool bBroadcast=false) override
Definition: atrfrm.cxx:2560
constexpr TypedWhichId< XColorItem > SDRATTR_SHADOWCOLOR(SDRATTR_SHADOW_FIRST+1)
constexpr tools::Long GetWidth() const
SdrCaptionType
WW8_DP_LINETYPE aLnt
Definition: ww8struc.hxx:792
void SetMergedItemSet(const SfxItemSet &rSet, bool bClearAllItems=false)
const SwFormatSurround & GetSurround(bool=true) const
Definition: fmtsrnd.hxx:66
void InsertTxbxText(SdrTextObj *pTextObj, Size const *pObjSiz, sal_uInt16 nTxBxS, sal_uInt16 nSequence, tools::Long nPosCp, SwFrameFormat const *pFlyFormat, bool bMakeSdrGrafObj, bool &rbEraseTextObj, bool *pbTestTxbxContainsText=nullptr, tools::Long *pnStartCp=nullptr, tools::Long *pnEndCp=nullptr, bool *pbContainsGraphics=nullptr, SvxMSDffImportRec const *pRecord=nullptr)
Definition: ww8graf.cxx:1016
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
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)
virtual void GetSprms(WW8PLCFxDesc *p) override
Definition: ww8scan.cxx:3406
DocumentType eType
SVBT16 dhgt
Definition: ww8struc.hxx:701
ContactObject for connection between frames (or their formats respectively) in SwClient and the drawo...
Definition: dcontact.hxx:175
SwFrameFormat * Read_GrafLayer(tools::Long nGrafAnchorCp)
Definition: ww8graf.cxx:2504
void SendObjectToHeaven(SdrObject &rObject) const
Make Object lives in the top layer.
const Color & GetColor() const
sal_Int32 nDxTextRight
MSO_LineDashing eLineDashing
bool IsInRange(sal_uInt16 nWhich) const
void SetAttributesAtGrfNode(const SvxMSDffImportRec &rRecord, const SwFrameFormat &rFlyFormat, WW8_FSPA const *pF)
Definition: ww8graf.cxx:2110
virtual void SetLayer(SdrLayerID nLayer)
sal_Int32 nEndPara
Style of a layout element.
Definition: frmfmt.hxx:58
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:2863
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
constexpr TypedWhichId< SdrGrafLuminanceItem > SDRATTR_GRAFLUMINANCE(SDRATTR_GRAF_FIRST+3)
int i
void SetAlpha(sal_uInt8 cAlpha)
void SetDistance(double nNewDistance)
constexpr TypedWhichId< XFillBitmapItem > XATTR_FILLBITMAP(XATTR_FILL_FIRST+4)
mso_lineDashGEL
among others for fields, that is, the same number of attr as positions, if Ctor-Param bNoEnd = false ...
Definition: ww8scan.hxx:220
SVBT16 flpp
Definition: ww8struc.hxx:739
SwTwips MakeSafePositioningValue(SwTwips nIn)
Clips a value to MAX/MIN 16bit value to make it safe for use as a position value to give to writer...
void SetValue(EnumT nTheValue)
bool TxbxChainContainsRealText(sal_uInt16 nTxBxS, tools::Long &rStartCp, tools::Long &rEndCp)
Definition: ww8graf.cxx:1220
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
sal_uInt32 GetTextLen() const
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:2848
std::unique_ptr< OutlinerParaObject > ImportAsOutliner(OUString &rString, WW8_CP nStartCp, WW8_CP nEndCp, ManTypes eType)
Definition: ww8graf.cxx:963
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.
void SetMergedItemSetAndBroadcast(const SfxItemSet &rSet, bool bClearAllItems=false)
void SetRed(sal_uInt8 nRed)
float u
void MatchEscherMirrorIntoFlySet(const SvxMSDffImportRec &rRecord, SfxItemSet &rFlySet)
Definition: ww8graf.cxx:3066
static const int RELTO_DEFAULT
constexpr TypedWhichId< SdrGrafModeItem > SDRATTR_GRAFMODE(SDRATTR_GRAF_FIRST+8)
void Move(tools::Long nHorzMove, tools::Long nVertMove)
SwFrameSize GetWidthSizeType() const
Definition: fmtfsize.hxx:83
void SetTop(sal_Int32 nVal)
sal_uInt32 GetOrdNum() const
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:2043
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:31
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:604
tools::Long GetHeight() const
tools::Long Top() 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:50
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
sal_uInt16 nwrk
Definition: ww8struc.hxx:933
static void AdjustULWrapForWordMargins(const SvxMSDffImportRec &rRecord, SvxULSpaceItem &rUL)
Definition: ww8graf.cxx:1960
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:3257
SdrObject * ReadTextBox(WW8_DPHEAD const *pHd, SfxAllItemSet &rSet)
Definition: ww8graf.cxx:1230
sal_uInt8 bx
Definition: ww8struc.hxx:685
WW8_DP_SHADOW aShd
Definition: ww8struc.hxx:794
virtual void NbcSetOutlinerParaObject(std::unique_ptr< OutlinerParaObject > pTextObject) override
constexpr TypedWhichId< XFillColorItem > XATTR_FILLCOLOR(XATTR_FILL_FIRST+1)
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
SVBT32 fc
Definition: ww8struc.hxx:677
constexpr TypedWhichId< SdrMetricItem > SDRATTR_SHADOWXDIST(SDRATTR_SHADOW_FIRST+2)
void setClosed(bool bNew)
void SetDashes(sal_uInt16 nNewDashes)
sal_uInt16 bRcaSimple
Definition: ww8struc.hxx:939
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_LIGHTCYAN
std::optional< sal_uInt32 > nYRelTo
#define SW_UD_IMAPDATA
Definition: ww8par.hxx:59
virtual SwDrawFrameFormat * InsertDrawObj(const SwPaM &rRg, SdrObject &rDrawObj, const SfxItemSet &rFlyAttrSet)=0
Insert a DrawObject.
virtual bool IsVerticalWriting() const
mso_sptTextBox
constexpr sal_uInt16 RES_FLTRATTR_END(197)
sal_Int32 nDyWrapDistBottom
SfxItemState
constexpr TypedWhichId< SvxBrushItem > RES_BACKGROUND(105)
MSO_LineStyle eLineStyle
SVBT16 yaStart
Definition: ww8struc.hxx:761
void SetLeft(const tools::Long nL, const sal_uInt16 nProp=100)
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
sal_uInt16 GetWhich(sal_uInt16 nSlot, bool bDeep=true) const
#define SAL_WARN_IF(condition, area, stream)
#define WW8ITEMVALUE(ItemSet, Id, Cast)
Definition: ww8graf.cxx:1661
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:2241
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:2211
SwFlyFrameFormat * ImportReplaceableDrawables(SdrObject *&rpObject, SdrObject *&rpOurNewObject, SvxMSDffImportRec &rRecord, WW8_FSPA &rF, SfxItemSet &rFlySet)
Definition: ww8graf.cxx:3081
WW8_DP_TXTBOX dptxbx
Definition: ww8struc.hxx:831
SdrObject * ReadGrafPrimitive(short &rLeft, SfxAllItemSet &rSet)
Definition: ww8graf.cxx:1376
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)
std::unique_ptr< tools::Polygon > pWrapPolygon
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:686
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)
Degree100 abs(Degree100 x)
constexpr sal_uInt16 EE_FEATURE_FIELD(EE_FEATURE_NOTCONV+1)
SdrObject * pObj
void ReadGrafLayer1(WW8PLCFspecial &rPF, tools::Long nGrafAnchorCp)
Definition: ww8graf.cxx:1433
std::optional< sal_uInt32 > nXRelTo
virtual void NbcSetSnapRect(const tools::Rectangle &rRect) override
sal_uInt16 nwr
Definition: ww8struc.hxx:924
SwFlyFrameFormat * ConvertDrawTextToFly(SdrObject *&rpObject, SdrObject *&rpOurNewObject, const SvxMSDffImportRec &rRecord, RndStdIds eAnchor, const WW8_FSPA &rF, SfxItemSet &rFlySet)
Definition: ww8graf.cxx:2958
bool m_bColl
Definition: ww8par.hxx: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:1339
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:3213
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:138
constexpr TypedWhichId< SvxULSpaceItem > RES_UL_SPACE(92)
WW8_DP_LINETYPE aLnt
Definition: ww8struc.hxx:771
virtual void SetVerticalWriting(bool bVertical)
tools::Long Right() const
sal_uInt16 Which() const
SdrObject * FindRealSdrObject()
Definition: atrfrm.cxx:2802
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:1583
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:2230