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  case 0xE000: // version 15 aka Microsoft Word 2013
2476  {
2477  // #i98037#
2478  // adjustment of conditions needed after deeper analysis of
2479  // certain test cases.
2480  if ( nLayoutInTableCell == 0xFFFFFFFF || // no explicit attribute value given
2481  nLayoutInTableCell == 0x80008000 ||
2482  ( nLayoutInTableCell & 0x02000000 &&
2483  !(nLayoutInTableCell & 0x80000000 ) ) )
2484  {
2485  bIsObjectLayoutInTableCell = true;
2486  }
2487  else
2488  {
2489  // Documented in [MS-ODRAW], 2.3.4.44 "Group Shape Boolean Properties".
2490  bool fUsefLayoutInCell = (nLayoutInTableCell & 0x80000000) >> 31;
2491  bool fLayoutInCell = (nLayoutInTableCell & 0x8000) >> 15;
2492  bIsObjectLayoutInTableCell = fUsefLayoutInCell && fLayoutInCell;
2493  }
2494  }
2495  break;
2496  default:
2497  {
2498  OSL_FAIL( "unknown version." );
2499  }
2500  }
2501  }
2502 
2503  return bIsObjectLayoutInTableCell;
2504 }
2505 
2507 {
2508  if( m_nIniFlags & WW8FL_NO_GRAFLAYER )
2509  return nullptr;
2510 
2511  ::SetProgressState(m_nProgress, m_pDocShell); // Update
2512 
2513  m_nDrawCpO = 0;
2514  m_bDrawCpOValid = m_xWwFib->GetBaseCp(m_xPlcxMan->GetManType() == MAN_HDFT ? MAN_TXBX_HDFT : MAN_TXBX, &m_nDrawCpO);
2515 
2516  GrafikCtor();
2517 
2518  WW8PLCFspecial* pPF = m_xPlcxMan->GetFdoa();
2519  if( !pPF )
2520  {
2521  OSL_ENSURE( false, "Where is the graphic (1) ?" );
2522  return nullptr;
2523  }
2524 
2525  if( m_bVer67 )
2526  {
2527  long nOldPos = m_pStrm->Tell();
2528 
2529  m_nDrawXOfs = m_nDrawYOfs = 0;
2530  ReadGrafLayer1( pPF, nGrafAnchorCp );
2531 
2532  m_pStrm->Seek( nOldPos );
2533  return nullptr;
2534  }
2535 
2536  // Normal case of Word 8+ version stuff
2537  pPF->SeekPos( nGrafAnchorCp );
2538 
2539  WW8_FC nStartFc;
2540  void* pF0;
2541  if( !pPF->Get( nStartFc, pF0 ) ){
2542  OSL_ENSURE( false, "+Where is the graphic (2) ?" );
2543  return nullptr;
2544  }
2545 
2546  WW8_FSPA_SHADOW* pFS = static_cast<WW8_FSPA_SHADOW*>(pF0);
2547  WW8_FSPA* pF;
2548  WW8_FSPA aFSFA;
2549  pF = &aFSFA;
2550  WW8FSPAShadowToReal( pFS, pF );
2551  if( !pF->nSpId )
2552  {
2553  OSL_ENSURE( false, "+Where is the graphic (3) ?" );
2554  return nullptr;
2555  }
2556 
2557  if (!m_xMSDffManager->GetModel())
2558  m_xMSDffManager->SetModel(m_pDrawModel, 1440);
2559 
2560  tools::Rectangle aRect(pF->nXaLeft, pF->nYaTop, pF->nXaRight, pF->nYaBottom);
2561  SvxMSDffImportData aData( aRect );
2562 
2563  /*
2564  #i20540#
2565  The SdrOle2Obj will try and manage any ole objects it finds, causing all
2566  sorts of trouble later on
2567  */
2568  SwDocShell* pPersist = m_rDoc.GetDocShell();
2569  m_rDoc.SetDocShell(nullptr); // #i20540# Persist guard
2570 
2571  SdrObject* pObject = nullptr;
2572  bool bOk = (m_xMSDffManager->GetShape(pF->nSpId, pObject, aData) && pObject);
2573 
2574  m_rDoc.SetDocShell(pPersist); // #i20540# Persist guard
2575 
2576  if (!bOk)
2577  {
2578  OSL_ENSURE( false, "Where is the Shape ?" );
2579  return nullptr;
2580  }
2581 
2582  // tdf#118375 Word relates position to the unrotated rectangle,
2583  // Writer uses the rotated one.
2584  if (pObject->GetRotateAngle())
2585  {
2586  tools::Rectangle aObjSnapRect(pObject->GetSnapRect()); // recalculates the SnapRect
2587  pF->nXaLeft = aObjSnapRect.Left();
2588  pF->nYaTop = aObjSnapRect.Top();
2589  pF->nXaRight = aObjSnapRect.Right();
2590  pF->nYaBottom = aObjSnapRect.Bottom();
2591  }
2592 
2593  bool bDone = false;
2594  SdrObject* pOurNewObject = nullptr;
2595  bool bReplaceable = false;
2596 
2597  switch (SdrObjKind(pObject->GetObjIdentifier()))
2598  {
2599  case OBJ_GRAF:
2600  bReplaceable = true;
2601  bDone = true;
2602  break;
2603  case OBJ_OLE2:
2604  bReplaceable = true;
2605  break;
2606  default:
2607  break;
2608 
2609  }
2610 
2611  // when in a header or footer word appears to treat all elements as wrap through
2612 
2613  // determine wrapping mode
2615  Reader::ResetFrameFormatAttrs(aFlySet); // tdf#122425: Explicitly remove borders and spacing
2616  css::text::WrapTextMode eSurround = css::text::WrapTextMode_PARALLEL;
2617  bool bContour = false;
2618  switch (pF->nwr)
2619  {
2620  case 0: // 0 like 2, but doesn't require absolute object
2621  case 2: // 2 wrap around absolute object
2622  eSurround = css::text::WrapTextMode_PARALLEL;
2623  break;
2624  case 1: // 1 no text next to shape
2625  eSurround = css::text::WrapTextMode_NONE;
2626  break;
2627  case 3: // 3 wrap as if no object present
2628  eSurround = css::text::WrapTextMode_THROUGH;
2629  break;
2630  case 4: // 4 wrap tightly around object
2631  case 5: // 5 wrap tightly, but allow holes
2632  eSurround = css::text::WrapTextMode_PARALLEL;
2633  bContour = true;
2634  break;
2635  }
2636 
2637  // if mode 2 or 4 also regard the additional parameters
2638  if ( (2 == pF->nwr) || (4 == pF->nwr) )
2639  {
2640  switch( pF->nwrk )
2641  {
2642  // 0 wrap both sides
2643  case 0:
2644  eSurround = css::text::WrapTextMode_PARALLEL;
2645  break;
2646  // 1 wrap only on left
2647  case 1:
2648  eSurround = css::text::WrapTextMode_LEFT;
2649  break;
2650  // 2 wrap only on right
2651  case 2:
2652  eSurround = css::text::WrapTextMode_RIGHT;
2653  break;
2654  // 3 wrap only on largest side
2655  case 3:
2656  eSurround = css::text::WrapTextMode_DYNAMIC;
2657  break;
2658  }
2659  }
2660 
2661  SwFormatSurround aSur( eSurround );
2662  aSur.SetContour( bContour );
2663  aSur.SetOutside(true); // Winword can only do outside contours
2664  aFlySet.Put( aSur );
2665 
2666  // now position imported object correctly and so on (can be a whole group)
2667 
2668  OSL_ENSURE(!((aData.size() != 1) && bReplaceable),
2669  "Replaceable drawing with > 1 entries ?");
2670 
2671  if (aData.size() != 1)
2672  bReplaceable = false;
2673 
2674  /*
2675  Get the record for top level object, so we can get the word anchoring
2676  and wrapping information for it.
2677  */
2678  SvxMSDffImportRec* pRecord = aData.find(pObject);
2679  OSL_ENSURE(pRecord, "how did that happen?");
2680  if (!pRecord)
2681  {
2682  // remove old object from the Z-Order list
2683  m_xMSDffManager->RemoveFromShapeOrder(pObject);
2684  // and delete the object
2685  SdrObject::Free(pObject);
2686  return nullptr;
2687  }
2688  const bool bLayoutInTableCell =
2689  m_nInTable && IsObjectLayoutInTableCell( pRecord->nLayoutInTableCell );
2690 
2691  // #i18732# - Switch on 'follow text flow', if object is laid out
2692  // inside table cell
2693  if (bLayoutInTableCell)
2694  {
2695  SwFormatFollowTextFlow aFollowTextFlow( true );
2696  aFlySet.Put( aFollowTextFlow );
2697  }
2698 
2699  // #i21847#
2700  // Some shapes are set to *hidden*, don't import those ones.
2701  if (pRecord->bHidden)
2702  {
2703  // remove old object from the Z-Order list
2704  m_xMSDffManager->RemoveFromShapeOrder(pObject);
2705  // and delete the object
2706  SdrObject::Free(pObject);
2707  return nullptr;
2708  }
2709 
2710  sal_uInt16 nCount = pObject->GetUserDataCount();
2711  if(nCount)
2712  {
2713  OUString lnName, aObjName, aTarFrame;
2714  for (sal_uInt16 i = 0; i < nCount; i++ )
2715  {
2716  SdrObjUserData* pData = pObject->GetUserData( i );
2717  if( pData && pData->GetInventor() == SdrInventor::ScOrSwDraw
2718  && pData->GetId() == SW_UD_IMAPDATA)
2719  {
2720  SwMacroInfo* macInf = dynamic_cast<SwMacroInfo*>(pData);
2721  if( macInf && macInf->GetShapeId() == pF->nSpId )
2722  {
2723  lnName = macInf->GetHlink();
2724  aObjName = macInf->GetName();
2725  aTarFrame = macInf->GetTarFrame();
2726  break;
2727  }
2728  }
2729  }
2730  SwFormatURL* pFormatURL = new SwFormatURL();
2731  pFormatURL->SetURL( lnName, false );
2732  if (!aObjName.isEmpty())
2733  pFormatURL->SetName(aObjName);
2734  if (!aTarFrame.isEmpty())
2735  pFormatURL->SetTargetFrameName(aTarFrame);
2736  pFormatURL->SetMap(nullptr);
2737  aFlySet.Put(*pFormatURL);
2738  }
2739 
2740  // If we are to be "below text" then we are not to be opaque
2741  // #i14045# MM If we are in a header or footer then make the object transparent
2742  // Not exactly like word but close enough for now
2743 
2744  // both flags <bBelowText> and <bDrawHell> have to be set to move object into the background.
2745  // #i46794# - it reveals that value of flag <bBelowText> can be neglected.
2746  const bool bMoveToBackgrd = pRecord->bDrawHell ||
2747  ( ( m_bIsHeader || m_bIsFooter ) && pF->nwr == 3 );
2748  if ( bMoveToBackgrd )
2749  aFlySet.Put(SvxOpaqueItem(RES_OPAQUE,false));
2750 
2751  OUString aObjName = pObject->GetName();
2752 
2753  SwFrameFormat* pRetFrameFormat = nullptr;
2754  if (bReplaceable)
2755  {
2756  // Single graphics or ole objects
2757  pRetFrameFormat = ImportReplaceableDrawables(pObject, pOurNewObject, pRecord,
2758  pF, aFlySet);
2759  }
2760  else
2761  {
2762  // Drawing objects, (e.g. ovals or drawing groups)
2763  if (pF->bRcaSimple)
2764  {
2767  }
2768 
2769  RndStdIds eAnchor = ProcessEscherAlign(pRecord, pF, aFlySet);
2770 
2771  // Should we, and is it possible to make this into a writer textbox
2772  if ((!(m_nIniFlags1 & WW8FL_NO_FLY_FOR_TXBX)) && pRecord->bReplaceByFly)
2773  {
2774  pRetFrameFormat = ConvertDrawTextToFly(pObject, pOurNewObject, pRecord,
2775  eAnchor, pF, aFlySet);
2776  if (pRetFrameFormat)
2777  bDone = true;
2778  }
2779 
2780  if (!bDone)
2781  {
2782  sw::util::SetLayer aSetLayer(m_rDoc);
2783  if ( bMoveToBackgrd )
2784  aSetLayer.SendObjectToHell(*pObject);
2785  else
2786  aSetLayer.SendObjectToHeaven(*pObject);
2787 
2788  if (!IsInlineEscherHack())
2789  {
2790  /* Need to make sure that the correct layer ordering is applied. */
2791  // pass information, if object is in page header|footer to method.
2792  m_xWWZOrder->InsertEscherObject( pObject, pF->nSpId,
2793  m_bIsHeader || m_bIsFooter );
2794  }
2795  else
2796  {
2797  m_xWWZOrder->InsertTextLayerObject(pObject);
2798  }
2799 
2800  pRetFrameFormat = m_rDoc.getIDocumentContentOperations().InsertDrawObj(*m_pPaM, *pObject, aFlySet );
2801 
2802  OSL_ENSURE(pRetFrameFormat->GetAnchor().GetAnchorId() ==
2803  eAnchor, "Not the anchor type requested!");
2804 
2805  /*
2806  Insert text if necessary into textboxes contained in groups.
2807  */
2808  for (const auto& it : aData)
2809  {
2810  pRecord = it.get();
2811  if (pRecord->pObj && pRecord->aTextId.nTxBxS)
2812  { // #i52825# pRetFrameFormat can be NULL
2813  pRetFrameFormat = MungeTextIntoDrawBox(
2814  pRecord, nGrafAnchorCp, pRetFrameFormat);
2815  }
2816  }
2817  }
2818  }
2819 
2820  // #i44344#, #i44681# - positioning attributes already set
2821  if ( pRetFrameFormat /*#i52825# */ && dynamic_cast< const SwDrawFrameFormat *>( pRetFrameFormat ) != nullptr )
2822  {
2823  static_cast<SwDrawFrameFormat*>(pRetFrameFormat)->PosAttrSet();
2824  }
2825  if (!IsInlineEscherHack())
2826  MapWrapIntoFlyFormat(pRecord, pRetFrameFormat);
2827 
2828  // Set frame name with object name
2829  if( pRetFrameFormat /*#i52825# */ && !aObjName.isEmpty() )
2830  pRetFrameFormat->SetName( aObjName );
2831  return AddAutoAnchor(pRetFrameFormat);
2832 }
2833 
2835 {
2836  /*
2837  * anchored to character at the current position will move along the
2838  * paragraph as text is added because we are at the insertion point.
2839  *
2840  * Leave to later and set the correct location then.
2841  */
2842  if (pFormat && (pFormat->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR))
2843  {
2844  m_xAnchorStck->AddAnchor(*m_pPaM->GetPoint(), pFormat);
2845  }
2846  return pFormat;
2847 }
2848 
2850  long nGrafAnchorCp, SwFrameFormat* pRetFrameFormat)
2851 {
2852  SdrObject* pTrueObject = pRecord->pObj;
2853 
2854  SdrTextObj* pSdrTextObj;
2855 
2856  // check for group object (e.g. two parentheses)
2857  if (SdrObjGroup* pThisGroup = dynamic_cast<SdrObjGroup*>( pRecord->pObj) )
2858  {
2859  // Group objects don't have text. Insert a text object into
2860  // the group for holding the text.
2861  pSdrTextObj = new SdrRectObj(
2862  *m_pDrawModel,
2863  OBJ_TEXT,
2864  pThisGroup->GetCurrentBoundRect());
2865 
2866  SfxItemSet aSet(m_pDrawModel->GetItemPool());
2867  aSet.Put(XFillStyleItem(drawing::FillStyle_NONE));
2868  aSet.Put(XLineStyleItem(drawing::LineStyle_NONE));
2869  aSet.Put(SdrTextFitToSizeTypeItem( drawing::TextFitToSizeType_NONE ));
2870  aSet.Put(makeSdrTextAutoGrowHeightItem(false));
2871  aSet.Put(makeSdrTextAutoGrowWidthItem(false));
2872  pSdrTextObj->SetMergedItemSet(aSet);
2873  pSdrTextObj->NbcSetLayer( pThisGroup->GetLayer() );
2874  pThisGroup->GetSubList()->NbcInsertObject(pSdrTextObj);
2875  }
2876  else
2877  pSdrTextObj = dynamic_cast<SdrTextObj*>( pRecord->pObj );
2878 
2879  if( pSdrTextObj )
2880  {
2881  Size aObjSize(pSdrTextObj->GetSnapRect().GetWidth(),
2882  pSdrTextObj->GetSnapRect().GetHeight());
2883 
2884  // Object is part of a group?
2885  SdrObject* pGroupObject = pSdrTextObj->getParentSdrObjectFromSdrObject();
2886 
2887  const size_t nOrdNum = pSdrTextObj->GetOrdNum();
2888  bool bEraseThisObject;
2889  InsertTxbxText( pSdrTextObj, &aObjSize, pRecord->aTextId.nTxBxS,
2890  pRecord->aTextId.nSequence, nGrafAnchorCp, pRetFrameFormat,
2891  (pSdrTextObj != pTrueObject) || (nullptr != pGroupObject),
2892  bEraseThisObject, nullptr, nullptr, nullptr, nullptr, pRecord);
2893 
2894  // was this object replaced ??
2895  if (bEraseThisObject)
2896  {
2897  if( pGroupObject || (pSdrTextObj != pTrueObject) )
2898  {
2899  // Object is already replaced by a new SdrGrafObj (in the group
2900  // and) the Drawing-Page.
2901 
2902  SdrObject* pNewObj = pGroupObject ?
2903  pGroupObject->GetSubList()->GetObj(nOrdNum) : pTrueObject;
2904  if (pSdrTextObj != pNewObj)
2905  {
2906  // Replace object in the Z-Order-List
2907  m_xMSDffManager->ExchangeInShapeOrder(pSdrTextObj, 0, pNewObj);
2908  // now delete object
2909  SdrObject::Free( pRecord->pObj );
2910  // and save the new object.
2911  pRecord->pObj = pNewObj;
2912  }
2913  }
2914  else
2915  {
2916  // remove the object from Z-Order list
2917  m_xMSDffManager->RemoveFromShapeOrder( pSdrTextObj );
2918  // take the object from the drawing page
2919  if( pSdrTextObj->getSdrPageFromSdrObject() )
2920  m_pDrawPg->RemoveObject( pSdrTextObj->GetOrdNum() );
2921  // and delete FrameFormat, because replaced by graphic
2922  // (this also deletes the object)
2923  m_rDoc.DelFrameFormat( pRetFrameFormat );
2924  pRetFrameFormat = nullptr;
2925  // also delete the object record
2926  pRecord->pObj = nullptr;
2927  }
2928  }
2929  else
2930  {
2931  // use ww8-default border distance
2932  SfxItemSet aItemSet(m_pDrawModel->GetItemPool(),
2934  aItemSet.Put( makeSdrTextLeftDistItem( pRecord->nDxTextLeft ) );
2935  aItemSet.Put( makeSdrTextRightDistItem( pRecord->nDxTextRight ) );
2936  aItemSet.Put( makeSdrTextUpperDistItem( pRecord->nDyTextTop ) );
2937  aItemSet.Put( makeSdrTextLowerDistItem( pRecord->nDyTextBottom ) );
2938  pSdrTextObj->SetMergedItemSetAndBroadcast(aItemSet);
2939  }
2940  }
2941  return pRetFrameFormat;
2942 }
2943 
2945  SdrObject* &rpOurNewObject, SvxMSDffImportRec const * pRecord, RndStdIds eAnchor,
2946  WW8_FSPA const *pF, SfxItemSet &rFlySet)
2947 {
2948  SwFlyFrameFormat* pRetFrameFormat = nullptr;
2949  long nStartCp;
2950  long nEndCp;
2951 
2952  // Check if this textbox chain contains text as conversion of an empty
2953  // chain would not make sense.
2954  if ( TxbxChainContainsRealText(pRecord->aTextId.nTxBxS,nStartCp,nEndCp) )
2955  {
2956  // The Text is not read into SdrTextObj! Rather insert a frame and
2957  // insert the text from nStartCp to nEndCp.
2958 
2959  // More attributes can be used in a frame compared to the
2960  // Edit-Engine, and it can contain field, OLEs or graphics...
2961  tools::Rectangle aInnerDist(pRecord->nDxTextLeft, pRecord->nDyTextTop,
2962  pRecord->nDxTextRight, pRecord->nDyTextBottom);
2963 
2964  SwFormatFrameSize aFrameSize(SwFrameSize::Fixed, pF->nXaRight - pF->nXaLeft, pF->nYaBottom - pF->nYaTop);
2966  rFlySet.Put(aFrameSize);
2967 
2968  MatchSdrItemsIntoFlySet( rpObject, rFlySet, pRecord->eLineStyle,
2969  pRecord->eLineDashing, pRecord->eShapeType, aInnerDist );
2970 
2971  SdrTextObj *pSdrTextObj = dynamic_cast<SdrTextObj*>(rpObject);
2972  if (pSdrTextObj && pSdrTextObj->IsVerticalWriting())
2973  rFlySet.Put(SvxFrameDirectionItem(SvxFrameDirection::Vertical_RL_TB, RES_FRAMEDIR));
2974 
2975  pRetFrameFormat = m_rDoc.MakeFlySection(eAnchor, m_pPaM->GetPoint(), &rFlySet);
2976  OSL_ENSURE(pRetFrameFormat->GetAnchor().GetAnchorId() == eAnchor,
2977  "Not the anchor type requested!");
2978 
2979  // if everything is OK, find pointer on new object and correct
2980  // Z-order list (or delete entry)
2981  rpOurNewObject = CreateContactObject(pRetFrameFormat);
2982 
2983  // remove old object from the Z-Order list
2984  m_xMSDffManager->RemoveFromShapeOrder( rpObject );
2985 
2986  // and delete the object
2987  SdrObject::Free( rpObject );
2988  /*
2989  NB: only query pOrgShapeObject starting here!
2990  */
2991 
2992  if (rpOurNewObject)
2993  {
2994  /*
2995  We do not store our rpOutNewObject in the ShapeOrder because we
2996  have a FrameFormat from which we can regenerate the contact object when
2997  we need it. Because, we can have frames anchored to paragraphs in
2998  header/footers and we can copy header/footers, if we do copy a
2999  header/footer with a nonpage anchored frame in it then the contact
3000  objects are invalidated. Under this condition the FrameFormat will be
3001  updated to reflect this change and can be used to get a new
3002  contact object, while a raw rpOutNewObject stored here becomes
3003  deleted and useless.
3004  */
3005  m_xMSDffManager->StoreShapeOrder(pF->nSpId,
3006  (static_cast<sal_uLong>(pRecord->aTextId.nTxBxS) << 16) +
3007  pRecord->aTextId.nSequence, nullptr, pRetFrameFormat);
3008 
3009  // The Contact object has to be inserted into the draw page, so
3010  // SwWW8ImplReader::LoadDoc1() can determine the z-order.
3011  if (!rpOurNewObject->IsInserted())
3012  {
3013  // pass information, if object is in page header|footer to method.
3014  m_xWWZOrder->InsertEscherObject( rpOurNewObject, pF->nSpId,
3015  m_bIsHeader || m_bIsFooter );
3016  }
3017  }
3018 
3019  // Box-0 receives the text for the whole chain!
3020  if( !pRecord->aTextId.nSequence )
3021  {
3022  // save flags etc and reset them
3023  WW8ReaderSave aSave( this );
3024 
3025  MoveInsideFly(pRetFrameFormat);
3026 
3027  m_xWWZOrder->InsideEscher(pF->nSpId);
3028 
3029  // read in the text
3030  m_bTxbxFlySection = true;
3031  bool bJoined = ReadText(nStartCp, (nEndCp-nStartCp),
3032  MAN_MAINTEXT == m_xPlcxMan->GetManType() ?
3034 
3035  m_xWWZOrder->OutsideEscher();
3036 
3037  MoveOutsideFly(pRetFrameFormat, aSave.GetStartPos(),!bJoined);
3038 
3039  aSave.Restore( this );
3040 
3041  StripNegativeAfterIndent(pRetFrameFormat);
3042  }
3043 
3044  }
3045  return pRetFrameFormat;
3046 }
3047 
3049  SfxItemSet &rFlySet)
3050 {
3051  if (rRecord.bVFlip || rRecord.bHFlip)
3052  {
3054  if (rRecord.bVFlip && rRecord.bHFlip)
3055  eType = MirrorGraph::Both;
3056  else if (rRecord.bVFlip)
3057  eType = MirrorGraph::Horizontal;
3058  else
3059  eType = MirrorGraph::Vertical;
3060  rFlySet.Put( SwMirrorGrf(eType) );
3061  }
3062 }
3063 
3065  SdrObject* &rpOurNewObject, SvxMSDffImportRec* pRecord, WW8_FSPA *pF,
3066  SfxItemSet &rFlySet )
3067 {
3068  SwFlyFrameFormat* pRetFrameFormat = nullptr;
3069  sal_Int32 nWidthTw = o3tl::saturating_sub(pF->nXaRight, pF->nXaLeft);
3070  if (0 > nWidthTw)
3071  nWidthTw = 0;
3072  sal_Int32 nHeightTw = o3tl::saturating_sub(pF->nYaBottom, pF->nYaTop);
3073  if (0 > nHeightTw)
3074  nHeightTw = 0;
3075 
3076  ProcessEscherAlign(pRecord, pF, rFlySet);
3077 
3078  rFlySet.Put(SwFormatFrameSize(SwFrameSize::Fixed, nWidthTw, nHeightTw));
3079 
3080  SfxItemSet aGrSet(m_rDoc.GetAttrPool(), svl::Items<RES_GRFATR_BEGIN, RES_GRFATR_END-1>{});
3081 
3082  if (pRecord)
3083  {
3084  // Note that the escher inner distance only seems to be honoured in
3085  // word for textboxes, not for graphics and ole objects.
3086  tools::Rectangle aInnerDist(0, 0, 0, 0);
3087 
3088  MatchSdrItemsIntoFlySet(rpObject, rFlySet, pRecord->eLineStyle,
3089  pRecord->eLineDashing, pRecord->eShapeType, aInnerDist);
3090 
3091  MatchEscherMirrorIntoFlySet(*pRecord, aGrSet);
3092  }
3093 
3094  OUString aObjectName(rpObject->GetName());
3095  if (OBJ_OLE2 == SdrObjKind(rpObject->GetObjIdentifier()))
3096  pRetFrameFormat = InsertOle(*static_cast<SdrOle2Obj*>(rpObject), rFlySet, &aGrSet);
3097  else
3098  {
3099  const SdrGrafObj *pGrf = static_cast<const SdrGrafObj*>(rpObject);
3100  bool bDone = false;
3101  if (pGrf->IsLinkedGraphic() && !pGrf->GetFileName().isEmpty())
3102  {
3103  GraphicType eType = pGrf->GetGraphicType();
3104  OUString aGrfName(
3106  INetURLObject(m_sBaseURL), pGrf->GetFileName(),
3108  // correction of fix for issue #i10939#:
3109  // One of the two conditions have to be true to insert the graphic
3110  // as a linked graphic -
3111  if (GraphicType::NONE == eType || CanUseRemoteLink(aGrfName))
3112  {
3113  pRetFrameFormat = m_rDoc.getIDocumentContentOperations().InsertGraphic(
3114  *m_pPaM, aGrfName, OUString(), nullptr,
3115  &rFlySet, &aGrSet, nullptr);
3116  bDone = true;
3117  }
3118  }
3119  if (!bDone)
3120  {
3121  const Graphic& rGraph = pGrf->GetGraphic();
3122  pRetFrameFormat = m_rDoc.getIDocumentContentOperations().InsertGraphic(
3123  *m_pPaM, OUString(), OUString(), &rGraph,
3124  &rFlySet, &aGrSet, nullptr);
3125  }
3126  }
3127 
3128  if (pRetFrameFormat)
3129  {
3130  if( pRecord )
3131  {
3132  if( OBJ_OLE2 != SdrObjKind(rpObject->GetObjIdentifier()) )
3133  SetAttributesAtGrfNode( pRecord, pRetFrameFormat, pF );
3134  }
3135  // avoid multiple occurrences of the same graphic name
3136  m_aGrfNameGenerator.SetUniqueGraphName(pRetFrameFormat, aObjectName);
3137  }
3138  // if everything is OK, determine pointer to new object and correct
3139  // Z-Order-List accordingly (or delete entry)
3140  rpOurNewObject = CreateContactObject(pRetFrameFormat);
3141 
3142  // remove old object from Z-Order-List
3143  m_xMSDffManager->RemoveFromShapeOrder( rpObject );
3144  // remove from Drawing-Page
3145  if( rpObject->getSdrPageFromSdrObject() )
3146  m_pDrawPg->RemoveObject( rpObject->GetOrdNum() );
3147 
3148  // and delete the object
3149  SdrObject::Free( rpObject );
3150  /*
3151  Warning: from now on query only pOrgShapeObject!
3152  */
3153 
3154  // add Contact-Object to the Z-Order-List and the page
3155  if (rpOurNewObject)
3156  {
3157  if (!m_bHdFtFootnoteEdn)
3158  m_xMSDffManager->StoreShapeOrder(pF->nSpId, 0, rpOurNewObject );
3159 
3160  // The Contact-Object MUST be set in the Draw-Page, so that in
3161  // SwWW8ImplReader::LoadDoc1() the Z-Order can be defined !!!
3162  if (!rpOurNewObject->IsInserted())
3163  {
3164  // pass information, if object is in page header|footer to method.
3165  m_xWWZOrder->InsertEscherObject( rpOurNewObject, pF->nSpId,
3166  m_bIsHeader || m_bIsFooter );
3167  }
3168  }
3169  return pRetFrameFormat;
3170 }
3171 
3172 void SwWW8ImplReader::GrafikCtor() // For SVDraw and VCControls and Escher
3173 {
3174  if (!m_pDrawModel)
3175  {
3176  m_rDoc.getIDocumentDrawModelAccess().GetOrCreateDrawModel(); // #i52858# - method name changed
3177  m_pDrawModel = m_rDoc.getIDocumentDrawModelAccess().GetDrawModel();
3178  OSL_ENSURE(m_pDrawModel, "Cannot create DrawModel");
3179  m_pDrawPg = m_pDrawModel->GetPage(0);
3180 
3181  m_xMSDffManager.reset(new SwMSDffManager(*this, m_bSkipImages));
3182  m_xMSDffManager->SetModel(m_pDrawModel, 1440);
3183  /*
3184  Now the dff manager always needs a controls converter as well, but a
3185  control converter may still exist without a dffmanager.
3186  */
3187  m_xFormImpl.reset(new SwMSConvertControls(m_pDocShell, m_pPaM));
3188 
3189  m_xWWZOrder.reset(new wwZOrderer(sw::util::SetLayer(m_rDoc), m_pDrawPg,
3190  m_xMSDffManager->GetShapeOrders()));
3191  }
3192 }
3193 
3195 {
3196  m_pDrawEditEngine.reset(); // maybe created by graphic
3197  m_xWWZOrder.reset(); // same
3198 }
3199 
3201 {
3202  OSL_ENSURE(pFormat->GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR,
3203  "Don't use fltanchors with inline frames, slap!");
3204  NewAttr(rPos, SwFltAnchor(pFormat));
3205 }
3206 
3208 {
3209  size_t nCnt = size();
3210  for (size_t i=0; i < nCnt; ++i)
3211  {
3212  SwFltStackEntry &rEntry = (*this)[i];
3213  SwPosition aDummy(rEntry.m_aMkPos.m_nNode);
3214  SetAttrInDoc(aDummy, rEntry);
3215  DeleteAndDestroy(i--);
3216  --nCnt;
3217  }
3218 }
3219 
3220 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void GrafikDtor()
Definition: ww8graf.cxx:3194
long Width() const
void SetTransparency(sal_uInt8 cTransparency)
constexpr TypedWhichId< SdrOnOffItem > SDRATTR_TEXT_AUTOGROWHEIGHT(SDRATTR_MISC_FIRST+2)
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
constexpr TypedWhichId< SvxFrameDirectionItem > RES_FRAMEDIR(120)
long GetWidth() const
sal_uInt16 nby
Definition: ww8struc.hxx:909
constexpr TypedWhichId< SdrGrafGamma100Item > SDRATTR_GRAFGAMMA(SDRATTR_GRAF_FIRST+5)
URL aURL
bool checkRead(SvStream &rSt, void *pDest, sal_uInt32 nLength)
Definition: ww8scan.cxx:8467
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
constexpr sal_uInt16 RES_FLTRATTR_BEGIN(RES_MSG_END)
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
SvxMSDffImportRec * find(const SdrObject *pObj)
sal_Int32 nDxTextLeft
std::unique_ptr< ContentProperties > pData
std::string GetValue
SwNodeIndex m_nNode
Definition: fltshell.hxx:51
SwFrameFormat * MungeTextIntoDrawBox(SvxMSDffImportRec *pRecord, long nGrafAnchorCp, SwFrameFormat *pRetFrameFormat)
Definition: ww8graf.cxx:2849
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
constexpr TypedWhichId< SwFormatFrameSize > RES_FRM_SIZE(89)
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
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)
constexpr TypedWhichId< XFillStyleItem > XATTR_FILLSTYLE(XATTR_FILL_FIRST)
sal_uInt16 GetCurrentId() const
Definition: ww8scan.hxx:283
static void AdjustLRWrapForWordMargins(const SvxMSDffImportRec &rRecord, SvxLRSpaceItem &rLR)
Definition: ww8graf.cxx:1904
constexpr TypedWhichId< XLineWidthItem > XATTR_LINEWIDTH(XATTR_LINE_FIRST+2)
const sal_uInt8 * pMemPos
Definition: ww8scan.hxx:853
#define WW8FL_NO_GRAFLAYER
Definition: ww8par.hxx:124
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:524
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)
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
constexpr TypedWhichId< XLineStyleItem > XATTR_LINESTYLE(XATTR_LINE_FIRST)
bool CanUseRemoteLink(const OUString &rGrfName)
Definition: ww8par5.cxx:2365
constexpr::Color COL_LIGHTRED(0xFF, 0x00, 0x00)
constexpr TypedWhichId< SvxOpaqueItem > RES_OPAQUE(99)
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
OBJ_PLIN
const OUString & GetName() const
Definition: ww8par.hxx:528
WW8_DP_LINEEND aEpp
Definition: ww8struc.hxx:755
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:522
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
constexpr TypedWhichId< SwFormatVertOrient > RES_VERT_ORIENT(102)
GPOS_TILED
WW8_DP_FILL aFill
Definition: ww8struc.hxx:801
SVBT16 dpk
Definition: ww8struc.hxx:699
sal_uInt16 sal_Unicode
const OUString & GetValue() const
Definition: fmtinfmt.hxx:75
static void ResetFrameFormatAttrs(SfxItemSet &rFrameSet)
Definition: shellio.cxx:612
long Right() const
void SetLeft(const long nL, const sal_uInt16 nProp=100)
MSO_LineDashing
constexpr TypedWhichId< SwFormatHoriOrient > RES_HORI_ORIENT(103)
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:3064
constexpr::Color COL_CYAN(0x00, 0x80, 0x80)
int nCount
constexpr sal_uInt16 POOLATTR_BEGIN(HINT_BEGIN)
sal_uLong GetIndex() const
Definition: ndindex.hxx:152
static void lcl_StripFields(OUString &rString, WW8_CP &rNewStartCp)
Definition: ww8graf.cxx:525
static void SetStdAttr(SfxItemSet &rSet, WW8_DP_LINETYPE &rL, WW8_DP_SHADOW const &rSh)
Definition: ww8graf.cxx:197
virtual void SetName(const OUString &rNewName, bool bBroadcast=false) override
Definition: atrfrm.cxx:2460
constexpr TypedWhichId< XColorItem > SDRATTR_SHADOWCOLOR(SDRATTR_SHADOW_FIRST+1)
SdrCaptionType
WW8_DP_LINETYPE aLnt
Definition: ww8struc.hxx:782
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:1739
void GrafikCtor()
Definition: ww8graf.cxx:3172
constexpr TypedWhichId< SdrOnOffItem > SDRATTR_SHADOW(SDRATTR_SHADOW_FIRST+0)
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)
constexpr TypedWhichId< SwFormatINetFormat > RES_TXTATR_INETFMT(51)
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:3385
DocumentType eType
SVBT16 dhgt
Definition: ww8struc.hxx:691
constexpr sal_uInt16 RES_FLTRATTR_END(195)
ContactObject for connection between frames (or their formats respectively) in SwClient and the drawo...
Definition: dcontact.hxx:175
void SendObjectToHeaven(SdrObject &rObject) const
Make Object lives in the top layer.
const Color & GetColor() const
sal_Int32 nDxTextRight
MSO_LineDashing eLineDashing
bool IsInRange(sal_uInt16 nWhich) const
virtual void SetLayer(SdrLayerID nLayer)
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
constexpr TypedWhichId< XFillTransparenceItem > XATTR_FILLTRANSPARENCE(XATTR_FILL_FIRST+5)
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:81
constexpr TypedWhichId< SdrGrafLuminanceItem > SDRATTR_GRAFLUMINANCE(SDRATTR_GRAF_FIRST+3)
int i
constexpr TypedWhichId< XFillBitmapItem > XATTR_FILLBITMAP(XATTR_FILL_FIRST+4)
mso_lineDashGEL
among others for fields, that is, the same number of attr as positions, if Ctor-Param bNoEnd = false ...
Definition: ww8scan.hxx: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()
SwFormat * m_pFormat
Definition: ww8par.hxx:228
const Graphic & GetGraphic() const
SwFrameFormat * AddAutoAnchor(SwFrameFormat *pFormat)
Definition: ww8graf.cxx:2834
std::unique_ptr< OutlinerParaObject > ImportAsOutliner(OUString &rString, WW8_CP nStartCp, WW8_CP nEndCp, ManTypes eType)
Definition: ww8graf.cxx:952
constexpr sal_uInt16 XATTR_START
WW8_DP_LINETYPE aLnt
Definition: ww8struc.hxx: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
sal_Int32 indexOfAny(OUString const &rIn, sal_Unicode const *const pChars, sal_Int32 const nPos)
void SetMergedItemSetAndBroadcast(const SfxItemSet &rSet, bool bClearAllItems=false)
void SetRed(sal_uInt8 nRed)
float u
void MatchEscherMirrorIntoFlySet(const SvxMSDffImportRec &rRecord, SfxItemSet &rFlySet)
Definition: ww8graf.cxx:3048
static const int RELTO_DEFAULT
constexpr TypedWhichId< SdrGrafModeItem > SDRATTR_GRAFMODE(SDRATTR_GRAF_FIRST+8)
long Bottom() const
SwFrameSize GetWidthSizeType() const
Definition: fmtfsize.hxx:83
void SetTop(sal_Int32 nVal)
sal_uInt32 GetOrdNum() const
WW8_DP_SHADOW aShd
Definition: ww8struc.hxx:756
constexpr TypedWhichId< SdrMetricItem > SDRATTR_SHADOWYDIST(SDRATTR_SHADOW_FIRST+3)
void Restore(SwWW8ImplReader *pRdr)
Definition: ww8par.cxx:2060
mso_lineThinThick
size
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
Definition: format.cxx:396
bool SeekPos(long nPos)
Definition: ww8scan.cxx:2172
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
constexpr sal_uInt16 RES_GRFATR_END(148)
const sal_uInt16 LN_CObjLocation
Definition: sprmids.hxx:45
sal_uInt32 nLayoutInTableCell
constexpr::Color COL_LIGHTMAGENTA(0xFF, 0x00, 0xFF)
ManTypes
Definition: ww8scan.hxx:866
void SetDistance(sal_uInt16 nNew, SvxBoxItemLine nLine)
::basegfx::B2DPolygon getB2DPolygon() const
void SetURL(const OUString &rURL, bool bServerMap)
Definition: atrfrm.cxx:1733
sal_Int32 nDyTextTop
constexpr sal_uInt16 XATTR_END
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
SfxItemPool * GetPool() const
SwFrameFormat * Read_GrafLayer(long nGrafAnchorCp)
Definition: ww8graf.cxx:2506
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
constexpr sal_uInt16 POOLATTR_END(RES_UNKNOWNATR_END)
static void removePositions(EditEngine &rDrawEditEngine, const std::vector< sal_Int32 > &rDosLineEndDummies)
Definition: ww8graf.cxx:943
WW8_DP_FILL aFill
Definition: ww8struc.hxx:783
sal_Int32 WW8_CP
Definition: ww8struc.hxx:153
virtual SdrLayerID GetLayer() const
bool Get(WW8_CP &rStart, void *&rpValue) const
Definition: ww8scan.cxx:2238
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:898
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:458
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:2944
bool IsLinkedGraphic() const
void GetPCDSprms(WW8PLCFxDesc &rDesc)
Definition: ww8scan.cxx:3236
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
constexpr sal_uInt16 RES_FRMATR_END(131)
constexpr TypedWhichId< XFillColorItem > XATTR_FILLCOLOR(XATTR_FILL_FIRST+1)
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
SVBT32 fc
Definition: ww8struc.hxx:667
constexpr TypedWhichId< SdrMetricItem > SDRATTR_SHADOWXDIST(SDRATTR_SHADOW_FIRST+2)
void setClosed(bool bNew)
void SetDashes(sal_uInt16 nNewDashes)
sal_uInt16 bRcaSimple
Definition: ww8struc.hxx:929
std::optional< sal_uInt32 > nYRelTo
#define SW_UD_IMAPDATA
Definition: ww8par.hxx:58
virtual bool IsVerticalWriting() const
mso_sptTextBox
sal_Int32 nDyWrapDistBottom
SfxItemState
constexpr TypedWhichId< SvxBrushItem > RES_BACKGROUND(105)
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
void SetName(const OUString &rNm)
Definition: fmturl.hxx:72
constexpr sal_uInt16 RES_GRFATR_BEGIN(RES_FRMATR_END)
SwTwips GetPos() const
Definition: fmtornt.hxx:59
sal_uInt16 GetId() const
const o3tl::enumarray< SvxAdjust, unsigned short > aSvxToUnoAdjust USHRT_MAX
Definition: unosett.cxx:253
void SetGreen(sal_uInt8 nGreen)
sal_uInt16 nSprmId
Definition: ww8scan.hxx:854
#define SAL_INFO(area, stream)
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:629
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)
constexpr TypedWhichId< XFillBmpTileItem > XATTR_FILLBMP_TILE(XATTR_FILL_FIRST+7)
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
constexpr TypedWhichId< SvxLRSpaceItem > RES_LR_SPACE(91)
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
constexpr TypedWhichId< SvxBoxItem > RES_BOX(106)
SdrObject * getParentSdrObjectFromSdrObject() const
const SwFormatContent & GetContent(bool=true) const
Definition: fmtcntnt.hxx:55
void SetPos(SwTwips nNew)
Definition: fmtornt.hxx:93
constexpr::Color COL_LIGHTBLUE(0x00, 0x00, 0xFF)
SVBT16 xaEnd
Definition: ww8struc.hxx:752
const sal_Int32 & GetShapeId() const
Definition: ww8par.hxx:526
WW8_DP_FILL aFill
Definition: ww8struc.hxx:773
SVBT16 dya
Definition: ww8struc.hxx:707
SdrMetricItem makeSdrTextRightDistItem(long mnHeight)
SdrObject * ReadArc(WW8_DPHEAD const *pHd, SfxAllItemSet &rSet)
Definition: ww8graf.cxx:390
sal_Int32 nDyWrapDistTop
constexpr TypedWhichId< SdrGrafContrastItem > SDRATTR_GRAFCONTRAST(SDRATTR_GRAF_FIRST+4)
#define SAL_WARN(area, stream)
SdrObject * ReadLine(WW8_DPHEAD const *pHd, SfxAllItemSet &rSet)
Definition: ww8graf.cxx:308
RndStdIds
void SendObjectToHell(SdrObject &rObject) const
Make Object live in the bottom drawing layer.
constexpr::Color COL_BLUE(0x00, 0x00, 0x80)
constexpr sal_uInt16 EE_FEATURE_FIELD(EE_FEATURE_NOTCONV+1)
SdrObject * pObj
std::optional< sal_uInt32 > nXRelTo
virtual void NbcSetSnapRect(const tools::Rectangle &rRect) override
sal_uInt16 nwr
Definition: ww8struc.hxx:914
bool m_bColl
Definition: ww8par.hxx:250
const SwPosition & GetStartPos() const
Definition: ww8par.hxx:625
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)
constexpr TypedWhichId< XLineColorItem > XATTR_LINECOLOR(XATTR_LINE_FIRST+3)
mso_lineSimple
void AddAnchor(const SwPosition &rPos, SwFrameFormat *pFormat)
Definition: ww8graf.cxx:3200
static std::vector< sal_Int32 > replaceDosLineEndsButPreserveLength(OUString &rIn)
Definition: ww8graf.cxx:917
const sal_uInt8 * pMemPos
Definition: ww8scan.hxx:879
static ESelection GetESelection(EditEngine const &rDrawEditEngine, long nCpStart, long nCpEnd)
Definition: ww8graf.cxx:465
constexpr sal_uInt16 RES_FRMATR_BEGIN(RES_PARATR_LIST_END)
sal_Int32 nYaTop
Definition: ww8struc.hxx:898
WW8_DP_FILL aFill
Definition: ww8struc.hxx:794
SdrObject * FindSdrObject()
Definition: frmfmt.hxx:137
constexpr TypedWhichId< SvxULSpaceItem > RES_UL_SPACE(92)
WW8_DP_LINETYPE aLnt
Definition: ww8struc.hxx:761
virtual void SetVerticalWriting(bool bVertical)
sal_uInt16 Which() const
SdrObject * FindRealSdrObject()
Definition: atrfrm.cxx:2706
constexpr TypedWhichId< SvxShadowItem > RES_SHADOW(107)
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:1483
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