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