xref: /trunk/main/sw/source/filter/html/htmldraw.cxx (revision 26ea3662)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_sw.hxx"
24 
25 #include "hintids.hxx"
26 #include <vcl/svapp.hxx>
27 #include <vcl/wrkwin.hxx>
28 #include <svx/svdmodel.hxx>
29 #include <svx/svdpage.hxx>
30 #include <svx/svdobj.hxx>
31 #include <svx/svdotext.hxx>
32 #include <editeng/eeitem.hxx>
33 #ifndef _OUTLINER_HXX //autogen
34 #define _EEITEMID_HXX
35 #include <editeng/outliner.hxx>
36 #endif
37 #include <svx/xfillit.hxx>
38 #include <editeng/colritem.hxx>
39 #include <editeng/brshitem.hxx>
40 #include <editeng/lrspitem.hxx>
41 #include <editeng/ulspitem.hxx>
42 #include <svl/itemiter.hxx>
43 #include <svl/whiter.hxx>
44 #include <svtools/htmlout.hxx>
45 #include <svtools/htmltokn.h>
46 #include <svtools/htmlkywd.hxx>
47 #include <svx/svdpool.hxx>
48 #include "charatr.hxx"
49 #include <frmfmt.hxx>
50 #include <fmtanchr.hxx>
51 #include <fmtsrnd.hxx>
52 #include "ndtxt.hxx"
53 #include "doc.hxx"
54 #include "dcontact.hxx"
55 #include "poolfmt.hxx"
56 #include "swcss1.hxx"
57 #include "swhtml.hxx"
58 #include "wrthtml.hxx"
59 #include <drawdoc.hxx>
60 
61 using namespace ::com::sun::star;
62 
63 const sal_uInt32 HTML_FRMOPTS_MARQUEE 	=
64 	HTML_FRMOPT_ALIGN |
65 	HTML_FRMOPT_SPACE;
66 
67 const sal_uInt32 HTML_FRMOPTS_MARQUEE_CSS1 	=
68 	HTML_FRMOPT_S_ALIGN |
69 	HTML_FRMOPT_S_SPACE;
70 
71 static HTMLOptionEnum __FAR_DATA aHTMLMarqBehaviorTable[] =
72 {
73 	{ OOO_STRING_SVTOOLS_HTML_BEHAV_scroll,		SDRTEXTANI_SCROLL		},
74 	{ OOO_STRING_SVTOOLS_HTML_BEHAV_alternate,	SDRTEXTANI_ALTERNATE	},
75 	{ OOO_STRING_SVTOOLS_HTML_BEHAV_slide,		SDRTEXTANI_SLIDE		},
76 	{ 0,						0						}
77 };
78 
79 static HTMLOptionEnum __FAR_DATA aHTMLMarqDirectionTable[] =
80 {
81 	{ OOO_STRING_SVTOOLS_HTML_AL_left,			SDRTEXTANI_LEFT			},
82 	{ OOO_STRING_SVTOOLS_HTML_AL_right,			SDRTEXTANI_RIGHT		},
83 	{ 0,						0						}
84 };
85 
86 /*  */
InsertDrawObject(SdrObject * pNewDrawObj,const Size & rPixSpace,sal_Int16 eVertOri,sal_Int16 eHoriOri,SfxItemSet & rCSS1ItemSet,SvxCSS1PropertyInfo & rCSS1PropInfo,sal_Bool bHidden)87 void SwHTMLParser::InsertDrawObject( SdrObject* pNewDrawObj,
88 									 const Size& rPixSpace,
89                                      sal_Int16 eVertOri,
90                                      sal_Int16 eHoriOri,
91 									 SfxItemSet& rCSS1ItemSet,
92 									 SvxCSS1PropertyInfo& rCSS1PropInfo,
93 									 sal_Bool bHidden )
94 {
95     // always on top of text.
96     // OD 02.07.2003 #108784# but in invisible layer. <ConnectToLayout> will
97     // move the object to the visible layer.
98     pNewDrawObj->SetLayer( pDoc->GetInvisibleHeavenId() );
99 
100 	SfxItemSet aFrmSet( pDoc->GetAttrPool(),
101 						RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
102 	if( !IsNewDoc() )
103 		Reader::ResetFrmFmtAttrs( aFrmSet );
104 
105 	sal_uInt16 nLeftSpace = 0, nRightSpace = 0, nUpperSpace = 0, nLowerSpace = 0;
106 	if( (rPixSpace.Width() || rPixSpace.Height()) && Application::GetDefaultDevice() )
107 	{
108 		Size aTwipSpc( rPixSpace.Width(), rPixSpace.Height() );
109 		aTwipSpc =
110 			Application::GetDefaultDevice()->PixelToLogic( aTwipSpc,
111 												MapMode(MAP_TWIP) );
112 		nLeftSpace = nRightSpace = (sal_uInt16)aTwipSpc.Width();
113 		nUpperSpace = nLowerSpace = (sal_uInt16)aTwipSpc.Height();
114 	}
115 
116 	// linken/rechten Rand setzen
117 	const SfxPoolItem *pItem;
118 	if( SFX_ITEM_SET==rCSS1ItemSet.GetItemState( RES_LR_SPACE, sal_True, &pItem ) )
119 	{
120 		// Ggf. den Erstzeilen-Einzug noch plaetten
121 		const SvxLRSpaceItem *pLRItem = (const SvxLRSpaceItem *)pItem;
122 		SvxLRSpaceItem aLRItem( *pLRItem );
123 		aLRItem.SetTxtFirstLineOfst( 0 );
124 		if( rCSS1PropInfo.bLeftMargin )
125 		{
126             nLeftSpace = static_cast< sal_uInt16 >(aLRItem.GetLeft());
127 			rCSS1PropInfo.bLeftMargin = sal_False;
128 		}
129 		if( rCSS1PropInfo.bRightMargin )
130 		{
131             nRightSpace = static_cast< sal_uInt16 >(aLRItem.GetRight());
132 			rCSS1PropInfo.bRightMargin = sal_False;
133 		}
134 		rCSS1ItemSet.ClearItem( RES_LR_SPACE );
135 	}
136 	if( nLeftSpace || nRightSpace )
137 	{
138         SvxLRSpaceItem aLRItem( RES_LR_SPACE );
139 		aLRItem.SetLeft( nLeftSpace );
140 		aLRItem.SetRight( nRightSpace );
141 		aFrmSet.Put( aLRItem );
142 	}
143 
144 	// oberen/unteren Rand setzen
145 	if( SFX_ITEM_SET==rCSS1ItemSet.GetItemState( RES_UL_SPACE, sal_True, &pItem ) )
146 	{
147 		// Ggf. den Erstzeilen-Einzug noch plaetten
148 		const SvxULSpaceItem *pULItem = (const SvxULSpaceItem *)pItem;
149 		if( rCSS1PropInfo.bTopMargin )
150 		{
151 			nUpperSpace = pULItem->GetUpper();
152 			rCSS1PropInfo.bTopMargin = sal_False;
153 		}
154 		if( rCSS1PropInfo.bBottomMargin )
155 		{
156 			nLowerSpace = pULItem->GetLower();
157 			rCSS1PropInfo.bBottomMargin = sal_False;
158 		}
159 
160 		rCSS1ItemSet.ClearItem( RES_UL_SPACE );
161 	}
162 	if( nUpperSpace || nLowerSpace )
163 	{
164         SvxULSpaceItem aULItem( RES_UL_SPACE );
165 		aULItem.SetUpper( nUpperSpace );
166 		aULItem.SetLower( nLowerSpace );
167 		aFrmSet.Put( aULItem );
168 	}
169 
170     SwFmtAnchor aAnchor( FLY_AS_CHAR );
171 	if( SVX_CSS1_POS_ABSOLUTE == rCSS1PropInfo.ePosition &&
172 		SVX_CSS1_LTYPE_TWIP == rCSS1PropInfo.eLeftType &&
173 		SVX_CSS1_LTYPE_TWIP	== rCSS1PropInfo.eTopType )
174 	{
175 		const SwStartNode *pFlySttNd =
176             pPam->GetPoint()->nNode.GetNode().FindFlyStartNode();
177 
178 		if( pFlySttNd )
179 		{
180 			aAnchor.SetType( FLY_AT_FLY );
181 			SwPosition aPos( *pFlySttNd );
182 			aAnchor.SetAnchor( &aPos );
183 		}
184 		else
185         {
186             aAnchor.SetType( FLY_AT_PAGE );
187         }
188         // OD 2004-04-13 #i26791# - direct positioning for <SwDoc::Insert(..)>
189         pNewDrawObj->SetRelativePos( Point(rCSS1PropInfo.nLeft + nLeftSpace,
190 										   rCSS1PropInfo.nTop + nUpperSpace) );
191 		aFrmSet.Put( SwFmtSurround(SURROUND_THROUGHT) );
192 	}
193 	else if( SVX_ADJUST_LEFT == rCSS1PropInfo.eFloat ||
194              text::HoriOrientation::LEFT == eHoriOri )
195     {
196         aAnchor.SetType( FLY_AT_PARA );
197 		aFrmSet.Put( SwFmtSurround(bHidden ? SURROUND_THROUGHT
198 											 : SURROUND_RIGHT) );
199         // OD 2004-04-13 #i26791# - direct positioning for <SwDoc::Insert(..)>
200 		pNewDrawObj->SetRelativePos( Point(nLeftSpace, nUpperSpace) );
201 	}
202     else if( text::VertOrientation::NONE != eVertOri )
203 	{
204 		aFrmSet.Put( SwFmtVertOrient( 0, eVertOri ) );
205 	}
206 
207     if (FLY_AT_PAGE == aAnchor.GetAnchorId())
208     {
209 		aAnchor.SetPageNum( 1 );
210     }
211 	else if( FLY_AT_FLY != aAnchor.GetAnchorId() )
212     {
213 		aAnchor.SetAnchor( pPam->GetPoint() );
214     }
215 	aFrmSet.Put( aAnchor );
216 
217 	pDoc->InsertDrawObj( *pPam, *pNewDrawObj, aFrmSet );
218 }
219 
220 /*  */
221 
PutEEPoolItem(SfxItemSet & rEEItemSet,const SfxPoolItem & rSwItem)222 static void PutEEPoolItem( SfxItemSet &rEEItemSet,
223 						   const SfxPoolItem& rSwItem )
224 {
225 
226 	sal_uInt16 nEEWhich = 0;
227 
228 	switch( rSwItem.Which() )
229 	{
230 	case RES_CHRATR_COLOR:			nEEWhich = EE_CHAR_COLOR; break;
231 	case RES_CHRATR_CROSSEDOUT:		nEEWhich = EE_CHAR_STRIKEOUT; break;
232 	case RES_CHRATR_ESCAPEMENT:		nEEWhich = EE_CHAR_ESCAPEMENT; break;
233 	case RES_CHRATR_FONT:			nEEWhich = EE_CHAR_FONTINFO; break;
234 	case RES_CHRATR_CJK_FONT:		nEEWhich = EE_CHAR_FONTINFO_CJK; break;
235 	case RES_CHRATR_CTL_FONT:		nEEWhich = EE_CHAR_FONTINFO_CTL; break;
236 	case RES_CHRATR_FONTSIZE:		nEEWhich = EE_CHAR_FONTHEIGHT; break;
237 	case RES_CHRATR_CJK_FONTSIZE:	nEEWhich = EE_CHAR_FONTHEIGHT_CJK; break;
238 	case RES_CHRATR_CTL_FONTSIZE:	nEEWhich = EE_CHAR_FONTHEIGHT_CTL; break;
239 	case RES_CHRATR_KERNING: 		nEEWhich = EE_CHAR_KERNING; break;
240 	case RES_CHRATR_POSTURE: 		nEEWhich = EE_CHAR_ITALIC; break;
241 	case RES_CHRATR_CJK_POSTURE: 	nEEWhich = EE_CHAR_ITALIC_CJK; break;
242 	case RES_CHRATR_CTL_POSTURE: 	nEEWhich = EE_CHAR_ITALIC_CTL; break;
243 	case RES_CHRATR_UNDERLINE:		nEEWhich = EE_CHAR_UNDERLINE; break;
244 	case RES_CHRATR_WEIGHT:   		nEEWhich = EE_CHAR_WEIGHT; break;
245 	case RES_CHRATR_CJK_WEIGHT:   	nEEWhich = EE_CHAR_WEIGHT_CJK; break;
246 	case RES_CHRATR_CTL_WEIGHT:   	nEEWhich = EE_CHAR_WEIGHT_CTL; break;
247 	case RES_BACKGROUND:
248 	case RES_CHRATR_BACKGROUND:
249 		{
250 			const SvxBrushItem& rBrushItem = (const SvxBrushItem&)rSwItem;
251 			rEEItemSet.Put( XFillStyleItem(XFILL_SOLID) );
252 			rEEItemSet.Put( XFillColorItem(aEmptyStr,
253 							rBrushItem.GetColor()) );
254 		}
255 		break;
256 	}
257 
258 	if( nEEWhich )
259 	{
260 		SfxPoolItem *pEEItem = rSwItem.Clone();
261 		pEEItem->SetWhich( nEEWhich );
262 		rEEItemSet.Put( *pEEItem );
263 		delete pEEItem;
264 	}
265 }
266 
NewMarquee(HTMLTable * pCurTable)267 void SwHTMLParser::NewMarquee( HTMLTable *pCurTable )
268 {
269 
270 	ASSERT( !pMarquee, "Marquee in Marquee???" );
271 	aContents.Erase();
272 
273 	String aId, aStyle, aClass;
274 
275 	long nWidth=0, nHeight=0;
276 	sal_Bool bPrcWidth = sal_False, bDirection = sal_False, bBGColor = sal_False;
277 	Size aSpace( 0, 0 );
278     sal_Int16 eVertOri = text::VertOrientation::TOP;
279     sal_Int16 eHoriOri = text::HoriOrientation::NONE;
280 	SdrTextAniKind eAniKind = SDRTEXTANI_SCROLL;
281 	SdrTextAniDirection eAniDir = SDRTEXTANI_LEFT;
282 	sal_uInt16 nCount = 0, nDelay = 60;
283 	sal_Int16 nAmount = -6;
284 	Color aBGColor;
285 
286 	const HTMLOptions *pHTMLOptions = GetOptions();
287 	sal_uInt16 nArrLen = pHTMLOptions->Count();
288 	for ( sal_uInt16 i=0; i<nArrLen; i++ )
289 	{
290 		const HTMLOption *pOption = (*pHTMLOptions)[i];
291 		switch( pOption->GetToken() )
292 		{
293 			case HTML_O_ID:
294 				aId = pOption->GetString();
295 				break;
296 			case HTML_O_STYLE:
297 				aStyle = pOption->GetString();
298 				break;
299 			case HTML_O_CLASS:
300 				aClass = pOption->GetString();
301 				break;
302 
303 			case HTML_O_BEHAVIOR:
304 				eAniKind =
305 					(SdrTextAniKind)pOption->GetEnum( aHTMLMarqBehaviorTable,
306                                                       static_cast< sal_uInt16 >(eAniKind) );
307 				break;
308 
309 			case HTML_O_BGCOLOR:
310 				pOption->GetColor( aBGColor );
311 				bBGColor = sal_True;
312 				break;
313 
314 			case HTML_O_DIRECTION:
315 				eAniDir =
316 					(SdrTextAniDirection)pOption->GetEnum( aHTMLMarqDirectionTable,
317                                                       static_cast< sal_uInt16 >(eAniDir) );
318 				bDirection = sal_True;
319 				break;
320 
321 			case HTML_O_LOOP:
322 				if( pOption->GetString().
323 						EqualsIgnoreCaseAscii(OOO_STRING_SVTOOLS_HTML_LOOP_infinite) )
324 				{
325 					nCount = 0;
326 				}
327 				else
328 				{
329 					sal_uInt32 nLoop = pOption->GetSNumber();
330 					nCount = (sal_uInt16)(nLoop>0 ? nLoop : 0 );
331 				}
332 				break;
333 
334 			case HTML_O_SCROLLAMOUNT:
335 				nAmount = -((sal_Int16)pOption->GetNumber());
336 				break;
337 
338 			case HTML_O_SCROLLDELAY:
339 				nDelay = (sal_uInt16)pOption->GetNumber();
340 				break;
341 
342 			case HTML_O_WIDTH:
343 				// erstmal nur als Pixelwerte merken!
344 				nWidth = pOption->GetNumber();
345 				bPrcWidth = pOption->GetString().Search('%') != STRING_NOTFOUND;
346 				if( bPrcWidth && nWidth>100 )
347 					nWidth = 100;
348 				break;
349 
350 			case HTML_O_HEIGHT:
351 				// erstmal nur als Pixelwerte merken!
352 				nHeight = pOption->GetNumber();
353 				if( pOption->GetString().Search('%') != STRING_NOTFOUND )
354 					nHeight = 0;
355 				break;
356 
357 			case HTML_O_HSPACE:
358 				// erstmal nur als Pixelwerte merken!
359 				aSpace.Height() = pOption->GetNumber();
360 				break;
361 
362 			case HTML_O_VSPACE:
363 				// erstmal nur als Pixelwerte merken!
364 				aSpace.Width() = pOption->GetNumber();
365 				break;
366 
367 			case HTML_O_ALIGN:
368 				eVertOri =
369                     pOption->GetEnum( aHTMLImgVAlignTable,
370                                                     text::VertOrientation::TOP );
371 				eHoriOri =
372                     pOption->GetEnum( aHTMLImgHAlignTable,
373                                                     text::HoriOrientation::NONE );
374 				break;
375 		}
376 	}
377 
378 	// Ein DrawTxtobj anlegen
379     // --> OD 2005-08-08 #i52858# - method name changed
380     SwDrawModel* pModel = pDoc->GetOrCreateDrawModel();
381     // <--
382 	SdrPage* pPg = pModel->GetPage( 0 );
383 	pMarquee = SdrObjFactory::MakeNewObject( SdrInventor,
384 											 OBJ_TEXT, pPg, pModel );
385 	if( !pMarquee )
386 		return;
387 
388 	pPg->InsertObject( pMarquee );
389 
390 	if( aId.Len() )
391 		InsertBookmark( aId );
392 
393 	// (Nur) Alternate leueft per Default von links nach rechts
394 	if( SDRTEXTANI_ALTERNATE==eAniKind && !bDirection )
395 		eAniDir = SDRTEXTANI_RIGHT;
396 
397 	// die fuer das Scrollen benoetigten Attribute umsetzen
398 	sal_uInt16 aWhichMap[7] =	{ XATTR_FILL_FIRST,	  XATTR_FILL_LAST,
399 							  SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST,
400 							  EE_CHAR_START,	  EE_CHAR_END,
401 							  0	};
402 	SfxItemSet aItemSet( pModel->GetItemPool(), aWhichMap );
403 	aItemSet.Put( SdrTextAutoGrowWidthItem( sal_False ) );
404 	aItemSet.Put( SdrTextAutoGrowHeightItem( sal_True ) );
405 	aItemSet.Put( SdrTextAniKindItem( eAniKind ) );
406 	aItemSet.Put( SdrTextAniDirectionItem( eAniDir ) );
407 	aItemSet.Put( SdrTextAniCountItem( nCount ) );
408 	aItemSet.Put( SdrTextAniDelayItem( nDelay ) );
409 	aItemSet.Put( SdrTextAniAmountItem( nAmount ) );
410 	if( SDRTEXTANI_ALTERNATE==eAniKind )
411 	{
412 		// (Nur) Alternate startet und stoppt per default Inside
413 		aItemSet.Put( SdrTextAniStartInsideItem(sal_True) );
414 		aItemSet.Put( SdrTextAniStopInsideItem(sal_True) );
415 		if( SDRTEXTANI_LEFT==eAniDir )
416 			aItemSet.Put( SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT) );
417 	}
418 
419 	// die Default-Farbe (aus der Standard-Vorlage) setzen, damit ueberhaupt
420 	// eine sinnvolle Farbe gesetzt ist.
421 	const Color& rDfltColor =
422 		pCSS1Parser->GetTxtCollFromPool( RES_POOLCOLL_STANDARD )
423 			->GetColor().GetValue();
424 	aItemSet.Put( SvxColorItem( rDfltColor, EE_CHAR_COLOR ) );
425 
426 	// Die Attribute der aktuellen Absatzvorlage setzen
427 	sal_uInt16 nWhichIds[] =
428 	{
429 		RES_CHRATR_COLOR,   RES_CHRATR_CROSSEDOUT, RES_CHRATR_ESCAPEMENT,
430 		RES_CHRATR_FONT,    RES_CHRATR_FONTSIZE,   RES_CHRATR_KERNING,
431 		RES_CHRATR_POSTURE, RES_CHRATR_UNDERLINE,  RES_CHRATR_WEIGHT,
432 		RES_CHRATR_BACKGROUND,
433 		RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONTSIZE,
434 		RES_CHRATR_CJK_POSTURE, RES_CHRATR_CJK_WEIGHT,
435 		RES_CHRATR_CTL_FONT, RES_CHRATR_CTL_FONTSIZE,
436 		RES_CHRATR_CTL_POSTURE, RES_CHRATR_CTL_WEIGHT,
437 		0
438 	};
439     SwTxtNode const*const pTxtNd =
440         pPam->GetPoint()->nNode.GetNode().GetTxtNode();
441 	if( pTxtNd )
442 	{
443 		const SfxItemSet& rItemSet = pTxtNd->GetAnyFmtColl().GetAttrSet();
444 		const SfxPoolItem *pItem;
445 		for( sal_uInt16 i=0; nWhichIds[i]; i++ )
446 		{
447 			if( SFX_ITEM_SET == rItemSet.GetItemState( nWhichIds[i], sal_True, &pItem ) )
448 				PutEEPoolItem( aItemSet, *pItem );
449 		}
450 	}
451 
452 	// die Attribute der Umgebung am Draw-Objekt setzen
453 	_HTMLAttr** pTbl = (_HTMLAttr**)&aAttrTab;
454 	for( sal_uInt16 nCnt = sizeof( _HTMLAttrTable ) / sizeof( _HTMLAttr* );
455 		 nCnt--; ++pTbl )
456 	{
457 		_HTMLAttr *pAttr = *pTbl;
458 		if( pAttr )
459 			PutEEPoolItem( aItemSet, pAttr->GetItem() );
460 	}
461 
462 	if( bBGColor )
463 	{
464 		aItemSet.Put( XFillStyleItem(XFILL_SOLID) );
465 		aItemSet.Put( XFillColorItem(aEmptyStr, aBGColor) );
466 	}
467 
468 	// Styles parsen (funktioniert hier nur fuer Attribute, die auch
469 	// am Zeichen-Objekt gesetzt werden koennen)
470 	SfxItemSet aStyleItemSet( pDoc->GetAttrPool(),
471 							  pCSS1Parser->GetWhichMap() );
472 	SvxCSS1PropertyInfo aPropInfo;
473 	if( HasStyleOptions( aStyle, aId, aClass )  &&
474 		ParseStyleOptions( aStyle, aId, aClass, aStyleItemSet, aPropInfo ) )
475 	{
476 		SfxItemIter aIter( aStyleItemSet );
477 
478 		const SfxPoolItem *pItem = aIter.FirstItem();
479 		while( pItem )
480 		{
481 			PutEEPoolItem( aItemSet, *pItem );
482 			pItem = aIter.NextItem();
483 		}
484 	}
485 
486 	// jetzt noch die Groesse setzen
487 	Size aTwipSz( bPrcWidth ? 0 : nWidth, nHeight );
488 	if( (aTwipSz.Width() || aTwipSz.Height()) && Application::GetDefaultDevice() )
489 	{
490 		aTwipSz = Application::GetDefaultDevice()
491 					->PixelToLogic( aTwipSz, MapMode( MAP_TWIP ) );
492 	}
493 
494 	if( SVX_CSS1_LTYPE_TWIP== aPropInfo.eWidthType )
495 	{
496 		aTwipSz.Width() = aPropInfo.nWidth;
497 		nWidth = 1; // != 0;
498 		bPrcWidth = sal_False;
499 	}
500 	if( SVX_CSS1_LTYPE_TWIP== aPropInfo.eHeightType )
501 		aTwipSz.Height() = aPropInfo.nHeight;
502 
503 	bFixMarqueeWidth = sal_False;
504 	if( !nWidth || bPrcWidth )
505 	{
506 		if( pTable )
507 		{
508 			if( !pCurTable )
509 			{
510 				// Die Laufschrift steht in einer Tabelle, aber nicht
511 				// in einer Zelle. Da jetzt keine vernuenftige Zuordung
512 				// zu einer Zelle moeglich ist, passen wir hir die
513 				// Breite dem Inhalt der Laufschrift an.
514 				bFixMarqueeWidth = sal_True;
515 			}
516 			else if( !nWidth )
517 			{
518 				// Da wir wissen, in welcher Zelle die Laufschrift ist,
519 				// koennen wir die Breite auch anpassen. Keine Breitenangabe
520 				// wird wie 100% behandelt.
521 				nWidth = 100;
522 				bPrcWidth = sal_True;
523 			}
524 			aTwipSz.Width() = MINLAY;
525 		}
526 		else
527 		{
528 			long nBrowseWidth = GetCurrentBrowseWidth();
529 			aTwipSz.Width() = !nWidth ? nBrowseWidth
530 									  : (nWidth*nBrowseWidth) / 100;
531 		}
532 	}
533 
534 	// Die Hoehe ist nur eine Mindest-Hoehe
535 	if( aTwipSz.Height() < MINFLY )
536 		aTwipSz.Height() = MINFLY;
537 	aItemSet.Put( SdrTextMinFrameHeightItem( aTwipSz.Height() ) );
538 
539 	pMarquee->SetMergedItemSetAndBroadcast(aItemSet);
540 
541 	if( aTwipSz.Width() < MINFLY )
542 		aTwipSz.Width() = MINFLY;
543 	pMarquee->SetLogicRect( Rectangle( 0, 0, aTwipSz.Width(), aTwipSz.Height() ) );
544 
545 	// und das Objekt in das Dok einfuegen
546 	InsertDrawObject( pMarquee, aSpace, eVertOri, eHoriOri, aStyleItemSet,
547 					  aPropInfo	);
548 
549 	// Das Zeichen-Objekt der Tabelle bekanntmachen. Ist ein bisserl
550 	// umstaendlich, weil noch ueber den Parser gegangen wird, obwohl die
551 	// Tabelle bekannt ist, aber anderenfalls muesste man die Tabelle
552 	// oeffentlich machen, und das ist auch nicht schoen. Das globale
553 	// pTable kann uebrigens auch nicht verwendet werden, denn die
554 	// Laufschrift kann sich auch mal in einer Sub-Tabelle befinden.
555 	if( pCurTable && bPrcWidth)
556 		RegisterDrawObjectToTable( pCurTable, pMarquee, (sal_uInt8)nWidth );
557 }
558 
EndMarquee()559 void SwHTMLParser::EndMarquee()
560 {
561 	ASSERT( pMarquee && OBJ_TEXT==pMarquee->GetObjIdentifier(),
562 			"kein Marquee oder falscher Typ" );
563 
564 	if( bFixMarqueeWidth )
565 	{
566 		// Da es keine fixe Hoehe gibt, das Text-Objekt erstmal breiter
567 		// als den Text machen, damit nicht umgebrochen wird.
568 		const Rectangle& rOldRect = pMarquee->GetLogicRect();
569 		pMarquee->SetLogicRect( Rectangle( rOldRect.TopLeft(),
570 										   Size( USHRT_MAX, 240 ) ) );
571 	}
572 
573 	// den gesammelten Text einfuegen
574 	((SdrTextObj*)pMarquee)->SetText( aContents );
575 	pMarquee->SetMergedItemSetAndBroadcast( pMarquee->GetMergedItemSet() );
576 
577 	if( bFixMarqueeWidth )
578 	{
579 		// die Groesse dem Text anpassen.
580 		((SdrTextObj*)pMarquee)->FitFrameToTextSize();
581 	}
582 
583 	aContents.Erase();
584 	pMarquee = 0;
585 }
586 
InsertMarqueeText()587 void SwHTMLParser::InsertMarqueeText()
588 {
589 	ASSERT( pMarquee && OBJ_TEXT==pMarquee->GetObjIdentifier(),
590 			"kein Marquee oder falscher Typ" );
591 
592 	// das akteulle Textstueck an den Text anhaengen
593 	aContents += aToken;
594 }
595 
ResizeDrawObject(SdrObject * pObj,SwTwips nWidth)596 void SwHTMLParser::ResizeDrawObject( SdrObject* pObj, SwTwips nWidth )
597 {
598 	ASSERT( OBJ_TEXT==pObj->GetObjIdentifier(),
599 			"kein Marquee oder falscher Typ" );
600 
601 	if( OBJ_TEXT!=pObj->GetObjIdentifier() )
602 		return;
603 
604 	// die alte Groesse
605 	const Rectangle& rOldRect = pObj->GetLogicRect();
606 	Size aNewSz( nWidth, rOldRect.GetSize().Height() );
607 	pObj->SetLogicRect( Rectangle( rOldRect.TopLeft(), aNewSz ) );
608 }
609 
610 /*  */
611 
GetMarqueeTextObj(const SwDrawFrmFmt & rFmt)612 const SdrObject *SwHTMLWriter::GetMarqueeTextObj( const SwDrawFrmFmt& rFmt )
613 {
614 	const SdrObject* pObj = rFmt.FindSdrObject();
615 	return (pObj && ::IsMarqueeTextObj( *pObj )) ? pObj : 0;
616 }
617 
GetEEAttrsFromDrwObj(SfxItemSet & rItemSet,const SdrObject * pObj,sal_Bool bSetDefaults)618 void SwHTMLWriter::GetEEAttrsFromDrwObj( SfxItemSet& rItemSet,
619 										 const SdrObject *pObj,
620 										 sal_Bool bSetDefaults )
621 {
622     // die Edit script::Engine-Attribute aus dem Objekt holen
623 	SfxItemSet rObjItemSet = pObj->GetMergedItemSet();
624 
625     // ueber die Edit script::Engine-Attribute iterieren und die Attribute
626 	// in SW-Attrs wandeln bzw. default setzen
627 	SfxWhichIter aIter( rObjItemSet );
628 	sal_uInt16 nEEWhich = aIter.FirstWhich();
629 	while( nEEWhich )
630 	{
631 		const SfxPoolItem *pEEItem;
632 		sal_Bool bSet = SFX_ITEM_SET == rObjItemSet.GetItemState( nEEWhich, sal_False,
633 															  &pEEItem );
634 
635 		if( bSet || bSetDefaults )
636 		{
637 			sal_uInt16 nSwWhich = 0;
638 			switch( nEEWhich )
639 			{
640 			case EE_CHAR_COLOR:			nSwWhich = RES_CHRATR_COLOR;		break;
641 			case EE_CHAR_STRIKEOUT: 	nSwWhich = RES_CHRATR_CROSSEDOUT;	break;
642 			case EE_CHAR_ESCAPEMENT:	nSwWhich = RES_CHRATR_ESCAPEMENT;	break;
643 			case EE_CHAR_FONTINFO: 		nSwWhich = RES_CHRATR_FONT;		    break;
644 			case EE_CHAR_FONTINFO_CJK: 	nSwWhich = RES_CHRATR_CJK_FONT;	    break;
645 			case EE_CHAR_FONTINFO_CTL: 	nSwWhich = RES_CHRATR_CTL_FONT;		break;
646 			case EE_CHAR_FONTHEIGHT:	nSwWhich = RES_CHRATR_FONTSIZE;	    break;
647 			case EE_CHAR_FONTHEIGHT_CJK:nSwWhich = RES_CHRATR_CJK_FONTSIZE; break;
648 			case EE_CHAR_FONTHEIGHT_CTL:nSwWhich = RES_CHRATR_CTL_FONTSIZE; break;
649 			case EE_CHAR_KERNING: 		nSwWhich = RES_CHRATR_KERNING; 	    break;
650 			case EE_CHAR_ITALIC: 		nSwWhich = RES_CHRATR_POSTURE; 	    break;
651 			case EE_CHAR_ITALIC_CJK:	nSwWhich = RES_CHRATR_CJK_POSTURE;  break;
652 			case EE_CHAR_ITALIC_CTL:	nSwWhich = RES_CHRATR_CTL_POSTURE;  break;
653 			case EE_CHAR_UNDERLINE: 	nSwWhich = RES_CHRATR_UNDERLINE;	break;
654 			case EE_CHAR_WEIGHT: 		nSwWhich = RES_CHRATR_WEIGHT;   	break;
655 			case EE_CHAR_WEIGHT_CJK: 	nSwWhich = RES_CHRATR_CJK_WEIGHT;  	break;
656 			case EE_CHAR_WEIGHT_CTL: 	nSwWhich = RES_CHRATR_CTL_WEIGHT;  	break;
657 			}
658 
659 			if( nSwWhich )
660 			{
661 				// wenn das Item nicht gesetzt ist nehmen wir ggf. das
662 				// Default-Item
663 				if( !bSet )
664 					pEEItem = &rObjItemSet.GetPool()->GetDefaultItem(nEEWhich);
665 
666 				// jetzt Clonen wir das Item mit der Which-Id des Writers
667 				SfxPoolItem *pSwItem = pEEItem->Clone();
668 				pSwItem->SetWhich( nSwWhich );
669 				rItemSet.Put( *pSwItem );
670 				delete pSwItem;
671 			}
672 		}
673 
674 		nEEWhich = aIter.NextWhich();
675 	}
676 }
677 
678 
OutHTML_DrawFrmFmtAsMarquee(Writer & rWrt,const SwDrawFrmFmt & rFmt,const SdrObject & rSdrObject)679 Writer& OutHTML_DrawFrmFmtAsMarquee( Writer& rWrt,
680 									 const SwDrawFrmFmt& rFmt,
681 									 const SdrObject& rSdrObject )
682 {
683 	SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
684 
685 	ASSERT( rWrt.pDoc->GetDrawModel(), "Da gibt's ein Draw-Obj ohne ein Draw-Model zu haben?" );
686 	const SdrTextObj *pTextObj = (const SdrTextObj *)&rSdrObject;
687 
688 	// Gibt es ueberhaupt auszugebenden Text
689 	const OutlinerParaObject *pOutlinerParaObj =
690 		pTextObj->GetOutlinerParaObject();
691 	if( !pOutlinerParaObj )
692 		return rWrt;
693 
694 	ByteString sOut( '<' );
695 	sOut += OOO_STRING_SVTOOLS_HTML_marquee;
696 
697 	// Die Attribute des Objektd holen
698 	const SfxItemSet& rItemSet = pTextObj->GetMergedItemSet();
699 
700 	// BEHAVIOUR
701 	SdrTextAniKind eAniKind = pTextObj->GetTextAniKind();
702 	ASSERT( SDRTEXTANI_SCROLL==eAniKind ||
703 			SDRTEXTANI_ALTERNATE==eAniKind ||
704 			SDRTEXTANI_SLIDE==eAniKind,
705 			"Text-Draw-Objekt nicht fuer Marquee geeignet" )
706 
707 	const sal_Char *pStr = 0;
708 	switch( eAniKind )
709 	{
710 	case SDRTEXTANI_SCROLL:		pStr = OOO_STRING_SVTOOLS_HTML_BEHAV_scroll;		break;
711 	case SDRTEXTANI_SLIDE:		pStr = OOO_STRING_SVTOOLS_HTML_BEHAV_slide;		break;
712 	case SDRTEXTANI_ALTERNATE:	pStr = OOO_STRING_SVTOOLS_HTML_BEHAV_alternate;	break;
713 	default:
714 		;
715 	}
716 
717 	if( pStr )
718 		(((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_behavior) += '=') += pStr;
719 
720 	// DIRECTION
721 	pStr = 0;
722 	SdrTextAniDirection eAniDir = pTextObj->GetTextAniDirection();
723 	switch( eAniDir )
724 	{
725 	case SDRTEXTANI_LEFT:		pStr = OOO_STRING_SVTOOLS_HTML_AL_left;		break;
726 	case SDRTEXTANI_RIGHT:		pStr = OOO_STRING_SVTOOLS_HTML_AL_right;		break;
727 	default:
728 		;
729 	}
730 
731 	if( pStr )
732 		(((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_direction) += '=') += pStr;
733 
734 	// LOOP
735 	sal_Int32 nCount =
736 		((const SdrTextAniCountItem&)rItemSet.Get( SDRATTR_TEXT_ANICOUNT ))
737 											 .GetValue();
738 	if( 0==nCount )
739 		nCount = SDRTEXTANI_SLIDE==eAniKind ? 1 : -1;
740 	(((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_loop) += '=')
741 		+= ByteString::CreateFromInt32( nCount );
742 
743 	// SCROLLDELAY
744 	sal_uInt16 nDelay =
745 		((const SdrTextAniDelayItem&)rItemSet.Get( SDRATTR_TEXT_ANIDELAY ))
746 											.GetValue();
747 	(((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_scrolldelay) += '=')
748 		+= ByteString::CreateFromInt32( nDelay );
749 
750 	// SCROLLAMOUNT
751 	sal_Int16 nAmount =
752 		((const SdrTextAniAmountItem&)rItemSet.Get( SDRATTR_TEXT_ANIAMOUNT ))
753 											 .GetValue();
754 	if( nAmount < 0 )
755 	{
756 		nAmount = -nAmount;
757 	}
758 	else if( nAmount && Application::GetDefaultDevice() )
759 	{
760 		nAmount = (sal_uInt16)(Application::GetDefaultDevice()
761 							->LogicToPixel( Size(nAmount,0),
762 											MapMode(MAP_TWIP) ).Width());
763 	}
764 	if( nAmount )
765 		(((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_scrollamount) += '=')
766 			+= ByteString::CreateFromInt32( nAmount );
767 
768 	Size aTwipSz( pTextObj->GetLogicRect().GetSize() );
769 	if( pTextObj->IsAutoGrowWidth() )
770 		aTwipSz.Width() = 0;
771 	// Die Hoehe ist bei MS eine Mindesthoehe, also geben wir auch die
772 	// Mindestheoehe aus, wenn es sie gibt. Da eine Mindesthoehe MINFLY
773 	// mit hoher Wahrscheinlichkeit vom Import kommt, wird sie nicht mit
774 	// ausgegeben. Falsch machen kann man da nichst, denn jeder Font ist
775 	// hoeher.
776 	if( pTextObj->IsAutoGrowHeight() )
777 	{
778 		aTwipSz.Height() = pTextObj->GetMinTextFrameHeight();
779 		if( MINFLY==aTwipSz.Height() )
780 			aTwipSz.Height() = 0;
781 	}
782 
783 	if( (aTwipSz.Width() || aTwipSz.Height()) &&
784 		Application::GetDefaultDevice() )
785 	{
786 		Size aPixelSz =
787 			Application::GetDefaultDevice()->LogicToPixel( aTwipSz,
788 												MapMode(MAP_TWIP) );
789 		if( !aPixelSz.Width() && aTwipSz.Width() )
790 			aPixelSz.Width() = 1;
791 		if( !aPixelSz.Height() && aTwipSz.Height() )
792 			aPixelSz.Height() = 1;
793 
794 		if( aPixelSz.Width() )
795 			(((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_width) += '=')
796 				+= ByteString::CreateFromInt32( aPixelSz.Width() );
797 
798 		if( aPixelSz.Height() )
799 			(((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_height) += '=')
800 				+= ByteString::CreateFromInt32( aPixelSz.Height() );
801 	}
802 
803 	// BGCOLOR
804 	XFillStyle eFillStyle =
805 		((const XFillStyleItem&)rItemSet.Get(XATTR_FILLSTYLE)).GetValue();
806 	if( XFILL_SOLID==eFillStyle )
807 	{
808 		const Color& rFillColor =
809 			((const XFillColorItem&)rItemSet.Get(XATTR_FILLCOLOR)).GetColorValue();
810 
811 		((sOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_bgcolor) += '=';
812 		rWrt.Strm() << sOut.GetBuffer();
813 		HTMLOutFuncs::Out_Color( rWrt.Strm(), rFillColor, rHTMLWrt.eDestEnc );
814 		sOut.Erase();
815 	}
816 
817 	if( sOut.Len() )
818 		rWrt.Strm() << sOut.GetBuffer();
819 
820 	// und nun noch ALIGN, HSPACE und VSPACE
821 	ByteString aEndTags;
822 	sal_uInt32 nFrmFlags = HTML_FRMOPTS_MARQUEE;
823 	if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_DRAW ) )
824 		nFrmFlags |= HTML_FRMOPTS_MARQUEE_CSS1;
825 	rHTMLWrt.OutFrmFmtOptions( rFmt, aEmptyStr, aEndTags, nFrmFlags );
826 	if( rHTMLWrt.IsHTMLMode( HTMLMODE_ABS_POS_DRAW ) )
827 		rHTMLWrt.OutCSS1_FrmFmtOptions( rFmt, nFrmFlags, &rSdrObject );
828 
829 
830 	rWrt.Strm() << '>';
831 
832 	// Was jetzt kommt ist das Gegenstueck zu SdrTextObjectt::SetText()
833 	Outliner aOutliner(0, OUTLINERMODE_TEXTOBJECT);
834 	aOutliner.SetUpdateMode( sal_False );
835 	aOutliner.SetText( *pOutlinerParaObj );
836 	String aText( aOutliner.GetText( aOutliner.GetParagraph(0),
837 									 aOutliner.GetParagraphCount() ) );
838 	HTMLOutFuncs::Out_String( rWrt.Strm(), aText,
839 						  	  rHTMLWrt.eDestEnc, &rHTMLWrt.aNonConvertableCharacters );
840 
841 	HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_marquee, sal_False );
842 
843 	if( aEndTags.Len() )
844 		rWrt.Strm() << aEndTags.GetBuffer();
845 
846 	return rWrt;
847 }
848 
849 
850