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