Line data Source code
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 <svx/fmglob.hxx>
25 : #include <svx/sdtaitm.hxx>
26 : #include <editeng/lrspitem.hxx>
27 : #include <editeng/udlnitem.hxx>
28 : #include <svx/xlineit.hxx>
29 : #include <svx/xfillit.hxx>
30 : #include <svx/svdmodel.hxx>
31 : #include <svx/svdocapt.hxx>
32 : #include <svx/sxctitm.hxx>
33 : #include <editeng/editeng.hxx>
34 : #include <svx/svdpage.hxx>
35 : #include <svx/svdopath.hxx>
36 : #include <svx/svdocirc.hxx>
37 : #include <editeng/outlobj.hxx>
38 : #include <svx/svdogrp.hxx>
39 : #include <svx/svdograf.hxx>
40 : #include <svx/svdoole2.hxx>
41 : #include <editeng/colritem.hxx>
42 : #include <editeng/fhgtitem.hxx>
43 : #include <editeng/postitem.hxx>
44 : #include <editeng/adjustitem.hxx>
45 : #include <editeng/wghtitem.hxx>
46 : #include <editeng/crossedoutitem.hxx>
47 : #include <editeng/contouritem.hxx>
48 : #include <editeng/shdditem.hxx>
49 : #include <editeng/fontitem.hxx>
50 : #include <editeng/ulspitem.hxx>
51 : #include <svx/svdoattr.hxx>
52 : #include <editeng/brushitem.hxx>
53 : #include <svx/rectenum.hxx>
54 : #include <editeng/opaqitem.hxx>
55 : #include <editeng/shaditem.hxx>
56 : #include <editeng/boxitem.hxx>
57 : #include <editeng/outliner.hxx>
58 : #include <editeng/frmdiritem.hxx>
59 : #include <svx/xfltrit.hxx>
60 : #include <filter/msfilter/msdffimp.hxx>
61 : #include <grfatr.hxx> // class SwCropGrf
62 : #include <fmtornt.hxx>
63 : #include <fmtcntnt.hxx>
64 : #include <frmfmt.hxx>
65 : #include <fmtanchr.hxx>
66 : #include <pam.hxx>
67 : #include <doc.hxx>
68 : #include <docary.hxx>
69 : #include <ndgrf.hxx>
70 : #include <ndtxt.hxx>
71 : #include <dcontact.hxx>
72 : #include <docsh.hxx>
73 : #include <mdiexp.hxx> // Progress
74 : #include <fmtcnct.hxx>
75 : #include "ww8struc.hxx"
76 : #include "ww8scan.hxx"
77 : #include "ww8par.hxx" // class SwWWImplReader
78 : #include "ww8par2.hxx" // SwWW8StyInf
79 : #include "ww8graf.hxx"
80 : #include <fmtinfmt.hxx>
81 : #include <editeng/eeitem.hxx>
82 : #include <editeng/flditem.hxx>
83 : // #i18732#
84 : #include <fmtfollowtextflow.hxx>
85 : #include "writerhelper.hxx"
86 : #include "writerwordglue.hxx"
87 : #include <basegfx/point/b2dpoint.hxx>
88 : #include <basegfx/polygon/b2dpolygon.hxx>
89 : #include <editeng/editobj.hxx>
90 : #include <boost/scoped_ptr.hpp>
91 : #include <math.h>
92 :
93 : using ::editeng::SvxBorderLine;
94 : using namespace ::com::sun::star;
95 : using namespace sw::types;
96 : using namespace sw::util;
97 :
98 : // Hilfsroutinen
99 :
100 0 : Color WW8TransCol(SVBT32 nWC)
101 : {
102 : #if 1 // 1 = Vordefinierte Farben benutzen, 0 = ignorieren
103 :
104 : // Farbtabelle zum Umrechnen RGB-Werte in vordefinierte Farben
105 : // ( Damit bei der Writer-UI die Farbnamen stimmen )
106 : // Die Tabelle int im *3er-System* aufgeteilt. Die Grauwerte fehlen,
107 : // da sie nicht ins 3er-System passen ( 4 Werte: sw, ws, 2 * grau )
108 : static ColorData eColA[] = { // B G R B G R B G R
109 : COL_BLACK, COL_RED, COL_LIGHTRED, // 0 0 0, 0 0 1, 0 0 2
110 : COL_GREEN, COL_BROWN, COL_BLACK, // 0 1 0, 0 1 1, 0 1 2
111 : COL_LIGHTGREEN, COL_BLACK, COL_YELLOW, // 0 2 0, 0 2 1, 0 2 2
112 : COL_BLUE, COL_MAGENTA, COL_BLACK, // 1 0 0, 1 0 1, 1 0 2
113 : COL_CYAN, COL_LIGHTGRAY, COL_BLACK, // 1 1 0, 1 1 1, 1 1 2
114 : COL_BLACK, COL_BLACK, COL_BLACK, // 1 2 0, 1 2 1, 1 2 2
115 : COL_LIGHTBLUE, COL_BLACK, COL_LIGHTMAGENTA, // 2 0 0, 2 0 1, 2 0 2
116 : COL_BLACK, COL_BLACK, COL_BLACK, // 2 1 0, 2 1 1, 2 1 2
117 : COL_LIGHTCYAN, COL_BLACK, COL_WHITE }; // 2 2 0, 2 2 1, 2 2 2
118 :
119 : // In nWC[3] steht ein Byte, dass in der WW-Doku nicht beschrieben ist.
120 : // Die Bedeutung ist anscheinend folgende: Bei 0 ist es eine normale
121 : // Farbe, dessen RGB-Wert in nWC[0..2] steht. stehen in nWC[3] die
122 : // Werte 0x1, 0x7d oder 0x83, dann ist es ein Grauwert, dessen
123 : // Schwarzanteil in 1/2 % in nWC[0] steht.
124 : // Ich vermute, dass es auf Bit0 in nWV[3] ankommt, ob es RGB oder Grau ist.
125 :
126 0 : if( !( nWC[3] & 0x1 ) && // keine Spezial-Farbe (grau)
127 0 : ( ( nWC[0] == 0 || nWC[0]== 0x80 || nWC[0] == 0xff ) // R-Anteil
128 0 : && ( nWC[1] == 0 || nWC[1]== 0x80 || nWC[1] == 0xff ) // G-Anteil
129 0 : && ( nWC[2] == 0 || nWC[2]== 0x80 || nWC[2] == 0xff ) ) ){// B-Anteil
130 0 : int nIdx = 0; // und nun: Idx-Berechnung im 3er-System
131 0 : for (int i = 2; i >= 0; i--)
132 : {
133 0 : nIdx *= 3;
134 0 : if (nWC[i])
135 0 : nIdx += ((nWC[i] == 0xff) ? 2 : 1);
136 : }
137 0 : if (eColA[nIdx] != COL_BLACK)
138 0 : return Color(eColA[nIdx]); // Standard-Color
139 : }
140 : #endif
141 :
142 0 : if (nWC[3] & 0x1)
143 : {
144 : //Special colour gray
145 0 : sal_uInt8 u = (sal_uInt8)( (sal_uLong)( 200 - nWC[0] ) * 256 / 200 );
146 0 : return Color(u, u, u);
147 : }
148 :
149 : // User-Color
150 0 : return Color(nWC[0], nWC[1], nWC[2]);
151 : }
152 :
153 13 : void wwFrameNamer::SetUniqueGraphName(SwFrmFmt *pFrmFmt, const OUString &rFixed)
154 : {
155 13 : if (mbIsDisabled || rFixed.isEmpty())
156 26 : return;
157 :
158 0 : pFrmFmt->SetName(msSeed+OUString::valueOf(++mnImportedGraphicsCount) + ": " + rFixed);
159 : }
160 :
161 : // ReadGrafStart liest die ObjektDaten ein und erzeugt falls noetig einen Anker
162 0 : bool SwWW8ImplReader::ReadGrafStart(void* pData, short nDataSiz,
163 : WW8_DPHEAD* pHd, const WW8_DO* pDo, SfxAllItemSet &rSet)
164 : {
165 0 : if (SVBT16ToShort(pHd->cb) < sizeof(WW8_DPHEAD) + nDataSiz)
166 : {
167 : OSL_ENSURE( !this, "+Grafik-Element: Size ?" );
168 0 : pStrm->SeekRel(SVBT16ToShort(pHd->cb) - sizeof(WW8_DPHEAD));
169 0 : return false;
170 : }
171 :
172 0 : bool bCouldRead = checkRead(*pStrm, pData, nDataSiz);
173 : OSL_ENSURE(bCouldRead, "Short Graphic header");
174 0 : if (!bCouldRead)
175 0 : return false;
176 :
177 0 : RndStdIds eAnchor = (SVBT8ToByte(pDo->by) < 2) ? FLY_AT_PAGE : FLY_AT_PARA;
178 0 : rSet.Put(SwFmtAnchor(eAnchor));
179 :
180 0 : nDrawXOfs2 = nDrawXOfs;
181 0 : nDrawYOfs2 = nDrawYOfs;
182 :
183 0 : if (eAnchor == FLY_AT_PARA)
184 : {
185 0 : if( SVBT8ToByte( pDo->bx ) == 1 ) // Pos: echt links
186 0 : nDrawXOfs2 = static_cast< short >(nDrawXOfs2 - maSectionManager.GetPageLeft());
187 0 : if( nInTable ) // Obj in Table
188 0 : nDrawXOfs2 = nDrawXOfs2 - GetTableLeft(); // -> siehe Kommentar
189 : // bei GetTableLeft()
190 : }
191 : else
192 : {
193 0 : if( SVBT8ToByte( pDo->bx ) != 1 )
194 0 : nDrawXOfs2 = static_cast< short >(nDrawXOfs2 + maSectionManager.GetPageLeft());
195 : }
196 :
197 0 : return true;
198 : }
199 :
200 : // SetStdAttr() setzt die Attribute, die jedes Objekt hat
201 :
202 0 : static void SetStdAttr( SfxItemSet& rSet, WW8_DP_LINETYPE& rL,
203 : WW8_DP_SHADOW& rSh )
204 : {
205 0 : if( SVBT16ToShort( rL.lnps ) == 5 ){ // unsichtbar
206 0 : rSet.Put( XLineStyleItem( XLINE_NONE ) );
207 : }else{ // sichtbar
208 0 : Color aCol( WW8TransCol( rL.lnpc ) ); // LinienFarbe
209 0 : rSet.Put( XLineColorItem( aEmptyStr, aCol ) );
210 0 : rSet.Put( XLineWidthItem( SVBT16ToShort( rL.lnpw ) ) );
211 : // LinienDicke
212 0 : if( SVBT16ToShort( rL.lnps ) >= 1
213 0 : && SVBT16ToShort(rL.lnps ) <= 4 ){ // LinienStil
214 0 : rSet.Put( XLineStyleItem( XLINE_DASH ) );
215 0 : sal_Int16 nLen = SVBT16ToShort( rL.lnpw );
216 0 : XDash aD( XDASH_RECT, 1, 2 * nLen, 1, 5 * nLen, 5 * nLen );
217 0 : switch( SVBT16ToShort( rL.lnps ) ){
218 0 : case 1: aD.SetDots( 0 ); // Dash
219 0 : aD.SetDashLen( 6 * nLen );
220 0 : aD.SetDistance( 4 * nLen );
221 0 : break;
222 0 : case 2: aD.SetDashes( 0 ); break; // Dot
223 0 : case 3: break; // Dash Dot
224 0 : case 4: aD.SetDots( 2 ); break; // Dash Dot Dot
225 : }
226 0 : rSet.Put( XLineDashItem( aEmptyStr, aD ) );
227 : }else{
228 0 : rSet.Put( XLineStyleItem( XLINE_SOLID ) ); // noetig fuer TextBox
229 : }
230 : }
231 0 : if( SVBT16ToShort( rSh.shdwpi ) ){ // Schatten
232 0 : rSet.Put(SdrShadowItem(true));
233 0 : rSet.Put( SdrShadowXDistItem( SVBT16ToShort( rSh.xaOffset ) ) );
234 0 : rSet.Put( SdrShadowYDistItem( SVBT16ToShort( rSh.yaOffset ) ) );
235 : }
236 0 : }
237 :
238 : // SetFill setzt Fuellattribute wie Vordergrund- und Hintergrund-Farbe
239 : // und Muster durch Reduktion auf eine Farbe.
240 : // SetFill() setzt z.Zt kein Muster, da Sdr das nur sehr umstaendlich kann
241 : // und die Sdr-Schraffur ( XDash ) noch nicht fertig ist.
242 : // Statt dessen wird eine Mischfarbe gewaehlt, die auf den entsprechenden
243 : // Farbton zwischen den Farben liegt.
244 :
245 0 : static void SetFill( SfxItemSet& rSet, WW8_DP_FILL& rFill )
246 : {
247 : static sal_uInt8 nPatA[] =
248 : {
249 : 0, 0, 5, 10, 20, 25, 30, 40, 50, 60, 70, 75, 80,
250 : 90, 50, 50, 50, 50, 50, 50, 33, 33, 33, 33, 33, 33
251 : };
252 0 : sal_uInt16 nPat = SVBT16ToShort(rFill.flpp);
253 :
254 0 : if (nPat == 0) // transparent
255 0 : rSet.Put(XFillStyleItem(XFILL_NONE));
256 : else
257 : {
258 0 : rSet.Put(XFillStyleItem(XFILL_SOLID)); // necessary for textbox
259 0 : if (nPat <= 1 || ((sizeof(nPatA)/sizeof(nPatA[0])) <= nPat))
260 : {
261 : // Solid Background or unknown
262 0 : rSet.Put(XFillColorItem(aEmptyStr, WW8TransCol(rFill.dlpcBg)));
263 : }
264 : else
265 : { // Brush -> Farbmischung
266 0 : Color aB( WW8TransCol( rFill.dlpcBg ) );
267 0 : Color aF( WW8TransCol( rFill.dlpcFg ) );
268 0 : aB.SetRed( (sal_uInt8)( ( (sal_uLong)aF.GetRed() * nPatA[nPat]
269 0 : + (sal_uLong)aB.GetRed() * ( 100 - nPatA[nPat] ) ) / 100 ) );
270 0 : aB.SetGreen( (sal_uInt8)( ( (sal_uLong)aF.GetGreen() * nPatA[nPat]
271 0 : + (sal_uLong)aB.GetGreen() * ( 100 - nPatA[nPat] ) ) / 100 ) );
272 0 : aB.SetBlue( (sal_uInt8)( ( (sal_uLong)aF.GetBlue() * nPatA[nPat]
273 0 : + (sal_uLong)aB.GetBlue() * ( 100 - nPatA[nPat] ) ) / 100 ) );
274 0 : rSet.Put( XFillColorItem( aEmptyStr, aB ) );
275 : }
276 : }
277 0 : }
278 :
279 0 : static void SetLineEndAttr( SfxItemSet& rSet, WW8_DP_LINEEND& rLe,
280 : WW8_DP_LINETYPE& rLt )
281 : {
282 0 : sal_uInt16 aSB = SVBT16ToShort( rLe.aStartBits );
283 0 : if( aSB & 0x3 )
284 : {
285 0 : ::basegfx::B2DPolygon aPolygon;
286 0 : aPolygon.append(::basegfx::B2DPoint(0.0, 330.0));
287 0 : aPolygon.append(::basegfx::B2DPoint(100.0, 0.0));
288 0 : aPolygon.append(::basegfx::B2DPoint(200.0, 330.0));
289 0 : aPolygon.setClosed(true);
290 0 : rSet.Put( XLineEndItem( aEmptyStr, ::basegfx::B2DPolyPolygon(aPolygon) ) );
291 0 : sal_uInt16 nSiz = SVBT16ToShort( rLt.lnpw )
292 0 : * ( ( aSB >> 2 & 0x3 ) + ( aSB >> 4 & 0x3 ) );
293 0 : if( nSiz < 220 ) nSiz = 220;
294 0 : rSet.Put(XLineEndWidthItem(nSiz));
295 0 : rSet.Put(XLineEndCenterItem(false));
296 : }
297 :
298 0 : sal_uInt16 aEB = SVBT16ToShort( rLe.aEndBits );
299 0 : if( aEB & 0x3 ){
300 0 : ::basegfx::B2DPolygon aPolygon;
301 0 : aPolygon.append(::basegfx::B2DPoint(0.0, 330.0));
302 0 : aPolygon.append(::basegfx::B2DPoint(100.0, 0.0));
303 0 : aPolygon.append(::basegfx::B2DPoint(200.0, 330.0));
304 0 : aPolygon.setClosed(true);
305 0 : rSet.Put( XLineStartItem( aEmptyStr, ::basegfx::B2DPolyPolygon(aPolygon) ) );
306 0 : sal_uInt16 nSiz = SVBT16ToShort( rLt.lnpw )
307 0 : * ( ( aEB >> 2 & 0x3 ) + ( aEB >> 4 & 0x3 ) );
308 0 : if( nSiz < 220 ) nSiz = 220;
309 0 : rSet.Put(XLineStartWidthItem(nSiz));
310 0 : rSet.Put(XLineStartCenterItem(false));
311 : }
312 0 : }
313 :
314 : // Ab hier folgen die Routinen fuer die einzelnen Objekte
315 0 : SdrObject* SwWW8ImplReader::ReadLine( WW8_DPHEAD* pHd, const WW8_DO* pDo,
316 : SfxAllItemSet &rSet)
317 : {
318 : WW8_DP_LINE aLine;
319 :
320 0 : if( !ReadGrafStart( (void*)&aLine, sizeof( aLine ), pHd, pDo, rSet ) )
321 0 : return 0;
322 :
323 0 : Point aP[2];
324 : {
325 0 : Point& rP0 = aP[0];
326 0 : Point& rP1 = aP[1];
327 :
328 0 : rP0.X() = (sal_Int16)SVBT16ToShort( pHd->xa ) + nDrawXOfs2;
329 0 : rP0.Y() = (sal_Int16)SVBT16ToShort( pHd->ya ) + nDrawYOfs2;
330 0 : rP1 = rP0;
331 0 : rP0.X() += (sal_Int16)SVBT16ToShort( aLine.xaStart );
332 0 : rP0.Y() += (sal_Int16)SVBT16ToShort( aLine.yaStart );
333 0 : rP1.X() += (sal_Int16)SVBT16ToShort( aLine.xaEnd );
334 0 : rP1.Y() += (sal_Int16)SVBT16ToShort( aLine.yaEnd );
335 : }
336 :
337 0 : ::basegfx::B2DPolygon aPolygon;
338 0 : aPolygon.append(::basegfx::B2DPoint(aP[0].X(), aP[0].Y()));
339 0 : aPolygon.append(::basegfx::B2DPoint(aP[1].X(), aP[1].Y()));
340 0 : SdrObject* pObj = new SdrPathObj(OBJ_LINE, ::basegfx::B2DPolyPolygon(aPolygon));
341 :
342 0 : SetStdAttr( rSet, aLine.aLnt, aLine.aShd );
343 0 : SetLineEndAttr( rSet, aLine.aEpp, aLine.aLnt );
344 :
345 0 : return pObj;
346 : }
347 :
348 0 : SdrObject* SwWW8ImplReader::ReadRect( WW8_DPHEAD* pHd, const WW8_DO* pDo,
349 : SfxAllItemSet &rSet)
350 : {
351 : WW8_DP_RECT aRect;
352 :
353 0 : if( !ReadGrafStart( (void*)&aRect, sizeof( aRect ), pHd, pDo, rSet ) )
354 0 : return 0;
355 :
356 0 : Point aP0( (sal_Int16)SVBT16ToShort( pHd->xa ) + nDrawXOfs2,
357 0 : (sal_Int16)SVBT16ToShort( pHd->ya ) + nDrawYOfs2 );
358 0 : Point aP1( aP0 );
359 0 : aP1.X() += (sal_Int16)SVBT16ToShort( pHd->dxa );
360 0 : aP1.Y() += (sal_Int16)SVBT16ToShort( pHd->dya );
361 :
362 0 : SdrObject* pObj = new SdrRectObj( Rectangle( aP0, aP1 ) );
363 :
364 0 : SetStdAttr( rSet, aRect.aLnt, aRect.aShd );
365 0 : SetFill( rSet, aRect.aFill );
366 :
367 0 : return pObj;
368 : }
369 :
370 0 : SdrObject* SwWW8ImplReader::ReadElipse( WW8_DPHEAD* pHd, const WW8_DO* pDo,
371 : SfxAllItemSet &rSet)
372 : {
373 : WW8_DP_ELIPSE aElipse;
374 :
375 0 : if( !ReadGrafStart( (void*)&aElipse, sizeof( aElipse ), pHd, pDo, rSet ) )
376 0 : return 0;
377 :
378 0 : Point aP0( (sal_Int16)SVBT16ToShort( pHd->xa ) + nDrawXOfs2,
379 0 : (sal_Int16)SVBT16ToShort( pHd->ya ) + nDrawYOfs2 );
380 0 : Point aP1( aP0 );
381 0 : aP1.X() += (sal_Int16)SVBT16ToShort( pHd->dxa );
382 0 : aP1.Y() += (sal_Int16)SVBT16ToShort( pHd->dya );
383 :
384 0 : SdrObject* pObj = new SdrCircObj( OBJ_CIRC, Rectangle( aP0, aP1 ) );
385 :
386 0 : SetStdAttr( rSet, aElipse.aLnt, aElipse.aShd );
387 0 : SetFill( rSet, aElipse.aFill );
388 :
389 0 : return pObj;
390 : }
391 :
392 0 : SdrObject* SwWW8ImplReader::ReadArc( WW8_DPHEAD* pHd, const WW8_DO* pDo,
393 : SfxAllItemSet &rSet)
394 : {
395 : WW8_DP_ARC aArc;
396 :
397 0 : if( !ReadGrafStart( (void*)&aArc, sizeof( aArc ), pHd, pDo, rSet ) )
398 0 : return 0;
399 :
400 0 : Point aP0( (sal_Int16)SVBT16ToShort( pHd->xa ) + nDrawXOfs2,
401 0 : (sal_Int16)SVBT16ToShort( pHd->ya ) + nDrawYOfs2 );
402 0 : Point aP1( aP0 );
403 0 : aP1.X() += (sal_Int16)SVBT16ToShort( pHd->dxa ) * 2;
404 0 : aP1.Y() += (sal_Int16)SVBT16ToShort( pHd->dya ) * 2;
405 :
406 0 : short nA[] = { 2, 3, 1, 0 };
407 0 : short nW = nA[ ( ( SVBT8ToByte( aArc.fLeft ) & 1 ) << 1 )
408 0 : + ( SVBT8ToByte( aArc.fUp ) & 1 ) ];
409 0 : if( !SVBT8ToByte( aArc.fLeft ) ){
410 0 : aP0.Y() -= (sal_Int16)SVBT16ToShort( pHd->dya );
411 0 : aP1.Y() -= (sal_Int16)SVBT16ToShort( pHd->dya );
412 : }
413 0 : if( SVBT8ToByte( aArc.fUp ) ){
414 0 : aP0.X() -= (sal_Int16)SVBT16ToShort( pHd->dxa );
415 0 : aP1.X() -= (sal_Int16)SVBT16ToShort( pHd->dxa );
416 : }
417 :
418 : SdrObject* pObj = new SdrCircObj( OBJ_SECT, Rectangle( aP0, aP1 ),
419 0 : nW * 9000, ( ( nW + 1 ) & 3 ) * 9000 );
420 :
421 0 : SetStdAttr( rSet, aArc.aLnt, aArc.aShd );
422 0 : SetFill( rSet, aArc.aFill );
423 :
424 0 : return pObj;
425 : }
426 :
427 0 : SdrObject* SwWW8ImplReader::ReadPolyLine( WW8_DPHEAD* pHd, const WW8_DO* pDo,
428 : SfxAllItemSet &rSet)
429 : {
430 : WW8_DP_POLYLINE aPoly;
431 :
432 0 : if( !ReadGrafStart( (void*)&aPoly, sizeof( aPoly ), pHd, pDo, rSet ) )
433 0 : return 0;
434 :
435 0 : sal_uInt16 nCount = SVBT16ToShort( aPoly.aBits1 ) >> 1 & 0x7fff;
436 0 : boost::scoped_array<SVBT16> xP(new SVBT16[nCount * 2]);
437 :
438 0 : bool bCouldRead = checkRead(*pStrm, xP.get(), nCount * 4); // Punkte einlesen
439 : OSL_ENSURE(bCouldRead, "Short PolyLine header");
440 0 : if (!bCouldRead)
441 0 : return 0;
442 :
443 0 : Polygon aP( nCount );
444 0 : Point aPt;
445 0 : for (sal_uInt16 i=0; i<nCount; ++i)
446 : {
447 0 : aPt.X() = SVBT16ToShort( xP[i << 1] ) + nDrawXOfs2
448 0 : + (sal_Int16)SVBT16ToShort( pHd->xa );
449 0 : aPt.Y() = SVBT16ToShort( xP[( i << 1 ) + 1] ) + nDrawYOfs2
450 0 : + (sal_Int16)SVBT16ToShort( pHd->ya );
451 0 : aP[i] = aPt;
452 : }
453 0 : xP.reset();
454 :
455 0 : SdrObject* pObj = new SdrPathObj(( SVBT16ToShort( aPoly.aBits1 ) & 0x1 ) ? OBJ_POLY : OBJ_PLIN, ::basegfx::B2DPolyPolygon(aP.getB2DPolygon()));
456 0 : SetStdAttr( rSet, aPoly.aLnt, aPoly.aShd );
457 0 : SetFill( rSet, aPoly.aFill );
458 :
459 0 : return pObj;
460 : }
461 :
462 120 : ESelection SwWW8ImplReader::GetESelection( long nCpStart, long nCpEnd )
463 : {
464 120 : sal_Int32 nPCnt = mpDrawEditEngine->GetParagraphCount();
465 120 : sal_Int32 nSP = 0;
466 120 : sal_Int32 nEP = 0;
467 240 : while( (nSP < nPCnt)
468 120 : && (nCpStart >= mpDrawEditEngine->GetTextLen( nSP ) + 1) )
469 : {
470 0 : nCpStart -= mpDrawEditEngine->GetTextLen( nSP ) + 1;
471 0 : nSP++;
472 : }
473 : // Beim Ende erst 1 Zeichen spaeter auf naechste Zeile umschalten,
474 : // da sonst Zeilenattribute immer eine Zeile zu weit reichen.
475 240 : while( (nEP < nPCnt)
476 120 : && (nCpEnd > mpDrawEditEngine->GetTextLen( nEP ) + 1) )
477 : {
478 0 : nCpEnd -= mpDrawEditEngine->GetTextLen( nEP ) + 1;
479 0 : nEP++;
480 : }
481 120 : return ESelection( nSP, nCpStart, nEP, nCpEnd );
482 : }
483 :
484 : // InsertTxbxStyAttrs() setzt die Style-Attribute in den uebergebenen ItemSet.
485 : // Es werden die SW-Styles genommen, die Import-WW-Styles sind zu diesem
486 : // Zeitpunkt schon destruiert.
487 : // Die SW-Styles werden per Tiefensuche, d.h. mit Parent-Styles nach den
488 : // in aSrcTab angegebenen Attributen untersucht. Diese werden per Clone
489 : // dupliziert, bei den Duplikaten werden die Which-IDs
490 : // gemaess der Tabelle aDstTab umgesetzt, damit die EditEngine sie nicht
491 : // ignoriert.
492 : // Es werden hierbei sowohl Para- wie auch Zeichen-Attribute in den
493 : // ItemSet gestopft.
494 120 : void SwWW8ImplReader::InsertTxbxStyAttrs( SfxItemSet& rS, sal_uInt16 nColl )
495 : {
496 120 : SwWW8StyInf * pStyInf = GetStyle(nColl);
497 120 : if( pStyInf != NULL && pStyInf->pFmt && pStyInf->bColl )
498 : {
499 : const SfxPoolItem* pItem;
500 17400 : 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 17280 : if ( SFX_ITEM_SET == pStyInf->pFmt->GetItemState(
505 17280 : i, true, &pItem ) )
506 : {
507 1465 : SfxItemPool *pEditPool = rS.GetPool();
508 1465 : sal_uInt16 nWhich = i;
509 1465 : sal_uInt16 nSlotId = rDoc.GetAttrPool().GetSlotId(nWhich);
510 1465 : if (
511 2930 : nSlotId && nWhich != nSlotId &&
512 2930 : 0 != (nWhich = pEditPool->GetWhich(nSlotId)) &&
513 2690 : nWhich != nSlotId &&
514 1225 : ( SFX_ITEM_SET != rS.GetItemState(nWhich, false) )
515 : )
516 : {
517 1050 : SfxPoolItem* pCopy = pItem->Clone();
518 1050 : pCopy->SetWhich( nWhich );
519 1050 : rS.Put( *pCopy );
520 1050 : delete pCopy;
521 : }
522 : }
523 : }
524 : }
525 :
526 120 : }
527 :
528 61 : static void lcl_StripFields(String &rString, long &rNewStartCp)
529 : {
530 627 : for(sal_uInt16 i=0; i < rString.Len(); i++)
531 : {
532 566 : if( 0x13 == rString.GetChar( i ) )
533 : {
534 0 : do
535 : {
536 0 : rString.Erase( i, 1 );
537 0 : rNewStartCp++;
538 : }
539 0 : while( rString.Len()
540 0 : && ( i < rString.Len())
541 0 : && (0x14 != rString.GetChar( i ) )
542 0 : && (0x15 != rString.GetChar( i ) ) );
543 0 : if( rString.Len() )
544 : {
545 0 : if( 0x14 == rString.GetChar( i ) )
546 : {
547 0 : rString.Erase( i, 1 );
548 0 : rNewStartCp++;
549 0 : do
550 : {
551 0 : i++;
552 : }
553 0 : while( rString.Len()
554 0 : && ( i < rString.Len())
555 0 : && (0x15 != rString.GetChar( i ) ) );
556 0 : if( i < rString.Len() )
557 0 : rString.Erase( i, 1 );
558 : }
559 0 : else if( 0x15 == rString.GetChar( i ) )
560 0 : rString.Erase( i, 1 );
561 : }
562 : }
563 : }
564 61 : }
565 :
566 0 : class Chunk
567 : {
568 : private:
569 : String msURL;
570 : long mnStartPos; //0x13
571 : long mnEndPos; //0x15
572 : public:
573 0 : explicit Chunk(long nStart, const String &rURL)
574 0 : : msURL(rURL), mnStartPos(nStart), mnEndPos(0) {}
575 0 : Chunk(const Chunk &rChunk)
576 : : msURL(rChunk.msURL), mnStartPos(rChunk.mnStartPos),
577 0 : mnEndPos(rChunk.mnEndPos) {}
578 : Chunk& operator=(const Chunk &rChunk)
579 : {
580 : msURL = rChunk.msURL;
581 : mnStartPos = rChunk.mnStartPos;
582 : mnEndPos = rChunk.mnEndPos;
583 : return *this;
584 : }
585 0 : void SetEndPos(long nEnd) { mnEndPos = nEnd; }
586 0 : long GetStartPos() const {return mnStartPos;}
587 0 : long GetEndPos() const {return mnEndPos;}
588 0 : const String &GetURL() const {return msURL;}
589 0 : void Adjust(xub_StrLen nAdjust)
590 : {
591 0 : mnStartPos-=nAdjust;
592 0 : mnEndPos-=nAdjust;
593 0 : }
594 : };
595 :
596 : // InsertAttrsAsDrawingAttrs() setzt zwischen StartCp und EndCp die Attribute.
597 : // Dabei werden Style-Attribute als harte Attribute, Absatz- und Zeichen-
598 : // attribute gesetzt.
599 57 : void SwWW8ImplReader::InsertAttrsAsDrawingAttrs(long nStartCp, long nEndCp,
600 : ManTypes eType, bool bONLYnPicLocFc)
601 : {
602 : /*
603 : Save and create new plcxman for this drawing object, of the type that
604 : will include the para end mark inside a paragraph property range, as
605 : drawing boxes have real paragraph marks as part of their text, while
606 : normal writer has separate nodes for each paragraph and so has no actual
607 : paragraph mark as part of the paragraph text.
608 : */
609 57 : WW8ReaderSave aSave(this);
610 57 : pPlcxMan = new WW8PLCFMan(pSBase, eType, nStartCp, true);
611 :
612 57 : WW8_CP nStart = pPlcxMan->Where();
613 57 : WW8_CP nNext, nEnd, nStartReplace=0;
614 :
615 57 : bool bDoingSymbol = false;
616 57 : sal_Unicode cReplaceSymbol = cSymbol;
617 :
618 57 : SfxItemSet *pS = new SfxItemSet(mpDrawEditEngine->GetEmptyItemSet());
619 : WW8PLCFManResult aRes;
620 :
621 114 : std::deque<Chunk> aChunks;
622 :
623 : //Here store stack location
624 57 : size_t nCurrentCount = pCtrlStck->size();
625 778 : while (nStart < nEndCp)
626 : {
627 : //nStart is the beginning of the attributes for this range, and
628 : //may be before the text itself. So watch out for that
629 664 : WW8_CP nTxtStart = nStart;
630 664 : if (nTxtStart < nStartCp)
631 55 : nTxtStart = nStartCp;
632 : // get position of next SPRM
633 664 : bool bStartAttr = pPlcxMan->Get(&aRes);
634 664 : nAktColl = pPlcxMan->GetColl();
635 664 : if (aRes.nSprmId)
636 : {
637 591 : if( bONLYnPicLocFc )
638 : {
639 0 : if ( (68 == aRes.nSprmId) || (0x6A03 == aRes.nSprmId) )
640 : {
641 : Read_PicLoc(aRes.nSprmId, aRes.pMemPos +
642 0 : mpSprmParser->DistanceToData(aRes.nSprmId), 4);
643 : // Ok, that's what we were looking for. Now let's get
644 : // out of here!
645 0 : break;
646 : }
647 : }
648 1182 : else if ( aRes.nSprmId && (
649 1182 : (eFTN > aRes.nSprmId) || (0x0800 <= aRes.nSprmId) ) )
650 : {
651 : //Here place them onto our usual stack and we will pop them
652 : //off and convert them later
653 591 : if (bStartAttr)
654 : {
655 575 : ImportSprm(aRes.pMemPos, aRes.nSprmId);
656 575 : if (!bDoingSymbol && bSymbol == true)
657 : {
658 0 : bDoingSymbol = true;
659 0 : nStartReplace = nTxtStart;
660 0 : cReplaceSymbol = cSymbol;
661 : }
662 : }
663 : else
664 : {
665 16 : EndSprm( aRes.nSprmId );
666 16 : if (bSymbol == false && bDoingSymbol)
667 : {
668 0 : bDoingSymbol = false;
669 0 : OUStringBuffer sTemp;
670 : comphelper::string::padToLength(sTemp,
671 0 : nTxtStart - nStartReplace, cReplaceSymbol);
672 : mpDrawEditEngine->QuickInsertText(sTemp.makeStringAndClear(),
673 : GetESelection(nStartReplace - nStartCp,
674 0 : nTxtStart - nStartCp ) );
675 : }
676 591 : }
677 : }
678 0 : else if (aRes.nSprmId == eFLD)
679 : {
680 0 : if (bStartAttr)
681 : {
682 0 : size_t nCount = pCtrlStck->size();
683 0 : if (maFieldStack.empty() && Read_Field(&aRes))
684 : {
685 0 : String sURL;
686 0 : for (size_t nI = pCtrlStck->size(); nI > nCount; --nI)
687 : {
688 0 : const SfxPoolItem *pItem = ((*pCtrlStck)[nI-1]).pAttr;
689 0 : sal_uInt16 nWhich = pItem->Which();
690 0 : if (nWhich == RES_TXTATR_INETFMT)
691 : {
692 : const SwFmtINetFmt *pURL =
693 0 : (const SwFmtINetFmt *)pItem;
694 0 : sURL = pURL->GetValue();
695 : }
696 0 : pCtrlStck->DeleteAndDestroy(nI-1);
697 : }
698 0 : aChunks.push_back(Chunk(nStart, sURL));
699 : }
700 : }
701 : else
702 : {
703 0 : if (!maFieldStack.empty() && End_Field())
704 0 : aChunks.back().SetEndPos(nStart+1);
705 : }
706 : }
707 : }
708 :
709 664 : pPlcxMan->advance();
710 664 : nNext = pPlcxMan->Where();
711 :
712 664 : if( (nNext != nStart) && !bONLYnPicLocFc )
713 : {
714 120 : nEnd = ( nNext < nEndCp ) ? nNext : nEndCp;
715 120 : SfxItemPool *pEditPool = pS->GetPool();
716 :
717 : //Here read current properties and convert them into pS
718 : //and put those attrs into the draw box if they can be converted
719 : //to draw attributes
720 120 : if (pCtrlStck->size() - nCurrentCount)
721 : {
722 391 : for (size_t i = nCurrentCount; i < pCtrlStck->size(); ++i)
723 : {
724 326 : const SfxPoolItem *pItem = ((*pCtrlStck)[i]).pAttr;
725 326 : sal_uInt16 nWhich = pItem->Which();
726 326 : if( nWhich < RES_FLTRATTR_BEGIN ||
727 : nWhich >= RES_FLTRATTR_END )
728 : {
729 326 : sal_uInt16 nSlotId = rDoc.GetAttrPool().GetSlotId(nWhich);
730 326 : if (
731 652 : nSlotId && nWhich != nSlotId &&
732 978 : 0 != (nWhich = pEditPool->GetWhich(nSlotId)) &&
733 : nWhich != nSlotId
734 : )
735 : {
736 324 : SfxPoolItem* pCopy = pItem->Clone();
737 324 : pCopy->SetWhich( nWhich );
738 324 : pS->Put( *pCopy );
739 324 : delete pCopy;
740 : }
741 : }
742 : }
743 : }
744 : //Fill in the remainder from the style
745 120 : InsertTxbxStyAttrs(*pS, nAktColl);
746 :
747 120 : if( pS->Count() )
748 : {
749 : mpDrawEditEngine->QuickSetAttribs( *pS,
750 120 : GetESelection( nTxtStart - nStartCp, nEnd - nStartCp ) );
751 120 : delete pS;
752 120 : pS = new SfxItemSet(mpDrawEditEngine->GetEmptyItemSet());
753 : }
754 : }
755 664 : nStart = nNext;
756 : }
757 57 : delete pS;
758 :
759 : //pop off as far as recorded location just in case there were some left
760 : //unclosed
761 363 : for (size_t nI = pCtrlStck->size(); nI > nCurrentCount; --nI)
762 306 : pCtrlStck->DeleteAndDestroy(nI-1);
763 :
764 : typedef std::deque<Chunk>::iterator myIter;
765 57 : myIter aEnd = aChunks.end();
766 57 : for (myIter aIter = aChunks.begin(); aIter != aEnd; ++aIter)
767 : {
768 0 : ESelection aSel(GetESelection(aIter->GetStartPos()-nStartCp,
769 0 : aIter->GetEndPos()-nStartCp));
770 0 : String aString(mpDrawEditEngine->GetText(aSel));
771 0 : xub_StrLen nOrigLen = aString.Len();
772 0 : long nDummy(0);
773 0 : lcl_StripFields(aString, nDummy);
774 :
775 : xub_StrLen nChanged;
776 0 : if (aIter->GetURL().Len())
777 : {
778 0 : SvxURLField aURL(aIter->GetURL(), aString,
779 0 : SVXURLFORMAT_APPDEFAULT);
780 0 : mpDrawEditEngine->QuickInsertField(SvxFieldItem(aURL, EE_FEATURE_FIELD), aSel);
781 0 : nChanged = nOrigLen - 1;
782 : }
783 : else
784 : {
785 0 : mpDrawEditEngine->QuickInsertText(aString, aSel);
786 0 : nChanged = nOrigLen - aString.Len();
787 : }
788 0 : for (myIter aIter2 = aIter+1; aIter2 != aEnd; ++aIter2)
789 0 : aIter2->Adjust(nChanged);
790 0 : }
791 :
792 : /*
793 : Don't worry about the new pPlcxMan, the restorer removes it when
794 : replacing the current one with the old one.
795 : */
796 114 : aSave.Restore(this);
797 57 : }
798 :
799 71 : bool SwWW8ImplReader::GetTxbxTextSttEndCp(WW8_CP& rStartCp, WW8_CP& rEndCp,
800 : sal_uInt16 nTxBxS, sal_uInt16 nSequence)
801 : {
802 : // rasch den TextBox-PLCF greifen
803 71 : WW8PLCFspecial* pT = pPlcxMan ? pPlcxMan->GetTxbx() : 0;
804 71 : if( !pT )
805 : {
806 : OSL_ENSURE( !this, "+Wo ist der Grafik-Text (1) ?" );
807 0 : return false;
808 : }
809 :
810 : // ggfs. zuerst die richtige TextBox-Story finden
811 71 : bool bCheckTextBoxStory = ( nTxBxS && pT->GetIMax() >= nTxBxS );
812 71 : if( bCheckTextBoxStory )
813 71 : pT->SetIdx( nTxBxS-1 );
814 :
815 : // dann Start und Ende ermitteln
816 : void* pT0;
817 71 : if( !pT->Get( rStartCp, pT0 ) )
818 : {
819 : OSL_ENSURE( !this, "+Wo ist der Grafik-Text (2) ?" );
820 0 : return false;
821 : }
822 :
823 71 : if( bCheckTextBoxStory )
824 : {
825 71 : bool bReusable = (0 != SVBT16ToShort( ((WW8_TXBXS*)pT0)->fReusable ));
826 142 : while( bReusable )
827 : {
828 0 : pT->advance();
829 0 : if( !pT->Get( rStartCp, pT0 ) )
830 : {
831 : OSL_ENSURE( !this, "+Wo ist der Grafik-Text (2-a) ?" );
832 0 : return false;
833 : }
834 0 : bReusable = (0 != SVBT16ToShort( ((WW8_TXBXS*)pT0)->fReusable ));
835 : }
836 : }
837 71 : pT->advance();
838 71 : if( !pT->Get( rEndCp, pT0 ) )
839 : {
840 : OSL_ENSURE( !this, "+Wo ist der Grafik-Text (3) ?" );
841 0 : return false;
842 : }
843 :
844 : // jetzt ggfs. die passende Page in der Break-Table finden
845 71 : if( bCheckTextBoxStory )
846 : {
847 : // Sonderfall: gesamte(!) Kette soll ermittelt werden,
848 : // dann sind wir hier schon fertig!
849 71 : if( USHRT_MAX > nSequence )
850 : {
851 67 : long nMinStartCp = rStartCp;
852 67 : long nMaxEndCp = rEndCp;
853 : // rasch den TextBox-Break-Deskriptor-PLCF greifen
854 67 : pT = pPlcxMan->GetTxbxBkd();
855 67 : if (!pT) //It can occur on occasion, Caolan
856 0 : return false;
857 :
858 : // den ersten Eintrag fuer diese TextBox-Story finden
859 67 : if( !pT->SeekPos( rStartCp ) )
860 : {
861 : OSL_ENSURE( !this, "+Wo ist der Grafik-Text (4) ?" );
862 0 : return false;
863 : }
864 : // ggfs. entsprechende Anzahl Eintraege weitergehen
865 67 : for (sal_uInt16 iSequence = 0; iSequence < nSequence; ++iSequence)
866 0 : pT->advance();
867 : // dann die tatsaechlichen Start und Ende ermitteln
868 134 : if( (!pT->Get( rStartCp, pT0 ))
869 67 : || ( nMinStartCp > rStartCp ) )
870 : {
871 : OSL_ENSURE( !this, "+Wo ist der Grafik-Text (5) ?" );
872 0 : return false;
873 : }
874 67 : if( rStartCp >= nMaxEndCp )
875 0 : rEndCp = rStartCp; // kein Error: leerer String!
876 : else
877 : {
878 67 : pT->advance();
879 67 : if ( (!pT->Get(rEndCp, pT0)) || (nMaxEndCp < rEndCp-1) )
880 : {
881 : OSL_ENSURE( !this, "+Wo ist der Grafik-Text (6) ?" );
882 0 : return false;
883 : }
884 67 : rEndCp -= 1;
885 : }
886 : }
887 : else
888 4 : rEndCp -= 1;
889 : }
890 : else
891 0 : rEndCp -= 1;
892 71 : return true;
893 : }
894 :
895 : // TxbxText() holt aus WW-File den Text und gibt diesen und den Anfangs- und
896 : // den um -2 (bzw. -1 bei Ver8) korrigierten End-Cp zurueck
897 61 : bool SwWW8ImplReader::GetRangeAsDrawingString(String& rString, long nStartCp, long nEndCp, ManTypes eType)
898 : {
899 61 : WW8_CP nOffset = pWwFib->GetBaseCp(eType);
900 :
901 61 : bool bOk = false;
902 : OSL_ENSURE(nStartCp <= nEndCp, "+Wo ist der Grafik-Text (7) ?");
903 61 : if (nStartCp == nEndCp)
904 0 : rString.Erase(); // leerer String: durchaus denkbar!
905 61 : else if (nStartCp < nEndCp)
906 : {
907 : // den Text einlesen: kann sich ueber mehrere Pieces erstrecken!!!
908 : sal_uInt16 nLen = pSBase->WW8ReadString(*pStrm, rString,
909 61 : nStartCp + nOffset, nEndCp - nStartCp, GetCurrentCharSet());
910 : OSL_ENSURE(nLen, "+Wo ist der Grafik-Text (8) ?");
911 61 : if (nLen)
912 : {
913 61 : bOk = true;
914 61 : if( 0x0d == rString.GetChar(nLen - 1) )
915 61 : rString.Erase(nLen - 1);
916 :
917 61 : rString.SearchAndReplaceAll( 0xb, 0xa );
918 : }
919 : }
920 61 : return bOk;
921 : }
922 :
923 1 : OutlinerParaObject* SwWW8ImplReader::ImportAsOutliner(String &rString, WW8_CP nStartCp, WW8_CP nEndCp, ManTypes eType)
924 : {
925 1 : OutlinerParaObject* pRet = 0;
926 :
927 1 : if (GetRangeAsDrawingString( rString, nStartCp, nEndCp, eType ))
928 : {
929 1 : if (!mpDrawEditEngine)
930 1 : mpDrawEditEngine = new EditEngine(0);
931 :
932 1 : mpDrawEditEngine->SetText(rString);
933 1 : InsertAttrsAsDrawingAttrs(nStartCp, nEndCp, eType);
934 :
935 : //Annotations typically begin with a (useless) 0x5
936 1 : if ((eType == MAN_AND) && mpDrawEditEngine->GetTextLen())
937 : {
938 1 : ESelection aFirstChar(0, 0, 0, 1);
939 1 : if (comphelper::string::equals(mpDrawEditEngine->GetText( aFirstChar ), 0x5))
940 0 : mpDrawEditEngine->QuickDelete(aFirstChar);
941 : }
942 :
943 1 : EditTextObject* pTemporaryText = mpDrawEditEngine->CreateTextObject();
944 1 : pRet = new OutlinerParaObject(*pTemporaryText);
945 1 : pRet->SetOutlinerMode( OUTLINERMODE_TEXTOBJECT );
946 1 : delete pTemporaryText;
947 :
948 1 : mpDrawEditEngine->SetText( aEmptyStr );
949 1 : mpDrawEditEngine->SetParaAttribs(0, mpDrawEditEngine->GetEmptyItemSet());
950 :
951 : //Strip out fields, leaving the result
952 1 : long nDummy(0);
953 1 : lcl_StripFields(rString, nDummy);
954 : //Strip out word's special characters for the simple string
955 1 : rString = comphelper::string::remove(rString, 0x1);
956 1 : rString = comphelper::string::remove(rString, 0x5);
957 1 : rString = comphelper::string::remove(rString, 0x8);
958 1 : rString.SearchAndReplaceAllAscii("\007\007", OUString("\007\012"));
959 1 : rString.SearchAndReplaceAll(0x7, ' ');
960 :
961 : }
962 :
963 1 : return pRet;
964 : }
965 :
966 : // InsertTxbxText() fuegt fuer TextBoxen und CaptionBoxen den Text
967 : // und die Attribute ein
968 60 : SwFrmFmt* SwWW8ImplReader::InsertTxbxText(SdrTextObj* pTextObj,
969 : Size* pObjSiz, sal_uInt16 nTxBxS, sal_uInt16 nSequence, long nPosCp,
970 : SwFrmFmt* pOldFlyFmt, bool bMakeSdrGrafObj, bool& rbEraseTextObj,
971 : bool* pbTestTxbxContainsText, long* pnStartCp, long* pnEndCp,
972 : bool* pbContainsGraphics, SvxMSDffImportRec* pRecord)
973 : {
974 60 : SwFrmFmt* pFlyFmt = 0;
975 60 : sal_uLong nOld = pStrm->Tell();
976 :
977 60 : ManTypes eType = pPlcxMan->GetManType() == MAN_HDFT ? MAN_TXBX_HDFT : MAN_TXBX;
978 :
979 60 : rbEraseTextObj = false;
980 :
981 60 : String aString;
982 : WW8_CP nStartCp, nEndCp;
983 60 : bool bContainsGraphics = false;
984 : bool bTextWasRead = GetTxbxTextSttEndCp( nStartCp, nEndCp, nTxBxS,
985 60 : nSequence ) && GetRangeAsDrawingString( aString, nStartCp, nEndCp, eType );
986 :
987 60 : if (!mpDrawEditEngine)
988 6 : mpDrawEditEngine = new EditEngine(0);
989 60 : if( pObjSiz )
990 56 : mpDrawEditEngine->SetPaperSize( *pObjSiz );
991 :
992 120 : String aOrigString(aString);
993 60 : if( bTextWasRead )
994 : {
995 60 : long nNewStartCp = nStartCp;
996 60 : lcl_StripFields(aString, nNewStartCp);
997 :
998 60 : if (1 != aString.Len())
999 : {
1000 72 : if ( (STRING_NOTFOUND != aString.Search(0x1)) ||
1001 36 : (STRING_NOTFOUND != aString.Search(0x8)) )
1002 : {
1003 0 : bContainsGraphics = true;
1004 : }
1005 : }
1006 : else // May be a single graphic or object
1007 : {
1008 24 : bool bDone = true;
1009 24 : switch( aString.GetChar(0) )
1010 : {
1011 : case 0x1:
1012 0 : if (!pbTestTxbxContainsText)
1013 : {
1014 0 : WW8ReaderSave aSave(this, nNewStartCp -1);
1015 0 : bool bOldEmbeddObj = bEmbeddObj;
1016 : //bEmbedd Ordinarily would have been set by field
1017 : //parse, but this is impossible here so...
1018 0 : bEmbeddObj = true;
1019 :
1020 : // 1st look for OLE- or Graph-Indicator Sprms
1021 0 : WW8PLCFx_Cp_FKP* pChp = pPlcxMan->GetChpPLCF();
1022 0 : WW8PLCFxDesc aDesc;
1023 0 : pChp->GetSprms( &aDesc );
1024 : WW8SprmIter aSprmIter(aDesc.pMemPos, aDesc.nSprmsLen,
1025 0 : *mpSprmParser);
1026 :
1027 0 : const sal_uInt8* pParams = aSprmIter.GetAktParams();
1028 0 : for( int nLoop = 0; nLoop < 2; ++nLoop )
1029 : {
1030 0 : while( aSprmIter.GetSprms()
1031 0 : && (0 != (pParams = aSprmIter.GetAktParams())) )
1032 : {
1033 0 : sal_uInt16 nAktId = aSprmIter.GetAktId();
1034 0 : switch( nAktId )
1035 : {
1036 : case 75:
1037 : case 118:
1038 : case 0x080A:
1039 : case 0x0856:
1040 0 : Read_Obj(nAktId, pParams, 1);
1041 0 : break;
1042 : case 68: // Read_Pic()
1043 : case 0x6A03:
1044 : case 0x680E:
1045 0 : Read_PicLoc(nAktId, pParams, 1);
1046 0 : break;
1047 : }
1048 0 : aSprmIter.advance();
1049 : }
1050 :
1051 0 : if( !nLoop )
1052 : {
1053 0 : pChp->GetPCDSprms( aDesc );
1054 : aSprmIter.SetSprms( aDesc.pMemPos,
1055 0 : aDesc.nSprmsLen );
1056 : }
1057 : }
1058 0 : aSave.Restore(this);
1059 0 : bEmbeddObj=bOldEmbeddObj;
1060 :
1061 : // then import either an OLE of a Graphic
1062 0 : if( bObj )
1063 : {
1064 0 : if( bMakeSdrGrafObj && pTextObj &&
1065 0 : pTextObj->GetUpGroup() )
1066 : {
1067 : // SdrOleObj/SdrGrafObj anstatt des
1068 : // SdrTextObj in dessen Gruppe einsetzen
1069 :
1070 0 : Graphic aGraph;
1071 0 : SdrObject* pNew = ImportOleBase(aGraph);
1072 :
1073 0 : if( !pNew )
1074 : {
1075 0 : pNew = new SdrGrafObj;
1076 0 : ((SdrGrafObj*)pNew)->SetGraphic(aGraph);
1077 : }
1078 :
1079 0 : GrafikCtor();
1080 :
1081 0 : pNew->SetModel( pDrawModel );
1082 0 : pNew->SetLogicRect( pTextObj->GetCurrentBoundRect() );
1083 0 : pNew->SetLayer( pTextObj->GetLayer() );
1084 :
1085 0 : pTextObj->GetUpGroup()->GetSubList()->
1086 0 : ReplaceObject(pNew, pTextObj->GetOrdNum());
1087 : }
1088 : else
1089 0 : pFlyFmt = ImportOle();
1090 0 : bObj = false;
1091 : }
1092 : else
1093 : {
1094 : InsertAttrsAsDrawingAttrs(nNewStartCp, nNewStartCp+1,
1095 0 : eType, true);
1096 : pFlyFmt = ImportGraf(bMakeSdrGrafObj ? pTextObj : 0,
1097 0 : pOldFlyFmt);
1098 0 : }
1099 : }
1100 0 : break;
1101 : case 0x8:
1102 0 : if ( (!pbTestTxbxContainsText) && (!bObj) )
1103 0 : pFlyFmt = Read_GrafLayer( nPosCp );
1104 0 : break;
1105 : default:
1106 24 : bDone = false;
1107 24 : break;
1108 : }
1109 :
1110 24 : if( bDone )
1111 : {
1112 0 : if( pFlyFmt )
1113 : {
1114 0 : if( pRecord )
1115 : {
1116 0 : SfxItemSet aFlySet( rDoc.GetAttrPool(),
1117 0 : RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
1118 :
1119 : Rectangle aInnerDist( pRecord->nDxTextLeft,
1120 : pRecord->nDyTextTop,
1121 : pRecord->nDxTextRight,
1122 0 : pRecord->nDyTextBottom );
1123 : MatchSdrItemsIntoFlySet( pTextObj,
1124 : aFlySet,
1125 : pRecord->eLineStyle,
1126 : pRecord->eLineDashing,
1127 : pRecord->eShapeType,
1128 0 : aInnerDist );
1129 :
1130 0 : pFlyFmt->SetFmtAttr( aFlySet );
1131 :
1132 0 : MapWrapIntoFlyFmt(pRecord, pFlyFmt);
1133 : }
1134 : }
1135 0 : aString.Erase();
1136 0 : rbEraseTextObj = (0 != pFlyFmt);
1137 : }
1138 : }
1139 : }
1140 :
1141 60 : if( pnStartCp )
1142 4 : *pnStartCp = nStartCp;
1143 60 : if( pnEndCp )
1144 4 : *pnEndCp = nEndCp;
1145 :
1146 60 : if( pbTestTxbxContainsText )
1147 4 : *pbTestTxbxContainsText = bTextWasRead && ! rbEraseTextObj;
1148 56 : else if( !rbEraseTextObj )
1149 : {
1150 56 : if( bTextWasRead )
1151 : {
1152 56 : mpDrawEditEngine->SetText(aOrigString);
1153 56 : InsertAttrsAsDrawingAttrs(nStartCp, nEndCp, eType);
1154 : }
1155 :
1156 56 : bool bVertical = pTextObj->IsVerticalWriting() ? true : false;
1157 56 : EditTextObject* pTemporaryText = mpDrawEditEngine->CreateTextObject();
1158 56 : OutlinerParaObject* pOp = new OutlinerParaObject(*pTemporaryText);
1159 56 : pOp->SetOutlinerMode( OUTLINERMODE_TEXTOBJECT );
1160 56 : pOp->SetVertical( bVertical );
1161 56 : delete pTemporaryText;
1162 56 : pTextObj->NbcSetOutlinerParaObject( pOp );
1163 56 : pTextObj->SetVerticalWriting(bVertical);
1164 :
1165 : // Fuer die naechste Textbox noch die alten Absatz-Attribute
1166 : // und Styles entfernen, sonst startet die naechste Box
1167 : // mit falschen Attributen.
1168 : // Vorgehen: Text loeschen = auf 1 Absatz reduzieren
1169 : // und an diesem Absatz die Absatzattribute und Styles loeschen
1170 : // (Empfehlung JOE)
1171 56 : mpDrawEditEngine->SetText( aEmptyStr );
1172 56 : mpDrawEditEngine->SetParaAttribs(0, mpDrawEditEngine->GetEmptyItemSet());
1173 : }
1174 :
1175 60 : pStrm->Seek( nOld );
1176 60 : if (pbContainsGraphics)
1177 0 : *pbContainsGraphics = bContainsGraphics;
1178 120 : return pFlyFmt;
1179 : }
1180 :
1181 :
1182 4 : bool SwWW8ImplReader::TxbxChainContainsRealText(sal_uInt16 nTxBxS, long& rStartCp,
1183 : long& rEndCp)
1184 : {
1185 : bool bErase, bContainsText;
1186 : InsertTxbxText( 0,0,nTxBxS,USHRT_MAX,0,0,0, bErase, &bContainsText,
1187 4 : &rStartCp, &rEndCp );
1188 4 : return bContainsText;
1189 : }
1190 :
1191 :
1192 : // TextBoxes only for Ver67 !!
1193 0 : SdrObject* SwWW8ImplReader::ReadTxtBox( WW8_DPHEAD* pHd, const WW8_DO* pDo,
1194 : SfxAllItemSet &rSet)
1195 : {
1196 : bool bDummy;
1197 : WW8_DP_TXTBOX aTxtB;
1198 :
1199 0 : if( !ReadGrafStart( (void*)&aTxtB, sizeof( aTxtB ), pHd, pDo, rSet ) )
1200 0 : return 0;
1201 :
1202 0 : Point aP0( (sal_Int16)SVBT16ToShort( pHd->xa ) + nDrawXOfs2,
1203 0 : (sal_Int16)SVBT16ToShort( pHd->ya ) + nDrawYOfs2 );
1204 0 : Point aP1( aP0 );
1205 0 : aP1.X() += (sal_Int16)SVBT16ToShort( pHd->dxa );
1206 0 : aP1.Y() += (sal_Int16)SVBT16ToShort( pHd->dya );
1207 :
1208 0 : SdrObject* pObj = new SdrRectObj( OBJ_TEXT, Rectangle( aP0, aP1 ) );
1209 0 : pObj->SetModel( pDrawModel );
1210 0 : pObj->NbcSetSnapRect(Rectangle(aP0, aP1));
1211 0 : Size aSize( (sal_Int16)SVBT16ToShort( pHd->dxa ) ,
1212 0 : (sal_Int16)SVBT16ToShort( pHd->dya ) );
1213 :
1214 : long nStartCpFly,nEndCpFly;
1215 : bool bContainsGraphics;
1216 0 : InsertTxbxText(PTR_CAST(SdrTextObj,pObj), &aSize, 0, 0, 0, 0, false,
1217 0 : bDummy,0,&nStartCpFly,&nEndCpFly,&bContainsGraphics);
1218 :
1219 0 : SetStdAttr( rSet, aTxtB.aLnt, aTxtB.aShd );
1220 0 : SetFill( rSet, aTxtB.aFill );
1221 :
1222 0 : rSet.Put( SdrTextFitToSizeTypeItem( SDRTEXTFIT_NONE ) );
1223 0 : rSet.Put( SdrTextAutoGrowWidthItem(false));
1224 0 : rSet.Put( SdrTextAutoGrowHeightItem(false));
1225 0 : rSet.Put( SdrTextLeftDistItem( MIN_BORDER_DIST*2 ) );
1226 0 : rSet.Put( SdrTextRightDistItem( MIN_BORDER_DIST*2 ) );
1227 0 : rSet.Put( SdrTextUpperDistItem( MIN_BORDER_DIST ) );
1228 0 : rSet.Put( SdrTextLowerDistItem( MIN_BORDER_DIST ) );
1229 :
1230 0 : return pObj;
1231 : }
1232 :
1233 0 : SdrObject* SwWW8ImplReader::ReadCaptionBox( WW8_DPHEAD* pHd, const WW8_DO* pDo,
1234 : SfxAllItemSet &rSet)
1235 : {
1236 : static SdrCaptionType aCaptA[] = { SDRCAPT_TYPE1, SDRCAPT_TYPE2,
1237 : SDRCAPT_TYPE3, SDRCAPT_TYPE4 };
1238 :
1239 : WW8_DP_CALLOUT_TXTBOX aCallB;
1240 :
1241 0 : if( !ReadGrafStart( (void*)&aCallB, sizeof( aCallB ), pHd, pDo, rSet ) )
1242 0 : return 0;
1243 :
1244 0 : sal_uInt16 nCount = SVBT16ToShort( aCallB.dpPolyLine.aBits1 ) >> 1 & 0x7fff;
1245 0 : boost::scoped_array<SVBT16> xP(new SVBT16[nCount * 2]);
1246 :
1247 0 : bool bCouldRead = checkRead(*pStrm, xP.get(), nCount * 4); // Punkte einlesen
1248 : OSL_ENSURE(bCouldRead, "Short CaptionBox header");
1249 0 : if (!bCouldRead)
1250 0 : return 0;
1251 :
1252 0 : sal_uInt8 nTyp = (sal_uInt8)nCount - 1;
1253 0 : if( nTyp == 1 && SVBT16ToShort( xP[0] ) == SVBT16ToShort( xP[2] ) )
1254 0 : nTyp = 0;
1255 :
1256 0 : Point aP0( (sal_Int16)SVBT16ToShort( pHd->xa ) +
1257 0 : (sal_Int16)SVBT16ToShort( aCallB.dpheadTxbx.xa ) + nDrawXOfs2,
1258 0 : (sal_Int16)SVBT16ToShort( pHd->ya )
1259 0 : + (sal_Int16)SVBT16ToShort( aCallB.dpheadTxbx.ya ) + nDrawYOfs2 );
1260 0 : Point aP1( aP0 );
1261 0 : aP1.X() += (sal_Int16)SVBT16ToShort( aCallB.dpheadTxbx.dxa );
1262 0 : aP1.Y() += (sal_Int16)SVBT16ToShort( aCallB.dpheadTxbx.dya );
1263 0 : Point aP2( (sal_Int16)SVBT16ToShort( pHd->xa )
1264 0 : + (sal_Int16)SVBT16ToShort( aCallB.dpheadPolyLine.xa )
1265 0 : + nDrawXOfs2 + (sal_Int16)SVBT16ToShort( xP[0] ),
1266 0 : (sal_Int16)SVBT16ToShort( pHd->ya )
1267 0 : + (sal_Int16)SVBT16ToShort( aCallB.dpheadPolyLine.ya )
1268 0 : + nDrawYOfs2 + (sal_Int16)SVBT16ToShort( xP[1] ) );
1269 0 : xP.reset();
1270 :
1271 0 : SdrCaptionObj* pObj = new SdrCaptionObj( Rectangle( aP0, aP1 ), aP2 );
1272 0 : pObj->SetModel( pDrawModel );
1273 0 : pObj->NbcSetSnapRect(Rectangle(aP0, aP1));
1274 0 : Size aSize( (sal_Int16)SVBT16ToShort( aCallB.dpheadTxbx.dxa ),
1275 0 : (sal_Int16)SVBT16ToShort( aCallB.dpheadTxbx.dya ) );
1276 : bool bEraseThisObject;
1277 :
1278 0 : InsertTxbxText(pObj, &aSize, 0, 0, 0, 0, false, bEraseThisObject );
1279 :
1280 0 : if( SVBT16ToShort( aCallB.dptxbx.aLnt.lnps ) != 5 ) // Umrandung sichtbar ?
1281 0 : SetStdAttr( rSet, aCallB.dptxbx.aLnt, aCallB.dptxbx.aShd );
1282 : else // nein -> Nimm Linie
1283 0 : SetStdAttr( rSet, aCallB.dpPolyLine.aLnt, aCallB.dptxbx.aShd );
1284 0 : SetFill( rSet, aCallB.dptxbx.aFill );
1285 0 : rSet.Put( SdrCaptionTypeItem( aCaptA[nTyp] ) );
1286 :
1287 0 : return pObj;
1288 : }
1289 :
1290 :
1291 0 : SdrObject *SwWW8ImplReader::ReadGroup( WW8_DPHEAD* pHd, const WW8_DO* pDo,
1292 : SfxAllItemSet &rSet)
1293 : {
1294 : sal_Int16 nGrouped;
1295 :
1296 0 : if( !ReadGrafStart( (void*)&nGrouped, sizeof( nGrouped ), pHd, pDo, rSet ) )
1297 0 : return 0;
1298 :
1299 : #ifdef OSL_BIGENDIAN
1300 : nGrouped = (sal_Int16)OSL_SWAPWORD( nGrouped );
1301 : #endif
1302 :
1303 0 : nDrawXOfs = nDrawXOfs + (sal_Int16)SVBT16ToShort( pHd->xa );
1304 0 : nDrawYOfs = nDrawYOfs + (sal_Int16)SVBT16ToShort( pHd->ya );
1305 :
1306 0 : SdrObject* pObj = new SdrObjGroup;
1307 :
1308 0 : short nLeft = (sal_Int16)SVBT16ToShort( pHd->cb ) - sizeof( WW8_DPHEAD );
1309 0 : for (int i = 0; i < nGrouped; i++)
1310 : {
1311 0 : SfxAllItemSet aSet(pDrawModel->GetItemPool());
1312 0 : if (SdrObject *pObject = ReadGrafPrimitive(nLeft, pDo, aSet))
1313 : {
1314 : // first add and then set ItemSet
1315 0 : SdrObjList *pSubGroup = pObj->GetSubList();
1316 : OSL_ENSURE(pSubGroup, "Why no sublist available?");
1317 0 : if (pSubGroup)
1318 0 : pSubGroup->InsertObject(pObject, 0);
1319 0 : pObject->SetMergedItemSetAndBroadcast(aSet);
1320 : }
1321 0 : }
1322 :
1323 0 : nDrawXOfs = nDrawXOfs - (sal_Int16)SVBT16ToShort( pHd->xa );
1324 0 : nDrawYOfs = nDrawYOfs - (sal_Int16)SVBT16ToShort( pHd->ya );
1325 :
1326 0 : return pObj;
1327 : }
1328 :
1329 0 : SdrObject* SwWW8ImplReader::ReadGrafPrimitive( short& rLeft, const WW8_DO* pDo,
1330 : SfxAllItemSet &rSet)
1331 : {
1332 : //cmc: This whole archaic word 6 graphic import can probably be refactored
1333 : //into an object hierarachy with a little effort.
1334 0 : SdrObject *pRet=0;
1335 : WW8_DPHEAD aHd; // Lese Draw-Primitive-Header
1336 0 : bool bCouldRead = checkRead(*pStrm, &aHd, sizeof(WW8_DPHEAD));
1337 : OSL_ENSURE(bCouldRead, "Graphic Primitive header short read" );
1338 0 : if (!bCouldRead)
1339 : {
1340 0 : rLeft=0;
1341 0 : return pRet;
1342 : }
1343 :
1344 0 : if( rLeft >= SVBT16ToShort(aHd.cb) ) // Vorsichtsmassmahme
1345 : {
1346 0 : rSet.Put(SwFmtSurround(SURROUND_THROUGHT));
1347 0 : switch (SVBT16ToShort(aHd.dpk) & 0xff )
1348 : {
1349 : case 0:
1350 0 : pRet = ReadGroup( &aHd, pDo, rSet );
1351 0 : break;
1352 : case 1:
1353 0 : pRet = ReadLine( &aHd, pDo, rSet );
1354 0 : break;
1355 : case 2:
1356 0 : pRet = ReadTxtBox( &aHd, pDo, rSet );
1357 0 : break;
1358 : case 3:
1359 0 : pRet = ReadRect( &aHd, pDo, rSet );
1360 0 : break;
1361 : case 4:
1362 0 : pRet = ReadElipse( &aHd, pDo, rSet );
1363 0 : break;
1364 : case 5:
1365 0 : pRet = ReadArc( &aHd, pDo, rSet );
1366 0 : break;
1367 : case 6:
1368 0 : pRet = ReadPolyLine( &aHd, pDo, rSet );
1369 0 : break;
1370 : case 7:
1371 0 : pRet = ReadCaptionBox( &aHd, pDo, rSet );
1372 0 : break;
1373 : default: // unbekannt
1374 0 : pStrm->SeekRel(SVBT16ToShort(aHd.cb) - sizeof(WW8_DPHEAD));
1375 0 : break;
1376 : }
1377 : }
1378 : else
1379 : {
1380 : OSL_ENSURE( !this, "+Grafik-Overlap" );
1381 : }
1382 0 : rLeft = rLeft - SVBT16ToShort( aHd.cb );
1383 0 : return pRet;
1384 : }
1385 :
1386 0 : void SwWW8ImplReader::ReadGrafLayer1( WW8PLCFspecial* pPF, long nGrafAnchorCp )
1387 : {
1388 0 : pPF->SeekPos( nGrafAnchorCp );
1389 : WW8_FC nStartFc;
1390 : void* pF0;
1391 0 : if( !pPF->Get( nStartFc, pF0 ) )
1392 : {
1393 : OSL_ENSURE( !this, "+Wo ist die Grafik (2) ?" );
1394 0 : return;
1395 : }
1396 0 : WW8_FDOA* pF = (WW8_FDOA*)pF0;
1397 0 : if( !SVBT32ToUInt32( pF->fc ) )
1398 : {
1399 : OSL_ENSURE( !this, "+Wo ist die Grafik (3) ?" );
1400 0 : return;
1401 : }
1402 :
1403 0 : bool bCouldSeek = checkSeek(*pStrm, SVBT32ToUInt32(pF->fc));
1404 : OSL_ENSURE(bCouldSeek, "Invalid Graphic offset");
1405 0 : if (!bCouldSeek)
1406 0 : return;
1407 :
1408 : // Lese Draw-Header
1409 : WW8_DO aDo;
1410 0 : bool bCouldRead = checkRead(*pStrm, &aDo, sizeof(WW8_DO));
1411 : OSL_ENSURE(bCouldRead, "Short Graphic header");
1412 0 : if (!bCouldRead)
1413 0 : return;
1414 :
1415 0 : short nLeft = SVBT16ToShort( aDo.cb ) - sizeof( WW8_DO );
1416 0 : while (nLeft > static_cast<short>(sizeof(WW8_DPHEAD)))
1417 : {
1418 0 : SfxAllItemSet aSet( pDrawModel->GetItemPool() );
1419 0 : if (SdrObject *pObject = ReadGrafPrimitive( nLeft, &aDo, aSet ))
1420 : {
1421 0 : pWWZOrder->InsertDrawingObject(pObject, SVBT16ToShort(aDo.dhgt));
1422 0 : SwFrmFmt *pFrm = rDoc.Insert( *pPaM, *pObject, &aSet, NULL);
1423 0 : pObject->SetMergedItemSet(aSet);
1424 0 : pAnchorStck->AddAnchor(*pPaM->GetPoint(), pFrm);
1425 : }
1426 0 : }
1427 : }
1428 :
1429 34 : sal_Int32 SwMSDffManager::GetEscherLineMatch(MSO_LineStyle eStyle,
1430 : MSO_SPT eShapeType, sal_Int32 &rThick)
1431 : {
1432 34 : sal_Int32 nOutsideThick = 0;
1433 : /*
1434 : Beachte: im Gegensatz zu den Winword-ueblichen Tabellen- und
1435 : Rahmen-Randbreiten-Angaben, bei denen jeweils aus der Staerke *einer*
1436 : Linie die Gesamt-Randbreite zu errechnen ist, liegen die aus dem ESCHER
1437 : stammenden Daten bereits als Gesamt-Breite [twips] vor!
1438 :
1439 : Der Winword default ist 15 tw. Wir nehmen hierfuer unsere 20 tw Linie. (
1440 : 0.75 pt uns 1.0 pt sehen sich auf dem Ausdruck naemlich aehnlicher als
1441 : etwas 0.75 pt und unsere 0.05 pt Haarlinie. ) Die Haarlinie setzen wir nur
1442 : bei Winword-Staerken bis zu maximal 0.5 pt ein.
1443 : */
1444 34 : switch( eStyle )
1445 : {
1446 : case mso_lineTriple:
1447 : case mso_lineSimple:
1448 8 : nOutsideThick = eShapeType != mso_sptTextBox ? rThick : rThick/2;
1449 8 : break;
1450 : case mso_lineDouble:
1451 0 : if (eShapeType == mso_sptTextBox)
1452 : {
1453 0 : nOutsideThick = rThick/6;
1454 0 : rThick = rThick*2/3;
1455 : }
1456 : else
1457 0 : nOutsideThick = rThick*2/3;
1458 0 : break;
1459 : case mso_lineThickThin:
1460 0 : if (eShapeType == mso_sptTextBox)
1461 : {
1462 0 : nOutsideThick = rThick*3/10;
1463 0 : rThick = rThick*4/5;
1464 : }
1465 : else
1466 0 : nOutsideThick = rThick*4/5;
1467 0 : break;
1468 : case mso_lineThinThick:
1469 : {
1470 0 : if (eShapeType == mso_sptTextBox)
1471 : {
1472 0 : nOutsideThick = rThick/10;
1473 0 : rThick = rThick*3/5;
1474 : }
1475 : else
1476 0 : nOutsideThick = rThick*3/5;
1477 : }
1478 0 : break;
1479 : default:
1480 26 : break;
1481 : }
1482 34 : return nOutsideThick;
1483 : }
1484 :
1485 : //Returns the thickness of the line outside the frame, the logic of
1486 : //words positioning of borders around floating objects is that of a
1487 : //disturbed mind.
1488 34 : sal_Int32 SwWW8ImplReader::MatchSdrBoxIntoFlyBoxItem(const Color& rLineColor,
1489 : MSO_LineStyle eLineStyle, MSO_LineDashing eDashing, MSO_SPT eShapeType, sal_Int32 &rLineThick,
1490 : SvxBoxItem& rBox )
1491 : {
1492 34 : sal_Int32 nOutsideThick = 0;
1493 34 : if( !rLineThick )
1494 0 : return nOutsideThick;
1495 :
1496 34 : ::editeng::SvxBorderStyle nIdx = table::BorderLineStyle::NONE;
1497 :
1498 34 : sal_Int32 nLineThick=rLineThick;
1499 : nOutsideThick = SwMSDffManager::GetEscherLineMatch(eLineStyle,
1500 34 : eShapeType, rLineThick);
1501 :
1502 : /*
1503 : Beachte: im Gegensatz zu den Winword-ueblichen Tabellen- und
1504 : Rahmen-Randbreiten-Angaben, bei denen jeweils aus der Staerke *einer*
1505 : Linie die Gesamt-Randbreite zu errechnen ist, liegen die aus dem ESCHER
1506 : stammenden Daten bereits als Gesamt-Breite [twips] vor!
1507 :
1508 : Der Winword default ist 15 tw. Wir nehmen hierfuer unsere 20 tw Linie. (
1509 : 0.75 pt uns 1.0 pt sehen sich auf dem Ausdruck naemlich aehnlicher als
1510 : etwas 0.75 pt und unsere 0.05 pt Haarlinie. ) Die Haarlinie setzen wir nur
1511 : bei Winword-Staerken bis zu maximal 0.5 pt ein.
1512 : */
1513 34 : switch( +eLineStyle )
1514 : {
1515 : // zuerst die Einzel-Linien
1516 : case mso_lineSimple:
1517 8 : nIdx = table::BorderLineStyle::SOLID;
1518 8 : break;
1519 : // dann die Doppel-Linien, fuer die wir feine Entsprechungen haben :-)))
1520 : case mso_lineDouble:
1521 0 : nIdx = table::BorderLineStyle::DOUBLE;
1522 0 : break;
1523 : case mso_lineThickThin:
1524 0 : nIdx = table::BorderLineStyle::THICKTHIN_SMALLGAP;
1525 0 : break;
1526 : case mso_lineThinThick:
1527 0 : nIdx = table::BorderLineStyle::THINTHICK_SMALLGAP;
1528 0 : break;
1529 : // We have no triple border, use double instead.
1530 : case mso_lineTriple:
1531 0 : nIdx = table::BorderLineStyle::DOUBLE;
1532 0 : break;
1533 : // no line style is set
1534 : case (MSO_LineStyle)USHRT_MAX:
1535 26 : break;
1536 : // erroneously not implemented line style is set
1537 : default:
1538 : OSL_ENSURE(!this, "eLineStyle is not (yet) implemented!");
1539 0 : break;
1540 : }
1541 :
1542 34 : switch( eDashing )
1543 : {
1544 : case mso_lineDashGEL:
1545 0 : nIdx = table::BorderLineStyle::DASHED;
1546 0 : break;
1547 : case mso_lineDotGEL:
1548 0 : nIdx = table::BorderLineStyle::DOTTED;
1549 0 : break;
1550 : default:
1551 34 : break;
1552 : }
1553 :
1554 34 : if (table::BorderLineStyle::NONE != nIdx)
1555 : {
1556 8 : SvxBorderLine aLine;
1557 8 : aLine.SetColor( rLineColor );
1558 :
1559 8 : aLine.SetWidth( nLineThick ); // No conversion here, nLineThick is already in twips
1560 8 : aLine.SetBorderLineStyle(nIdx);
1561 :
1562 40 : for(sal_uInt16 nLine = 0; nLine < 4; ++nLine)
1563 : {
1564 : //aLine is cloned by SetLine
1565 32 : rBox.SetLine(&aLine, nLine);
1566 : }
1567 : }
1568 :
1569 34 : return nOutsideThick;
1570 : }
1571 :
1572 : #define WW8ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue()
1573 :
1574 34 : void SwWW8ImplReader::MatchSdrItemsIntoFlySet( SdrObject* pSdrObj,
1575 : SfxItemSet& rFlySet, MSO_LineStyle eLineStyle, MSO_LineDashing eDashing, MSO_SPT eShapeType,
1576 : Rectangle& rInnerDist )
1577 : {
1578 : /*
1579 : am Rahmen zu setzende Frame-Attribute
1580 : ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1581 : SwFmtFrmSize falls noch nicht gesetzt, hier setzen
1582 : SvxLRSpaceItem hier setzen
1583 : SvxULSpaceItem hier setzen
1584 : SvxOpaqueItem (Derzeit bei Rahmen nicht moeglich! khz 10.2.1999)
1585 : SwFmtSurround bereits gesetzt
1586 : SwFmtVertOrient bereits gesetzt
1587 : SwFmtHoriOrient bereits gesetzt
1588 : SwFmtAnchor bereits gesetzt
1589 : SvxBoxItem hier setzen
1590 : SvxBrushItem hier setzen
1591 : SvxShadowItem hier setzen
1592 : */
1593 :
1594 : // 1. GrafikObjekt des Docs?
1595 34 : GrafikCtor();
1596 :
1597 34 : const SfxItemSet& rOldSet = pSdrObj->GetMergedItemSet();
1598 :
1599 : // einige Items koennen direkt so uebernommen werden
1600 34 : const sal_uInt16 nDirectMatch = 2;
1601 : static RES_FRMATR const aDirectMatch[ nDirectMatch ] =
1602 : {
1603 : RES_LR_SPACE, // Aussenabstand links/rechts: SvxLRSpaceItem
1604 : RES_UL_SPACE // Aussenabstand Oben/unten: SvxULSpaceItem
1605 : };
1606 : const SfxPoolItem* pPoolItem;
1607 102 : for(sal_uInt16 nItem = 0; nItem < nDirectMatch; ++nItem)
1608 68 : if( SFX_ITEM_SET == rOldSet.GetItemState(
1609 68 : static_cast< sal_uInt16 >(aDirectMatch[ nItem ]), false, &pPoolItem) )
1610 : {
1611 0 : rFlySet.Put( *pPoolItem );
1612 : }
1613 :
1614 :
1615 : // jetzt die Umrandung berechnen und die Box bauen: Das Mass wird fuer die
1616 : // Rahmen-GROESSE benoetigt!
1617 34 : SvxBoxItem aBox(sw::util::ItemGet<SvxBoxItem>(rFlySet, RES_BOX));
1618 : // dashed oder solid wird zu solid
1619 : // WW-default: 0.75 pt = 15 twips
1620 34 : sal_Int32 nLineThick = 15, nOutside=0;
1621 :
1622 : // check if LineStyle is *really* set!
1623 : const SfxPoolItem* pItem;
1624 :
1625 34 : SfxItemState eState = rOldSet.GetItemState(XATTR_LINESTYLE,true,&pItem);
1626 34 : if( eState == SFX_ITEM_SET )
1627 : {
1628 : // Now, that we know there is a line style we will make use the
1629 : // parameter given to us when calling the method... :-)
1630 : const Color aLineColor = static_cast< XLineColorItem const & >(
1631 34 : rOldSet.Get(XATTR_LINECOLOR)).GetColorValue();
1632 34 : nLineThick = WW8ITEMVALUE(rOldSet, XATTR_LINEWIDTH, XLineWidthItem);
1633 :
1634 34 : if( !nLineThick )
1635 32 : nLineThick = 1; // for Writer, zero is "no border", so set a minimal value
1636 :
1637 : nOutside = MatchSdrBoxIntoFlyBoxItem(aLineColor, eLineStyle,
1638 34 : eDashing, eShapeType, nLineThick, aBox);
1639 : }
1640 :
1641 34 : rInnerDist.Left()+=nLineThick;
1642 34 : rInnerDist.Top()+=nLineThick;
1643 34 : rInnerDist.Right()+=nLineThick;
1644 34 : rInnerDist.Bottom()+=nLineThick;
1645 :
1646 : const SvxBorderLine *pLine;
1647 34 : if (0 != (pLine = aBox.GetLine(BOX_LINE_LEFT)))
1648 : {
1649 8 : rInnerDist.Left() -= (pLine->GetScaledWidth());
1650 : }
1651 :
1652 34 : if (0 != (pLine = aBox.GetLine(BOX_LINE_TOP)))
1653 : {
1654 8 : rInnerDist.Top() -= (pLine->GetScaledWidth());
1655 : }
1656 :
1657 34 : if (0 != (pLine = aBox.GetLine(BOX_LINE_RIGHT)))
1658 : {
1659 8 : rInnerDist.Right() -= (pLine->GetScaledWidth());
1660 : }
1661 :
1662 34 : if (0 != (pLine = aBox.GetLine(BOX_LINE_BOTTOM)))
1663 : {
1664 8 : rInnerDist.Bottom() -= (pLine->GetScaledWidth());
1665 : }
1666 :
1667 : // set distances from box's border to text contained within the box
1668 34 : if( 0 < rInnerDist.Left() )
1669 28 : aBox.SetDistance( (sal_uInt16)rInnerDist.Left(), BOX_LINE_LEFT );
1670 34 : if( 0 < rInnerDist.Top() )
1671 28 : aBox.SetDistance( (sal_uInt16)rInnerDist.Top(), BOX_LINE_TOP );
1672 34 : if( 0 < rInnerDist.Right() )
1673 33 : aBox.SetDistance( (sal_uInt16)rInnerDist.Right(), BOX_LINE_RIGHT );
1674 34 : if( 0 < rInnerDist.Bottom() )
1675 33 : aBox.SetDistance( (sal_uInt16)rInnerDist.Bottom(), BOX_LINE_BOTTOM );
1676 :
1677 34 : bool bFixSize = !(WW8ITEMVALUE(rOldSet, SDRATTR_TEXT_AUTOGROWHEIGHT,
1678 34 : SdrTextAutoGrowHeightItem));
1679 :
1680 : // Size: SwFmtFrmSize
1681 34 : if( SFX_ITEM_SET != rFlySet.GetItemState(RES_FRM_SIZE, false) )
1682 : {
1683 0 : const Rectangle& rSnapRect = pSdrObj->GetSnapRect();
1684 : // if necessary adapt width and position of the framework: The
1685 : // recorded interior is to remain equally large despite thick edges.
1686 : rFlySet.Put( SwFmtFrmSize(bFixSize ? ATT_FIX_SIZE : ATT_VAR_SIZE,
1687 0 : rSnapRect.GetWidth() + 2*nOutside,
1688 0 : rSnapRect.GetHeight() + 2*nOutside) );
1689 : }
1690 : else //If a size is set, adjust it to consider border thickness
1691 : {
1692 34 : SwFmtFrmSize aSize = (const SwFmtFrmSize &)(rFlySet.Get(RES_FRM_SIZE));
1693 :
1694 : SwFmtFrmSize aNewSize = SwFmtFrmSize(bFixSize ? ATT_FIX_SIZE : ATT_VAR_SIZE,
1695 34 : aSize.GetWidth() + 2*nOutside,
1696 102 : aSize.GetHeight() + 2*nOutside);
1697 34 : aNewSize.SetWidthSizeType(aSize.GetWidthSizeType());
1698 68 : rFlySet.Put( aNewSize );
1699 : }
1700 :
1701 : //Sadly word puts escher borders outside the graphic, but orients the
1702 : //graphic in relation to the top left inside the border. We don't
1703 34 : if (nOutside)
1704 : {
1705 : SwFmtHoriOrient aHori = (const SwFmtHoriOrient &)(rFlySet.Get(
1706 7 : RES_HORI_ORIENT));
1707 7 : aHori.SetPos(MakeSafePositioningValue(aHori.GetPos()-nOutside));
1708 7 : rFlySet.Put(aHori);
1709 :
1710 : SwFmtVertOrient aVert = (const SwFmtVertOrient &)(rFlySet.Get(
1711 14 : RES_VERT_ORIENT));
1712 7 : aVert.SetPos(aVert.GetPos()-nOutside);
1713 14 : rFlySet.Put(aVert);
1714 : }
1715 :
1716 : // jetzt die Umrandung setzen
1717 34 : rFlySet.Put( aBox );
1718 :
1719 : // Schattenwurf der Box: SvxShadowItem
1720 34 : if( WW8ITEMVALUE(rOldSet, SDRATTR_SHADOW, SdrShadowItem) )
1721 : {
1722 2 : SvxShadowItem aShadow( RES_SHADOW );
1723 :
1724 : const Color aShdColor = static_cast< SdrShadowColorItem const & >(
1725 2 : rOldSet.Get(SDRATTR_SHADOWCOLOR)).GetColorValue();
1726 2 : const sal_Int32 nShdDistX = WW8ITEMVALUE(rOldSet, SDRATTR_SHADOWXDIST,
1727 : SdrShadowXDistItem);
1728 2 : const sal_Int32 nShdDistY = WW8ITEMVALUE(rOldSet, SDRATTR_SHADOWYDIST,
1729 : SdrShadowYDistItem);
1730 :
1731 2 : aShadow.SetColor( Color( aShdColor ) );
1732 :
1733 4 : aShadow.SetWidth(writer_cast<sal_uInt16>((std::abs( nShdDistX) +
1734 4 : std::abs( nShdDistY )) / 2 ));
1735 :
1736 : SvxShadowLocation eShdPosi;
1737 2 : if( 0 <= nShdDistX )
1738 : {
1739 2 : if( 0 <= nShdDistY )
1740 2 : eShdPosi = SVX_SHADOW_BOTTOMRIGHT;
1741 : else
1742 0 : eShdPosi = SVX_SHADOW_TOPRIGHT;
1743 : }
1744 : else
1745 : {
1746 0 : if( 0 <= nShdDistY )
1747 0 : eShdPosi = SVX_SHADOW_BOTTOMLEFT;
1748 : else
1749 0 : eShdPosi = SVX_SHADOW_TOPLEFT;
1750 : }
1751 2 : aShadow.SetLocation( eShdPosi );
1752 :
1753 2 : rFlySet.Put( aShadow );
1754 : }
1755 34 : Color Temp(COL_WHITE);
1756 68 : SvxBrushItem aBrushItem(Temp, RES_BACKGROUND);
1757 34 : bool bBrushItemOk = false;
1758 34 : sal_uInt8 nTrans = 0;
1759 :
1760 : //Separate transparency
1761 34 : eState = rOldSet.GetItemState(XATTR_FILLTRANSPARENCE, true, &pItem);
1762 34 : if (eState == SFX_ITEM_SET)
1763 : {
1764 3 : sal_uInt16 nRes = WW8ITEMVALUE(rOldSet, XATTR_FILLTRANSPARENCE,
1765 : XFillTransparenceItem);
1766 3 : nTrans = sal_uInt8((nRes * 0xFE) / 100);
1767 3 : aBrushItem.GetColor().SetTransparency(nTrans);
1768 3 : bBrushItemOk = true;
1769 : }
1770 :
1771 : // Hintergrund: SvxBrushItem
1772 34 : eState = rOldSet.GetItemState(XATTR_FILLSTYLE, true, &pItem);
1773 34 : if (eState == SFX_ITEM_SET)
1774 : {
1775 34 : const XFillStyle eFill = ((const XFillStyleItem*)pItem)->GetValue();
1776 :
1777 34 : switch (eFill)
1778 : {
1779 : case XFILL_NONE:
1780 : //Writer graphics don't have it yet
1781 19 : if (eShapeType != mso_sptPictureFrame)
1782 : {
1783 0 : aBrushItem.GetColor().SetTransparency(0xFE);
1784 0 : bBrushItemOk = true;
1785 : }
1786 19 : break;
1787 : case XFILL_SOLID:
1788 : case XFILL_GRADIENT:
1789 : {
1790 : const Color aColor = static_cast< XFillColorItem const & >(
1791 15 : rOldSet.Get(XATTR_FILLCOLOR)).GetColorValue();
1792 15 : aBrushItem.SetColor(aColor);
1793 :
1794 15 : if (bBrushItemOk) //has trans
1795 3 : aBrushItem.GetColor().SetTransparency(nTrans);
1796 :
1797 15 : bBrushItemOk = true;
1798 : }
1799 15 : break;
1800 : //case XFILL_GRADIENT:
1801 : //break;
1802 : case XFILL_HATCH:
1803 0 : break;
1804 : case XFILL_BITMAP:
1805 : {
1806 0 : GraphicObject aGrfObj(static_cast< XFillBitmapItem const & >(rOldSet.Get(XATTR_FILLBITMAP)).GetGraphicObject());
1807 0 : const bool bTile(WW8ITEMVALUE(rOldSet, XATTR_FILLBMP_TILE, SfxBoolItem) ? true: false);
1808 :
1809 0 : if(bBrushItemOk) //has trans
1810 : {
1811 0 : GraphicAttr aAttr(aGrfObj.GetAttr());
1812 :
1813 0 : aAttr.SetTransparency(nTrans);
1814 0 : aGrfObj.SetAttr(aAttr);
1815 : }
1816 :
1817 0 : aBrushItem.SetGraphicObject(aGrfObj);
1818 0 : aBrushItem.SetGraphicPos(bTile ? GPOS_TILED : GPOS_AREA);
1819 0 : bBrushItemOk = true;
1820 : }
1821 0 : break;
1822 : }
1823 : }
1824 :
1825 34 : if (bBrushItemOk)
1826 49 : rFlySet.Put(aBrushItem, RES_BACKGROUND);
1827 34 : }
1828 :
1829 64 : void SwWW8ImplReader::AdjustLRWrapForWordMargins(
1830 : const SvxMSDffImportRec &rRecord, SvxLRSpaceItem &rLR)
1831 : {
1832 64 : sal_uInt32 nXRelTo = SvxMSDffImportRec::RELTO_DEFAULT;
1833 64 : if ( rRecord.pXRelTo )
1834 : {
1835 52 : nXRelTo = *(rRecord.pXRelTo);
1836 : }
1837 :
1838 : // Left adjustments - if horizontally aligned to left of
1839 : // margin or column then remove the left wrapping
1840 64 : if (rRecord.nXAlign == 1)
1841 : {
1842 1 : if ((nXRelTo == 0) || (nXRelTo == 2))
1843 0 : rLR.SetLeft((sal_uInt16)0);
1844 : }
1845 :
1846 : // Right adjustments - if horizontally aligned to right of
1847 : // margin or column then remove the right wrapping
1848 64 : if (rRecord.nXAlign == 3)
1849 : {
1850 0 : if ((nXRelTo == 0) || (nXRelTo == 2))
1851 0 : rLR.SetRight((sal_uInt16)0);
1852 : }
1853 :
1854 : //Inside margin, remove left wrapping
1855 64 : if ((rRecord.nXAlign == 4) && (nXRelTo == 0))
1856 : {
1857 0 : rLR.SetLeft((sal_uInt16)0);
1858 : }
1859 :
1860 : //Outside margin, remove left wrapping
1861 64 : if ((rRecord.nXAlign == 5) && (nXRelTo == 0))
1862 : {
1863 0 : rLR.SetRight((sal_uInt16)0);
1864 : }
1865 64 : }
1866 :
1867 :
1868 0 : void SwWW8ImplReader::AdjustULWrapForWordMargins(
1869 : const SvxMSDffImportRec &rRecord, SvxULSpaceItem &rUL)
1870 : {
1871 0 : sal_uInt32 nYRelTo = SvxMSDffImportRec::RELTO_DEFAULT;
1872 0 : if ( rRecord.pYRelTo )
1873 : {
1874 0 : nYRelTo = *(rRecord.pYRelTo);
1875 : }
1876 :
1877 : // Top adjustment - remove upper wrapping if aligned to page
1878 : // printable area or to page
1879 0 : if (rRecord.nYAlign == 1)
1880 : {
1881 0 : if ((nYRelTo == 0) || (nYRelTo == 1))
1882 0 : rUL.SetUpper((sal_uInt16)0);
1883 : }
1884 :
1885 : // Bottom adjustment - remove bottom wrapping if aligned to page or
1886 : // printable area or to page
1887 0 : if (rRecord.nYAlign == 3)
1888 : {
1889 0 : if ((nYRelTo == 0) || (nYRelTo == 1))
1890 0 : rUL.SetLower((sal_uInt16)0);
1891 : }
1892 :
1893 : //Remove top margin if aligned vertically inside margin
1894 0 : if ((rRecord.nYAlign == 4) && (nYRelTo == 0))
1895 0 : rUL.SetUpper((sal_uInt16)0);
1896 0 : }
1897 :
1898 66 : void SwWW8ImplReader::MapWrapIntoFlyFmt(SvxMSDffImportRec* pRecord,
1899 : SwFrmFmt* pFlyFmt)
1900 : {
1901 66 : if (!pRecord || !pFlyFmt)
1902 66 : return;
1903 :
1904 66 : if (pRecord->nDxWrapDistLeft || pRecord->nDxWrapDistRight)
1905 : {
1906 64 : SvxLRSpaceItem aLR(writer_cast<sal_uInt16>(pRecord->nDxWrapDistLeft),
1907 128 : writer_cast<sal_uInt16>(pRecord->nDxWrapDistRight), 0, 0, RES_LR_SPACE);
1908 64 : AdjustLRWrapForWordMargins(*pRecord, aLR);
1909 64 : pFlyFmt->SetFmtAttr(aLR);
1910 : }
1911 66 : if (pRecord->nDyWrapDistTop || pRecord->nDyWrapDistBottom)
1912 : {
1913 0 : SvxULSpaceItem aUL(writer_cast<sal_uInt16>(pRecord->nDyWrapDistTop),
1914 0 : writer_cast<sal_uInt16>(pRecord->nDyWrapDistBottom), RES_UL_SPACE);
1915 0 : AdjustULWrapForWordMargins(*pRecord, aUL);
1916 0 : pFlyFmt->SetFmtAttr(aUL);
1917 : }
1918 :
1919 : //If we are contoured and have a custom polygon...
1920 66 : if (pRecord->pWrapPolygon && pFlyFmt->GetSurround().IsContour())
1921 : {
1922 0 : if (SwNoTxtNode *pNd = GetNoTxtNodeFromSwFrmFmt(*pFlyFmt))
1923 : {
1924 :
1925 : /*
1926 : Gather round children and hear of a tale that will raise the
1927 : hairs on the back of your neck this dark halloween night.
1928 :
1929 : There is a polygon in word that describes the wraping around
1930 : the graphic.
1931 :
1932 : Here are some sample values for the simplest case of a square
1933 : around some solid coloured graphics
1934 :
1935 : X Y Pixel size of graphic
1936 : TopLeft -54 21600 400x400
1937 : Bottom Right 0 21546
1938 :
1939 : TopLeft -108 21600 200x200
1940 : Bottom Right 0 21492
1941 :
1942 : TopLeft -216 21600 100x100
1943 : Bottom Right 0 21384
1944 :
1945 : TopLeft -432 21600 50x50
1946 : Bottom Right 0 21168
1947 :
1948 : TopLeft -76 21600 283x212
1949 : Bottom Right 0 21498
1950 :
1951 : So given that the size of the values remains pretty much the
1952 : same despite the size of the graphic, we can tell that the
1953 : polygon is measured in units that are independent of the
1954 : graphic. But why does the left corner move a different value
1955 : to the left each time, and why does the bottom move upwards
1956 : each time, when the right and top remain at the same value ?
1957 :
1958 : I have no idea, but clearly once we calculate the values out
1959 : we see that the left margin is always a fixed realworld
1960 : distance from the true left and the polygon bottom is the same
1961 : fixed value from the bottom. i.e. 15twips.
1962 :
1963 : So here we take our word provided polygon, shift it to the
1964 : right by 15twips and rescale it widthwise to shrink the width
1965 : a little to fit the now moved right margin back to where it
1966 : was, and stretch the height a little to make the bottom move
1967 : down the missing 15twips then we get a polygon that matches
1968 : what I actually see in word
1969 : */
1970 :
1971 0 : PolyPolygon aPoly(*pRecord->pWrapPolygon);
1972 0 : const Size &rSize = pNd->GetTwipSize();
1973 : /*
1974 : Move to the left by 15twips, and rescale to
1975 : a) shrink right bound back to orig position
1976 : b) stretch bottom bound to where I think it should have been
1977 : in the first place
1978 : */
1979 0 : Fraction aMoveHack(ww::nWrap100Percent, rSize.Width());
1980 0 : aMoveHack *= Fraction(15, 1);
1981 0 : long nMove(aMoveHack);
1982 0 : aPoly.Move(nMove, 0);
1983 :
1984 0 : Fraction aHackX(ww::nWrap100Percent, ww::nWrap100Percent + nMove);
1985 0 : Fraction aHackY(ww::nWrap100Percent, ww::nWrap100Percent - nMove);
1986 0 : aPoly.Scale(aHackX, aHackY);
1987 :
1988 : //Turn polygon back into units that match the graphic's
1989 0 : const Size &rOrigSize = pNd->GetGraphic().GetPrefSize();
1990 0 : Fraction aMapPolyX(rOrigSize.Width(), ww::nWrap100Percent);
1991 0 : Fraction aMapPolyY(rOrigSize.Height(), ww::nWrap100Percent);
1992 0 : aPoly.Scale(aMapPolyX, aMapPolyY);
1993 :
1994 : // #i47277# - contour is already in unit of the
1995 : // graphic prefered unit. Thus, call method <SetContour(..)>
1996 0 : pNd->SetContour(&aPoly);
1997 : }
1998 : }
1999 : }
2000 :
2001 : void
2002 25 : SwWW8ImplReader::SetAttributesAtGrfNode(SvxMSDffImportRec const*const pRecord,
2003 : SwFrmFmt *pFlyFmt, WW8_FSPA *pF )
2004 : {
2005 25 : const SwNodeIndex* pIdx = pFlyFmt->GetCntnt(false).GetCntntIdx();
2006 : SwGrfNode* pGrfNd;
2007 25 : if( pIdx && 0 != (pGrfNd = rDoc.GetNodes()[pIdx->GetIndex() + 1]->GetGrfNode() ))
2008 : {
2009 20 : Size aSz(pGrfNd->GetTwipSize());
2010 : // use type <sal_uInt64> instead of sal_uLong to get correct results
2011 : // in the following calculations.
2012 20 : sal_uInt64 rHeight = aSz.Height();
2013 20 : sal_uInt64 rWidth = aSz.Width();
2014 20 : if( !rWidth && pF)
2015 0 : rWidth = pF->nXaRight - pF->nXaLeft;
2016 20 : else if( !rHeight && pF)
2017 0 : rHeight = pF->nYaBottom - pF->nYaTop;
2018 :
2019 20 : if( pRecord->nCropFromTop || pRecord->nCropFromBottom ||
2020 20 : pRecord->nCropFromLeft || pRecord->nCropFromRight )
2021 : {
2022 0 : SwCropGrf aCrop; // Cropping is stored in 'fixed floats'
2023 : // 16.16 (it est fraction times total
2024 0 : if( pRecord->nCropFromTop ) // image width or height resp.)
2025 : aCrop.SetTop( static_cast< sal_Int32 >(
2026 0 : ( ( (pRecord->nCropFromTop >> 16 ) * rHeight )
2027 0 : + (((pRecord->nCropFromTop & 0xffff) * rHeight ) >> 16) )));
2028 0 : if( pRecord->nCropFromBottom )
2029 : aCrop.SetBottom( static_cast< sal_Int32 >(
2030 0 : ( ( (pRecord->nCropFromBottom >> 16 ) * rHeight )
2031 0 : + (((pRecord->nCropFromBottom & 0xffff) * rHeight ) >> 16) )));
2032 0 : if( pRecord->nCropFromLeft )
2033 : aCrop.SetLeft( static_cast< sal_Int32 >(
2034 0 : ( ( (pRecord->nCropFromLeft >> 16 ) * rWidth )
2035 0 : + (((pRecord->nCropFromLeft & 0xffff) * rWidth ) >> 16) )));
2036 0 : if( pRecord->nCropFromRight )
2037 : aCrop.SetRight( static_cast< sal_Int32 >(
2038 0 : ( ( (pRecord->nCropFromRight >> 16 ) * rWidth )
2039 0 : + (((pRecord->nCropFromRight & 0xffff) * rWidth ) >> 16) )));
2040 :
2041 0 : pGrfNd->SetAttr( aCrop );
2042 : }
2043 :
2044 20 : if (pRecord && pRecord->pObj)
2045 : {
2046 20 : const SfxItemSet& rOldSet = pRecord->pObj->GetMergedItemSet();
2047 : //contrast
2048 20 : if (WW8ITEMVALUE(rOldSet, SDRATTR_GRAFCONTRAST,
2049 : SdrGrafContrastItem))
2050 : {
2051 : SwContrastGrf aContrast(
2052 0 : WW8ITEMVALUE(rOldSet,
2053 0 : SDRATTR_GRAFCONTRAST, SdrGrafContrastItem));
2054 0 : pGrfNd->SetAttr( aContrast );
2055 : }
2056 :
2057 : //luminance
2058 20 : if (WW8ITEMVALUE(rOldSet, SDRATTR_GRAFLUMINANCE,
2059 : SdrGrafLuminanceItem))
2060 : {
2061 0 : SwLuminanceGrf aLuminance(WW8ITEMVALUE(rOldSet,
2062 0 : SDRATTR_GRAFLUMINANCE, SdrGrafLuminanceItem));
2063 0 : pGrfNd->SetAttr( aLuminance );
2064 : }
2065 : //gamma
2066 20 : if (WW8ITEMVALUE(rOldSet, SDRATTR_GRAFGAMMA, SdrGrafGamma100Item))
2067 : {
2068 20 : double fVal = WW8ITEMVALUE(rOldSet, SDRATTR_GRAFGAMMA,
2069 : SdrGrafGamma100Item);
2070 20 : pGrfNd->SetAttr(SwGammaGrf(fVal/100.));
2071 : }
2072 :
2073 : //drawmode
2074 20 : if (WW8ITEMVALUE(rOldSet, SDRATTR_GRAFMODE, SdrGrafModeItem))
2075 : {
2076 0 : SwDrawModeGrf aDrawMode( static_cast< sal_uInt16 >(WW8ITEMVALUE(rOldSet,
2077 0 : SDRATTR_GRAFMODE, SdrGrafModeItem)) );
2078 0 : pGrfNd->SetAttr( aDrawMode );
2079 : }
2080 : }
2081 : }
2082 25 : }
2083 :
2084 47 : SdrObject* SwWW8ImplReader::CreateContactObject(SwFrmFmt* pFlyFmt)
2085 : {
2086 47 : if (pFlyFmt)
2087 : {
2088 47 : SdrObject* pNewObject = mbNewDoc ? 0 : pFlyFmt->FindRealSdrObject();
2089 47 : if (!pNewObject)
2090 47 : pNewObject = pFlyFmt->FindSdrObject();
2091 47 : if (!pNewObject && pFlyFmt->ISA(SwFlyFrmFmt))
2092 : {
2093 : SwFlyDrawContact* pContactObject
2094 : = new SwFlyDrawContact(static_cast<SwFlyFrmFmt*>(pFlyFmt),
2095 29 : pDrawModel);
2096 29 : pNewObject = pContactObject->GetMaster();
2097 : }
2098 47 : return pNewObject;
2099 : }
2100 0 : return 0;
2101 : }
2102 :
2103 : // Miserable miserable hack to fudge word's graphic layout in RTL mode to ours.
2104 77 : bool SwWW8ImplReader::MiserableRTLGraphicsHack(SwTwips &rLeft, SwTwips nWidth,
2105 : sal_Int16 eHoriOri, sal_Int16 eHoriRel)
2106 : {
2107 77 : if (!IsRightToLeft())
2108 69 : return false;
2109 : return RTLGraphicsHack(rLeft, nWidth, eHoriOri, eHoriRel,
2110 8 : maSectionManager.GetPageLeft(),
2111 8 : maSectionManager.GetPageRight(),
2112 24 : maSectionManager.GetPageWidth());
2113 : }
2114 :
2115 69 : RndStdIds SwWW8ImplReader::ProcessEscherAlign(SvxMSDffImportRec* pRecord,
2116 : WW8_FSPA *pFSPA, SfxItemSet &rFlySet, bool /*bOrgObjectWasReplace*/)
2117 : {
2118 : OSL_ENSURE(pRecord || pFSPA, "give me something! to work with for anchoring");
2119 69 : if (!pRecord && !pFSPA)
2120 0 : return FLY_AT_PAGE;
2121 69 : sal_Bool bCurSectionVertical = maSectionManager.CurrentSectionIsVertical();
2122 :
2123 69 : SvxMSDffImportRec aRecordFromFSPA;
2124 69 : if (!pRecord)
2125 0 : pRecord = &aRecordFromFSPA;
2126 69 : if (!(pRecord->pXRelTo) && pFSPA)
2127 : {
2128 49 : pRecord->pXRelTo = new sal_uInt32;
2129 49 : *(pRecord->pXRelTo) = pFSPA->nbx;
2130 : }
2131 69 : if (!(pRecord->pYRelTo) && pFSPA)
2132 : {
2133 49 : pRecord->pYRelTo = new sal_uInt32;
2134 49 : *(pRecord->pYRelTo) = pFSPA->nby;
2135 : }
2136 :
2137 : // nXAlign - abs. Position, Left, Centered, Right, Inside, Outside
2138 : // nYAlign - abs. Position, Top, Centered, Bottom, Inside, Outside
2139 :
2140 : // nXRelTo - Page printable area, Page, Column, Character
2141 : // nYRelTo - Page printable area, Page, Paragraph, Line
2142 :
2143 69 : const sal_uInt32 nCntXAlign = 6;
2144 69 : const sal_uInt32 nCntYAlign = 6;
2145 :
2146 69 : const sal_uInt32 nCntRelTo = 4;
2147 :
2148 69 : sal_uInt32 nXAlign = nCntXAlign > pRecord->nXAlign ? pRecord->nXAlign : 1;
2149 69 : sal_uInt32 nYAlign = nCntYAlign > pRecord->nYAlign ? pRecord->nYAlign : 1;
2150 :
2151 69 : if (pFSPA)
2152 : {
2153 : /*
2154 : #i15718# #i19008#
2155 : Strangely in this case the FSPA value seems to be considered before
2156 : the newer escher nXRelTo record.
2157 : */
2158 : // #i52565# - correct condition checking:
2159 : // first check, if <nXRelTo> and <nYRelTo> have default values. This
2160 : // is a hint that these values aren't set by the escher import - see
2161 : // method <SwMSDffManager::ProcessObj(..)>. Then, check if for each
2162 : // values, if it differs from the one in the FSPA.
2163 :
2164 69 : if ( *(pRecord->pXRelTo) == 2 && *(pRecord->pYRelTo) == 2 && !bCurSectionVertical)
2165 : {
2166 : // if <nYRelTo> differs from <FSPA.nby> overwrite <nYRelTo>
2167 65 : if ( pFSPA->nby != *(pRecord->pYRelTo) )
2168 : {
2169 0 : *(pRecord->pYRelTo) = pFSPA->nby;
2170 : }
2171 : }
2172 : }
2173 :
2174 69 : sal_uInt32 nXRelTo = nCntRelTo > *(pRecord->pXRelTo) ? *(pRecord->pXRelTo) : 1;
2175 69 : sal_uInt32 nYRelTo = nCntRelTo > *(pRecord->pYRelTo) ? *(pRecord->pYRelTo) : 1;
2176 :
2177 69 : RndStdIds eAnchor = IsInlineEscherHack() ? FLY_AS_CHAR : FLY_AT_CHAR; // #i43718#
2178 :
2179 138 : SwFmtAnchor aAnchor( eAnchor );
2180 69 : aAnchor.SetAnchor( pPaM->GetPoint() );
2181 69 : rFlySet.Put( aAnchor );
2182 :
2183 69 : if (pFSPA)
2184 : {
2185 : // #i18732#
2186 : //Given new layout where everything is changed to be anchored to
2187 : //character the following 4 tables may need to be changed.
2188 :
2189 : // horizontal Adjustment
2190 : static const sal_Int16 aHoriOriTab[ nCntXAlign ] =
2191 : {
2192 : text::HoriOrientation::NONE, // From left position
2193 : text::HoriOrientation::LEFT, // left
2194 : text::HoriOrientation::CENTER, // centered
2195 : text::HoriOrientation::RIGHT, // right
2196 : // #i36649#
2197 : // - inside -> text::HoriOrientation::LEFT and outside -> text::HoriOrientation::RIGHT
2198 : text::HoriOrientation::LEFT, // inside
2199 : text::HoriOrientation::RIGHT // outside
2200 : };
2201 :
2202 :
2203 : // generic vertical Adjustment
2204 : static const sal_Int16 aVertOriTab[ nCntYAlign ] =
2205 : {
2206 : text::VertOrientation::NONE, // From Top position
2207 : text::VertOrientation::TOP, // top
2208 : text::VertOrientation::CENTER, // centered
2209 : text::VertOrientation::BOTTOM, // bottom
2210 : text::VertOrientation::LINE_TOP, // inside (obscure)
2211 : text::VertOrientation::LINE_BOTTOM // outside (obscure)
2212 : };
2213 :
2214 : // #i22673# - to-line vertical alignment
2215 : static const sal_Int16 aToLineVertOriTab[ nCntYAlign ] =
2216 : {
2217 : text::VertOrientation::NONE, // below
2218 : text::VertOrientation::LINE_BOTTOM, // top
2219 : text::VertOrientation::LINE_CENTER, // centered
2220 : text::VertOrientation::LINE_TOP, // bottom
2221 : text::VertOrientation::LINE_BOTTOM, // inside (obscure)
2222 : text::VertOrientation::LINE_TOP // outside (obscure)
2223 : };
2224 :
2225 : // Adjustment is horizontally relative to...
2226 : static const sal_Int16 aHoriRelOriTab[nCntRelTo] =
2227 : {
2228 : text::RelOrientation::PAGE_PRINT_AREA, // 0 is page textarea margin
2229 : text::RelOrientation::PAGE_FRAME, // 1 is page margin
2230 : text::RelOrientation::FRAME, // 2 is relative to column
2231 : text::RelOrientation::CHAR // 3 is relative to character
2232 : };
2233 :
2234 : // Adjustment is vertically relative to...
2235 : // #i22673# - adjustment for new vertical alignment at top of line.
2236 : static const sal_Int16 aVertRelOriTab[nCntRelTo] =
2237 : {
2238 : text::RelOrientation::PAGE_PRINT_AREA, // 0 is page textarea margin
2239 : text::RelOrientation::PAGE_FRAME, // 1 is page margin
2240 : text::RelOrientation::FRAME, // 2 is relative to paragraph
2241 : text::RelOrientation::TEXT_LINE // 3 is relative to line
2242 : };
2243 :
2244 69 : sal_Int16 eHoriOri = aHoriOriTab[ nXAlign ];
2245 69 : sal_Int16 eHoriRel = aHoriRelOriTab[ nXRelTo ];
2246 :
2247 : // #i36649# - adjustments for certain alignments
2248 69 : if ( eHoriOri == text::HoriOrientation::LEFT && eHoriRel == text::RelOrientation::PAGE_FRAME )
2249 : {
2250 : // convert 'left to page' to 'from left -<width> to page text area'
2251 1 : eHoriOri = text::HoriOrientation::NONE;
2252 1 : eHoriRel = text::RelOrientation::PAGE_PRINT_AREA;
2253 1 : const long nWidth = pFSPA->nXaRight - pFSPA->nXaLeft;
2254 1 : pFSPA->nXaLeft = -nWidth;
2255 1 : pFSPA->nXaRight = 0;
2256 : }
2257 68 : else if ( eHoriOri == text::HoriOrientation::RIGHT && eHoriRel == text::RelOrientation::PAGE_FRAME )
2258 : {
2259 : // convert 'right to page' to 'from left 0 to right page border'
2260 0 : eHoriOri = text::HoriOrientation::NONE;
2261 0 : eHoriRel = text::RelOrientation::PAGE_RIGHT;
2262 0 : const long nWidth = pFSPA->nXaRight - pFSPA->nXaLeft;
2263 0 : pFSPA->nXaLeft = 0;
2264 0 : pFSPA->nXaRight = nWidth;
2265 : }
2266 :
2267 : // #i24255# - position of floating screen objects in
2268 : // R2L layout are given in L2R layout, thus convert them of all
2269 : // floating screen objects, which are imported.
2270 : {
2271 : // Miserable miserable hack.
2272 69 : SwTwips nWidth = (pFSPA->nXaRight - pFSPA->nXaLeft);
2273 69 : SwTwips nLeft = pFSPA->nXaLeft;
2274 69 : if (MiserableRTLGraphicsHack(nLeft, nWidth, eHoriOri,
2275 69 : eHoriRel))
2276 : {
2277 5 : pFSPA->nXaLeft = nLeft;
2278 5 : pFSPA->nXaRight = pFSPA->nXaLeft + nWidth;
2279 : }
2280 : }
2281 :
2282 : // if the object is anchored inside a table cell, is horizontal aligned
2283 : // at frame|character and has wrap through, but its attribute
2284 : // 'layout in table cell' isn't set, convert its horizontal alignment to page text area.
2285 : // #i84783# - use new method <IsObjectLayoutInTableCell()>
2286 82 : if ( nInTable &&
2287 13 : ( eHoriRel == text::RelOrientation::FRAME || eHoriRel == text::RelOrientation::CHAR ) &&
2288 95 : pFSPA->nwr == 3 &&
2289 13 : !IsObjectLayoutInTableCell( pRecord->nLayoutInTableCell ) )
2290 : {
2291 0 : eHoriRel = text::RelOrientation::PAGE_PRINT_AREA;
2292 : }
2293 :
2294 :
2295 : //Writer honours this wrap distance when aligned as "left" or "right",
2296 : //Word doesn't. Writer doesn't honour it when its "from left".
2297 69 : if (eHoriOri == text::HoriOrientation::LEFT)
2298 0 : pRecord->nDxWrapDistLeft=0;
2299 69 : else if (eHoriOri == text::HoriOrientation::RIGHT)
2300 0 : pRecord->nDxWrapDistRight=0;
2301 :
2302 : sal_Int16 eVertRel;
2303 :
2304 69 : eVertRel = aVertRelOriTab[ nYRelTo ]; // #i18732#
2305 69 : if ( bCurSectionVertical && nYRelTo == 2 )
2306 0 : eVertRel = text::RelOrientation::PAGE_PRINT_AREA;
2307 : // #i22673# - fill <eVertOri> in dependence of <eVertRel>
2308 : sal_Int16 eVertOri;
2309 69 : if ( eVertRel == text::RelOrientation::TEXT_LINE )
2310 : {
2311 3 : eVertOri = aToLineVertOriTab[ nYAlign ];
2312 : }
2313 : else
2314 : {
2315 66 : eVertOri = aVertOriTab[ nYAlign ];
2316 : }
2317 :
2318 : //Below line in word is a positive value, while in writer its
2319 : //negative
2320 69 : long nYPos = pFSPA->nYaTop;
2321 : // #i22673#
2322 69 : if ((eVertRel == text::RelOrientation::TEXT_LINE) && (eVertOri == text::VertOrientation::NONE))
2323 3 : nYPos = -nYPos;
2324 :
2325 : SwFmtHoriOrient aHoriOri(MakeSafePositioningValue( bCurSectionVertical ? nYPos : pFSPA->nXaLeft ),
2326 : bCurSectionVertical ? eVertOri : eHoriOri,
2327 69 : bCurSectionVertical ? eVertRel : eHoriRel);
2328 69 : if( 4 <= nXAlign )
2329 0 : aHoriOri.SetPosToggle(true);
2330 69 : rFlySet.Put( aHoriOri );
2331 :
2332 : rFlySet.Put(SwFmtVertOrient(MakeSafePositioningValue( !bCurSectionVertical ? nYPos : -pFSPA->nXaRight ),
2333 : !bCurSectionVertical ? eVertOri : eHoriOri,
2334 69 : !bCurSectionVertical ? eVertRel : eHoriRel ));
2335 : }
2336 :
2337 138 : return eAnchor;
2338 : }
2339 :
2340 : // #i84783#
2341 26 : bool SwWW8ImplReader::IsObjectLayoutInTableCell( const sal_uInt32 nLayoutInTableCell ) const
2342 : {
2343 26 : bool bIsObjectLayoutInTableCell = false;
2344 :
2345 26 : if ( bVer8 )
2346 : {
2347 26 : const sal_uInt16 nWWVersion = pWwFib->nProduct & 0xE000;
2348 26 : switch ( nWWVersion )
2349 : {
2350 : case 0x0000: // version 8 aka Microsoft Word 97
2351 : {
2352 0 : bIsObjectLayoutInTableCell = false;
2353 : OSL_ENSURE( nLayoutInTableCell == 0xFFFFFFFF,
2354 : "no explicit object attribute layout in table cell expected." );
2355 : }
2356 0 : break;
2357 : case 0x2000: // version 9 aka Microsoft Word 2000
2358 : case 0x4000: // version 10 aka Microsoft Word 2002
2359 : case 0x6000: // version 11 aka Microsoft Word 2003
2360 : case 0x8000: // version 12 aka Microsoft Word 2007
2361 : case 0xC000: // version 14 aka Microsoft Word 2010
2362 : {
2363 : // #i98037#
2364 : // adjustment of conditions needed after deeper analysis of
2365 : // certain test cases.
2366 26 : if ( nLayoutInTableCell == 0xFFFFFFFF || // no explicit attribute value given
2367 0 : nLayoutInTableCell == 0x80008000 ||
2368 0 : ( nLayoutInTableCell & 0x02000000 &&
2369 0 : !(nLayoutInTableCell & 0x80000000 ) ) )
2370 : {
2371 26 : bIsObjectLayoutInTableCell = true;
2372 : }
2373 : else
2374 : {
2375 0 : bIsObjectLayoutInTableCell = false;
2376 : }
2377 : }
2378 26 : break;
2379 : default:
2380 : {
2381 : OSL_FAIL( "unknown version." );
2382 : }
2383 : }
2384 : }
2385 :
2386 26 : return bIsObjectLayoutInTableCell;
2387 : }
2388 :
2389 69 : SwFrmFmt* SwWW8ImplReader::Read_GrafLayer( long nGrafAnchorCp )
2390 : {
2391 69 : if( nIniFlags & WW8FL_NO_GRAFLAYER )
2392 0 : return 0;
2393 :
2394 69 : ::SetProgressState(nProgress, mpDocShell); // Update
2395 :
2396 69 : nDrawCpO = pWwFib->GetBaseCp(pPlcxMan->GetManType() == MAN_HDFT ? MAN_TXBX_HDFT : MAN_TXBX);
2397 :
2398 69 : GrafikCtor();
2399 :
2400 69 : WW8PLCFspecial* pPF = pPlcxMan->GetFdoa();
2401 69 : if( !pPF )
2402 : {
2403 : OSL_ENSURE( !this, "Where is the grapic (1) ?" );
2404 0 : return 0;
2405 : }
2406 :
2407 69 : if( bVer67 )
2408 : {
2409 0 : long nOldPos = pStrm->Tell();
2410 :
2411 0 : nDrawXOfs = nDrawYOfs = 0;
2412 0 : ReadGrafLayer1( pPF, nGrafAnchorCp );
2413 :
2414 0 : pStrm->Seek( nOldPos );
2415 0 : return 0;
2416 : }
2417 :
2418 : //Normal case of Word 8+ version stuff
2419 69 : pPF->SeekPos( nGrafAnchorCp );
2420 :
2421 : WW8_FC nStartFc;
2422 : void* pF0;
2423 69 : if( !pPF->Get( nStartFc, pF0 ) ){
2424 : OSL_ENSURE( !this, "+Wo ist die Grafik (2) ?" );
2425 0 : return 0;
2426 : }
2427 :
2428 69 : WW8_FSPA_SHADOW* pFS = (WW8_FSPA_SHADOW*)pF0;
2429 : WW8_FSPA* pF;
2430 : #ifdef __WW8_NEEDS_COPY
2431 : WW8_FSPA aFSFA;
2432 69 : pF = &aFSFA;
2433 69 : WW8FSPAShadowToReal( pFS, pF );
2434 : #else
2435 : pF = (WW8_FSPA*)pFS;
2436 : #endif // defined __WW8_NEEDS_COPY
2437 69 : if( !pF->nSpId )
2438 : {
2439 : OSL_ENSURE( !this, "+Wo ist die Grafik (3) ?" );
2440 0 : return 0;
2441 : }
2442 :
2443 69 : if (!pMSDffManager->GetModel())
2444 0 : pMSDffManager->SetModel(pDrawModel, 1440);
2445 :
2446 :
2447 69 : Rectangle aRect(pF->nXaLeft, pF->nYaTop, pF->nXaRight, pF->nYaBottom);
2448 69 : SvxMSDffImportData aData( aRect );
2449 :
2450 : /*
2451 : #i20540#
2452 : The SdrOle2Obj will try and manage any ole objects it finds, causing all
2453 : sorts of trouble later on
2454 : */
2455 69 : SwDocShell* pPersist = rDoc.GetDocShell();
2456 69 : rDoc.SetDocShell(0); //#i20540# Persist guard
2457 :
2458 69 : SdrObject* pObject = 0;
2459 69 : bool bOk = (pMSDffManager->GetShape(pF->nSpId, pObject, aData) && pObject);
2460 :
2461 69 : rDoc.SetDocShell(pPersist); //#i20540# Persist guard
2462 :
2463 69 : if (!bOk)
2464 : {
2465 : OSL_ENSURE( !this, "Where is the Shape ?" );
2466 0 : return 0;
2467 : }
2468 :
2469 69 : bool bDone = false;
2470 69 : SdrObject* pOurNewObject = 0;
2471 69 : bool bReplaceable = false;
2472 :
2473 69 : switch (SdrObjKind(pObject->GetObjIdentifier()))
2474 : {
2475 : case OBJ_GRAF:
2476 13 : bReplaceable = true;
2477 13 : bDone = true;
2478 13 : break;
2479 : case OBJ_OLE2:
2480 0 : bReplaceable = true;
2481 0 : break;
2482 : default:
2483 56 : break;
2484 :
2485 : }
2486 :
2487 : // when in a header or footer word appears to treat all elements as wrap through
2488 :
2489 : // Umfluss-Modus ermitteln
2490 69 : SfxItemSet aFlySet(rDoc.GetAttrPool(), RES_FRMATR_BEGIN, RES_FRMATR_END-1);
2491 69 : SwSurround eSurround = SURROUND_PARALLEL;
2492 69 : bool bContour = false;
2493 69 : switch (pF->nwr)
2494 : {
2495 : case 0: //0 like 2, but doesn't require absolute object
2496 : case 2: //2 wrap around absolute object
2497 4 : eSurround = SURROUND_PARALLEL;
2498 4 : break;
2499 : case 1: //1 no text next to shape
2500 0 : eSurround = SURROUND_NONE;
2501 0 : break;
2502 : case 3: //3 wrap as if no object present
2503 65 : eSurround = SURROUND_THROUGHT;
2504 65 : break;
2505 : case 4: //4 wrap tightly around object
2506 : case 5: //5 wrap tightly, but allow holes
2507 0 : eSurround = SURROUND_PARALLEL;
2508 0 : bContour = true;
2509 0 : break;
2510 : }
2511 :
2512 : // bei Modus 2 oder 4 auch den Zusatzparameter beruecksichtigen
2513 69 : if ( (2 == pF->nwr) || (4 == pF->nwr) )
2514 : {
2515 4 : switch( pF->nwrk )
2516 : {
2517 : //0 wrap both sides
2518 : case 0:
2519 2 : eSurround = SURROUND_PARALLEL;
2520 2 : break;
2521 : //1 wrap only on left
2522 : case 1:
2523 0 : eSurround = SURROUND_LEFT;
2524 0 : break;
2525 : //2 wrap only on right
2526 : case 2:
2527 0 : eSurround = SURROUND_RIGHT;
2528 0 : break;
2529 : //3 wrap only on largest side
2530 : case 3:
2531 2 : eSurround = SURROUND_IDEAL;
2532 2 : break;
2533 : }
2534 : }
2535 :
2536 69 : SwFmtSurround aSur( eSurround );
2537 69 : aSur.SetContour( bContour );
2538 69 : aSur.SetOutside(true); // Winword kann nur Aussen-Konturen
2539 69 : aFlySet.Put( aSur );
2540 :
2541 : // eingelesenes Objekt (kann eine ganze Gruppe sein) jetzt korrekt
2542 : // positionieren usw.
2543 :
2544 : OSL_ENSURE(!((aData.size() != 1) && bReplaceable),
2545 : "Replaceable drawing with > 1 entries ?");
2546 :
2547 69 : if (aData.size() != 1)
2548 14 : bReplaceable = false;
2549 :
2550 69 : SvxMSDffImportRec* pRecord = 0;
2551 : /*
2552 : Get the record for top level object, so we can get the word anchoring
2553 : and wrapping information for it.
2554 : */
2555 213 : for (MSDffImportRecords::const_iterator it = aData.begin();
2556 142 : it != aData.end(); ++it) // MSVC2008 wants const_iterator here???
2557 : {
2558 71 : if (it->pObj == pObject)
2559 : {
2560 69 : pRecord = &const_cast<SvxMSDffImportRec&>(*it);
2561 69 : break;
2562 : }
2563 : }
2564 :
2565 : OSL_ENSURE(pRecord, "how did that happen?");
2566 69 : if (!pRecord)
2567 0 : return 0;
2568 :
2569 : const bool bLayoutInTableCell =
2570 69 : nInTable && IsObjectLayoutInTableCell( pRecord->nLayoutInTableCell );
2571 :
2572 : // #i18732# - Switch on 'follow text flow', if object is laid out
2573 : // inside table cell and its wrapping isn't 'SURROUND_THROUGH'
2574 69 : if (bLayoutInTableCell && eSurround != SURROUND_THROUGHT)
2575 : {
2576 0 : SwFmtFollowTextFlow aFollowTextFlow( sal_True );
2577 0 : aFlySet.Put( aFollowTextFlow );
2578 : }
2579 :
2580 :
2581 : //#i21847#
2582 : //Some shapes are set to *hidden*, don't import those ones.
2583 69 : if (pRecord->bHidden)
2584 0 : return 0;
2585 :
2586 : // If we are to be "below text" then we are not to be opaque
2587 : // #i14045# MM If we are in a header or footer then make the object transparent
2588 : // Not exactly like word but close enough for now
2589 :
2590 : // both flags <bBelowText> and <bDrawHell> have to be set to move object into the background.
2591 : // #i46794# - it reveals that value of flag <bBelowText> can be neglected.
2592 71 : const bool bMoveToBackgrd = pRecord->bDrawHell ||
2593 136 : ( ( bIsHeader || bIsFooter ) && pF->nwr == 3 );
2594 69 : if ( bMoveToBackgrd )
2595 2 : aFlySet.Put(SvxOpaqueItem(RES_OPAQUE,false));
2596 :
2597 138 : String aObjName = pObject->GetName();
2598 :
2599 69 : SwFrmFmt* pRetFrmFmt = 0;
2600 69 : if (bReplaceable)
2601 : {
2602 : //Single graphics or ole objects
2603 : pRetFrmFmt = ImportReplaceableDrawables(pObject, pOurNewObject, pRecord,
2604 13 : pF, aFlySet);
2605 : }
2606 : else
2607 : {
2608 : //Drawing objects, (e.g. ovals or drawing groups)
2609 56 : if (pF->bRcaSimple)
2610 : {
2611 0 : pF->nbx = WW8_FSPA::RelPageBorder;
2612 0 : pF->nby = WW8_FSPA::RelPageBorder;
2613 : }
2614 :
2615 : RndStdIds eAnchor = ProcessEscherAlign(pRecord, pF, aFlySet,
2616 56 : bReplaceable);
2617 :
2618 : // Should we, and is it possible to make this into a writer textbox
2619 56 : if ((!(nIniFlags1 & WW8FL_NO_FLY_FOR_TXBX)) && pRecord->bReplaceByFly)
2620 : {
2621 : pRetFrmFmt = ConvertDrawTextToFly(pObject, pOurNewObject, pRecord,
2622 4 : eAnchor, pF, aFlySet);
2623 4 : if (pRetFrmFmt)
2624 4 : bDone = true;
2625 : }
2626 :
2627 56 : if (!bDone)
2628 : {
2629 52 : sw::util::SetLayer aSetLayer(rDoc);
2630 52 : if ( bMoveToBackgrd )
2631 0 : aSetLayer.SendObjectToHell(*pObject);
2632 : else
2633 52 : aSetLayer.SendObjectToHeaven(*pObject);
2634 :
2635 52 : if (!IsInlineEscherHack())
2636 : {
2637 : /* Need to make sure that the correct layer ordering is applied. */
2638 : // pass information, if object is in page header|footer to method.
2639 : pWWZOrder->InsertEscherObject( pObject, pF->nSpId,
2640 49 : bIsHeader || bIsFooter );
2641 : }
2642 : else
2643 : {
2644 3 : pWWZOrder->InsertTextLayerObject(pObject);
2645 : }
2646 :
2647 52 : pRetFrmFmt = rDoc.Insert(*pPaM, *pObject, &aFlySet, NULL);
2648 :
2649 : OSL_ENSURE(pRetFrmFmt->GetAnchor().GetAnchorId() ==
2650 : eAnchor, "Not the anchor type requested!");
2651 :
2652 : /*
2653 : Insert text if necessary into textboxes contained in groups.
2654 : */
2655 52 : if (!aData.empty())
2656 : {
2657 720 : for (MSDffImportRecords::const_iterator it = aData.begin();
2658 480 : it != aData.end(); ++it)
2659 : {
2660 188 : pRecord = &const_cast<SvxMSDffImportRec&>(*it);
2661 188 : if (pRecord->pObj && pRecord->aTextId.nTxBxS)
2662 : { // #i52825# pRetFrmFmt can be NULL
2663 : pRetFrmFmt = MungeTextIntoDrawBox(pRecord->pObj,
2664 56 : pRecord, nGrafAnchorCp, pRetFrmFmt);
2665 : }
2666 : }
2667 : }
2668 : }
2669 : }
2670 :
2671 : // #i44344#, #i44681# - positioning attributes already set
2672 69 : if ( pRetFrmFmt /*#i52825# */ && pRetFrmFmt->ISA(SwDrawFrmFmt) )
2673 : {
2674 52 : static_cast<SwDrawFrmFmt*>(pRetFrmFmt)->PosAttrSet();
2675 : }
2676 69 : if (!IsInlineEscherHack())
2677 66 : MapWrapIntoFlyFmt(pRecord, pRetFrmFmt);
2678 :
2679 : // Set frame name with object name
2680 69 : if( pRetFrmFmt /*#i52825# */ && aObjName.Len() )
2681 1 : pRetFrmFmt->SetName( aObjName );
2682 138 : return AddAutoAnchor(pRetFrmFmt);
2683 : }
2684 :
2685 82 : SwFrmFmt *SwWW8ImplReader::AddAutoAnchor(SwFrmFmt *pFmt)
2686 : {
2687 : /*
2688 : * anchored to character at the current position will move along the
2689 : * paragraph as text is added because we are at the insertion point.
2690 : *
2691 : * Leave to later and set the correct location then.
2692 : */
2693 82 : if ((pFmt) && (pFmt->GetAnchor().GetAnchorId() != FLY_AS_CHAR))
2694 : {
2695 67 : pAnchorStck->AddAnchor(*pPaM->GetPoint(), pFmt);
2696 : }
2697 82 : return pFmt;
2698 : }
2699 :
2700 56 : SwFrmFmt* SwWW8ImplReader::MungeTextIntoDrawBox(SdrObject* pTrueObject,
2701 : SvxMSDffImportRec *pRecord, long nGrafAnchorCp, SwFrmFmt* pRetFrmFmt)
2702 : {
2703 : SdrTextObj* pSdrTextObj;
2704 :
2705 : // Pruefen, ob Gruppenobjekt (z.B. zwei Klammern) vorliegt
2706 56 : if (SdrObjGroup* pThisGroup = PTR_CAST(SdrObjGroup, pRecord->pObj))
2707 : {
2708 : // Gruppenobjekte haben keinen Text. Fuege ein Textobjekt in die
2709 : // Gruppe ein, um den Text zu halten.
2710 0 : pSdrTextObj = new SdrRectObj( OBJ_TEXT, pThisGroup->GetCurrentBoundRect());
2711 :
2712 0 : SfxItemSet aSet(pDrawModel->GetItemPool());
2713 0 : aSet.Put(XFillStyleItem(XFILL_NONE));
2714 0 : aSet.Put(XLineStyleItem(XLINE_NONE));
2715 0 : aSet.Put(SdrTextFitToSizeTypeItem( SDRTEXTFIT_NONE ));
2716 0 : aSet.Put(SdrTextAutoGrowHeightItem(false));
2717 0 : aSet.Put(SdrTextAutoGrowWidthItem(false));
2718 0 : pSdrTextObj->SetMergedItemSet(aSet);
2719 :
2720 0 : long nAngle = pRecord->nTextRotationAngle;
2721 0 : if ( nAngle )
2722 : {
2723 0 : double a = nAngle*nPi180;
2724 0 : pSdrTextObj->NbcRotate(pSdrTextObj->GetCurrentBoundRect().Center(), nAngle,
2725 0 : sin(a), cos(a) );
2726 : }
2727 :
2728 0 : pSdrTextObj->NbcSetLayer( pThisGroup->GetLayer() );
2729 0 : pThisGroup->GetSubList()->NbcInsertObject(pSdrTextObj);
2730 : }
2731 : else
2732 56 : pSdrTextObj = PTR_CAST(SdrTextObj, pRecord->pObj);
2733 :
2734 56 : if( pSdrTextObj )
2735 : {
2736 56 : Size aObjSize(pSdrTextObj->GetSnapRect().GetWidth(),
2737 112 : pSdrTextObj->GetSnapRect().GetHeight());
2738 :
2739 : // Objekt ist Bestandteil einer Gruppe?
2740 56 : SdrObject* pGroupObject = pSdrTextObj->GetUpGroup();
2741 :
2742 56 : sal_uInt32 nOrdNum = pSdrTextObj->GetOrdNum();
2743 : bool bEraseThisObject;
2744 : InsertTxbxText( pSdrTextObj, &aObjSize, pRecord->aTextId.nTxBxS,
2745 : pRecord->aTextId.nSequence, nGrafAnchorCp, pRetFrmFmt,
2746 56 : (pSdrTextObj != pTrueObject) || (0 != pGroupObject),
2747 56 : bEraseThisObject, 0, 0, 0, 0, pRecord);
2748 :
2749 : // wurde dieses Objekt ersetzt ??
2750 56 : if (bEraseThisObject)
2751 : {
2752 0 : if( pGroupObject || (pSdrTextObj != pTrueObject) )
2753 : {
2754 : // Objekt wurde bereits (in der Gruppe und) der Drawing-Page
2755 : // durch ein neues SdrGrafObj ersetzt.
2756 :
2757 : SdrObject* pNewObj = pGroupObject ?
2758 0 : pGroupObject->GetSubList()->GetObj(nOrdNum) : pTrueObject;
2759 0 : if (pSdrTextObj != pNewObj)
2760 : {
2761 : // Objekt in der Z-Order-Liste ersetzen
2762 0 : pMSDffManager->ExchangeInShapeOrder(pSdrTextObj, 0,0, pNewObj);
2763 : // Objekt jetzt noch loeschen
2764 0 : SdrObject::Free( pRecord->pObj );
2765 : // und das neue Objekt merken.
2766 0 : pRecord->pObj = pNewObj;
2767 0 : }
2768 : }
2769 : else
2770 : {
2771 : // Objekt aus der Z-Order-Liste loeschen
2772 0 : pMSDffManager->RemoveFromShapeOrder( pSdrTextObj );
2773 : // Objekt aus der Drawing-Page rausnehmen
2774 0 : if( pSdrTextObj->GetPage() )
2775 0 : pDrawPg->RemoveObject( pSdrTextObj->GetOrdNum() );
2776 : // und FrameFormat entfernen, da durch Grafik ersetzt (dies
2777 : // loescht auch das Objekt)
2778 0 : rDoc.DelFrmFmt( pRetFrmFmt );
2779 0 : pRetFrmFmt = 0;
2780 : // auch den Objektmerker loeschen
2781 0 : pRecord->pObj = 0;
2782 : }
2783 : }
2784 : else
2785 : {
2786 : // ww8-default Randabstand einsetzen
2787 56 : SfxItemSet aItemSet(pDrawModel->GetItemPool(),
2788 56 : SDRATTR_TEXT_LEFTDIST, SDRATTR_TEXT_LOWERDIST);
2789 56 : aItemSet.Put( SdrTextLeftDistItem( pRecord->nDxTextLeft ) );
2790 56 : aItemSet.Put( SdrTextRightDistItem( pRecord->nDxTextRight ) );
2791 56 : aItemSet.Put( SdrTextUpperDistItem( pRecord->nDyTextTop ) );
2792 56 : aItemSet.Put( SdrTextLowerDistItem( pRecord->nDyTextBottom ) );
2793 56 : pSdrTextObj->SetMergedItemSetAndBroadcast(aItemSet);
2794 : }
2795 : }
2796 56 : return pRetFrmFmt;
2797 : }
2798 :
2799 4 : SwFlyFrmFmt* SwWW8ImplReader::ConvertDrawTextToFly(SdrObject* &rpObject,
2800 : SdrObject* &rpOurNewObject, SvxMSDffImportRec* pRecord, RndStdIds eAnchor,
2801 : WW8_FSPA *pF, SfxItemSet &rFlySet)
2802 : {
2803 4 : SwFlyFrmFmt* pRetFrmFmt = 0;
2804 : long nStartCp;
2805 : long nEndCp;
2806 :
2807 : // Check if this textbox chain contains text as conversion of an empty
2808 : // chain would not make sense.
2809 4 : if ( TxbxChainContainsRealText(pRecord->aTextId.nTxBxS,nStartCp,nEndCp) )
2810 : {
2811 : // The Text is not read into SdrTextObj! Rather insert a frame and
2812 : // insert the text from nStartCp to nEndCp.
2813 : //
2814 : // More attributes can be used in a frame compared to the
2815 : // Edit-Enging, and it can contain field, OLEs or graphics...
2816 : Rectangle aInnerDist(pRecord->nDxTextLeft, pRecord->nDyTextTop,
2817 4 : pRecord->nDxTextRight, pRecord->nDyTextBottom);
2818 :
2819 4 : SwFmtFrmSize aFrmSize(ATT_FIX_SIZE, pF->nXaRight - pF->nXaLeft, pF->nYaBottom - pF->nYaTop);
2820 4 : aFrmSize.SetWidthSizeType(pRecord->bAutoWidth ? ATT_VAR_SIZE : ATT_FIX_SIZE);
2821 4 : rFlySet.Put(aFrmSize);
2822 :
2823 : MatchSdrItemsIntoFlySet( rpObject, rFlySet, pRecord->eLineStyle,
2824 4 : pRecord->eLineDashing, pRecord->eShapeType, aInnerDist );
2825 :
2826 :
2827 4 : SdrTextObj *pSdrTextObj = PTR_CAST(SdrTextObj, rpObject);
2828 4 : if (pSdrTextObj && pSdrTextObj->IsVerticalWriting())
2829 0 : rFlySet.Put(SvxFrameDirectionItem(FRMDIR_VERT_TOP_RIGHT, RES_FRAMEDIR));
2830 :
2831 4 : pRetFrmFmt = rDoc.MakeFlySection(eAnchor, pPaM->GetPoint(), &rFlySet);
2832 : OSL_ENSURE(pRetFrmFmt->GetAnchor().GetAnchorId() == eAnchor,
2833 : "Not the anchor type requested!");
2834 :
2835 : // if everything is OK, find pointer on new object and correct
2836 : // Z-order list (oder delete entry)
2837 4 : rpOurNewObject = CreateContactObject(pRetFrmFmt);
2838 :
2839 : // remove old object from the Z-Order list
2840 4 : pMSDffManager->RemoveFromShapeOrder( rpObject );
2841 :
2842 : // and delete the object
2843 4 : SdrObject::Free( rpObject );
2844 : /*
2845 : NB: only query pOrgShapeObject starting here!
2846 : */
2847 :
2848 4 : if (rpOurNewObject)
2849 : {
2850 : /*
2851 : We do not store our rpOutNewObject in the ShapeOrder because we
2852 : have a FrmFmt from which we can regenerate the contact object when
2853 : we need it. Because, we can have frames anchored to paragraphs in
2854 : header/footers and we can copy header/footers, if we do copy a
2855 : header/footer with a nonpage anchored frame in it then the contact
2856 : objects are invalidated. Under this condition the FrmFmt will be
2857 : updated to reflect this change and can be used to get a new
2858 : contact object, while a raw rpOutNewObject stored here becomes
2859 : deleted and useless.
2860 : */
2861 : pMSDffManager->StoreShapeOrder(pF->nSpId,
2862 4 : (((sal_uLong)pRecord->aTextId.nTxBxS) << 16) +
2863 4 : pRecord->aTextId.nSequence, 0, pRetFrmFmt);
2864 :
2865 : // The Kontakt object has to be inserted into the draw page, so
2866 : // SwWW8ImplReader::LoadDoc1() can determine the z-order.
2867 4 : if (!rpOurNewObject->IsInserted())
2868 : {
2869 : // pass information, if object is in page header|footer to method.
2870 : pWWZOrder->InsertEscherObject( rpOurNewObject, pF->nSpId,
2871 4 : bIsHeader || bIsFooter );
2872 : }
2873 : }
2874 :
2875 : // Box-0 receives the text for the whole chain!
2876 4 : if( !pRecord->aTextId.nSequence )
2877 : {
2878 : // save flags etc and reset them
2879 4 : WW8ReaderSave aSave( this );
2880 :
2881 4 : MoveInsideFly(pRetFrmFmt);
2882 :
2883 8 : SwNodeIndex aStart(pPaM->GetPoint()->nNode);
2884 :
2885 4 : pWWZOrder->InsideEscher(pF->nSpId);
2886 :
2887 : // read in the text
2888 4 : bTxbxFlySection = true;
2889 : bool bJoined = ReadText(nStartCp, (nEndCp-nStartCp),
2890 4 : MAN_MAINTEXT == pPlcxMan->GetManType() ?
2891 4 : MAN_TXBX : MAN_TXBX_HDFT);
2892 :
2893 4 : pWWZOrder->OutsideEscher();
2894 :
2895 4 : MoveOutsideFly(pRetFrmFmt, aSave.GetStartPos(),!bJoined);
2896 :
2897 8 : aSave.Restore( this );
2898 4 : }
2899 : }
2900 4 : return pRetFrmFmt;
2901 : }
2902 :
2903 25 : void MatchEscherMirrorIntoFlySet(const SvxMSDffImportRec &rRecord,
2904 : SfxItemSet &rFlySet)
2905 : {
2906 25 : if (rRecord.bVFlip || rRecord.bHFlip)
2907 : {
2908 0 : MirrorGraph eType(RES_MIRROR_GRAPH_DONT);
2909 0 : if (rRecord.bVFlip && rRecord.bHFlip)
2910 0 : eType = RES_MIRROR_GRAPH_BOTH;
2911 0 : else if (rRecord.bVFlip)
2912 0 : eType = RES_MIRROR_GRAPH_HOR;
2913 : else
2914 0 : eType = RES_MIRROR_GRAPH_VERT;
2915 0 : rFlySet.Put( SwMirrorGrf(eType) );
2916 : }
2917 25 : }
2918 :
2919 13 : SwFlyFrmFmt* SwWW8ImplReader::ImportReplaceableDrawables( SdrObject* &rpObject,
2920 : SdrObject* &rpOurNewObject, SvxMSDffImportRec* pRecord, WW8_FSPA *pF,
2921 : SfxItemSet &rFlySet )
2922 : {
2923 13 : SwFlyFrmFmt* pRetFrmFmt = 0;
2924 13 : long nWidthTw = pF->nXaRight - pF->nXaLeft;
2925 13 : if (0 > nWidthTw)
2926 0 : nWidthTw = 0;
2927 13 : long nHeightTw = pF->nYaBottom - pF->nYaTop;
2928 13 : if (0 > nHeightTw)
2929 0 : nHeightTw = 0;
2930 :
2931 13 : ProcessEscherAlign(pRecord, pF, rFlySet, true);
2932 :
2933 13 : rFlySet.Put(SwFmtFrmSize(ATT_FIX_SIZE, nWidthTw, nHeightTw));
2934 :
2935 13 : SfxItemSet aGrSet(rDoc.GetAttrPool(), RES_GRFATR_BEGIN, RES_GRFATR_END-1);
2936 :
2937 13 : if (pRecord)
2938 : {
2939 : //Note that the escher inner distance only seems to be honoured in
2940 : //word for textboxes, not for graphics and ole objects.
2941 13 : Rectangle aInnerDist(0, 0, 0, 0);
2942 :
2943 : MatchSdrItemsIntoFlySet(rpObject, rFlySet, pRecord->eLineStyle,
2944 13 : pRecord->eLineDashing, pRecord->eShapeType, aInnerDist);
2945 :
2946 13 : MatchEscherMirrorIntoFlySet(*pRecord, aGrSet);
2947 : }
2948 :
2949 26 : String aObjectName(rpObject->GetName());
2950 13 : if (OBJ_OLE2 == SdrObjKind(rpObject->GetObjIdentifier()))
2951 0 : pRetFrmFmt = InsertOle(*((SdrOle2Obj*)rpObject), rFlySet, aGrSet);
2952 : else
2953 : {
2954 13 : const SdrGrafObj *pGrf= (const SdrGrafObj*)rpObject;
2955 13 : bool bDone = false;
2956 13 : if (pGrf->IsLinkedGraphic() && !pGrf->GetFileName().isEmpty())
2957 : {
2958 0 : GraphicType eType = pGrf->GetGraphicType();
2959 : String aGrfName(
2960 : URIHelper::SmartRel2Abs(
2961 0 : INetURLObject(sBaseURL), pGrf->GetFileName(),
2962 0 : URIHelper::GetMaybeFileHdl()));
2963 : // correction of fix for issue #i10939#:
2964 : // One of the two conditions have to be true to insert the graphic
2965 : // as a linked graphic -
2966 0 : if (GRAPHIC_NONE == eType || CanUseRemoteLink(aGrfName))
2967 : {
2968 : pRetFrmFmt = rDoc.Insert(*pPaM, aGrfName, aEmptyStr, 0,
2969 0 : &rFlySet, &aGrSet, NULL);
2970 0 : bDone = true;
2971 0 : }
2972 : }
2973 13 : if (!bDone)
2974 : {
2975 13 : const Graphic& rGraph = pGrf->GetGraphic();
2976 : pRetFrmFmt = rDoc.Insert(*pPaM, aEmptyStr, aEmptyStr, &rGraph,
2977 13 : &rFlySet, &aGrSet, NULL);
2978 : }
2979 : }
2980 :
2981 13 : if (pRetFrmFmt)
2982 : {
2983 13 : if( pRecord )
2984 : {
2985 13 : if( OBJ_OLE2 != SdrObjKind(rpObject->GetObjIdentifier()) )
2986 13 : SetAttributesAtGrfNode( pRecord, pRetFrmFmt, pF );
2987 : }
2988 : // mehrfaches Auftreten gleicher Grafik-Namen vermeiden
2989 13 : maGrfNameGenerator.SetUniqueGraphName(pRetFrmFmt, aObjectName);
2990 : }
2991 : //falls alles Ok, Zeiger auf neues Objekt ermitteln und Z-Order-Liste
2992 : //entsprechend korrigieren (oder Eintrag loeschen)
2993 13 : rpOurNewObject = CreateContactObject(pRetFrmFmt);
2994 :
2995 : // altes Objekt aus der Z-Order-Liste entfernen
2996 13 : pMSDffManager->RemoveFromShapeOrder( rpObject );
2997 : // aus der Drawing-Page rausnehmen
2998 13 : if( rpObject->GetPage() )
2999 0 : pDrawPg->RemoveObject( rpObject->GetOrdNum() );
3000 :
3001 : // und das Objekt loeschen
3002 13 : SdrObject::Free( rpObject );
3003 : /*
3004 : Achtung: ab jetzt nur noch pOrgShapeObject abfragen!
3005 : */
3006 :
3007 : // Kontakt-Objekt in die Z-Order-Liste und die Page aufnehmen
3008 13 : if (rpOurNewObject)
3009 : {
3010 13 : if (!bHdFtFtnEdn)
3011 11 : pMSDffManager->StoreShapeOrder(pF->nSpId, 0, rpOurNewObject, 0 );
3012 :
3013 : // Das Kontakt-Objekt MUSS in die Draw-Page gesetzt werden, damit in
3014 : // SwWW8ImplReader::LoadDoc1() die Z-Order festgelegt werden kann !!!
3015 13 : if (!rpOurNewObject->IsInserted())
3016 : {
3017 : // pass information, if object is in page header|footer to method.
3018 : pWWZOrder->InsertEscherObject( rpOurNewObject, pF->nSpId,
3019 13 : bIsHeader || bIsFooter );
3020 : }
3021 : }
3022 26 : return pRetFrmFmt;
3023 : }
3024 :
3025 140 : void SwWW8ImplReader::GrafikCtor() // Fuer SVDraw und VCControls und Escher
3026 : {
3027 140 : if (!pDrawModel)
3028 : {
3029 27 : rDoc.GetOrCreateDrawModel(); // #i52858# - method name changed
3030 27 : pDrawModel = rDoc.GetDrawModel();
3031 : OSL_ENSURE(pDrawModel, "Kann DrawModel nicht anlegen");
3032 27 : pDrawPg = pDrawModel->GetPage(0);
3033 :
3034 27 : pMSDffManager = new SwMSDffManager(*this);
3035 27 : pMSDffManager->SetModel(pDrawModel, 1440);
3036 : /*
3037 : Now the dff manager always needs a controls //converter as well, but a
3038 : control converter may still exist //without a dffmanager. cmc
3039 : */
3040 27 : pFormImpl = new SwMSConvertControls(mpDocShell, pPaM);
3041 :
3042 : pWWZOrder = new wwZOrderer(sw::util::SetLayer(rDoc), pDrawPg,
3043 27 : pMSDffManager ? pMSDffManager->GetShapeOrders() : 0);
3044 : }
3045 140 : }
3046 :
3047 50 : void SwWW8ImplReader::GrafikDtor()
3048 : {
3049 50 : DELETEZ(mpDrawEditEngine); // evtl. von Grafik angelegt
3050 50 : DELETEZ(pWWZOrder); // dito
3051 50 : }
3052 :
3053 71 : void SwWW8FltAnchorStack::AddAnchor(const SwPosition& rPos, SwFrmFmt *pFmt)
3054 : {
3055 : OSL_ENSURE(pFmt->GetAnchor().GetAnchorId() != FLY_AS_CHAR,
3056 : "Don't use fltanchors with inline frames, slap!");
3057 71 : NewAttr(rPos, SwFltAnchor(pFmt));
3058 71 : }
3059 :
3060 2331 : void SwWW8FltAnchorStack::Flush()
3061 : {
3062 2331 : size_t nCnt = size();
3063 2402 : for (size_t i=0; i < nCnt; ++i)
3064 : {
3065 71 : SwFltStackEntry &rEntry = (*this)[i];
3066 71 : SwPosition aDummy(rEntry.m_aMkPos.m_nNode);
3067 71 : SetAttrInDoc(aDummy, rEntry);
3068 71 : DeleteAndDestroy(i--);
3069 71 : --nCnt;
3070 71 : }
3071 2349 : }
3072 :
3073 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|