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