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