1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ww8graf.cxx,v $
10 * $Revision: 1.154.30.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
34 #include <svtools/urihelper.hxx>
35 #include <hintids.hxx>
36 #include <osl/endian.h>
37 #include <svx/fmglob.hxx>
38 #include <svx/sdtaitm.hxx>
39 #include <svx/lrspitem.hxx>
40 #include <svx/udlnitem.hxx>
41 #include <svx/xlineit.hxx>
42 #include <svx/xfillit.hxx>
43 #include <svx/svdmodel.hxx>
44 #include <svx/sdtaitm.hxx>
45 #include <svx/svdocapt.hxx>
46 #include <svx/sxctitm.hxx>
47 #include <svx/editeng.hxx>
48 #include <svx/svdpage.hxx>
49 #include <svx/svdopath.hxx>
50 #include <svx/svdocirc.hxx>
51 #include <svx/outlobj.hxx>
52 #include <svx/svdogrp.hxx>
53 #include <svx/svdograf.hxx>
54 #include <svx/svdoole2.hxx>
55 #include <svx/colritem.hxx>
56 #include <svx/fhgtitem.hxx>
57 #include <svx/postitem.hxx>
58 #include <svx/adjitem.hxx>
59 #include <svx/wghtitem.hxx>
60 #include <svx/crsditem.hxx>
61 #ifndef _SVX_CNTRITEM_HXX
62 #include <svx/cntritem.hxx>
64 #include <svx/shdditem.hxx>
65 #include <svx/fontitem.hxx>
66 #include <svx/ulspitem.hxx>
67 #include <svx/impgrf.hxx>
68 #include <svx/svdoattr.hxx>
69 #include <svx/brshitem.hxx>
70 #include <svx/rectenum.hxx>
71 #include <svx/opaqitem.hxx>
72 #include <svx/shaditem.hxx>
73 #include <svx/shaditem.hxx>
74 #include <svx/boxitem.hxx>
75 #include <svx/outliner.hxx> // #79453#
76 #include <svx/frmdiritem.hxx>
77 #include <svx/xfltrit.hxx>
78 #include <svx/msdffimp.hxx>
79 #include <grfatr.hxx> // class SwCropGrf
80 #include <fmtornt.hxx>
81 #include <fmtcntnt.hxx>
83 #include <fmtanchr.hxx>
89 #include <dcontact.hxx>
91 #include <mdiexp.hxx> // Progress
92 #include <fmtcnct.hxx>
93 #include <swunodef.hxx>
94 #include "ww8struc.hxx"
95 #include "ww8scan.hxx"
96 #include "ww8par.hxx" // class SwWWImplReader
97 #include "ww8par2.hxx" // SwWW8StyInf
98 #include "ww8graf.hxx"
99 #include <fmtinfmt.hxx>
100 #include <svx/eeitem.hxx>
101 #include <svx/flditem.hxx>
102 // OD 30.09.2003 #i18732#
103 #include <fmtfollowtextflow.hxx>
104 #include "writerhelper.hxx"
105 #include "writerwordglue.hxx"
106 #include <basegfx/point/b2dpoint.hxx>
107 #include <basegfx/polygon/b2dpolygon.hxx>
108 #include <svx/editobj.hxx>
112 using namespace ::com::sun::star
;
113 using namespace sw::types
;
114 using namespace sw::util
;
118 Color
WW8TransCol(SVBT32 nWC
)
120 #if 1 // 1 = Vordefinierte Farben benutzen, 0 = ignorieren
122 // Farbtabelle zum Umrechnen RGB-Werte in vordefinierte Farben
123 // ( Damit bei der Writer-UI die Farbnamen stimmen )
124 // Die Tabelle int im *3er-System* aufgeteilt. Die Grauwerte fehlen,
125 // da sie nicht ins 3er-System passen ( 4 Werte: sw, ws, 2 * grau )
126 static ColorData eColA
[] = { // B G R B G R B G R
127 COL_BLACK
, COL_RED
, COL_LIGHTRED
, // 0 0 0, 0 0 1, 0 0 2
128 COL_GREEN
, COL_BROWN
, COL_BLACK
, // 0 1 0, 0 1 1, 0 1 2
129 COL_LIGHTGREEN
, COL_BLACK
, COL_YELLOW
, // 0 2 0, 0 2 1, 0 2 2
130 COL_BLUE
, COL_MAGENTA
, COL_BLACK
, // 1 0 0, 1 0 1, 1 0 2
131 COL_CYAN
, COL_LIGHTGRAY
, COL_BLACK
, // 1 1 0, 1 1 1, 1 1 2
132 COL_BLACK
, COL_BLACK
, COL_BLACK
, // 1 2 0, 1 2 1, 1 2 2
133 COL_LIGHTBLUE
, COL_BLACK
, COL_LIGHTMAGENTA
, // 2 0 0, 2 0 1, 2 0 2
134 COL_BLACK
, COL_BLACK
, COL_BLACK
, // 2 1 0, 2 1 1, 2 1 2
135 COL_LIGHTCYAN
, COL_BLACK
, COL_WHITE
}; // 2 2 0, 2 2 1, 2 2 2
137 // In nWC[3] steht ein Byte, dass in der WW-Doku nicht beschrieben ist.
138 // Die Bedeutung ist anscheinend folgende: Bei 0 ist es eine normale
139 // Farbe, dessen RGB-Wert in nWC[0..2] steht. stehen in nWC[3] die
140 // Werte 0x1, 0x7d oder 0x83, dann ist es ein Grauwert, dessen
141 // Schwarzanteil in 1/2 % in nWC[0] steht.
142 // Ich vermute, dass es auf Bit0 in nWV[3] ankommt, ob es RGB oder Grau ist.
144 if( !( nWC
[3] & 0x1 ) && // keine Spezial-Farbe (grau)
145 ( ( nWC
[0] == 0 || nWC
[0]== 0x80 || nWC
[0] == 0xff ) // R-Anteil
146 && ( nWC
[1] == 0 || nWC
[1]== 0x80 || nWC
[1] == 0xff ) // G-Anteil
147 && ( nWC
[2] == 0 || nWC
[2]== 0x80 || nWC
[2] == 0xff ) ) ){// B-Anteil
148 int nIdx
= 0; // und nun: Idx-Berechnung im 3er-System
149 for (int i
= 2; i
>= 0; i
--)
153 nIdx
+= ((nWC
[i
] == 0xff) ? 2 : 1);
155 if (eColA
[nIdx
] != COL_BLACK
)
156 return Color(eColA
[nIdx
]); // Standard-Color
162 //Special colour gray
163 BYTE u
= (BYTE
)( (ULONG
)( 200 - nWC
[0] ) * 256 / 200 );
164 return Color(u
, u
, u
);
168 return Color(nWC
[0], nWC
[1], nWC
[2]);
171 void wwFrameNamer::SetUniqueGraphName(SwFrmFmt
*pFrmFmt
, const String
&rFixed
)
173 if (mbIsDisabled
|| !rFixed
.Len())
175 String
aName(msSeed
);
176 aName
+= String::CreateFromInt32(++mnImportedGraphicsCount
);
177 aName
.APPEND_CONST_ASC( ": " );
179 pFrmFmt
->SetName( aName
);
182 // ReadGrafStart liest die ObjektDaten ein und erzeugt falls noetig einen Anker
183 bool SwWW8ImplReader::ReadGrafStart(void* pData
, short nDataSiz
,
184 WW8_DPHEAD
* pHd
, const WW8_DO
* pDo
, SfxAllItemSet
&rSet
)
186 if (SVBT16ToShort(pHd
->cb
) < sizeof(WW8_DPHEAD
) + nDataSiz
)
188 ASSERT( !this, "+Grafik-Element: Size ?" );
189 pStrm
->SeekRel(SVBT16ToShort(pHd
->cb
) - sizeof(WW8_DPHEAD
));
192 pStrm
->Read(pData
, nDataSiz
);
194 RndStdIds eAnchor
= (SVBT8ToByte(pDo
->by
) < 2) ? FLY_PAGE
: FLY_AT_CNTNT
;
195 rSet
.Put(SwFmtAnchor(eAnchor
));
197 nDrawXOfs2
= nDrawXOfs
;
198 nDrawYOfs2
= nDrawYOfs
;
200 if( eAnchor
== FLY_AT_CNTNT
)
202 if( SVBT8ToByte( pDo
->bx
) == 1 ) // Pos: echt links
203 nDrawXOfs2
= static_cast< short >(nDrawXOfs2
- maSectionManager
.GetPageLeft());
204 if( nInTable
) // Obj in Table
205 nDrawXOfs2
= nDrawXOfs2
- GetTableLeft(); // -> siehe Kommentar
206 // bei GetTableLeft()
210 if( SVBT8ToByte( pDo
->bx
) != 1 )
211 nDrawXOfs2
= static_cast< short >(nDrawXOfs2
+ maSectionManager
.GetPageLeft());
217 // SetStdAttr() setzt die Attribute, die jedes Objekt hat
219 static void SetStdAttr( SfxItemSet
& rSet
, WW8_DP_LINETYPE
& rL
,
222 if( SVBT16ToShort( rL
.lnps
) == 5 ){ // unsichtbar
223 rSet
.Put( XLineStyleItem( XLINE_NONE
) );
225 Color
aCol( WW8TransCol( rL
.lnpc
) ); // LinienFarbe
226 rSet
.Put( XLineColorItem( aEmptyStr
, aCol
) );
227 rSet
.Put( XLineWidthItem( SVBT16ToShort( rL
.lnpw
) ) );
229 if( SVBT16ToShort( rL
.lnps
) >= 1
230 && SVBT16ToShort(rL
.lnps
) <= 4 ){ // LinienStil
231 rSet
.Put( XLineStyleItem( XLINE_DASH
) );
232 INT16 nLen
= SVBT16ToShort( rL
.lnpw
);
233 XDash
aD( XDASH_RECT
, 1, 2 * nLen
, 1, 5 * nLen
, 5 * nLen
);
234 switch( SVBT16ToShort( rL
.lnps
) ){
235 case 1: aD
.SetDots( 0 ); // Dash
236 aD
.SetDashLen( 6 * nLen
);
237 aD
.SetDistance( 4 * nLen
);
239 case 2: aD
.SetDashes( 0 ); break; // Dot
240 case 3: break; // Dash Dot
241 case 4: aD
.SetDots( 2 ); break; // Dash Dot Dot
243 rSet
.Put( XLineDashItem( aEmptyStr
, aD
) );
245 rSet
.Put( XLineStyleItem( XLINE_SOLID
) ); // noetig fuer TextBox
248 if( SVBT16ToShort( rSh
.shdwpi
) ){ // Schatten
249 rSet
.Put(SdrShadowItem(true));
250 rSet
.Put( SdrShadowXDistItem( SVBT16ToShort( rSh
.xaOffset
) ) );
251 rSet
.Put( SdrShadowYDistItem( SVBT16ToShort( rSh
.yaOffset
) ) );
255 // SetFill setzt Fuellattribute wie Vordergrund- und Hintergrund-Farbe
256 // und Muster durch Reduktion auf eine Farbe.
257 // SetFill() setzt z.Zt kein Muster, da Sdr das nur sehr umstaendlich kann
258 // und die Sdr-Schraffur ( XDash ) noch nicht fertig ist.
259 // Statt dessen wird eine Mischfarbe gewaehlt, die auf den entsprechenden
260 // Farbton zwischen den Farben liegt.
262 static void SetFill( SfxItemSet
& rSet
, WW8_DP_FILL
& rFill
)
264 static BYTE nPatA
[] =
266 0, 0, 5, 10, 20, 25, 30, 40, 50, 60, 70, 75, 80,
267 90, 50, 50, 50, 50, 50, 50, 33, 33, 33, 33, 33, 33
269 sal_uInt16 nPat
= SVBT16ToShort(rFill
.flpp
);
271 if (nPat
== 0) // transparent
272 rSet
.Put(XFillStyleItem(XFILL_NONE
));
275 rSet
.Put(XFillStyleItem(XFILL_SOLID
)); // necessary for textbox
276 if (nPat
<= 1 || nPat
> sizeof(nPatA
))
278 // Solid Background or unknown
279 rSet
.Put(XFillColorItem(aEmptyStr
, WW8TransCol(rFill
.dlpcBg
)));
282 { // Brush -> Farbmischung
283 Color
aB( WW8TransCol( rFill
.dlpcBg
) );
284 Color
aF( WW8TransCol( rFill
.dlpcFg
) );
285 aB
.SetRed( (BYTE
)( ( (ULONG
)aF
.GetRed() * nPatA
[nPat
]
286 + (ULONG
)aB
.GetRed() * ( 100 - nPatA
[nPat
] ) ) / 100 ) );
287 aB
.SetGreen( (BYTE
)( ( (ULONG
)aF
.GetGreen() * nPatA
[nPat
]
288 + (ULONG
)aB
.GetGreen() * ( 100 - nPatA
[nPat
] ) ) / 100 ) );
289 aB
.SetBlue( (BYTE
)( ( (ULONG
)aF
.GetBlue() * nPatA
[nPat
]
290 + (ULONG
)aB
.GetBlue() * ( 100 - nPatA
[nPat
] ) ) / 100 ) );
291 rSet
.Put( XFillColorItem( aEmptyStr
, aB
) );
296 static void SetLineEndAttr( SfxItemSet
& rSet
, WW8_DP_LINEEND
& rLe
,
297 WW8_DP_LINETYPE
& rLt
)
299 UINT16 aSB
= SVBT16ToShort( rLe
.aStartBits
);
302 ::basegfx::B2DPolygon aPolygon
;
303 aPolygon
.append(::basegfx::B2DPoint(0.0, 330.0));
304 aPolygon
.append(::basegfx::B2DPoint(100.0, 0.0));
305 aPolygon
.append(::basegfx::B2DPoint(200.0, 330.0));
306 aPolygon
.setClosed(true);
307 rSet
.Put( XLineEndItem( aEmptyStr
, ::basegfx::B2DPolyPolygon(aPolygon
) ) );
308 USHORT nSiz
= SVBT16ToShort( rLt
.lnpw
)
309 * ( ( aSB
>> 2 & 0x3 ) + ( aSB
>> 4 & 0x3 ) );
310 if( nSiz
< 220 ) nSiz
= 220;
311 rSet
.Put(XLineEndWidthItem(nSiz
));
312 rSet
.Put(XLineEndCenterItem(false));
315 UINT16 aEB
= SVBT16ToShort( rLe
.aEndBits
);
317 ::basegfx::B2DPolygon aPolygon
;
318 aPolygon
.append(::basegfx::B2DPoint(0.0, 330.0));
319 aPolygon
.append(::basegfx::B2DPoint(100.0, 0.0));
320 aPolygon
.append(::basegfx::B2DPoint(200.0, 330.0));
321 aPolygon
.setClosed(true);
322 rSet
.Put( XLineStartItem( aEmptyStr
, ::basegfx::B2DPolyPolygon(aPolygon
) ) );
323 USHORT nSiz
= SVBT16ToShort( rLt
.lnpw
)
324 * ( ( aEB
>> 2 & 0x3 ) + ( aEB
>> 4 & 0x3 ) );
325 if( nSiz
< 220 ) nSiz
= 220;
326 rSet
.Put(XLineStartWidthItem(nSiz
));
327 rSet
.Put(XLineStartCenterItem(false));
331 // Ab hier folgen die Routinen fuer die einzelnen Objekte
332 SdrObject
* SwWW8ImplReader::ReadLine( WW8_DPHEAD
* pHd
, const WW8_DO
* pDo
,
337 if( !ReadGrafStart( (void*)&aLine
, sizeof( aLine
), pHd
, pDo
, rSet
) )
345 rP0
.X() = (INT16
)SVBT16ToShort( pHd
->xa
) + nDrawXOfs2
;
346 rP0
.Y() = (INT16
)SVBT16ToShort( pHd
->ya
) + nDrawYOfs2
;
348 rP0
.X() += (INT16
)SVBT16ToShort( aLine
.xaStart
);
349 rP0
.Y() += (INT16
)SVBT16ToShort( aLine
.yaStart
);
350 rP1
.X() += (INT16
)SVBT16ToShort( aLine
.xaEnd
);
351 rP1
.Y() += (INT16
)SVBT16ToShort( aLine
.yaEnd
);
354 ::basegfx::B2DPolygon aPolygon
;
355 aPolygon
.append(::basegfx::B2DPoint(aP
[0].X(), aP
[0].Y()));
356 aPolygon
.append(::basegfx::B2DPoint(aP
[1].X(), aP
[1].Y()));
357 SdrObject
* pObj
= new SdrPathObj(OBJ_LINE
, ::basegfx::B2DPolyPolygon(aPolygon
));
359 SetStdAttr( rSet
, aLine
.aLnt
, aLine
.aShd
);
360 SetLineEndAttr( rSet
, aLine
.aEpp
, aLine
.aLnt
);
365 SdrObject
* SwWW8ImplReader::ReadRect( WW8_DPHEAD
* pHd
, const WW8_DO
* pDo
,
370 if( !ReadGrafStart( (void*)&aRect
, sizeof( aRect
), pHd
, pDo
, rSet
) )
373 Point
aP0( (INT16
)SVBT16ToShort( pHd
->xa
) + nDrawXOfs2
,
374 (INT16
)SVBT16ToShort( pHd
->ya
) + nDrawYOfs2
);
376 aP1
.X() += (INT16
)SVBT16ToShort( pHd
->dxa
);
377 aP1
.Y() += (INT16
)SVBT16ToShort( pHd
->dya
);
379 SdrObject
* pObj
= new SdrRectObj( Rectangle( aP0
, aP1
) );
381 SetStdAttr( rSet
, aRect
.aLnt
, aRect
.aShd
);
382 SetFill( rSet
, aRect
.aFill
);
387 SdrObject
* SwWW8ImplReader::ReadElipse( WW8_DPHEAD
* pHd
, const WW8_DO
* pDo
,
390 WW8_DP_ELIPSE aElipse
;
392 if( !ReadGrafStart( (void*)&aElipse
, sizeof( aElipse
), pHd
, pDo
, rSet
) )
395 Point
aP0( (INT16
)SVBT16ToShort( pHd
->xa
) + nDrawXOfs2
,
396 (INT16
)SVBT16ToShort( pHd
->ya
) + nDrawYOfs2
);
398 aP1
.X() += (INT16
)SVBT16ToShort( pHd
->dxa
);
399 aP1
.Y() += (INT16
)SVBT16ToShort( pHd
->dya
);
401 SdrObject
* pObj
= new SdrCircObj( OBJ_CIRC
, Rectangle( aP0
, aP1
) );
403 SetStdAttr( rSet
, aElipse
.aLnt
, aElipse
.aShd
);
404 SetFill( rSet
, aElipse
.aFill
);
409 SdrObject
* SwWW8ImplReader::ReadArc( WW8_DPHEAD
* pHd
, const WW8_DO
* pDo
,
414 if( !ReadGrafStart( (void*)&aArc
, sizeof( aArc
), pHd
, pDo
, rSet
) )
417 Point
aP0( (INT16
)SVBT16ToShort( pHd
->xa
) + nDrawXOfs2
,
418 (INT16
)SVBT16ToShort( pHd
->ya
) + nDrawYOfs2
);
420 aP1
.X() += (INT16
)SVBT16ToShort( pHd
->dxa
) * 2;
421 aP1
.Y() += (INT16
)SVBT16ToShort( pHd
->dya
) * 2;
423 short nA
[] = { 2, 3, 1, 0 };
424 short nW
= nA
[ ( ( SVBT8ToByte( aArc
.fLeft
) & 1 ) << 1 )
425 + ( SVBT8ToByte( aArc
.fUp
) & 1 ) ];
426 if( !SVBT8ToByte( aArc
.fLeft
) ){
427 aP0
.Y() -= (INT16
)SVBT16ToShort( pHd
->dya
);
428 aP1
.Y() -= (INT16
)SVBT16ToShort( pHd
->dya
);
430 if( SVBT8ToByte( aArc
.fUp
) ){
431 aP0
.X() -= (INT16
)SVBT16ToShort( pHd
->dxa
);
432 aP1
.X() -= (INT16
)SVBT16ToShort( pHd
->dxa
);
435 SdrObject
* pObj
= new SdrCircObj( OBJ_SECT
, Rectangle( aP0
, aP1
),
436 nW
* 9000, ( ( nW
+ 1 ) & 3 ) * 9000 );
438 SetStdAttr( rSet
, aArc
.aLnt
, aArc
.aShd
);
439 SetFill( rSet
, aArc
.aFill
);
444 SdrObject
* SwWW8ImplReader::ReadPolyLine( WW8_DPHEAD
* pHd
, const WW8_DO
* pDo
,
447 WW8_DP_POLYLINE aPoly
;
449 if( !ReadGrafStart( (void*)&aPoly
, sizeof( aPoly
), pHd
, pDo
, rSet
) )
452 UINT16 nCount
= SVBT16ToShort( aPoly
.aBits1
) >> 1 & 0x7fff;
453 SVBT16
*pP
= new SVBT16
[nCount
* 2];
454 pStrm
->Read( pP
, nCount
* 4 ); // Punkte einlesen
455 Polygon
aP( nCount
);
459 for( i
=0; i
<nCount
; i
++ ){
460 aPt
.X() = SVBT16ToShort( pP
[i
<< 1] ) + nDrawXOfs2
461 + (INT16
)SVBT16ToShort( pHd
->xa
);
462 aPt
.Y() = SVBT16ToShort( pP
[( i
<< 1 ) + 1] ) + nDrawYOfs2
463 + (INT16
)SVBT16ToShort( pHd
->ya
);
468 SdrObject
* pObj
= new SdrPathObj(( SVBT16ToShort( aPoly
.aBits1
) & 0x1 ) ? OBJ_POLY
: OBJ_PLIN
, ::basegfx::B2DPolyPolygon(aP
.getB2DPolygon()));
469 SetStdAttr( rSet
, aPoly
.aLnt
, aPoly
.aShd
);
470 SetFill( rSet
, aPoly
.aFill
);
475 ESelection
SwWW8ImplReader::GetESelection( long nCpStart
, long nCpEnd
)
477 USHORT nPCnt
= mpDrawEditEngine
->GetParagraphCount();
481 && (nCpStart
>= mpDrawEditEngine
->GetTextLen( nSP
) + 1) )
483 nCpStart
-= mpDrawEditEngine
->GetTextLen( nSP
) + 1;
486 // Beim Ende erst 1 Zeichen spaeter auf naechste Zeile umschalten,
487 // da sonst Zeilenattribute immer eine Zeile zu weit reichen.
489 && (nCpEnd
> mpDrawEditEngine
->GetTextLen( nEP
) + 1) )
491 nCpEnd
-= mpDrawEditEngine
->GetTextLen( nEP
) + 1;
494 return ESelection( nSP
, (USHORT
)nCpStart
, nEP
, (USHORT
)nCpEnd
);
497 // InsertTxbxStyAttrs() setzt die Style-Attribute in den uebergebenen ItemSet.
498 // Es werden die SW-Styles genommen, die Import-WW-Styles sind zu diesem
499 // Zeitpunkt schon destruiert.
500 // Die SW-Styles werden per Tiefensuche, d.h. mit Parent-Styles nach den
501 // in aSrcTab angegebenen Attributen untersucht. Diese werden per Clone
502 // dupliziert, bei den Duplikaten werden die Which-IDs
503 // gemaess der Tabelle aDstTab umgesetzt, damit die EditEngine sie nicht
505 // Es werden hierbei sowohl Para- wie auch Zeichen-Attribute in den
507 void SwWW8ImplReader::InsertTxbxStyAttrs( SfxItemSet
& rS
, USHORT nColl
)
509 if( nColl
< nColls
&& pCollA
[nColl
].pFmt
&& pCollA
[nColl
].bColl
)
511 const SfxPoolItem
* pItem
;
512 for( USHORT i
= POOLATTR_BEGIN
; i
< POOLATTR_END
; i
++ )
514 //If we are set in the source and not set in the destination
516 if ( SFX_ITEM_SET
== pCollA
[nColl
].pFmt
->GetItemState(
519 SfxItemPool
*pEditPool
= rS
.GetPool();
521 USHORT nSlotId
= rDoc
.GetAttrPool().GetSlotId(nWhich
);
523 nSlotId
&& nWhich
!= nSlotId
&&
524 0 != (nWhich
= pEditPool
->GetWhich(nSlotId
)) &&
526 ( SFX_ITEM_SET
!= rS
.GetItemState(nWhich
, false) )
529 SfxPoolItem
* pCopy
= pItem
->Clone();
530 pCopy
->SetWhich( nWhich
);
540 static void lcl_StripFields(String
&rString
, long &rNewStartCp
)
542 for(USHORT i
=0; i
< rString
.Len(); i
++)
544 if( 0x13 == rString
.GetChar( i
) )
548 rString
.Erase( i
, 1 );
552 && ( i
< rString
.Len())
553 && (0x14 != rString
.GetChar( i
) )
554 && (0x15 != rString
.GetChar( i
) ) );
557 if( 0x14 == rString
.GetChar( i
) )
559 rString
.Erase( i
, 1 );
566 && ( i
< rString
.Len())
567 && (0x15 != rString
.GetChar( i
) ) );
568 if( i
< rString
.Len() )
569 rString
.Erase( i
, 1 );
571 else if( 0x15 == rString
.GetChar( i
) )
572 rString
.Erase( i
, 1 );
582 long mnStartPos
; //0x13
583 long mnEndPos
; //0x15
585 explicit Chunk(long nStart
, const String
&rURL
)
586 : msURL(rURL
), mnStartPos(nStart
) {}
587 Chunk(const Chunk
&rChunk
)
588 : msURL(rChunk
.msURL
), mnStartPos(rChunk
.mnStartPos
),
589 mnEndPos(rChunk
.mnEndPos
) {}
590 Chunk
& operator=(const Chunk
&rChunk
)
592 msURL
= rChunk
.msURL
;
593 mnStartPos
= rChunk
.mnStartPos
;
594 mnEndPos
= rChunk
.mnEndPos
;
597 void SetEndPos(long nEnd
) { mnEndPos
= nEnd
; }
598 long GetStartPos() const {return mnStartPos
;}
599 long GetEndPos() const {return mnEndPos
;}
600 const String
&GetURL() const {return msURL
;}
601 void Adjust(xub_StrLen nAdjust
)
608 // InsertAttrsAsDrawingAttrs() setzt zwischen StartCp und EndCp die Attribute.
609 // Dabei werden Style-Attribute als harte Attribute, Absatz- und Zeichen-
610 // attribute gesetzt.
611 void SwWW8ImplReader::InsertAttrsAsDrawingAttrs(long nStartCp
, long nEndCp
,
612 ManTypes eType
, bool bONLYnPicLocFc
)
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.
621 WW8ReaderSave
aSave(this);
622 pPlcxMan
= new WW8PLCFMan(pSBase
, eType
, nStartCp
, true);
624 WW8_CP nStart
= pPlcxMan
->Where();
625 WW8_CP nNext
, nEnd
, nStartReplace
=0;
627 bool bDoingSymbol
= false;
628 sal_Unicode cReplaceSymbol
= cSymbol
;
630 SfxItemSet
*pS
= new SfxItemSet(mpDrawEditEngine
->GetEmptyItemSet());
631 WW8PLCFManResult aRes
;
633 std::deque
<Chunk
> aChunks
;
635 //Here store stack location
636 USHORT nCurrentCount
= static_cast< USHORT
>(pCtrlStck
->Count());
637 while (nStart
< nEndCp
)
639 //nStart is the beginning of the attributes for this range, and
640 //may be before the text itself. So watch out for that
641 WW8_CP nTxtStart
= nStart
;
642 if (nTxtStart
< nStartCp
)
643 nTxtStart
= nStartCp
;
644 // get position of next SPRM
645 bool bStartAttr
= pPlcxMan
->Get(&aRes
);
646 nAktColl
= pPlcxMan
->GetColl();
651 if ( (68 == aRes
.nSprmId
) || (0x6A03 == aRes
.nSprmId
) )
653 Read_PicLoc(aRes
.nSprmId
, aRes
.pMemPos
+
654 mpSprmParser
->DistanceToData(aRes
.nSprmId
), 4);
655 // Ok, that's what we were looking for. Now let's get
660 else if ( aRes
.nSprmId
&& (
661 (eFTN
> aRes
.nSprmId
) || (0x0800 <= aRes
.nSprmId
) ) )
663 //Here place them onto our usual stack and we will pop them
664 //off and convert them later
667 ImportSprm(aRes
.pMemPos
, aRes
.nSprmId
);
668 if (!bDoingSymbol
&& bSymbol
== true)
671 nStartReplace
= nTxtStart
;
672 cReplaceSymbol
= cSymbol
;
677 EndSprm( aRes
.nSprmId
);
678 if (bSymbol
== false && bDoingSymbol
)
680 bDoingSymbol
= false;
682 sTemp
.Fill(writer_cast
<xub_StrLen
>(
683 nTxtStart
- nStartReplace
), cReplaceSymbol
);
684 mpDrawEditEngine
->QuickInsertText(sTemp
,
685 GetESelection(nStartReplace
- nStartCp
,
686 nTxtStart
- nStartCp
) );
690 else if (aRes
.nSprmId
== eFLD
)
694 USHORT nCount
= static_cast< USHORT
>(pCtrlStck
->Count());
695 if (maFieldStack
.empty() && Read_Field(&aRes
))
698 for (USHORT nI
= static_cast< USHORT
>(pCtrlStck
->Count()); nI
> nCount
; --nI
)
700 const SfxPoolItem
*pItem
= ((*pCtrlStck
)[nI
-1])->pAttr
;
701 USHORT nWhich
= pItem
->Which();
702 if (nWhich
== RES_TXTATR_INETFMT
)
704 const SwFmtINetFmt
*pURL
=
705 (const SwFmtINetFmt
*)pItem
;
706 sURL
= pURL
->GetValue();
708 pCtrlStck
->DeleteAndDestroy(nI
-1);
710 aChunks
.push_back(Chunk(nStart
, sURL
));
715 if (!maFieldStack
.empty() && End_Field())
716 aChunks
.back().SetEndPos(nStart
+1);
722 nNext
= pPlcxMan
->Where();
724 if( (nNext
!= nStart
) && !bONLYnPicLocFc
)
726 nEnd
= ( nNext
< nEndCp
) ? nNext
: nEndCp
;
727 SfxItemPool
*pEditPool
= pS
->GetPool();
729 //Here read current properties and convert them into pS
730 //and put those attrs into the draw box if they can be converted
732 if (pCtrlStck
->Count() - nCurrentCount
)
734 for (USHORT i
= nCurrentCount
; i
< pCtrlStck
->Count(); i
++)
736 const SfxPoolItem
*pItem
= ((*pCtrlStck
)[i
])->pAttr
;
737 USHORT nWhich
= pItem
->Which();
738 if( nWhich
< RES_FLTRATTR_BEGIN
||
739 nWhich
>= RES_FLTRATTR_END
)
741 USHORT nSlotId
= rDoc
.GetAttrPool().GetSlotId(nWhich
);
743 nSlotId
&& nWhich
!= nSlotId
&&
744 0 != (nWhich
= pEditPool
->GetWhich(nSlotId
)) &&
748 SfxPoolItem
* pCopy
= pItem
->Clone();
749 pCopy
->SetWhich( nWhich
);
756 //Fill in the remainder from the style
757 InsertTxbxStyAttrs(*pS
, nAktColl
);
761 mpDrawEditEngine
->QuickSetAttribs( *pS
,
762 GetESelection( nTxtStart
- nStartCp
, nEnd
- nStartCp
) );
764 pS
= new SfxItemSet(mpDrawEditEngine
->GetEmptyItemSet());
771 //pop off as far as recorded location just in case there were some left
773 for (USHORT nI
= static_cast< USHORT
>(pCtrlStck
->Count()); nI
> nCurrentCount
; --nI
)
774 pCtrlStck
->DeleteAndDestroy(nI
-1);
776 typedef std::deque
<Chunk
>::iterator myIter
;
777 myIter aEnd
= aChunks
.end();
778 for (myIter aIter
= aChunks
.begin(); aIter
!= aEnd
; ++aIter
)
780 ESelection
aSel(GetESelection(aIter
->GetStartPos()-nStartCp
,
781 aIter
->GetEndPos()-nStartCp
));
782 String
aString(mpDrawEditEngine
->GetText(aSel
));
783 xub_StrLen nOrigLen
= aString
.Len();
785 lcl_StripFields(aString
, nDummy
);
788 if (aIter
->GetURL().Len())
790 SvxURLField
aURL(aIter
->GetURL(), aString
,
791 SVXURLFORMAT_APPDEFAULT
);
792 mpDrawEditEngine
->QuickInsertField(SvxFieldItem(aURL
, EE_FEATURE_FIELD
), aSel
);
793 nChanged
= nOrigLen
- 1;
797 mpDrawEditEngine
->QuickInsertText(aString
, aSel
);
798 nChanged
= nOrigLen
- aString
.Len();
800 for (myIter aIter2
= aIter
+1; aIter2
!= aEnd
; ++aIter2
)
801 aIter2
->Adjust(nChanged
);
805 Don't worry about the new pPlcxMan, the restorer removes it when
806 replacing the current one with the old one.
811 bool SwWW8ImplReader::GetTxbxTextSttEndCp(WW8_CP
& rStartCp
, WW8_CP
& rEndCp
,
812 USHORT nTxBxS
, USHORT nSequence
)
814 // rasch den TextBox-PLCF greifen
815 WW8PLCFspecial
* pT
= pPlcxMan
? pPlcxMan
->GetTxbx() : 0;
818 ASSERT( !this, "+Wo ist der Grafik-Text (1) ?" );
822 // ggfs. zuerst die richtige TextBox-Story finden
823 bool bCheckTextBoxStory
= ( nTxBxS
&& pT
->GetIMax() >= nTxBxS
);
824 if( bCheckTextBoxStory
)
825 pT
->SetIdx( nTxBxS
-1 );
827 // dann Start und Ende ermitteln
829 if( !pT
->Get( rStartCp
, pT0
) )
831 ASSERT( !this, "+Wo ist der Grafik-Text (2) ?" );
835 if( bCheckTextBoxStory
)
837 bool bReusable
= (0 != SVBT16ToShort( ((WW8_TXBXS
*)pT0
)->fReusable
));
841 if( !pT
->Get( rStartCp
, pT0
) )
843 ASSERT( !this, "+Wo ist der Grafik-Text (2-a) ?" );
846 bReusable
= (0 != SVBT16ToShort( ((WW8_TXBXS
*)pT0
)->fReusable
));
850 if( !pT
->Get( rEndCp
, pT0
) )
852 ASSERT( !this, "+Wo ist der Grafik-Text (3) ?" );
856 // jetzt ggfs. die passende Page in der Break-Table finden
857 if( bCheckTextBoxStory
)
859 // Sonderfall: gesamte(!) Kette soll ermittelt werden,
860 // dann sind wir hier schon fertig!
861 if( USHRT_MAX
> nSequence
)
863 long nMinStartCp
= rStartCp
;
864 long nMaxEndCp
= rEndCp
;
865 // rasch den TextBox-Break-Deskriptor-PLCF greifen
866 pT
= pPlcxMan
->GetTxbxBkd();
867 if (!pT
) //It can occur on occasion, Caolan
870 // den ersten Eintrag fuer diese TextBox-Story finden
871 if( !pT
->SeekPos( rStartCp
) )
873 ASSERT( !this, "+Wo ist der Grafik-Text (4) ?" );
876 // ggfs. entsprechende Anzahl Eintraege weitergehen
877 for(USHORT iSequence
= 0; iSequence
< nSequence
; iSequence
++) (*pT
)++;
878 // dann die tatsaechlichen Start und Ende ermitteln
879 if( (!pT
->Get( rStartCp
, pT0
))
880 || ( nMinStartCp
> rStartCp
) )
882 ASSERT( !this, "+Wo ist der Grafik-Text (5) ?" );
885 if( rStartCp
>= nMaxEndCp
)
886 rEndCp
= rStartCp
; // kein Error: leerer String!
890 if( (!pT
->Get( rEndCp
, pT0
))
891 || ( nMaxEndCp
< rEndCp
-1 ) )
893 ASSERT( !this, "+Wo ist der Grafik-Text (6) ?" );
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 bool SwWW8ImplReader::GetRangeAsDrawingString(String
& rString
, long nStartCp
, long nEndCp
, ManTypes eType
)
911 WW8_CP nOffset
= pWwFib
->GetBaseCp(eType
);
914 ASSERT(nStartCp
<= nEndCp
, "+Wo ist der Grafik-Text (7) ?");
915 if (nStartCp
== nEndCp
)
916 rString
.Erase(); // leerer String: durchaus denkbar!
917 else if (nStartCp
< nEndCp
)
919 // den Text einlesen: kann sich ueber mehrere Pieces erstrecken!!!
920 USHORT nLen
= pSBase
->WW8ReadString(*pStrm
, rString
,
921 nStartCp
+ nOffset
, nEndCp
- nStartCp
, GetCurrentCharSet());
922 ASSERT(nLen
, "+Wo ist der Grafik-Text (8) ?");
926 if( 0x0d == rString
.GetChar(nLen
- 1) )
927 rString
.Erase(nLen
- 1);
929 rString
.SearchAndReplaceAll( 0xb, 0xa );
935 OutlinerParaObject
* SwWW8ImplReader::ImportAsOutliner(String
&rString
, WW8_CP nStartCp
, WW8_CP nEndCp
, ManTypes eType
)
937 OutlinerParaObject
* pRet
= 0;
939 if (GetRangeAsDrawingString( rString
, nStartCp
, nEndCp
, eType
))
941 if (!mpDrawEditEngine
)
942 mpDrawEditEngine
= new EditEngine(0);
944 mpDrawEditEngine
->SetText(rString
);
945 InsertAttrsAsDrawingAttrs(nStartCp
, nEndCp
, eType
);
947 //Annotations typically begin with a (useless) 0x5
948 if ((eType
== MAN_AND
) && mpDrawEditEngine
->GetTextLen())
950 ESelection
aFirstChar(0, 0, 0, 1);
951 if (mpDrawEditEngine
->GetText( aFirstChar
) == String(sal_Unicode(0x5)))
952 mpDrawEditEngine
->QuickDelete(aFirstChar
);
955 EditTextObject
* pTemporaryText
= mpDrawEditEngine
->CreateTextObject();
956 pRet
= new OutlinerParaObject(*pTemporaryText
);
957 pRet
->SetOutlinerMode( OUTLINERMODE_TEXTOBJECT
);
958 delete pTemporaryText
;
960 mpDrawEditEngine
->SetText( aEmptyStr
);
961 mpDrawEditEngine
->SetParaAttribs(0, mpDrawEditEngine
->GetEmptyItemSet());
963 //Strip out fields, leaving the result
965 lcl_StripFields(rString
, nDummy
);
966 //Strip out word's special characters for the simple string
967 rString
.EraseAllChars(0x1);
968 rString
.EraseAllChars(0x5);
969 rString
.EraseAllChars(0x8);
970 rString
.SearchAndReplaceAllAscii("\007\007", String::CreateFromAscii("\007\012"));
971 rString
.SearchAndReplaceAll(0x7, ' ');
978 // InsertTxbxText() fuegt fuer TextBoxen und CaptionBoxen den Text
979 // und die Attribute ein
980 SwFrmFmt
* SwWW8ImplReader::InsertTxbxText(SdrTextObj
* pTextObj
,
981 Size
* pObjSiz
, USHORT nTxBxS
, USHORT nSequence
, long nPosCp
,
982 SwFrmFmt
* pOldFlyFmt
, bool bMakeSdrGrafObj
, bool& rbEraseTextObj
,
983 bool* pbTestTxbxContainsText
, long* pnStartCp
, long* pnEndCp
,
984 bool* pbContainsGraphics
, SvxMSDffImportRec
* pRecord
)
986 SwFrmFmt
* pFlyFmt
= 0;
987 ULONG nOld
= pStrm
->Tell();
989 ManTypes eType
= pPlcxMan
->GetManType() == MAN_HDFT
? MAN_TXBX_HDFT
: MAN_TXBX
;
991 rbEraseTextObj
= false;
994 WW8_CP nStartCp
, nEndCp
;
995 bool bContainsGraphics
= false;
996 bool bTextWasRead
= GetTxbxTextSttEndCp( nStartCp
, nEndCp
, nTxBxS
,
997 nSequence
) && GetRangeAsDrawingString( aString
, nStartCp
, nEndCp
, eType
);
999 if (!mpDrawEditEngine
)
1000 mpDrawEditEngine
= new EditEngine(0);
1002 mpDrawEditEngine
->SetPaperSize( *pObjSiz
);
1004 String
aOrigString(aString
);
1007 long nNewStartCp
= nStartCp
;
1008 lcl_StripFields(aString
, nNewStartCp
);
1010 if (1 != aString
.Len())
1012 if ( (STRING_NOTFOUND
!= aString
.Search(0x1)) ||
1013 (STRING_NOTFOUND
!= aString
.Search(0x8)) )
1015 bContainsGraphics
= true;
1018 else // May be a single graphic or object
1021 switch( aString
.GetChar(0) )
1024 if (!pbTestTxbxContainsText
)
1026 WW8ReaderSave
aSave(this, nNewStartCp
-1);
1027 bool bOldEmbeddObj
= bEmbeddObj
;
1028 //bEmbedd Ordinarily would have been set by field
1029 //parse, but this is impossible here so...
1032 // 1st look for OLE- or Graph-Indicator Sprms
1033 WW8PLCFx_Cp_FKP
* pChp
= pPlcxMan
->GetChpPLCF();
1035 pChp
->GetSprms( &aDesc
);
1036 WW8SprmIter
aSprmIter(aDesc
.pMemPos
, aDesc
.nSprmsLen
,
1039 const BYTE
* pParams
= aSprmIter
.GetAktParams();
1040 for( int nLoop
= 0; nLoop
< 2; ++nLoop
)
1042 while( aSprmIter
.GetSprms()
1043 && (0 != (pParams
= aSprmIter
.GetAktParams())) )
1045 USHORT nAktId
= aSprmIter
.GetAktId();
1052 Read_Obj(nAktId
, pParams
, 1);
1054 case 68: // Read_Pic()
1057 Read_PicLoc(nAktId
, pParams
, 1);
1063 //if( bRead_Obj || bRead_PicLoc ) break;
1066 pChp
->GetPCDSprms( aDesc
);
1067 aSprmIter
.SetSprms( aDesc
.pMemPos
,
1070 //if( bRead_Obj || bRead_PicLoc ) break;
1072 aSave
.Restore(this);
1073 bEmbeddObj
=bOldEmbeddObj
;
1075 // then import either an OLE of a Graphic
1078 if( bMakeSdrGrafObj
&& pTextObj
&&
1079 pTextObj
->GetUpGroup() )
1081 // SdrOleObj/SdrGrafObj anstatt des
1082 // SdrTextObj in dessen Gruppe einsetzen
1085 SdrObject
* pNew
= ImportOleBase(aGraph
);
1089 pNew
= new SdrGrafObj
;
1090 ((SdrGrafObj
*)pNew
)->SetGraphic(aGraph
);
1095 pNew
->SetModel( pDrawModel
);
1096 pNew
->SetLogicRect( pTextObj
->GetCurrentBoundRect() );
1097 pNew
->SetLayer( pTextObj
->GetLayer() );
1099 pTextObj
->GetUpGroup()->GetSubList()->
1100 ReplaceObject(pNew
, pTextObj
->GetOrdNum());
1103 pFlyFmt
= ImportOle();
1108 InsertAttrsAsDrawingAttrs(nNewStartCp
, nNewStartCp
+1,
1110 pFlyFmt
= ImportGraf(bMakeSdrGrafObj
? pTextObj
: 0,
1116 if ( (!pbTestTxbxContainsText
) && (!bObj
) )
1117 pFlyFmt
= Read_GrafLayer( nPosCp
);
1130 SfxItemSet
aFlySet( rDoc
.GetAttrPool(),
1131 RES_FRMATR_BEGIN
, RES_FRMATR_END
-1 );
1133 Rectangle
aInnerDist( pRecord
->nDxTextLeft
,
1134 pRecord
->nDyTextTop
,
1135 pRecord
->nDxTextRight
,
1136 pRecord
->nDyTextBottom
);
1137 MatchSdrItemsIntoFlySet( pTextObj
,
1139 pRecord
->eLineStyle
,
1140 pRecord
->eShapeType
,
1143 pFlyFmt
->SetFmtAttr( aFlySet
);
1145 MapWrapIntoFlyFmt(pRecord
, pFlyFmt
);
1149 rbEraseTextObj
= (0 != pFlyFmt
);
1155 *pnStartCp
= nStartCp
;
1159 if( pbTestTxbxContainsText
)
1160 *pbTestTxbxContainsText
= bTextWasRead
&& ! rbEraseTextObj
;
1161 else if( !rbEraseTextObj
)
1165 mpDrawEditEngine
->SetText(aOrigString
);
1166 InsertAttrsAsDrawingAttrs(nStartCp
, nEndCp
, eType
);
1169 bool bVertical
= pTextObj
->IsVerticalWriting() ? true : false;
1170 EditTextObject
* pTemporaryText
= mpDrawEditEngine
->CreateTextObject();
1171 OutlinerParaObject
* pOp
= new OutlinerParaObject(*pTemporaryText
);
1172 pOp
->SetOutlinerMode( OUTLINERMODE_TEXTOBJECT
);
1173 pOp
->SetVertical( bVertical
);
1174 delete pTemporaryText
;
1175 pTextObj
->NbcSetOutlinerParaObject( pOp
);
1176 pTextObj
->SetVerticalWriting(bVertical
);
1178 // Fuer die naechste Textbox noch die alten Absatz-Attribute
1179 // und Styles entfernen, sonst startet die naechste Box
1180 // mit falschen Attributen.
1181 // Vorgehen: Text loeschen = auf 1 Absatz reduzieren
1182 // und an diesem Absatz die Absatzattribute und Styles loeschen
1184 mpDrawEditEngine
->SetText( aEmptyStr
);
1185 mpDrawEditEngine
->SetParaAttribs(0, mpDrawEditEngine
->GetEmptyItemSet());
1188 pStrm
->Seek( nOld
);
1189 if (pbContainsGraphics
)
1190 *pbContainsGraphics
= bContainsGraphics
;
1195 bool SwWW8ImplReader::TxbxChainContainsRealText(USHORT nTxBxS
, long& rStartCp
,
1198 bool bErase
, bContainsText
;
1199 InsertTxbxText( 0,0,nTxBxS
,USHRT_MAX
,0,0,0, bErase
, &bContainsText
,
1200 &rStartCp
, &rEndCp
);
1201 return bContainsText
;
1205 // TextBoxes only for Ver67 !!
1206 SdrObject
* SwWW8ImplReader::ReadTxtBox( WW8_DPHEAD
* pHd
, const WW8_DO
* pDo
,
1207 SfxAllItemSet
&rSet
)
1210 WW8_DP_TXTBOX aTxtB
;
1212 if( !ReadGrafStart( (void*)&aTxtB
, sizeof( aTxtB
), pHd
, pDo
, rSet
) )
1215 Point
aP0( (INT16
)SVBT16ToShort( pHd
->xa
) + nDrawXOfs2
,
1216 (INT16
)SVBT16ToShort( pHd
->ya
) + nDrawYOfs2
);
1218 aP1
.X() += (INT16
)SVBT16ToShort( pHd
->dxa
);
1219 aP1
.Y() += (INT16
)SVBT16ToShort( pHd
->dya
);
1221 SdrObject
* pObj
= new SdrRectObj( OBJ_TEXT
, Rectangle( aP0
, aP1
) );
1222 pObj
->SetModel( pDrawModel
);
1223 pObj
->NbcSetSnapRect(Rectangle(aP0
, aP1
));
1224 Size
aSize( (INT16
)SVBT16ToShort( pHd
->dxa
) ,
1225 (INT16
)SVBT16ToShort( pHd
->dya
) );
1227 long nStartCpFly
,nEndCpFly
;
1228 bool bContainsGraphics
;
1229 InsertTxbxText(PTR_CAST(SdrTextObj
,pObj
), &aSize
, 0, 0, 0, 0, false,
1230 bDummy
,0,&nStartCpFly
,&nEndCpFly
,&bContainsGraphics
);
1232 SetStdAttr( rSet
, aTxtB
.aLnt
, aTxtB
.aShd
);
1233 SetFill( rSet
, aTxtB
.aFill
);
1235 rSet
.Put( SdrTextFitToSizeTypeItem( SDRTEXTFIT_NONE
) );
1236 rSet
.Put( SdrTextAutoGrowWidthItem(false));
1237 rSet
.Put( SdrTextAutoGrowHeightItem(false));
1238 rSet
.Put( SdrTextLeftDistItem( MIN_BORDER_DIST
*2 ) );
1239 rSet
.Put( SdrTextRightDistItem( MIN_BORDER_DIST
*2 ) );
1240 rSet
.Put( SdrTextUpperDistItem( MIN_BORDER_DIST
) );
1241 rSet
.Put( SdrTextLowerDistItem( MIN_BORDER_DIST
) );
1246 SdrObject
* SwWW8ImplReader::ReadCaptionBox( WW8_DPHEAD
* pHd
, const WW8_DO
* pDo
,
1247 SfxAllItemSet
&rSet
)
1249 static SdrCaptionType aCaptA
[] = { SDRCAPT_TYPE1
, SDRCAPT_TYPE2
,
1250 SDRCAPT_TYPE3
, SDRCAPT_TYPE4
};
1252 WW8_DP_CALLOUT_TXTBOX aCallB
;
1254 if( !ReadGrafStart( (void*)&aCallB
, sizeof( aCallB
), pHd
, pDo
, rSet
) )
1257 UINT16 nCount
= SVBT16ToShort( aCallB
.dpPolyLine
.aBits1
) >> 1 & 0x7fff;
1258 SVBT16
*pP
= new SVBT16
[nCount
* 2];
1259 pStrm
->Read( pP
, nCount
* 4 ); // Punkte einlesen
1260 BYTE nTyp
= (BYTE
)nCount
- 1;
1261 if( nTyp
== 1 && SVBT16ToShort( pP
[0] ) == SVBT16ToShort( pP
[2] ) )
1264 Point
aP0( (INT16
)SVBT16ToShort( pHd
->xa
) +
1265 (INT16
)SVBT16ToShort( aCallB
.dpheadTxbx
.xa
) + nDrawXOfs2
,
1266 (INT16
)SVBT16ToShort( pHd
->ya
)
1267 + (INT16
)SVBT16ToShort( aCallB
.dpheadTxbx
.ya
) + nDrawYOfs2
);
1269 aP1
.X() += (INT16
)SVBT16ToShort( aCallB
.dpheadTxbx
.dxa
);
1270 aP1
.Y() += (INT16
)SVBT16ToShort( aCallB
.dpheadTxbx
.dya
);
1271 Point
aP2( (INT16
)SVBT16ToShort( pHd
->xa
)
1272 + (INT16
)SVBT16ToShort( aCallB
.dpheadPolyLine
.xa
)
1273 + nDrawXOfs2
+ (INT16
)SVBT16ToShort( pP
[0] ),
1274 (INT16
)SVBT16ToShort( pHd
->ya
)
1275 + (INT16
)SVBT16ToShort( aCallB
.dpheadPolyLine
.ya
)
1276 + nDrawYOfs2
+ (INT16
)SVBT16ToShort( pP
[1] ) );
1279 SdrCaptionObj
* pObj
= new SdrCaptionObj( Rectangle( aP0
, aP1
), aP2
);
1280 pObj
->SetModel( pDrawModel
);
1281 pObj
->NbcSetSnapRect(Rectangle(aP0
, aP1
));
1282 Size
aSize( (INT16
)SVBT16ToShort( aCallB
.dpheadTxbx
.dxa
),
1283 (INT16
)SVBT16ToShort( aCallB
.dpheadTxbx
.dya
) );
1284 bool bEraseThisObject
;
1286 InsertTxbxText(pObj
, &aSize
, 0, 0, 0, 0, false, bEraseThisObject
);
1288 if( SVBT16ToShort( aCallB
.dptxbx
.aLnt
.lnps
) != 5 ) // Umrandung sichtbar ?
1289 SetStdAttr( rSet
, aCallB
.dptxbx
.aLnt
, aCallB
.dptxbx
.aShd
);
1290 else // nein -> Nimm Linie
1291 SetStdAttr( rSet
, aCallB
.dpPolyLine
.aLnt
, aCallB
.dptxbx
.aShd
);
1292 SetFill( rSet
, aCallB
.dptxbx
.aFill
);
1293 rSet
.Put( SdrCaptionTypeItem( aCaptA
[nTyp
] ) );
1299 SdrObject
*SwWW8ImplReader::ReadGroup( WW8_DPHEAD
* pHd
, const WW8_DO
* pDo
,
1300 SfxAllItemSet
&rSet
)
1304 if( !ReadGrafStart( (void*)&nGrouped
, sizeof( nGrouped
), pHd
, pDo
, rSet
) )
1307 #ifdef OSL_BIGENDIAN
1308 nGrouped
= (INT16
)SWAPSHORT( nGrouped
);
1311 nDrawXOfs
= nDrawXOfs
+ (INT16
)SVBT16ToShort( pHd
->xa
);
1312 nDrawYOfs
= nDrawYOfs
+ (INT16
)SVBT16ToShort( pHd
->ya
);
1314 SdrObject
* pObj
= new SdrObjGroup
;
1316 short nLeft
= (INT16
)SVBT16ToShort( pHd
->cb
) - sizeof( WW8_DPHEAD
);
1317 for (int i
= 0; i
< nGrouped
; i
++)
1319 SfxAllItemSet
aSet(pDrawModel
->GetItemPool());
1320 if (SdrObject
*pObject
= ReadGrafPrimitive(nLeft
, pDo
, aSet
))
1323 // first add and then set ItemSet
1324 SdrObjList
*pSubGroup
= pObj
->GetSubList();
1325 ASSERT(pSubGroup
, "Why no sublist available?");
1327 pSubGroup
->InsertObject(pObject
, 0);
1328 pObject
->SetMergedItemSetAndBroadcast(aSet
);
1332 nDrawXOfs
= nDrawXOfs
- (INT16
)SVBT16ToShort( pHd
->xa
);
1333 nDrawYOfs
= nDrawYOfs
- (INT16
)SVBT16ToShort( pHd
->ya
);
1338 SdrObject
* SwWW8ImplReader::ReadGrafPrimitive( short& rLeft
, const WW8_DO
* pDo
,
1339 SfxAllItemSet
&rSet
)
1341 //cmc: This whole archaic word 6 graphic import can probably be refactored
1342 //into an object hierarachy with a little effort.
1344 WW8_DPHEAD aHd
; // Lese Draw-Primitive-Header
1345 pStrm
->Read(&aHd
, sizeof(WW8_DPHEAD
));
1347 if( rLeft
>= SVBT16ToShort(aHd
.cb
) ) // Vorsichtsmassmahme
1349 rSet
.Put(SwFmtSurround(SURROUND_THROUGHT
));
1350 switch (SVBT16ToShort(aHd
.dpk
) & 0xff )
1353 pRet
= ReadGroup( &aHd
, pDo
, rSet
);
1356 pRet
= ReadLine( &aHd
, pDo
, rSet
);
1359 pRet
= ReadTxtBox( &aHd
, pDo
, rSet
);
1362 pRet
= ReadRect( &aHd
, pDo
, rSet
);
1365 pRet
= ReadElipse( &aHd
, pDo
, rSet
);
1368 pRet
= ReadArc( &aHd
, pDo
, rSet
);
1371 pRet
= ReadPolyLine( &aHd
, pDo
, rSet
);
1374 pRet
= ReadCaptionBox( &aHd
, pDo
, rSet
);
1376 default: // unbekannt
1377 pStrm
->SeekRel(SVBT16ToShort(aHd
.cb
) - sizeof(WW8_DPHEAD
));
1383 ASSERT( !this, "+Grafik-Overlap" );
1385 rLeft
= rLeft
- SVBT16ToShort( aHd
.cb
);
1389 void SwWW8ImplReader::ReadGrafLayer1( WW8PLCFspecial
* pPF
, long nGrafAnchorCp
)
1391 pPF
->SeekPos( nGrafAnchorCp
);
1394 if( !pPF
->Get( nStartFc
, pF0
) )
1396 ASSERT( !this, "+Wo ist die Grafik (2) ?" );
1399 WW8_FDOA
* pF
= (WW8_FDOA
*)pF0
;
1400 if( !SVBT32ToUInt32( pF
->fc
) )
1402 ASSERT( !this, "+Wo ist die Grafik (3) ?" );
1406 pStrm
->Seek( SVBT32ToUInt32( pF
->fc
) ); // Lese Draw-Header
1407 pStrm
->Read( &aDo
, sizeof( WW8_DO
) );
1409 short nLeft
= SVBT16ToShort( aDo
.cb
) - sizeof( WW8_DO
);
1410 while (nLeft
> static_cast<short>(sizeof(WW8_DPHEAD
)))
1412 SfxAllItemSet
aSet( pDrawModel
->GetItemPool() );
1413 if (SdrObject
*pObject
= ReadGrafPrimitive( nLeft
, &aDo
, aSet
))
1415 pWWZOrder
->InsertDrawingObject(pObject
, SVBT16ToShort(aDo
.dhgt
));
1416 SwFrmFmt
*pFrm
= rDoc
.Insert( *pPaM
, *pObject
, &aSet
, NULL
);
1417 pObject
->SetMergedItemSet(aSet
);
1418 pAnchorStck
->AddAnchor(*pPaM
->GetPoint(), pFrm
);
1423 const WW8_BordersSO
&WW8_BordersSO::Get0x01LineMatch(eBorderCode eCode
)
1426 // Linien-Defaults in Twips: fruehere Writer-Defaults,
1427 // siehe auch <svx/boxitem.hxx>
1428 #define DEF_LINE_WIDTH_0 1
1429 #define DEF_LINE_WIDTH_1 20
1430 #define DEF_LINE_WIDTH_2 50
1431 #define DEF_LINE_WIDTH_3 80
1432 #define DEF_LINE_WIDTH_4 100
1433 #define DEF_LINE_WIDTH_5 10
1435 #define DEF_MAX_LINE_WIDHT DEF_LINE_WIDTH_4
1436 #define DEF_MAX_LINE_DIST DEF_LINE_WIDTH_2
1438 #define DEF_DOUBLE_LINE0_OUT DEF_LINE_WIDTH_0
1439 #define DEF_DOUBLE_LINE0_IN DEF_LINE_WIDTH_0
1440 #define DEF_DOUBLE_LINE0_DIST DEF_LINE_WIDTH_1
1442 #define DEF_DOUBLE_LINE1_OUT DEF_LINE_WIDTH_1
1443 #define DEF_DOUBLE_LINE1_IN DEF_LINE_WIDTH_1
1444 #define DEF_DOUBLE_LINE1_DIST DEF_LINE_WIDTH_1
1446 #define DEF_DOUBLE_LINE2_OUT DEF_LINE_WIDTH_2
1447 #define DEF_DOUBLE_LINE2_IN DEF_LINE_WIDTH_2
1448 #define DEF_DOUBLE_LINE2_DIST DEF_LINE_WIDTH_2
1450 #define DEF_DOUBLE_LINE3_OUT DEF_LINE_WIDTH_2
1451 #define DEF_DOUBLE_LINE3_IN DEF_LINE_WIDTH_1
1452 #define DEF_DOUBLE_LINE3_DIST DEF_LINE_WIDTH_2
1454 #define DEF_DOUBLE_LINE4_OUT DEF_LINE_WIDTH_1
1455 #define DEF_DOUBLE_LINE4_IN DEF_LINE_WIDTH_2
1456 #define DEF_DOUBLE_LINE4_DIST DEF_LINE_WIDTH_1
1458 #define DEF_DOUBLE_LINE5_OUT DEF_LINE_WIDTH_3
1459 #define DEF_DOUBLE_LINE5_IN DEF_LINE_WIDTH_2
1460 #define DEF_DOUBLE_LINE5_DIST DEF_LINE_WIDTH_2
1462 #define DEF_DOUBLE_LINE6_OUT DEF_LINE_WIDTH_2
1463 #define DEF_DOUBLE_LINE6_IN DEF_LINE_WIDTH_3
1464 #define DEF_DOUBLE_LINE6_DIST DEF_LINE_WIDTH_2
1466 #define DEF_DOUBLE_LINE7_OUT DEF_LINE_WIDTH_0
1467 #define DEF_DOUBLE_LINE7_IN DEF_LINE_WIDTH_0
1468 #define DEF_DOUBLE_LINE7_DIST DEF_LINE_WIDTH_2
1470 #define DEF_DOUBLE_LINE8_OUT DEF_LINE_WIDTH_1
1471 #define DEF_DOUBLE_LINE8_IN DEF_LINE_WIDTH_0
1472 #define DEF_DOUBLE_LINE8_DIST DEF_LINE_WIDTH_2
1474 #define DEF_DOUBLE_LINE9_OUT DEF_LINE_WIDTH_2
1475 #define DEF_DOUBLE_LINE9_IN DEF_LINE_WIDTH_0
1476 #define DEF_DOUBLE_LINE9_DIST DEF_LINE_WIDTH_2
1478 #define DEF_DOUBLE_LINE10_OUT DEF_LINE_WIDTH_3
1479 #define DEF_DOUBLE_LINE10_IN DEF_LINE_WIDTH_0
1480 #define DEF_DOUBLE_LINE10_DIST DEF_LINE_WIDTH_2
1482 // Deklarationen gemaess BOXITEM.HXX
1483 static const WW8_BordersSO aLineTabVer8
[] =
1485 /* 0*/ { DEF_LINE_WIDTH_0
, 0, 0 },
1486 /* 1*/ { DEF_LINE_WIDTH_1
, 0, 0 },
1487 /* 2*/ { DEF_LINE_WIDTH_2
, 0, 0 },
1488 /* 3*/ { DEF_LINE_WIDTH_3
, 0, 0 },
1489 /* 4*/ { DEF_LINE_WIDTH_4
, 0, 0 },
1490 /* 5*/ { DEF_LINE_WIDTH_5
, 0, 0 },
1491 /* 6*/ { DEF_DOUBLE_LINE0_OUT
, DEF_DOUBLE_LINE0_IN
, DEF_DOUBLE_LINE0_DIST
},
1492 /* 7*/ { DEF_DOUBLE_LINE1_OUT
, DEF_DOUBLE_LINE1_IN
, DEF_DOUBLE_LINE1_DIST
},
1493 /* 8*/ { DEF_DOUBLE_LINE2_OUT
, DEF_DOUBLE_LINE2_IN
, DEF_DOUBLE_LINE2_DIST
},
1494 /* 9*/ { DEF_DOUBLE_LINE3_OUT
, DEF_DOUBLE_LINE3_IN
, DEF_DOUBLE_LINE3_DIST
},
1495 /*10*/ { DEF_DOUBLE_LINE4_OUT
, DEF_DOUBLE_LINE4_IN
, DEF_DOUBLE_LINE4_DIST
},
1496 /*11*/ { DEF_DOUBLE_LINE5_OUT
, DEF_DOUBLE_LINE5_IN
, DEF_DOUBLE_LINE5_DIST
},
1497 /*12*/ { DEF_DOUBLE_LINE6_OUT
, DEF_DOUBLE_LINE6_IN
, DEF_DOUBLE_LINE6_DIST
},
1498 /*13*/ { DEF_DOUBLE_LINE7_OUT
, DEF_DOUBLE_LINE7_IN
, DEF_DOUBLE_LINE7_DIST
},
1499 /*14*/ { DEF_DOUBLE_LINE8_OUT
, DEF_DOUBLE_LINE8_IN
, DEF_DOUBLE_LINE8_DIST
},
1500 /*15*/ { DEF_DOUBLE_LINE9_OUT
, DEF_DOUBLE_LINE9_IN
, DEF_DOUBLE_LINE9_DIST
},
1501 /*16*/ { DEF_DOUBLE_LINE10_OUT
,DEF_DOUBLE_LINE10_IN
,DEF_DOUBLE_LINE10_DIST
}
1503 size_t nPos
= static_cast<size_t>(eCode
);
1504 ASSERT(nPos
< sizeof(aLineTabVer8
), "Impossible");
1505 if (nPos
>= sizeof(aLineTabVer8
))
1507 return aLineTabVer8
[eCode
];
1510 INT32
SwMSDffManager::GetEscherLineMatch(MSO_LineStyle eStyle
,
1511 MSO_SPT eShapeType
, INT32
&rThick
)
1513 INT32 nOutsideThick
= 0;
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!
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.
1527 case mso_lineTriple
:
1528 case mso_lineSimple
:
1529 nOutsideThick
= eShapeType
!= mso_sptTextBox
? rThick
: rThick
/2;
1531 case mso_lineDouble
:
1532 if (eShapeType
== mso_sptTextBox
)
1534 nOutsideThick
= rThick
/6;
1535 rThick
= rThick
*2/3;
1538 nOutsideThick
= rThick
*2/3;
1540 case mso_lineThickThin
:
1541 if (eShapeType
== mso_sptTextBox
)
1543 nOutsideThick
= rThick
*3/10;
1544 rThick
= rThick
*4/5;
1547 nOutsideThick
= rThick
*4/5;
1549 case mso_lineThinThick
:
1551 if (eShapeType
== mso_sptTextBox
)
1553 nOutsideThick
= rThick
/10;
1554 rThick
= rThick
*3/5;
1557 nOutsideThick
= rThick
*3/5;
1563 return nOutsideThick
;
1566 //Returns the thickness of the line outside the frame, the logic of
1567 //words positioning of borders around floating objects is that of a
1569 INT32
SwWW8ImplReader::MatchSdrBoxIntoFlyBoxItem(const Color
& rLineColor
,
1570 MSO_LineStyle eLineStyle
, MSO_SPT eShapeType
, INT32
&rLineThick
,
1573 INT32 nOutsideThick
= 0;
1575 return nOutsideThick
;
1577 WW8_BordersSO::eBorderCode nIdx
= WW8_BordersSO::none
;
1579 INT32 nLineThick
=rLineThick
;
1580 nOutsideThick
= SwMSDffManager::GetEscherLineMatch(eLineStyle
,
1581 eShapeType
, rLineThick
);
1584 Beachte: im Gegensatz zu den Winword-ueblichen Tabellen- und
1585 Rahmen-Randbreiten-Angaben, bei denen jeweils aus der Staerke *einer*
1586 Linie die Gesamt-Randbreite zu errechnen ist, liegen die aus dem ESCHER
1587 stammenden Daten bereits als Gesamt-Breite [twips] vor!
1589 Der Winword default ist 15 tw. Wir nehmen hierfuer unsere 20 tw Linie. (
1590 0.75 pt uns 1.0 pt sehen sich auf dem Ausdruck naemlich aehnlicher als
1591 etwas 0.75 pt und unsere 0.05 pt Haarlinie. ) Die Haarlinie setzen wir nur
1592 bei Winword-Staerken bis zu maximal 0.5 pt ein.
1594 switch( +eLineStyle
)
1596 // zuerst die Einzel-Linien
1597 case mso_lineSimple
:
1598 if (nLineThick
< 10)
1599 nIdx
= WW8_BordersSO::single0
;// 1 Twip bei uns
1600 else if (nLineThick
< 20)
1601 nIdx
= WW8_BordersSO::single5
;// 10 Twips bei uns
1602 else if (nLineThick
< 50)
1603 nIdx
= WW8_BordersSO::single1
;// 20 Twips
1604 else if (nLineThick
< 80)
1605 nIdx
= WW8_BordersSO::single2
;// 50
1606 else if (nLineThick
< 100)
1607 nIdx
= WW8_BordersSO::single3
;// 80
1608 else if (nLineThick
<150)
1609 nIdx
= WW8_BordersSO::single4
;// 100
1610 // Pfusch: fuer die ganz dicken Linien muessen wir doppelte Linien
1611 // malen, weil unsere Einfach-Linie nicht dicker als 5 Punkt wird
1612 else if (nLineThick
<180)
1613 nIdx
= WW8_BordersSO::double2
;// 150
1615 nIdx
= WW8_BordersSO::double5
;// 180
1617 // dann die Doppel-Linien, fuer die wir feine Entsprechungen haben :-)))
1618 case mso_lineDouble
:
1619 if (nLineThick
< 60)
1620 nIdx
= WW8_BordersSO::double0
;// 22 Twips bei uns
1621 else if (nLineThick
< 135)
1622 nIdx
= WW8_BordersSO::double7
;// some more space
1623 else if (nLineThick
< 180)
1624 nIdx
= WW8_BordersSO::double1
;// 60
1626 nIdx
= WW8_BordersSO::double2
;// 150
1628 case mso_lineThickThin
:
1629 if (nLineThick
< 87)
1630 nIdx
= WW8_BordersSO::double8
;// 71 Twips bei uns
1631 else if (nLineThick
< 117)
1632 nIdx
= WW8_BordersSO::double9
;// 101
1633 else if (nLineThick
< 166)
1634 nIdx
= WW8_BordersSO::double10
;// 131
1636 nIdx
= WW8_BordersSO::double5
;// 180
1638 case mso_lineThinThick
:
1639 if (nLineThick
< 137)
1640 nIdx
= WW8_BordersSO::double4
;// 90 Twips bei uns
1642 nIdx
= WW8_BordersSO::double6
;// 180
1644 // zu guter Letzt die Dreifach-Linien, an deren Stelle wir eine
1645 // Doppel-Linie setzen
1646 case mso_lineTriple
:
1647 if (nLineThick
< 46)
1648 nIdx
= WW8_BordersSO::double0
;// 22 Twips bei uns
1649 else if (nLineThick
< 106)
1650 nIdx
= WW8_BordersSO::double1
;// 60
1651 else if (nLineThick
< 166)
1652 nIdx
= WW8_BordersSO::double2
;// 150
1654 nIdx
= WW8_BordersSO::double5
;// 180
1656 // no line style is set
1657 case (MSO_LineStyle
)USHRT_MAX
:
1659 // erroneously not implemented line style is set
1661 ASSERT(!this, "eLineStyle is not (yet) implemented!");
1665 if (WW8_BordersSO::none
!= nIdx
)
1667 SvxBorderLine aLine
;
1668 aLine
.SetColor( rLineColor
);
1670 const WW8_BordersSO
& rBorders
= WW8_BordersSO::Get0x01LineMatch(nIdx
);
1672 aLine
.SetOutWidth(rBorders
.mnOut
);
1673 aLine
.SetInWidth (rBorders
.mnIn
);
1674 aLine
.SetDistance(rBorders
.mnDist
);
1676 for(USHORT nLine
= 0; nLine
< 4; ++nLine
)
1677 rBox
.SetLine(new SvxBorderLine( aLine
), nLine
);
1680 return nOutsideThick
;
1683 #define WW8ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue()
1685 void SwWW8ImplReader::MatchSdrItemsIntoFlySet( SdrObject
* pSdrObj
,
1686 SfxItemSet
& rFlySet
, MSO_LineStyle eLineStyle
, MSO_SPT eShapeType
,
1687 Rectangle
& rInnerDist
)
1690 am Rahmen zu setzende Frame-Attribute
1691 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1692 SwFmtFrmSize falls noch nicht gesetzt, hier setzen
1693 SvxLRSpaceItem hier setzen
1694 SvxULSpaceItem hier setzen
1695 SvxOpaqueItem (Derzeit bei Rahmen nicht moeglich! khz 10.2.1999)
1696 SwFmtSurround bereits gesetzt
1697 SwFmtVertOrient bereits gesetzt
1698 SwFmtHoriOrient bereits gesetzt
1699 SwFmtAnchor bereits gesetzt
1700 SvxBoxItem hier setzen
1701 SvxBrushItem hier setzen
1702 SvxShadowItem hier setzen
1705 // 1. GrafikObjekt des Docs?
1708 const SfxItemSet
& rOldSet
= pSdrObj
->GetMergedItemSet();
1710 // einige Items koennen direkt so uebernommen werden
1711 const USHORT nDirectMatch
= 2;
1712 static RES_FRMATR __READONLY_DATA aDirectMatch
[ nDirectMatch
] =
1714 RES_LR_SPACE
, // Aussenabstand links/rechts: SvxLRSpaceItem
1715 RES_UL_SPACE
// Aussenabstand Oben/unten: SvxULSpaceItem
1717 const SfxPoolItem
* pPoolItem
;
1718 for(USHORT nItem
= 0; nItem
< nDirectMatch
; ++nItem
)
1719 if( SFX_ITEM_SET
== rOldSet
.GetItemState(
1720 static_cast< USHORT
>(aDirectMatch
[ nItem
]), false, &pPoolItem
) )
1722 rFlySet
.Put( *pPoolItem
);
1726 // jetzt die Umrandung berechnen und die Box bauen: Das Mass wird fuer die
1727 // Rahmen-GROESSE benoetigt!
1728 SvxBoxItem
aBox(sw::util::ItemGet
<SvxBoxItem
>(rFlySet
, RES_BOX
));
1729 // dashed oder solid wird zu solid
1730 INT32 nLineThick
= 0, nOutside
=0;
1732 // check if LineStyle is *really* set!
1733 const SfxPoolItem
* pItem
;
1735 SfxItemState eState
= rOldSet
.GetItemState(XATTR_LINESTYLE
,true,&pItem
);
1736 if( eState
== SFX_ITEM_SET
)
1738 // Now, that we know there is a line style we will make use the
1739 // parameter given to us when calling the method... :-)
1740 const Color aLineColor
= static_cast< XLineColorItem
const & >(
1741 rOldSet
.Get(XATTR_LINECOLOR
)).GetColorValue();
1742 nLineThick
= WW8ITEMVALUE(rOldSet
, XATTR_LINEWIDTH
, XLineWidthItem
);
1745 nLineThick
= 15; // WW-default: 0.75 pt
1747 nOutside
= MatchSdrBoxIntoFlyBoxItem(aLineColor
, eLineStyle
,
1748 eShapeType
, nLineThick
, aBox
);
1751 rInnerDist
.Left()+=nLineThick
;
1752 rInnerDist
.Top()+=nLineThick
;
1753 rInnerDist
.Right()+=nLineThick
;
1754 rInnerDist
.Bottom()+=nLineThick
;
1756 const SvxBorderLine
*pLine
;
1757 if (0 != (pLine
= aBox
.GetLine(BOX_LINE_LEFT
)))
1759 rInnerDist
.Left() -= (pLine
->GetOutWidth() + pLine
->GetInWidth() +
1760 pLine
->GetDistance());
1763 if (0 != (pLine
= aBox
.GetLine(BOX_LINE_TOP
)))
1765 rInnerDist
.Top() -= (pLine
->GetOutWidth() + pLine
->GetInWidth() +
1766 pLine
->GetDistance());
1769 if (0 != (pLine
= aBox
.GetLine(BOX_LINE_RIGHT
)))
1771 rInnerDist
.Right() -= (pLine
->GetOutWidth() + pLine
->GetInWidth() +
1772 pLine
->GetDistance());
1775 if (0 != (pLine
= aBox
.GetLine(BOX_LINE_BOTTOM
)))
1777 rInnerDist
.Bottom() -= (pLine
->GetOutWidth() + pLine
->GetInWidth() +
1778 pLine
->GetDistance());
1781 // set distances from box's border to text contained within the box
1782 if( 0 < rInnerDist
.Left() )
1783 aBox
.SetDistance( (USHORT
)rInnerDist
.Left(), BOX_LINE_LEFT
);
1784 if( 0 < rInnerDist
.Top() )
1785 aBox
.SetDistance( (USHORT
)rInnerDist
.Top(), BOX_LINE_TOP
);
1786 if( 0 < rInnerDist
.Right() )
1787 aBox
.SetDistance( (USHORT
)rInnerDist
.Right(), BOX_LINE_RIGHT
);
1788 if( 0 < rInnerDist
.Bottom() )
1789 aBox
.SetDistance( (USHORT
)rInnerDist
.Bottom(), BOX_LINE_BOTTOM
);
1791 bool bFixSize
= !(WW8ITEMVALUE(rOldSet
, SDRATTR_TEXT_AUTOGROWHEIGHT
,
1792 SdrTextAutoGrowHeightItem
));
1794 // Size: SwFmtFrmSize
1795 if( SFX_ITEM_SET
!= rFlySet
.GetItemState(RES_FRM_SIZE
, false) )
1797 const Rectangle
& rSnapRect
= pSdrObj
->GetSnapRect();
1798 // if necessary adapt width and position of the framework: The
1799 // recorded interior is to remain equally large despite thick edges.
1800 rFlySet
.Put( SwFmtFrmSize(bFixSize
? ATT_FIX_SIZE
: ATT_VAR_SIZE
,
1801 rSnapRect
.GetWidth() + 2*nOutside
,
1802 rSnapRect
.GetHeight() + 2*nOutside
) );
1804 else //If a size is set, adjust it to consider border thickness
1806 SwFmtFrmSize aSize
= (const SwFmtFrmSize
&)(rFlySet
.Get(RES_FRM_SIZE
));
1808 SwFmtFrmSize aNewSize
= SwFmtFrmSize(bFixSize
? ATT_FIX_SIZE
: ATT_VAR_SIZE
,
1809 aSize
.GetWidth() + 2*nOutside
,
1810 aSize
.GetHeight() + 2*nOutside
);
1811 aNewSize
.SetWidthSizeType(aSize
.GetWidthSizeType());
1812 rFlySet
.Put( aNewSize
);
1815 //Sadly word puts escher borders outside the graphic, but orients the
1816 //graphic in relation to the top left inside the border. We don't
1819 SwFmtHoriOrient aHori
= (const SwFmtHoriOrient
&)(rFlySet
.Get(
1821 aHori
.SetPos(MakeSafePositioningValue(aHori
.GetPos()-nOutside
));
1824 SwFmtVertOrient aVert
= (const SwFmtVertOrient
&)(rFlySet
.Get(
1826 aVert
.SetPos(aVert
.GetPos()-nOutside
);
1830 // jetzt die Umrandung setzen
1831 rFlySet
.Put( aBox
);
1833 // Schattenwurf der Box: SvxShadowItem
1834 if( WW8ITEMVALUE(rOldSet
, SDRATTR_SHADOW
, SdrShadowItem
) )
1836 SvxShadowItem
aShadow( RES_SHADOW
);
1838 const Color aShdColor
= static_cast< SdrShadowColorItem
const & >(
1839 rOldSet
.Get(SDRATTR_SHADOWCOLOR
)).GetColorValue();
1840 const INT32 nShdDistX
= WW8ITEMVALUE(rOldSet
, SDRATTR_SHADOWXDIST
,
1841 SdrShadowXDistItem
);
1842 const INT32 nShdDistY
= WW8ITEMVALUE(rOldSet
, SDRATTR_SHADOWYDIST
,
1843 SdrShadowYDistItem
);
1844 //const USHORT nShdTrans= WW8ITEMVALUE(rOldSet,
1845 // SDRATTR_SHADOWTRANSPARENCE, SdrShadowTransparenceItem);
1847 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1849 // SfxVoidItem( SDRATTR_SHADOW3D )
1850 // SfxVoidItem( SDRATTR_SHADOWPERSP )
1852 aShadow
.SetColor( Color( aShdColor
) );
1854 aShadow
.SetWidth(writer_cast
<USHORT
>((Abs( nShdDistX
) +
1855 Abs( nShdDistY
)) / 2 ));
1857 SvxShadowLocation eShdPosi
;
1858 if( 0 <= nShdDistX
)
1860 if( 0 <= nShdDistY
)
1861 eShdPosi
= SVX_SHADOW_BOTTOMRIGHT
;
1863 eShdPosi
= SVX_SHADOW_TOPRIGHT
;
1867 if( 0 <= nShdDistY
)
1868 eShdPosi
= SVX_SHADOW_BOTTOMLEFT
;
1870 eShdPosi
= SVX_SHADOW_TOPLEFT
;
1872 aShadow
.SetLocation( eShdPosi
);
1874 rFlySet
.Put( aShadow
);
1876 Color
Temp(COL_WHITE
);
1877 SvxBrushItem
aBrushItem(Temp
, RES_BACKGROUND
);
1878 bool bBrushItemOk
= false;
1879 sal_uInt8 nTrans
= 0;
1881 //Seperate transparency
1882 eState
= rOldSet
.GetItemState(XATTR_FILLTRANSPARENCE
, true, &pItem
);
1883 if (eState
== SFX_ITEM_SET
)
1885 sal_uInt16 nRes
= WW8ITEMVALUE(rOldSet
, XATTR_FILLTRANSPARENCE
,
1886 XFillTransparenceItem
);
1887 nTrans
= sal_uInt8((nRes
* 0xFE) / 100);
1888 aBrushItem
.GetColor().SetTransparency(nTrans
);
1889 bBrushItemOk
= true;
1892 // Hintergrund: SvxBrushItem
1893 eState
= rOldSet
.GetItemState(XATTR_FILLSTYLE
, true, &pItem
);
1894 if (eState
== SFX_ITEM_SET
)
1896 const XFillStyle eFill
= ((const XFillStyleItem
*)pItem
)->GetValue();
1901 //Writer graphics don't have it yet
1902 if (eShapeType
!= mso_sptPictureFrame
)
1904 aBrushItem
.GetColor().SetTransparency(0xFE);
1905 bBrushItemOk
= true;
1910 const Color aColor
= static_cast< XFillColorItem
const & >(
1911 rOldSet
.Get(XATTR_FILLCOLOR
)).GetColorValue();
1912 aBrushItem
.SetColor(aColor
);
1914 if (bBrushItemOk
) //has trans
1915 aBrushItem
.GetColor().SetTransparency(nTrans
);
1917 bBrushItemOk
= true;
1920 case XFILL_GRADIENT
:
1926 const Graphic
aGraphic(
1927 static_cast< XFillBitmapItem
const & >(
1928 rOldSet
.Get(XATTR_FILLBITMAP
)).
1929 GetBitmapValue().GetBitmap());
1930 bool bTile
= WW8ITEMVALUE(rOldSet
, XATTR_FILLBMP_TILE
,
1931 SfxBoolItem
) ? true: false;
1932 GraphicObject
aGrfObj(aGraphic
);
1934 aBrushItem
.SetGraphicObject(aGrfObj
);
1936 if (bBrushItemOk
) //has trans
1938 GraphicObject
*pGraphicObject
=
1939 const_cast<GraphicObject
*>
1940 (aBrushItem
.GetGraphicObject());
1941 GraphicAttr
aAttr(pGraphicObject
->GetAttr());
1942 aAttr
.SetTransparency(nTrans
);
1943 pGraphicObject
->SetAttr(aAttr
);
1946 aBrushItem
.SetGraphicPos(bTile
? GPOS_TILED
: GPOS_AREA
);
1948 bBrushItemOk
= true;
1955 rFlySet
.Put(aBrushItem
, RES_BACKGROUND
);
1958 void SwWW8ImplReader::AdjustLRWrapForWordMargins(
1959 const SvxMSDffImportRec
&rRecord
, SvxLRSpaceItem
&rLR
)
1961 // Left adjustments - if horizontally aligned to left of
1962 // margin or column then remove the left wrapping
1963 if (rRecord
.nXAlign
== 1)
1965 if ((rRecord
.nXRelTo
== 0) || (rRecord
.nXRelTo
== 2))
1966 rLR
.SetLeft((USHORT
)0);
1969 // Right adjustments - if horizontally aligned to right of
1970 // margin or column then remove the right wrapping
1971 if (rRecord
.nXAlign
== 3)
1973 if ((rRecord
.nXRelTo
== 0) || (rRecord
.nXRelTo
== 2))
1974 rLR
.SetRight((USHORT
)0);
1977 //Inside margin, remove left wrapping
1978 if ((rRecord
.nXAlign
== 4) && (rRecord
.nXRelTo
== 0))
1980 rLR
.SetLeft((USHORT
)0);
1983 //Outside margin, remove left wrapping
1984 if ((rRecord
.nXAlign
== 5) && (rRecord
.nXRelTo
== 0))
1986 rLR
.SetRight((USHORT
)0);
1991 void SwWW8ImplReader::AdjustULWrapForWordMargins(
1992 const SvxMSDffImportRec
&rRecord
, SvxULSpaceItem
&rUL
)
1994 // Top adjustment - remove upper wrapping if aligned to page
1995 // printable area or to page
1996 if (rRecord
.nYAlign
== 1)
1998 if ((rRecord
.nYRelTo
== 0) || (rRecord
.nYRelTo
== 1))
1999 rUL
.SetUpper((USHORT
)0);
2002 // Bottom adjustment - remove bottom wrapping if aligned to page or
2003 // printable area or to page
2004 if (rRecord
.nYAlign
== 3)
2006 if ((rRecord
.nYRelTo
== 0) || (rRecord
.nYRelTo
== 1))
2007 rUL
.SetLower((USHORT
)0);
2010 //Remove top margin if aligned vertically inside margin
2011 if ((rRecord
.nYAlign
== 4) && (rRecord
.nYRelTo
== 0))
2012 rUL
.SetUpper((USHORT
)0);
2015 // Something like this needs to be done once inside and outside are
2017 if (rRecord.nYAlign == 4)
2019 if (rRecord.nYRelTo == 0)
2020 rUL.SetUpper((USHORT)0);
2025 void SwWW8ImplReader::MapWrapIntoFlyFmt(SvxMSDffImportRec
* pRecord
,
2028 if (!pRecord
|| !pFlyFmt
)
2031 if (pRecord
->nDxWrapDistLeft
|| pRecord
->nDxWrapDistRight
)
2033 SvxLRSpaceItem
aLR(writer_cast
<USHORT
>(pRecord
->nDxWrapDistLeft
),
2034 writer_cast
<USHORT
>(pRecord
->nDxWrapDistRight
), 0, 0, RES_LR_SPACE
);
2035 AdjustLRWrapForWordMargins(*pRecord
, aLR
);
2036 pFlyFmt
->SetFmtAttr(aLR
);
2038 if (pRecord
->nDyWrapDistTop
|| pRecord
->nDyWrapDistBottom
)
2040 SvxULSpaceItem
aUL(writer_cast
<USHORT
>(pRecord
->nDyWrapDistTop
),
2041 writer_cast
<USHORT
>(pRecord
->nDyWrapDistBottom
), RES_UL_SPACE
);
2042 AdjustULWrapForWordMargins(*pRecord
, aUL
);
2043 pFlyFmt
->SetFmtAttr(aUL
);
2046 //If we are contoured and have a custom polygon...
2047 if (pRecord
->pWrapPolygon
&& pFlyFmt
->GetSurround().IsContour())
2049 if (SwNoTxtNode
*pNd
= GetNoTxtNodeFromSwFrmFmt(*pFlyFmt
))
2053 Gather round children and hear of a tale that will raise the
2054 hairs on the back of your neck this dark halloween night.
2056 There is a polygon in word that describes the wraping around
2059 Here are some sample values for the simplest case of a square
2060 around some solid coloured graphics
2062 X Y Pixel size of graphic
2063 TopLeft -54 21600 400x400
2064 Bottom Right 0 21546
2066 TopLeft -108 21600 200x200
2067 Bottom Right 0 21492
2069 TopLeft -216 21600 100x100
2070 Bottom Right 0 21384
2072 TopLeft -432 21600 50x50
2073 Bottom Right 0 21168
2075 TopLeft -76 21600 283x212
2076 Bottom Right 0 21498
2078 So given that the size of the values remains pretty much the
2079 same despite the size of the graphic, we can tell that the
2080 polygon is measured in units that are independant of the
2081 graphic. But why does the left corner move a different value
2082 to the left each time, and why does the bottom move upwards
2083 each time, when the right and top remain at the same value ?
2085 I have no idea, but clearly once we calculate the values out
2086 we see that the left margin is always a fixed realworld
2087 distance from the true left and the polygon bottom is the same
2088 fixed value from the bottom. i.e. 15twips.
2090 So here we take our word provided polygon, shift it to the
2091 right by 15twips and rescale it widthwise to shrink the width
2092 a little to fit the now moved right margin back to where it
2093 was, and stretch the height a little to make the bottom move
2094 down the missing 15twips then we get a polygon that matches
2095 what I actually see in word
2098 PolyPolygon
aPoly(*pRecord
->pWrapPolygon
);
2099 const Size
&rSize
= pNd
->GetTwipSize();
2101 Move to the left by 15twips, and rescale to
2102 a) shrink right bound back to orig position
2103 b) stretch bottom bound to where I think it should have been
2106 Fraction
aMoveHack(ww::nWrap100Percent
, rSize
.Width());
2107 aMoveHack
*= Fraction(15, 1);
2108 long nMove(aMoveHack
);
2109 aPoly
.Move(nMove
, 0);
2111 Fraction
aHackX(ww::nWrap100Percent
, ww::nWrap100Percent
+ nMove
);
2112 Fraction
aHackY(ww::nWrap100Percent
, ww::nWrap100Percent
- nMove
);
2113 aPoly
.Scale(aHackX
, aHackY
);
2115 //Turn polygon back into units that match the graphic's
2116 const Size
&rOrigSize
= pNd
->GetGraphic().GetPrefSize();
2117 Fraction
aMapPolyX(rOrigSize
.Width(), ww::nWrap100Percent
);
2118 Fraction
aMapPolyY(rOrigSize
.Height(), ww::nWrap100Percent
);
2119 aPoly
.Scale(aMapPolyX
, aMapPolyY
);
2121 // --> OD 2005-05-19 #i47277# - contour is already in unit of the
2122 // graphic prefered unit. Thus, call method <SetContour(..)>
2123 pNd
->SetContour(&aPoly
);
2129 void SwWW8ImplReader::SetAttributesAtGrfNode( SvxMSDffImportRec
* pRecord
,
2130 SwFrmFmt
*pFlyFmt
, WW8_FSPA
*pF
)
2132 const SwNodeIndex
* pIdx
= pFlyFmt
->GetCntnt(false).GetCntntIdx();
2134 if( pIdx
&& 0 != (pGrfNd
= rDoc
.GetNodes()[pIdx
->GetIndex() + 1]->GetGrfNode() ))
2136 Size
aSz(pGrfNd
->GetTwipSize());
2137 // --> OD 2005-08-01 #124722# - use type <sal_uInt64> instead of <ULONG>
2138 // to get correct results in the following calculations.
2139 sal_uInt64 rHeight
= aSz
.Height();
2140 sal_uInt64 rWidth
= aSz
.Width();
2143 rWidth
= pF
->nXaRight
- pF
->nXaLeft
;
2144 else if( !rHeight
&& pF
)
2145 rHeight
= pF
->nYaBottom
- pF
->nYaTop
;
2147 if( pRecord
->nCropFromTop
|| pRecord
->nCropFromBottom
||
2148 pRecord
->nCropFromLeft
|| pRecord
->nCropFromRight
)
2150 SwCropGrf aCrop
; // Cropping is stored in 'fixed floats'
2151 // 16.16 (it est fraction times total
2152 if( pRecord
->nCropFromTop
) // image width or height resp.)
2153 aCrop
.SetTop( static_cast< sal_Int32
>(
2154 ( ( (pRecord
->nCropFromTop
>> 16 ) * rHeight
)
2155 + (((pRecord
->nCropFromTop
& 0xffff) * rHeight
) >> 16) )));
2156 if( pRecord
->nCropFromBottom
)
2157 aCrop
.SetBottom( static_cast< sal_Int32
>(
2158 ( ( (pRecord
->nCropFromBottom
>> 16 ) * rHeight
)
2159 + (((pRecord
->nCropFromBottom
& 0xffff) * rHeight
) >> 16) )));
2160 if( pRecord
->nCropFromLeft
)
2161 aCrop
.SetLeft( static_cast< sal_Int32
>(
2162 ( ( (pRecord
->nCropFromLeft
>> 16 ) * rWidth
)
2163 + (((pRecord
->nCropFromLeft
& 0xffff) * rWidth
) >> 16) )));
2164 if( pRecord
->nCropFromRight
)
2165 aCrop
.SetRight( static_cast< sal_Int32
>(
2166 ( ( (pRecord
->nCropFromRight
>> 16 ) * rWidth
)
2167 + (((pRecord
->nCropFromRight
& 0xffff) * rWidth
) >> 16) )));
2169 pGrfNd
->SetAttr( aCrop
);
2172 if (pRecord
&& pRecord
->pObj
)
2174 const SfxItemSet
& rOldSet
= pRecord
->pObj
->GetMergedItemSet();
2176 if (WW8ITEMVALUE(rOldSet
, SDRATTR_GRAFCONTRAST
,
2177 SdrGrafContrastItem
))
2179 SwContrastGrf
aContrast(
2180 WW8ITEMVALUE(rOldSet
,
2181 SDRATTR_GRAFCONTRAST
, SdrGrafContrastItem
));
2182 pGrfNd
->SetAttr( aContrast
);
2186 if (WW8ITEMVALUE(rOldSet
, SDRATTR_GRAFLUMINANCE
,
2187 SdrGrafLuminanceItem
))
2189 SwLuminanceGrf
aLuminance(WW8ITEMVALUE(rOldSet
,
2190 SDRATTR_GRAFLUMINANCE
, SdrGrafLuminanceItem
));
2191 pGrfNd
->SetAttr( aLuminance
);
2194 if (WW8ITEMVALUE(rOldSet
, SDRATTR_GRAFGAMMA
, SdrGrafGamma100Item
))
2196 double fVal
= WW8ITEMVALUE(rOldSet
, SDRATTR_GRAFGAMMA
,
2197 SdrGrafGamma100Item
);
2198 pGrfNd
->SetAttr(SwGammaGrf(fVal
/100.));
2202 if (WW8ITEMVALUE(rOldSet
, SDRATTR_GRAFMODE
, SdrGrafModeItem
))
2204 SwDrawModeGrf
aDrawMode( static_cast< USHORT
>(WW8ITEMVALUE(rOldSet
,
2205 SDRATTR_GRAFMODE
, SdrGrafModeItem
)) );
2206 pGrfNd
->SetAttr( aDrawMode
);
2212 SdrObject
* SwWW8ImplReader::CreateContactObject(SwFrmFmt
* pFlyFmt
)
2216 //JP 11.1.2002: task 96329
2217 SdrObject
* pNewObject
= mbNewDoc
? 0 : pFlyFmt
->FindRealSdrObject();
2219 pNewObject
= pFlyFmt
->FindSdrObject();
2220 if (!pNewObject
&& pFlyFmt
->ISA(SwFlyFrmFmt
))
2222 SwFlyDrawContact
* pContactObject
2223 = new SwFlyDrawContact(static_cast<SwFlyFrmFmt
*>(pFlyFmt
),
2225 pNewObject
= pContactObject
->GetMaster();
2232 //#109311# Miserable miserable hack to fudge word's graphic layout in
2234 bool SwWW8ImplReader::MiserableRTLGraphicsHack(SwTwips
&rLeft
, SwTwips nWidth
,
2235 sal_Int16 eHoriOri
, sal_Int16 eHoriRel
)
2237 if (!IsRightToLeft())
2239 return RTLGraphicsHack(rLeft
, nWidth
, eHoriOri
, eHoriRel
,
2240 maSectionManager
.GetPageLeft(),
2241 maSectionManager
.GetPageRight(),
2242 maSectionManager
.GetPageWidth());
2245 RndStdIds
SwWW8ImplReader::ProcessEscherAlign(SvxMSDffImportRec
* pRecord
,
2246 WW8_FSPA
*pFSPA
, SfxItemSet
&rFlySet
, bool /*bOrgObjectWasReplace*/)
2248 ASSERT(pRecord
|| pFSPA
, "give me something! to work with for anchoring");
2249 if (!pRecord
&& !pFSPA
)
2252 SvxMSDffImportRec aRecordFromFSPA
;
2255 pRecord
= &aRecordFromFSPA
;
2256 pRecord
->nXRelTo
= pFSPA
->nbx
;
2257 pRecord
->nYRelTo
= pFSPA
->nby
;
2260 // nXAlign - abs. Position, Left, Centered, Right, Inside, Outside
2261 // nYAlign - abs. Position, Top, Centered, Bottom, Inside, Outside
2263 // nXRelTo - Page printable area, Page, Column, Character
2264 // nYRelTo - Page printable area, Page, Paragraph, Line
2266 const UINT32 nCntXAlign
= 6;
2267 const UINT32 nCntYAlign
= 6;
2269 const UINT32 nCntRelTo
= 4;
2271 UINT32 nXAlign
= nCntXAlign
> pRecord
->nXAlign
? pRecord
->nXAlign
: 1;
2272 UINT32 nYAlign
= nCntYAlign
> pRecord
->nYAlign
? pRecord
->nYAlign
: 1;
2277 #74188# #i15718# #i19008#
2278 Strangely in this case the FSPA value seems to be considered before
2279 the newer escher nXRelTo record.
2281 // --> OD 2005-08-04 #i52565# - correct condition checking:
2282 // first check, if <nXRelTo> and <nYRelTo> have default values. This
2283 // is a hint that these values aren't set by the escher import - see
2284 // method <SwMSDffManager::ProcessObj(..)>. Then, check if for each
2285 // values, if it differs from the one in the FSPA.
2286 if ( pRecord
->nXRelTo
== 2 && pRecord
->nYRelTo
== 2 )
2288 // if <nYRelTo> differs from <FSPA.nby> overwrite <nYRelTo>
2289 if ( pFSPA
->nby
!= pRecord
->nYRelTo
)
2291 pRecord
->nYRelTo
= pFSPA
->nby
;
2297 UINT32 nXRelTo
= nCntRelTo
> pRecord
->nXRelTo
? pRecord
->nXRelTo
: 1;
2298 UINT32 nYRelTo
= nCntRelTo
> pRecord
->nYRelTo
? pRecord
->nYRelTo
: 1;
2300 // --> OD 2005-03-03 #i43718#
2301 RndStdIds eAnchor
= IsInlineEscherHack() ? FLY_IN_CNTNT
: FLY_AUTO_CNTNT
;
2304 SwFmtAnchor
aAnchor( eAnchor
);
2305 aAnchor
.SetAnchor( pPaM
->GetPoint() );
2306 rFlySet
.Put( aAnchor
);
2310 // OD 14.10.2003 #i18732#
2311 //Given new layout where everything is changed to be anchored to
2312 //character the following 4 tables may need to be changed.
2314 // horizontal Adjustment
2315 static const sal_Int16 aHoriOriTab
[ nCntXAlign
] =
2317 text::HoriOrientation::NONE
, // From left position
2318 text::HoriOrientation::LEFT
, // left
2319 text::HoriOrientation::CENTER
, // centered
2320 text::HoriOrientation::RIGHT
, // right
2321 // --> OD 2004-12-06 #i36649#
2322 // - inside -> text::HoriOrientation::LEFT and outside -> text::HoriOrientation::RIGHT
2323 text::HoriOrientation::LEFT
, // inside
2324 text::HoriOrientation::RIGHT
// outside
2329 // generic vertical Adjustment
2330 static const sal_Int16 aVertOriTab
[ nCntYAlign
] =
2332 text::VertOrientation::NONE
, // From Top position
2333 text::VertOrientation::TOP
, // top
2334 text::VertOrientation::CENTER
, // centered
2335 text::VertOrientation::BOTTOM
, // bottom
2336 text::VertOrientation::LINE_TOP
, // inside (obscure)
2337 text::VertOrientation::LINE_BOTTOM
// outside (obscure)
2340 // CMC,OD 24.11.2003 #i22673# - to-line vertical alignment
2341 static const sal_Int16 aToLineVertOriTab
[ nCntYAlign
] =
2343 text::VertOrientation::NONE
, // below
2344 text::VertOrientation::LINE_BOTTOM
, // top
2345 text::VertOrientation::LINE_CENTER
, // centered
2346 text::VertOrientation::LINE_TOP
, // bottom
2347 text::VertOrientation::LINE_BOTTOM
, // inside (obscure)
2348 text::VertOrientation::LINE_TOP
// outside (obscure)
2351 // Adjustment is horizontally relative to...
2352 static const sal_Int16 aHoriRelOriTab
[nCntRelTo
] =
2354 text::RelOrientation::PAGE_PRINT_AREA
, // 0 is page textarea margin
2355 text::RelOrientation::PAGE_FRAME
, // 1 is page margin
2356 text::RelOrientation::FRAME
, // 2 is relative to column
2357 text::RelOrientation::CHAR
// 3 is relative to character
2360 // Adjustment is vertically relative to...
2361 // CMC, OD 24.11.2003 #i22673# - adjustment for new vertical alignment
2363 static const sal_Int16 aVertRelOriTab
[nCntRelTo
] =
2365 text::RelOrientation::PAGE_PRINT_AREA
, // 0 is page textarea margin
2366 text::RelOrientation::PAGE_FRAME
, // 1 is page margin
2367 text::RelOrientation::FRAME
, // 2 is relative to paragraph
2368 text::RelOrientation::TEXT_LINE
// 3 is relative to line
2371 sal_Int16 eHoriOri
= aHoriOriTab
[ nXAlign
];
2372 sal_Int16 eHoriRel
= aHoriRelOriTab
[ nXRelTo
];
2374 // --> OD 2004-12-06 #i36649# - adjustments for certain alignments
2375 if ( eHoriOri
== text::HoriOrientation::LEFT
&& eHoriRel
== text::RelOrientation::PAGE_FRAME
)
2377 // convert 'left to page' to 'from left -<width> to page text area'
2378 eHoriOri
= text::HoriOrientation::NONE
;
2379 eHoriRel
= text::RelOrientation::PAGE_PRINT_AREA
;
2380 const long nWidth
= pFSPA
->nXaRight
- pFSPA
->nXaLeft
;
2381 pFSPA
->nXaLeft
= -nWidth
;
2382 pFSPA
->nXaRight
= 0;
2384 else if ( eHoriOri
== text::HoriOrientation::RIGHT
&& eHoriRel
== text::RelOrientation::PAGE_FRAME
)
2386 // convert 'right to page' to 'from left 0 to right page border'
2387 eHoriOri
= text::HoriOrientation::NONE
;
2388 eHoriRel
= text::RelOrientation::PAGE_RIGHT
;
2389 const long nWidth
= pFSPA
->nXaRight
- pFSPA
->nXaLeft
;
2391 pFSPA
->nXaRight
= nWidth
;
2395 // --> OD 2005-02-07 #i24255# - position of floating screen objects in
2396 // R2L layout are given in L2R layout, thus convert them of all
2397 // floating screen objects, which are imported.
2399 //#109311# Miserable miserable hack.
2400 SwTwips nWidth
= (pFSPA
->nXaRight
- pFSPA
->nXaLeft
);
2401 SwTwips nLeft
= pFSPA
->nXaLeft
;
2402 if (MiserableRTLGraphicsHack(nLeft
, nWidth
, eHoriOri
,
2405 pFSPA
->nXaLeft
= nLeft
;
2406 pFSPA
->nXaRight
= pFSPA
->nXaLeft
+ nWidth
;
2411 // --> OD 2005-01-20 #118546# - if the object is anchored inside
2412 // a table cell, is horizontal aligned at frame|character and
2413 // has wrap through, but its attribute 'layout in table cell' isn't set,
2414 // convert its horizontal alignment to page text area.
2415 // --> OD 2008-04-10 #i84783# - use new method <IsObjectLayoutInTableCell()>
2417 ( eHoriRel
== text::RelOrientation::FRAME
|| eHoriRel
== text::RelOrientation::CHAR
) &&
2419 // pRecord->nLayoutInTableCell == 0x80000000 )
2420 !IsObjectLayoutInTableCell( pRecord
->nLayoutInTableCell
) )
2422 eHoriRel
= text::RelOrientation::PAGE_PRINT_AREA
;
2426 SwFmtHoriOrient
aHoriOri(MakeSafePositioningValue(pFSPA
->nXaLeft
),
2427 eHoriOri
, eHoriRel
);
2429 aHoriOri
.SetPosToggle(true);
2430 rFlySet
.Put( aHoriOri
);
2432 //Writer honours this wrap distance when aligned as "left" or "right",
2433 //Word doesn't. Writer doesn't honour it when its "from left".
2434 if (eHoriOri
== text::HoriOrientation::LEFT
)
2435 pRecord
->nDxWrapDistLeft
=0;
2436 else if (eHoriOri
== text::HoriOrientation::RIGHT
)
2437 pRecord
->nDxWrapDistRight
=0;
2440 // OD 14.10.2003 #i18732#
2441 eVertRel
= aVertRelOriTab
[ nYRelTo
];
2442 // CMC, OD 24.11.2003 #i22673# - fill <eVertOri> in dependence of <eVertRel>
2444 if ( eVertRel
== text::RelOrientation::TEXT_LINE
)
2446 eVertOri
= aToLineVertOriTab
[ nYAlign
];
2450 eVertOri
= aVertOriTab
[ nYAlign
];
2453 //Below line in word is a positive value, while in writer its
2455 long nYPos
= pFSPA
->nYaTop
;
2456 // CMC, OD 24.11.2003 #i22673#
2457 if ((eVertRel
== text::RelOrientation::TEXT_LINE
) && (eVertOri
== text::VertOrientation::NONE
))
2460 rFlySet
.Put(SwFmtVertOrient(MakeSafePositioningValue(nYPos
),
2461 eVertOri
, eVertRel
));
2464 (pFSPA
->nYaTop
< 0) && (eVertOri
== text::VertOrientation::NONE
) &&
2465 ((eAnchor
== FLY_AT_CNTNT
) || (eAnchor
== FLY_AUTO_CNTNT
))
2468 maTracer
.Log(sw::log::eNegativeVertPlacement
);
2475 // --> OD 2008-04-10 #i84783#
2476 bool SwWW8ImplReader::IsObjectLayoutInTableCell( const UINT32 nLayoutInTableCell
) const
2478 bool bIsObjectLayoutInTableCell
= false;
2482 const UINT16 nWWVersion
= pWwFib
->nProduct
& 0xE000;
2483 switch ( nWWVersion
)
2485 case 0x0000: // version 8 aka Microsoft Word 97
2487 bIsObjectLayoutInTableCell
= false;
2488 ASSERT( nLayoutInTableCell
== 0xFFFFFFFF,
2489 "no explicit object attribute layout in table cell excepted." );
2492 case 0x2000: // version 9 aka Microsoft Word 2000
2493 case 0x4000: // version 10 aka Microsoft Word 2002
2494 case 0x6000: // version 11 aka Microsoft Word 2003
2495 case 0x8000: // version 12 aka Microsoft Word 2007
2497 // --> OD 2009-01-13 #i98037#
2498 // adjustment of conditions needed after deeper analysis of
2499 // certain test cases.
2500 if ( nLayoutInTableCell
== 0xFFFFFFFF || // no explicit attribute value given
2501 nLayoutInTableCell
& 0x80008000 ||
2502 ( nLayoutInTableCell
& 0x02000000 &&
2503 !(nLayoutInTableCell
& 0x80000000 ) ) )
2506 bIsObjectLayoutInTableCell
= true;
2510 bIsObjectLayoutInTableCell
= false;
2517 "unknown version." );
2522 return bIsObjectLayoutInTableCell
;
2526 SwFrmFmt
* SwWW8ImplReader::Read_GrafLayer( long nGrafAnchorCp
)
2528 if( nIniFlags
& WW8FL_NO_GRAFLAYER
)
2531 ::SetProgressState(nProgress
, mpDocShell
); // Update
2533 nDrawCpO
= pWwFib
->GetBaseCp(pPlcxMan
->GetManType() == MAN_HDFT
? MAN_TXBX_HDFT
: MAN_TXBX
);
2537 WW8PLCFspecial
* pPF
= pPlcxMan
->GetFdoa();
2540 ASSERT( !this, "Where is the grapic (1) ?" );
2546 long nOldPos
= pStrm
->Tell();
2548 nDrawXOfs
= nDrawYOfs
= 0;
2549 ReadGrafLayer1( pPF
, nGrafAnchorCp
);
2551 pStrm
->Seek( nOldPos
);
2555 //Normal case of Word 8+ version stuff
2556 pPF
->SeekPos( nGrafAnchorCp
);
2560 if( !pPF
->Get( nStartFc
, pF0
) ){
2561 ASSERT( !this, "+Wo ist die Grafik (2) ?" );
2565 WW8_FSPA_SHADOW
* pFS
= (WW8_FSPA_SHADOW
*)pF0
;
2567 #ifdef __WW8_NEEDS_COPY
2570 WW8FSPAShadowToReal( pFS
, pF
);
2572 pF
= (WW8_FSPA
*)pFS
;
2573 #endif // defined __WW8_NEEDS_COPY
2576 ASSERT( !this, "+Wo ist die Grafik (3) ?" );
2580 if (!pMSDffManager
->GetModel())
2581 pMSDffManager
->SetModel(pDrawModel
, 1440);
2584 Rectangle
aRect(pF
->nXaLeft
, pF
->nYaTop
, pF
->nXaRight
, pF
->nYaBottom
);
2585 SvxMSDffImportData
aData( aRect
);
2589 The SdrOle2Obj will try and manage any ole objects it finds, causing all
2590 sorts of trouble later on
2592 SwDocShell
* pPersist
= rDoc
.GetDocShell();
2593 rDoc
.SetDocShell(0); //#i20540# Persist guard
2595 SdrObject
* pObject
= 0;
2596 bool bOk
= (pMSDffManager
->GetShape(pF
->nSpId
, pObject
, aData
) && pObject
);
2598 rDoc
.SetDocShell(pPersist
); //#i20540# Persist guard
2602 ASSERT( !this, "Where is the Shape ?" );
2607 SdrObject
* pOurNewObject
= 0;
2608 bool bReplaceable
= false;
2610 switch (SdrObjKind(pObject
->GetObjIdentifier()))
2613 bReplaceable
= true;
2617 bReplaceable
= true;
2624 // OD 14.10.2003 - keep wrapping of objects in page header/footer.
2626 //#108778# when in a header or footer word appears to treat all elements
2628 if (bIsHeader || bIsFooter)
2632 // Umfluss-Modus ermitteln
2633 SfxItemSet
aFlySet(rDoc
.GetAttrPool(), RES_FRMATR_BEGIN
, RES_FRMATR_END
-1);
2634 SwSurround eSurround
= SURROUND_PARALLEL
;
2635 bool bContour
= false;
2638 case 0: //0 like 2, but doesn't require absolute object
2639 case 2: //2 wrap around absolute object
2640 eSurround
= SURROUND_PARALLEL
;
2642 case 1: //1 no text next to shape
2643 eSurround
= SURROUND_NONE
;
2645 case 3: //3 wrap as if no object present
2646 eSurround
= SURROUND_THROUGHT
;
2648 case 4: //4 wrap tightly around object
2649 case 5: //5 wrap tightly, but allow holes
2650 eSurround
= SURROUND_PARALLEL
;
2655 // bei Modus 2 oder 4 auch den Zusatzparameter beruecksichtigen
2656 if ( (2 == pF
->nwr
) || (4 == pF
->nwr
) )
2662 eSurround
= SURROUND_PARALLEL
;
2664 //1 wrap only on left
2666 eSurround
= SURROUND_LEFT
;
2668 //2 wrap only on right
2670 eSurround
= SURROUND_RIGHT
;
2672 //3 wrap only on largest side
2674 eSurround
= SURROUND_IDEAL
;
2679 SwFmtSurround
aSur( eSurround
);
2680 aSur
.SetContour( bContour
);
2681 aSur
.SetOutside(true); // Winword kann nur Aussen-Konturen
2682 aFlySet
.Put( aSur
);
2684 // eingelesenes Objekt (kann eine ganze Gruppe sein) jetzt korrekt
2685 // positionieren usw.
2687 ASSERT(!((aData
.GetRecCount() != 1) && bReplaceable
),
2688 "Replaceable drawing with > 1 entries ?");
2690 if (aData
.GetRecCount() != 1)
2691 bReplaceable
= false;
2693 SvxMSDffImportRec
* pRecord
= 0;
2695 Get the record for top level object, so we can get the word anchoring
2696 and wrapping information for it.
2698 USHORT nRecCount
= aData
.GetRecCount();
2699 for (USHORT nTxbx
=0; nTxbx
< nRecCount
; ++nTxbx
)
2701 pRecord
= aData
.GetRecord( nTxbx
);
2702 if (pRecord
&& pRecord
->pObj
== pObject
)
2708 ASSERT(pRecord
, "how did that happen?");
2712 // --> OD 2008-04-10 #i84783#
2713 // //cmc: We're in a table, and the element has the magic Word XP bit set
2714 // //to enable layout inside a cell
2715 // // --> OD 2005-08-10 #124714# - undo change made for issue #i33442#
2716 // bool bLayoutInTableCell = ( nInTable &&
2717 // pRecord->nLayoutInTableCell & 0x00008000 );
2719 const bool bLayoutInTableCell
=
2720 nInTable
&& IsObjectLayoutInTableCell( pRecord
->nLayoutInTableCell
);
2723 // OD 14.10.2003 #i18732#
2724 // Switch on 'follow text flow',
2725 // if object is laid out inside table cell and
2726 // its wrapping isn't 'SURROUND_THROUGH'
2727 if (bLayoutInTableCell
&& eSurround
!= SURROUND_THROUGHT
)
2729 SwFmtFollowTextFlow
aFollowTextFlow( TRUE
);
2730 aFlySet
.Put( aFollowTextFlow
);
2735 //Some shapes are set to *hidden*, don't import those ones.
2736 if (pRecord
->bHidden
)
2739 // If we are to be "below text" then we are not to be opaque
2740 // #i14045# MM If we are in a header or footer then make the object transparent
2741 // Not exactly like word but close enough for now
2743 // --> OD 2005-03-07 #b6234902# - both flags <bBelowText> and <bDrawHell>
2744 // have to be set to move object into the background.
2745 // --> OD 2005-04-11 #i46794# - it reveals that value of flag <bBelowText>
2746 // can be neglected.
2747 const bool bMoveToBackgrd
= pRecord
->bDrawHell
||
2748 ( ( bIsHeader
|| bIsFooter
) && pF
->nwr
== 3 );
2749 if ( bMoveToBackgrd
)
2750 aFlySet
.Put(SvxOpaqueItem(RES_OPAQUE
,false));
2752 String aObjName
= pObject
->GetName();
2754 SwFrmFmt
* pRetFrmFmt
= 0;
2757 //Single graphics or ole objects
2758 pRetFrmFmt
= ImportReplaceableDrawables(pObject
, pOurNewObject
, pRecord
,
2763 //Drawing objects, (e.g. ovals or drawing groups)
2766 pF
->nbx
= WW8_FSPA::RelPageBorder
;
2767 pF
->nby
= WW8_FSPA::RelPageBorder
;
2770 RndStdIds eAnchor
= ProcessEscherAlign(pRecord
, pF
, aFlySet
,
2773 // Should we, and is it possible to make this into a writer textbox
2774 if ((!(nIniFlags1
& WW8FL_NO_FLY_FOR_TXBX
)) && pRecord
->bReplaceByFly
)
2776 pRetFrmFmt
= ConvertDrawTextToFly(pObject
, pOurNewObject
, pRecord
,
2777 eAnchor
, pF
, aFlySet
);
2784 sw::util::SetLayer
aSetLayer(rDoc
);
2785 if ( bMoveToBackgrd
)
2786 aSetLayer
.SendObjectToHell(*pObject
);
2788 aSetLayer
.SendObjectToHeaven(*pObject
);
2790 if (!IsInlineEscherHack())
2793 #97824# Need to make sure that the correct layer ordering is
2796 // --> OD 2004-12-13 #117915# - pass information, if object
2797 // is in page header|footer to method.
2798 pWWZOrder
->InsertEscherObject( pObject
, pF
->nSpId
,
2799 bIsHeader
|| bIsFooter
);
2804 pWWZOrder
->InsertTextLayerObject(pObject
);
2807 pRetFrmFmt
= rDoc
.Insert(*pPaM
, *pObject
, &aFlySet
, NULL
);
2809 ASSERT(pRetFrmFmt
->GetAnchor().GetAnchorId() ==
2810 eAnchor
, "Not the anchor type requested!");
2813 Insert text if necessary into textboxes contained in groups.
2815 if (aData
.HasRecords())
2817 USHORT nCount
= aData
.GetRecCount();
2818 for (USHORT nTxbx
=0; nTxbx
< nCount
; ++nTxbx
)
2820 pRecord
= aData
.GetRecord(nTxbx
);
2821 if (pRecord
&& pRecord
->pObj
&& pRecord
->aTextId
.nTxBxS
)
2822 { // #i52825# pRetFrmFmt can be NULL
2823 pRetFrmFmt
= MungeTextIntoDrawBox(pRecord
->pObj
,
2824 pRecord
, nGrafAnchorCp
, pRetFrmFmt
);
2831 // --> OD 2005-03-11 #i44344#, #i44681# - positioning attributes already set
2832 if ( pRetFrmFmt
/*#i52825# */ && pRetFrmFmt
->ISA(SwDrawFrmFmt
) )
2834 static_cast<SwDrawFrmFmt
*>(pRetFrmFmt
)->PosAttrSet();
2837 if (!IsInlineEscherHack())
2838 MapWrapIntoFlyFmt(pRecord
, pRetFrmFmt
);
2840 // Set frame name with object name
2841 if( aObjName
.Len() )
2842 pRetFrmFmt
->SetName( aObjName
);
2843 return AddAutoAnchor(pRetFrmFmt
);
2846 SwFrmFmt
*SwWW8ImplReader::AddAutoAnchor(SwFrmFmt
*pFmt
)
2848 if (pFmt
&& (pFmt
->GetAnchor().GetAnchorId() != FLY_IN_CNTNT
))
2850 sal_uInt16 nTextAreaWidth
= static_cast< sal_uInt16
>( maSectionManager
.GetPageWidth() -
2851 maSectionManager
.GetPageRight() - maSectionManager
.GetPageLeft());
2853 if (pFmt
->GetFrmSize().GetSize().Width() > nTextAreaWidth
)
2854 maTracer
.Log(sw::log::eTooWideAsChar
);
2858 * anchored to character at the current position will move along the
2859 * paragraph as text is added because we are at the insertion point.
2861 * Leave to later and set the correct location then.
2863 if ((pFmt
) && (pFmt
->GetAnchor().GetAnchorId() != FLY_IN_CNTNT
))
2864 pAnchorStck
->AddAnchor(*pPaM
->GetPoint(), pFmt
);
2868 SwFrmFmt
* SwWW8ImplReader::MungeTextIntoDrawBox(SdrObject
* pTrueObject
,
2869 SvxMSDffImportRec
*pRecord
, long nGrafAnchorCp
, SwFrmFmt
* pRetFrmFmt
)
2871 SdrTextObj
* pSdrTextObj
;
2873 // Pruefen, ob Gruppenobjekt (z.B. zwei Klammern) vorliegt
2874 if (SdrObjGroup
* pThisGroup
= PTR_CAST(SdrObjGroup
, pRecord
->pObj
))
2876 // Gruppenobjekte haben keinen Text. Fuege ein Textobjekt in die
2877 // Gruppe ein, um den Text zu halten.
2878 pSdrTextObj
= new SdrRectObj( OBJ_TEXT
, pThisGroup
->GetCurrentBoundRect());
2880 SfxItemSet
aSet(pDrawModel
->GetItemPool());
2881 aSet
.Put(XFillStyleItem(XFILL_NONE
));
2882 aSet
.Put(XLineStyleItem(XLINE_NONE
));
2883 aSet
.Put(SdrTextFitToSizeTypeItem( SDRTEXTFIT_NONE
));
2884 aSet
.Put(SdrTextAutoGrowHeightItem(false));
2885 aSet
.Put(SdrTextAutoGrowWidthItem(false));
2886 pSdrTextObj
->SetMergedItemSet(aSet
);
2888 long nAngle
= pRecord
->nTextRotationAngle
;
2891 double a
= nAngle
*nPi180
;
2892 pSdrTextObj
->NbcRotate(pSdrTextObj
->GetCurrentBoundRect().Center(), nAngle
,
2896 pSdrTextObj
->NbcSetLayer( pThisGroup
->GetLayer() );
2897 pThisGroup
->GetSubList()->NbcInsertObject(pSdrTextObj
);
2900 pSdrTextObj
= PTR_CAST(SdrTextObj
, pRecord
->pObj
);
2904 Size
aObjSize(pSdrTextObj
->GetSnapRect().GetWidth(),
2905 pSdrTextObj
->GetSnapRect().GetHeight());
2907 // Objekt ist Bestandteil einer Gruppe?
2908 SdrObject
* pGroupObject
= pSdrTextObj
->GetUpGroup();
2910 UINT32 nOrdNum
= pSdrTextObj
->GetOrdNum();
2911 bool bEraseThisObject
;
2912 InsertTxbxText( pSdrTextObj
, &aObjSize
, pRecord
->aTextId
.nTxBxS
,
2913 pRecord
->aTextId
.nSequence
, nGrafAnchorCp
, pRetFrmFmt
,
2914 (pSdrTextObj
!= pTrueObject
) || (0 != pGroupObject
),
2915 bEraseThisObject
, 0, 0, 0, 0, pRecord
);
2917 // wurde dieses Objekt ersetzt ??
2918 if (bEraseThisObject
)
2920 if( pGroupObject
|| (pSdrTextObj
!= pTrueObject
) )
2922 // Objekt wurde bereits (in der Gruppe und) der Drawing-Page
2923 // durch ein neues SdrGrafObj ersetzt.
2925 SdrObject
* pNewObj
= pGroupObject
?
2926 pGroupObject
->GetSubList()->GetObj(nOrdNum
) : pTrueObject
;
2927 if (pSdrTextObj
!= pNewObj
)
2929 // Objekt in der Z-Order-Liste ersetzen
2930 pMSDffManager
->ExchangeInShapeOrder(pSdrTextObj
, 0,0, pNewObj
);
2931 // Objekt jetzt noch loeschen
2932 SdrObject::Free( pRecord
->pObj
);
2933 // und das neue Objekt merken.
2934 pRecord
->pObj
= pNewObj
;
2939 // Objekt aus der Z-Order-Liste loeschen
2940 pMSDffManager
->RemoveFromShapeOrder( pSdrTextObj
);
2941 // Objekt aus der Drawing-Page rausnehmen
2942 if( pSdrTextObj
->GetPage() )
2943 pDrawPg
->RemoveObject( pSdrTextObj
->GetOrdNum() );
2944 // und FrameFormat entfernen, da durch Grafik ersetzt (dies
2945 // loescht auch das Objekt)
2946 rDoc
.DelFrmFmt( pRetFrmFmt
);
2948 // auch den Objektmerker loeschen
2954 // ww8-default Randabstand einsetzen
2955 SfxItemSet
aItemSet(pDrawModel
->GetItemPool(),
2956 SDRATTR_TEXT_LEFTDIST
, SDRATTR_TEXT_LOWERDIST
);
2957 aItemSet
.Put( SdrTextLeftDistItem( pRecord
->nDxTextLeft
) );
2958 aItemSet
.Put( SdrTextRightDistItem( pRecord
->nDxTextRight
) );
2959 aItemSet
.Put( SdrTextUpperDistItem( pRecord
->nDyTextTop
) );
2960 aItemSet
.Put( SdrTextLowerDistItem( pRecord
->nDyTextBottom
) );
2961 pSdrTextObj
->SetMergedItemSetAndBroadcast(aItemSet
);
2967 SwFlyFrmFmt
* SwWW8ImplReader::ConvertDrawTextToFly(SdrObject
* &rpObject
,
2968 SdrObject
* &rpOurNewObject
, SvxMSDffImportRec
* pRecord
, RndStdIds eAnchor
,
2969 WW8_FSPA
*pF
, SfxItemSet
&rFlySet
)
2971 SwFlyFrmFmt
* pRetFrmFmt
= 0;
2975 // Pruefen, ob in dieser Textbox-Kette denn Text enthalten ist. (
2976 // Umwandeln einer leeren Kette in Rahmen waere Unsinn. )
2977 if ( TxbxChainContainsRealText(pRecord
->aTextId
.nTxBxS
,nStartCp
,nEndCp
) )
2979 // Der Text wird nicht in das SdrTextObj eingelesen! Stattdessen wird
2980 // ein Rahmen eingefuegt und der Text von nStartCp bis nEndCp dort
2983 // Vorteil: im Rahmen sind viel mehr Attribute moeglich als in der
2984 // Edit-Enging, und es koennen auch Felder, OLEs oder Grafiken darin
2987 Rectangle
aInnerDist(pRecord
->nDxTextLeft
, pRecord
->nDyTextTop
,
2988 pRecord
->nDxTextRight
, pRecord
->nDyTextBottom
);
2990 SwFmtFrmSize
aFrmSize(ATT_FIX_SIZE
, pF
->nXaRight
- pF
->nXaLeft
, pF
->nYaBottom
- pF
->nYaTop
);
2991 aFrmSize
.SetWidthSizeType(pRecord
->bAutoWidth
? ATT_VAR_SIZE
: ATT_FIX_SIZE
);
2992 rFlySet
.Put(aFrmSize
);
2994 MatchSdrItemsIntoFlySet( rpObject
, rFlySet
, pRecord
->eLineStyle
,
2995 pRecord
->eShapeType
, aInnerDist
);
2998 SdrTextObj
*pSdrTextObj
= PTR_CAST(SdrTextObj
, rpObject
);
2999 if (pSdrTextObj
&& pSdrTextObj
->IsVerticalWriting())
3000 rFlySet
.Put(SvxFrameDirectionItem(FRMDIR_VERT_TOP_RIGHT
, RES_FRAMEDIR
));
3002 pRetFrmFmt
= rDoc
.MakeFlySection(eAnchor
, pPaM
->GetPoint(), &rFlySet
);
3003 ASSERT(pRetFrmFmt
->GetAnchor().GetAnchorId() == eAnchor
,
3004 "Not the anchor type requested!");
3006 // falls alles Ok, Zeiger auf neues Objekt ermitteln und Z-Order-Liste
3007 // entsprechend korrigieren (oder Eintrag loeschen)
3008 rpOurNewObject
= CreateContactObject(pRetFrmFmt
);
3010 // altes Objekt aus der Z-Order-Liste entfernen
3011 pMSDffManager
->RemoveFromShapeOrder( rpObject
);
3013 // und das Objekt loeschen
3014 SdrObject::Free( rpObject
);
3016 Achtung: ab jetzt nur noch pOrgShapeObject
3024 We do not store our rpOutNewObject in the ShapeOrder because we
3025 have a FrmFmt from which we can regenerate the contact object when
3026 we need it. Because, we can have frames anchored to paragraphs in
3027 header/footers and we can copy header/footers, if we do copy a
3028 header/footer with a nonpage anchored frame in it then the contact
3029 objects are invalidated. Under this condition the FrmFmt will be
3030 updated to reflect this change and can be used to get a new
3031 contact object, while a raw rpOutNewObject stored here becomes
3032 deleted and useless.
3034 pMSDffManager
->StoreShapeOrder(pF
->nSpId
,
3035 (((ULONG
)pRecord
->aTextId
.nTxBxS
) << 16) +
3036 pRecord
->aTextId
.nSequence
, 0, pRetFrmFmt
);
3038 // Das Kontakt-Objekt MUSS in die Draw-Page gesetzt werden, damit
3039 // in SwWW8ImplReader::LoadDoc1() die Z-Order festgelegt werden
3041 if (!rpOurNewObject
->IsInserted())
3043 // --> OD 2004-12-13 #117915# - pass information, if object
3044 // is in page header|footer to method.
3045 pWWZOrder
->InsertEscherObject( rpOurNewObject
, pF
->nSpId
,
3046 bIsHeader
|| bIsFooter
);
3051 // Box-0 erhaelt den Text fuer die ganze Kette!
3052 if( !pRecord
->aTextId
.nSequence
)
3054 // rette Flags u.ae. und setze sie zurueck
3055 WW8ReaderSave
aSave( this );
3057 MoveInsideFly(pRetFrmFmt
);
3059 SwNodeIndex
aStart(pPaM
->GetPoint()->nNode
);
3061 pWWZOrder
->InsideEscher(pF
->nSpId
);
3063 // lies den Text ein
3064 bTxbxFlySection
= true;
3065 bool bJoined
= ReadText(nStartCp
, (nEndCp
-nStartCp
),
3066 MAN_MAINTEXT
== pPlcxMan
->GetManType() ?
3067 MAN_TXBX
: MAN_TXBX_HDFT
);
3069 pWWZOrder
->OutsideEscher();
3071 MoveOutsideFly(pRetFrmFmt
, aSave
.GetStartPos(),!bJoined
);
3073 aSave
.Restore( this );
3079 void MatchEscherMirrorIntoFlySet(const SvxMSDffImportRec
&rRecord
,
3080 SfxItemSet
&rFlySet
)
3082 if (rRecord
.bVFlip
|| rRecord
.bHFlip
)
3084 MirrorGraph
eType(RES_MIRROR_GRAPH_DONT
);
3085 if (rRecord
.bVFlip
&& rRecord
.bHFlip
)
3086 eType
= RES_MIRROR_GRAPH_BOTH
;
3087 else if (rRecord
.bVFlip
)
3088 eType
= RES_MIRROR_GRAPH_HOR
;
3090 eType
= RES_MIRROR_GRAPH_VERT
;
3091 rFlySet
.Put( SwMirrorGrf(eType
) );
3095 SwFlyFrmFmt
* SwWW8ImplReader::ImportReplaceableDrawables( SdrObject
* &rpObject
,
3096 SdrObject
* &rpOurNewObject
, SvxMSDffImportRec
* pRecord
, WW8_FSPA
*pF
,
3097 SfxItemSet
&rFlySet
)
3099 SwFlyFrmFmt
* pRetFrmFmt
= 0;
3100 long nWidthTw
= pF
->nXaRight
- pF
->nXaLeft
;
3103 long nHeightTw
= pF
->nYaBottom
- pF
->nYaTop
;
3107 ProcessEscherAlign(pRecord
, pF
, rFlySet
, true);
3109 rFlySet
.Put(SwFmtFrmSize(ATT_FIX_SIZE
, nWidthTw
, nHeightTw
));
3111 SfxItemSet
aGrSet(rDoc
.GetAttrPool(), RES_GRFATR_BEGIN
, RES_GRFATR_END
-1);
3115 //Note that the escher inner distance only seems to be honoured in
3116 //word for textboxes, not for graphics and ole objects.
3117 Rectangle
aInnerDist(0, 0, 0, 0);
3119 MatchSdrItemsIntoFlySet(rpObject
, rFlySet
, pRecord
->eLineStyle
,
3120 pRecord
->eShapeType
, aInnerDist
);
3122 MatchEscherMirrorIntoFlySet(*pRecord
, aGrSet
);
3125 String
aObjectName(rpObject
->GetName());
3126 if (OBJ_OLE2
== SdrObjKind(rpObject
->GetObjIdentifier()))
3127 pRetFrmFmt
= InsertOle(*((SdrOle2Obj
*)rpObject
), rFlySet
, aGrSet
);
3130 const SdrGrafObj
*pGrf
= (const SdrGrafObj
*)rpObject
;
3132 if (pGrf
->IsLinkedGraphic() && pGrf
->GetFileName().Len())
3134 GraphicType eType
= pGrf
->GetGraphicType();
3136 URIHelper::SmartRel2Abs(
3137 INetURLObject(sBaseURL
), pGrf
->GetFileName(),
3138 URIHelper::GetMaybeFileHdl()));
3139 // --> OD 2005-07-04 #124117# - correction of fix for issue #i10939#:
3140 // One of the two conditions have to be true to insert the graphic
3141 // as a linked graphic -
3142 if (GRAPHIC_NONE
== eType
|| CanUseRemoteLink(aGrfName
))
3145 pRetFrmFmt
= rDoc
.Insert(*pPaM
, aGrfName
, aEmptyStr
, 0,
3146 &rFlySet
, &aGrSet
, NULL
);
3152 const Graphic
& rGraph
= pGrf
->GetGraphic();
3153 pRetFrmFmt
= rDoc
.Insert(*pPaM
, aEmptyStr
, aEmptyStr
, &rGraph
,
3154 &rFlySet
, &aGrSet
, NULL
);
3162 if( OBJ_OLE2
!= SdrObjKind(rpObject
->GetObjIdentifier()) )
3163 SetAttributesAtGrfNode( pRecord
, pRetFrmFmt
, pF
);
3165 // mehrfaches Auftreten gleicher Grafik-Namen vermeiden
3166 maGrfNameGenerator
.SetUniqueGraphName(pRetFrmFmt
, aObjectName
);
3168 //falls alles Ok, Zeiger auf neues Objekt ermitteln und Z-Order-Liste
3169 //entsprechend korrigieren (oder Eintrag loeschen)
3170 rpOurNewObject
= CreateContactObject(pRetFrmFmt
);
3172 // altes Objekt aus der Z-Order-Liste entfernen
3173 pMSDffManager
->RemoveFromShapeOrder( rpObject
);
3174 // aus der Drawing-Page rausnehmen
3175 if( rpObject
->GetPage() )
3176 pDrawPg
->RemoveObject( rpObject
->GetOrdNum() );
3178 // und das Objekt loeschen
3179 SdrObject::Free( rpObject
);
3181 Achtung: ab jetzt nur noch pOrgShapeObject abfragen!
3184 // Kontakt-Objekt in die Z-Order-Liste und die Page aufnehmen
3188 pMSDffManager
->StoreShapeOrder(pF
->nSpId
, 0, rpOurNewObject
, 0 );
3190 // Das Kontakt-Objekt MUSS in die Draw-Page gesetzt werden, damit in
3191 // SwWW8ImplReader::LoadDoc1() die Z-Order festgelegt werden kann !!!
3192 if (!rpOurNewObject
->IsInserted())
3194 // --> OD 2004-12-13 #117915# - pass information, if object
3195 // is in page header|footer to method.
3196 pWWZOrder
->InsertEscherObject( rpOurNewObject
, pF
->nSpId
,
3197 bIsHeader
|| bIsFooter
);
3204 void SwWW8ImplReader::GrafikCtor() // Fuer SVDraw und VCControls und Escher
3208 // --> OD 2005-08-08 #i52858# - method name changed
3209 rDoc
.GetOrCreateDrawModel();
3211 pDrawModel
= rDoc
.GetDrawModel();
3212 ASSERT(pDrawModel
, "Kann DrawModel nicht anlegen");
3213 pDrawPg
= pDrawModel
->GetPage(0);
3215 pMSDffManager
= new SwMSDffManager(*this);
3216 pMSDffManager
->SetModel(pDrawModel
, 1440);
3219 Now the dff manager always needs a controls //converter as well, but a
3220 control converter may still exist //without a dffmanager. cmc
3222 pFormImpl
= new SwMSConvertControls(mpDocShell
, pPaM
);
3224 pWWZOrder
= new wwZOrderer(sw::util::SetLayer(rDoc
), pDrawPg
,
3225 pMSDffManager
? pMSDffManager
->GetShapeOrders() : 0);
3229 void SwWW8ImplReader::GrafikDtor()
3231 DELETEZ(mpDrawEditEngine
); // evtl. von Grafik angelegt
3232 DELETEZ(pWWZOrder
); // dito
3235 void SwWW8FltAnchorStack::AddAnchor(const SwPosition
& rPos
, SwFrmFmt
*pFmt
)
3237 ASSERT(pFmt
->GetAnchor().GetAnchorId() != FLY_IN_CNTNT
,
3238 "Don't use fltanchors with inline frames, slap!");
3239 NewAttr(rPos
, SwFltAnchor(pFmt
));
3242 void SwWW8FltAnchorStack::Flush()
3244 USHORT nCnt
= static_cast< USHORT
>(Count());
3245 for (USHORT i
=0; i
< nCnt
; ++i
)
3247 SwFltStackEntry
*pEntry
= (*this)[i
];
3248 SwPosition
aDummy(pEntry
->nMkNode
);
3249 SetAttrInDoc(aDummy
,pEntry
);
3250 DeleteAndDestroy(i
--);
3255 /* vi:set tabstop=4 shiftwidth=4 expandtab: */