xref: /AOO41X/main/sw/source/filter/html/htmldraw.cxx (revision 5222b95b3ede3af7a8a07cdec672334a798315fa)
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