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