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