xref: /AOO41X/main/sw/source/filter/html/css1atr.cxx (revision dec99bbd1eb6ae693d6ee672c1a69e3a32d917e7)
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 
29 #include "hintids.hxx"
30 #include <vcl/svapp.hxx>
31 #include <vcl/wrkwin.hxx>
32 #include <svl/whiter.hxx>
33 #include <editeng/boxitem.hxx>
34 #include <editeng/ulspitem.hxx>
35 #include <editeng/udlnitem.hxx>
36 #include <editeng/crsditem.hxx>
37 #include <editeng/blnkitem.hxx>
38 #include <editeng/cmapitem.hxx>
39 #include <editeng/colritem.hxx>
40 #include <editeng/fontitem.hxx>
41 #include <editeng/fhgtitem.hxx>
42 #include <editeng/postitem.hxx>
43 #include <editeng/kernitem.hxx>
44 #include <editeng/wghtitem.hxx>
45 #include <editeng/lspcitem.hxx>
46 #include <editeng/adjitem.hxx>
47 #include <editeng/lrspitem.hxx>
48 #include <editeng/ulspitem.hxx>
49 #include <editeng/brshitem.hxx>
50 #include <editeng/brkitem.hxx>
51 #include <editeng/keepitem.hxx>
52 #include <editeng/widwitem.hxx>
53 #include <editeng/spltitem.hxx>
54 #include <editeng/orphitem.hxx>
55 #include <svx/xoutbmp.hxx>
56 #include <svx/svdobj.hxx>
57 #include <editeng/langitem.hxx>
58 #include <editeng/frmdiritem.hxx>
59 #include <svtools/htmlout.hxx>
60 #include <svtools/htmlkywd.hxx>
61 #include <svx/htmlmode.hxx>
62 #include <svl/urihelper.hxx>
63 #include <tools/urlobj.hxx>
64 #include <tools/bigint.hxx>
65 #include <unotools/charclass.hxx>
66 #include <i18npool/mslangid.hxx>
67 #include <charfmt.hxx>
68 #include <fmtcol.hxx>
69 #include <fmtfsize.hxx>
70 #include <fmtornt.hxx>
71 #include <fmtpdsc.hxx>
72 #include <fmtlsplt.hxx>
73 #include <pagedesc.hxx>
74 #include <fmtanchr.hxx>
75 #include <docary.hxx>
76 #include <pam.hxx>
77 #include <viewsh.hxx>
78 #include <viewopt.hxx>
79 #include <swtable.hxx>
80 // OTES
81 #include <ftninfo.hxx>
82 #include <ftnidx.hxx>
83 #include <txtftn.hxx>
84 #include <fmtftn.hxx>
85 // FOOTNOTES
86 #include "doc.hxx"
87 #include "swerror.h"
88 #include "charatr.hxx"
89 #include "paratr.hxx"
90 #include "frmatr.hxx"
91 #include "poolfmt.hxx"
92 #include "fltini.hxx"
93 #include "css1kywd.hxx"
94 #include "wrthtml.hxx"
95 #include "htmlnum.hxx"
96 
97 #include <IDocumentStylePoolAccess.hxx>
98 #include <numrule.hxx>
99 
100 /*
101  * um nicht immer wieder nach einem Update festzustellen, das irgendwelche
102  * Hint-Ids dazugekommen sind, wird hier definiert, die Groesse der Tabelle
103  * definiert und mit der akt. verglichen. Bei unterschieden wird der
104  * Compiler schon meckern.
105  *
106  * diese Section und die dazugeherigen Tabellen muessen in folgenden Files
107  * gepflegt werden: rtf\rtfatr.cxx, sw6\sw6atr.cxx, w4w\w4watr.cxx
108  */
109 #if !defined(UNX) && !defined(MSC) && !defined(PPC) && !defined(CSET) && !defined(__MWERKS__) && !defined(WTC) && !defined(__MINGW32__) && !defined(OS2)
110 
111 #define ATTRFNTAB_SIZE 130
112 #if ATTRFNTAB_SIZE != POOLATTR_END - POOLATTR_BEGIN
113 #error Attribut-Tabelle ist ungueltigt. Wurden neue Hint-IDs zugefuegt ??
114 #endif
115 
116 #endif
117 
118 #define HTML_HEADSPACE (12*20)
119 
120 #define CSS1_BACKGROUND_ATTR    1
121 #define CSS1_BACKGROUND_PAGE    2
122 #define CSS1_BACKGROUND_TABLE   3
123 #define CSS1_BACKGROUND_FLY     4
124 #define CSS1_BACKGROUND_SECTION 5
125 
126 #define CSS1_FRMSIZE_WIDTH      0x01
127 #define CSS1_FRMSIZE_VARHEIGHT  0x02
128 #define CSS1_FRMSIZE_MINHEIGHT  0x04
129 #define CSS1_FRMSIZE_FIXHEIGHT  0x08
130 #define CSS1_FRMSIZE_ANYHEIGHT  0x0e
131 #define CSS1_FRMSIZE_PIXEL      0x10
132 
133 using namespace ::com::sun::star;
134 
135 //-----------------------------------------------------------------------
136 
137 sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_rule_end, " }" );
138 sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sCSS1_span_tag_end, "\">" );
139 const sal_Char cCSS1_style_opt_end = '\"';
140 
141 sal_Char __FAR_DATA CSS1_CONSTASCII_DEF( sHTML_FTN_fontheight, "57%" );
142 
143 extern SwAttrFnTab aCSS1AttrFnTab;
144 
145 static Writer& OutCSS1_SwFmt( Writer& rWrt, const SwFmt& rFmt,
146                               IDocumentStylePoolAccess /*SwDoc*/ *pDoc, SwDoc *pTemplate );
147 static Writer& OutCSS1_SwPageDesc( Writer& rWrt, const SwPageDesc& rFmt,
148                                    IDocumentStylePoolAccess /*SwDoc*/ *pDoc, SwDoc *pTemplate,
149                                    sal_uInt16 nRefPoolId, sal_Bool bExtRef,
150                                    sal_Bool bPseudo=sal_True );
151 static Writer& OutCSS1_SwFtnInfo( Writer& rWrt, const SwEndNoteInfo& rInfo,
152                                   SwDoc *pDoc, sal_uInt16 nNotes, sal_Bool bEndNote );
153 static void OutCSS1_SwFmtDropAttrs( SwHTMLWriter& rHWrt,
154                                     const SwFmtDrop& rDrop,
155                                     const SfxItemSet *pCharFmtItemSet=0 );
156 static Writer& OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink( Writer& rWrt,
157                     const SvxUnderlineItem *pUItem,
158                     const SvxOverlineItem *pOItem,
159                     const SvxCrossedOutItem *pCOItem,
160                     const SvxBlinkItem *pBItem );
161 static Writer& OutCSS1_SvxFontWeight( Writer& rWrt, const SfxPoolItem& rHt );
162 static Writer& OutCSS1_SvxPosture( Writer& rWrt, const SfxPoolItem& rHt );
163 static Writer& OutCSS1_SvxULSpace( Writer& rWrt, const SfxPoolItem& rHt );
164 static Writer& OutCSS1_SvxLRSpace( Writer& rWrt, const SfxPoolItem& rHt );
165 static Writer& OutCSS1_SvxULSpace_SvxLRSpace( Writer& rWrt,
166                                         const SvxULSpaceItem *pULSpace,
167                                         const SvxLRSpaceItem *pLRSpace );
168 static Writer& OutCSS1_SvxULSpace_SvxLRSpace( Writer& rWrt,
169                                         const SfxItemSet& rItemSet,
170                                         sal_Bool bDeep );
171 static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt,
172                                  sal_uInt16 nMode, const String *pGrfName );
173 static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt );
174 static Writer& OutCSS1_SvxBox( Writer& rWrt, const SfxPoolItem& rHt );
175 static Writer& OutCSS1_SwFmtFrmSize( Writer& rWrt, const SfxPoolItem& rHt,
176                                      sal_uInt16 nMode );
177 static Writer& OutCSS1_SvxFmtBreak_SwFmtPDesc_SvxFmtKeep( Writer& rWrt,
178                                         const SfxItemSet& rItemSet,
179                                         sal_Bool bDeep );
180 static Writer& OutCSS1_SwFmtLayoutSplit( Writer& rWrt, const SfxPoolItem& rHt );
181 
ConvToHex(sal_uInt16 nHex,ByteString & rStr)182 static void ConvToHex( sal_uInt16 nHex, ByteString& rStr )
183 {
184     sal_Char aNToABuf[] = "00";
185 
186     // Pointer an das Bufferende setzen
187     sal_Char *pStr = aNToABuf + (sizeof(aNToABuf)-1);
188     for( sal_uInt8 n = 0; n < 2; ++n )
189     {
190         *(--pStr) = (sal_Char)(nHex & 0xf ) + 48;
191         if( *pStr > '9' )
192             *pStr += 39;
193         nHex >>= 4;
194     }
195 
196     rStr.Append( aNToABuf );
197 }
198 
GetCSS1Color(const Color & rColor,ByteString & rStr)199 static void GetCSS1Color( const Color& rColor, ByteString& rStr )
200 {
201     rStr += '#';
202 
203     ConvToHex( rColor.GetRed(), rStr );
204     ConvToHex( rColor.GetGreen(), rStr );
205     ConvToHex( rColor.GetBlue(), rStr );
206 }
207 
208 class SwCSS1OutMode
209 {
210     SwHTMLWriter& rWrt;
211     sal_uInt16 nOldMode;
212 
213 public:
214 
SwCSS1OutMode(SwHTMLWriter & rHWrt,sal_uInt16 nMode,sal_Bool bStartFirst=sal_True,const String * pSelector=0)215     SwCSS1OutMode( SwHTMLWriter& rHWrt, sal_uInt16 nMode, sal_Bool bStartFirst=sal_True,
216                    const String *pSelector=0 ) :
217         rWrt( rHWrt ),
218         nOldMode( rHWrt.nCSS1OutMode )
219     {
220         rWrt.nCSS1OutMode = nMode;
221         if( bStartFirst )
222             rWrt.bFirstCSS1Property = sal_True;
223         if( pSelector )
224             rWrt.aCSS1Selector = *pSelector;
225     }
226 
~SwCSS1OutMode()227     ~SwCSS1OutMode()
228     {
229         rWrt.nCSS1OutMode = nOldMode;
230     }
231 };
232 
233 
234 
OutCSS1_Property(const sal_Char * pProp,const sal_Char * pVal,const String * pSVal)235 void SwHTMLWriter::OutCSS1_Property( const sal_Char *pProp,
236                                      const sal_Char *pVal,
237                                      const String *pSVal )
238 {
239     ByteString sOut;
240 
241     if( bFirstCSS1Rule && (nCSS1OutMode & CSS1_OUTMODE_RULE_ON)!=0 )
242     {
243         bFirstCSS1Rule = sal_False;
244         OutNewLine();
245         ((((sOut += '<') += OOO_STRING_SVTOOLS_HTML_style) += ' ') += OOO_STRING_SVTOOLS_HTML_O_type) += "=\"text/css\">";
246         Strm() << sOut.GetBuffer();
247         sOut.Erase();
248         OutNewLine();
249         Strm() << '<' << OOO_STRING_SVTOOLS_HTML_comment;
250 
251         IncIndentLevel();
252     }
253 
254     if( bFirstCSS1Property )
255     {
256         switch( nCSS1OutMode & CSS1_OUTMODE_ANY_ON )
257         {
258         case CSS1_OUTMODE_SPAN_TAG_ON:
259         case CSS1_OUTMODE_SPAN_TAG1_ON:
260             if( bTagOn )
261             {
262                 ((((sOut += '<') += OOO_STRING_SVTOOLS_HTML_span) += ' ') += OOO_STRING_SVTOOLS_HTML_O_style) += "=\"";
263             }
264             else
265             {
266                 HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_span, sal_False );
267                 return;
268             }
269             break;
270 
271         case CSS1_OUTMODE_RULE_ON:
272             {
273                 ByteString sTmp( aCSS1Selector, eDestEnc );
274                 OutNewLine();
275                 (sOut = sTmp) += " { ";
276             }
277             break;
278 
279         case CSS1_OUTMODE_STYLE_OPT_ON:
280             ((sOut = ' ') += OOO_STRING_SVTOOLS_HTML_O_style) += "=\"";
281             break;
282         }
283         bFirstCSS1Property = sal_False;
284     }
285     else
286     {
287         sOut += "; ";
288     }
289 
290 
291     (sOut += pProp) += ": ";
292     if( nCSS1OutMode & CSS1_OUTMODE_ENCODE )
293     {
294         // In STYLE-Optionen den String codieren
295         Strm() << sOut.GetBuffer();
296         sOut.Erase();
297         if( pVal )
298             HTMLOutFuncs::Out_String( Strm(), String::CreateFromAscii(pVal),
299                                       eDestEnc, &aNonConvertableCharacters );
300         else if( pSVal )
301             HTMLOutFuncs::Out_String( Strm(), *pSVal, eDestEnc, &aNonConvertableCharacters );
302     }
303     else
304     {
305         // Im STYLE-Tag des String direct ausgeben
306         if( pVal )
307             sOut += pVal;
308         else if( pSVal )
309         {
310             ByteString sTmp( *pSVal, eDestEnc );
311             sOut += sTmp;
312         }
313     }
314 
315     if( sOut.Len() )
316         Strm() << sOut.GetBuffer();
317 }
318 
AddUnitPropertyValue(long nVal,FieldUnit eUnit,ByteString & rOut)319 static void AddUnitPropertyValue( long nVal, FieldUnit eUnit, ByteString& rOut )
320 {
321     if( nVal < 0 )
322     {
323         // Vorzeichen extra behandeln
324         nVal = -nVal;
325         rOut += '-';
326     }
327 
328     // Die umgerechnete Einheit ergibt sich aus (x * nMul)/(nDiv*nFac*10)
329     long nMul = 1000;
330     long nDiv = 1;
331     long nFac = 100;
332     const sal_Char *pUnit;
333     switch( eUnit )
334     {
335     case FUNIT_100TH_MM:
336         ASSERT( FUNIT_MM == eUnit, "Masseinheit wird nicht unterstuetzt" );
337     case FUNIT_MM:
338         // 0.01mm = 0.57twip
339         nMul = 25400;   // 25.4 * 1000
340         nDiv = 1440;    // 72 * 20;
341         nFac = 100;
342         pUnit = sCSS1_UNIT_mm;
343         break;
344 
345     case FUNIT_M:
346     case FUNIT_KM:
347         ASSERT( FUNIT_CM == eUnit, "Masseinheit wird nicht unterstuetzt" );
348     case FUNIT_CM:
349 #ifdef EXACT_VALUES
350         // 0.001cm = 0.57twip
351         nMul = 25400;   // 2.54 * 10000
352         nDiv = 1440;    // 72 * 20;
353         nFac = 1000;
354 #else
355         // 0.01cm = 5.7twip (ist zwar ungenau, aber die UI ist auch ungenau)
356         nMul = 2540;    // 2.54 * 1000
357         nDiv = 1440;    // 72 * 20;
358         nFac = 100;
359 #endif
360         pUnit = sCSS1_UNIT_cm;
361         break;
362 
363     case FUNIT_TWIP:
364         ASSERT( FUNIT_POINT == eUnit, "Masseinheit wird nicht unterstuetzt" );
365     case FUNIT_POINT:
366 #ifdef EXACT_VALUES
367         // 0.01pt = 0.2twip
368         nMul = 1000;
369         nDiv = 20;
370         nFac = 100;
371 #else
372         // 0.1pt = 2.0twip (ist zwar ungenau, aber die UI ist auch ungenau)
373         nMul = 100;
374         nDiv = 20;
375         nFac = 10;
376 #endif
377         pUnit = sCSS1_UNIT_pt;
378         break;
379 
380     case FUNIT_PICA:
381 #ifdef EXACT_VALUES
382         // 0.001pc = 0.24twip
383         nMul = 10000;
384         nDiv = 12 * 20;
385         nFac = 1000;
386 #else
387         // 0.01pc = 2.40twip (ist zwar ungenau, aber die UI ist auch ungenau)
388         nMul = 1000;
389         nDiv = 240;     // 12 * 20;
390         nFac = 100;
391 #endif
392         pUnit = sCSS1_UNIT_pc;
393         break;
394 
395     case FUNIT_NONE:
396     case FUNIT_FOOT:
397     case FUNIT_MILE:
398     case FUNIT_CUSTOM:
399     case FUNIT_PERCENT:
400     case FUNIT_INCH:
401     default:
402         ASSERT( FUNIT_INCH == eUnit, "Masseinheit wird nicht unterstuetzt" );
403 #ifdef EXACT_VALUES
404         // 0.0001in = 0.144twip
405         nMul = 100000;
406         nDiv = 1440;    // 72 * 20;
407         nFac = 10000;
408 #else
409         // 0.01in = 14.4twip (ist zwar ungenau, aber die UI ist auch ungenau)
410         nMul = 1000;
411         nDiv = 1440;    // 72 * 20;
412         nFac = 100;
413 #endif
414         pUnit = sCSS1_UNIT_inch;
415         break;
416     }
417 
418     long nLongVal = 0;
419     sal_Bool bOutLongVal = sal_True;
420     if( nVal > LONG_MAX / nMul )
421     {
422         // Zum Unrechnen der Einheit wird ein BigInt benoetigt
423 #ifdef SAL_INT64_IS_STRUCT
424         BigInt nBigVal( nVal );
425         nBigVal *= nMul;
426         nBigVal /= nDiv;
427         nBigVal += 5;
428         nBigVal /= 10;
429 
430         if( nBigVal.IsLong() )
431         {
432             // Zum Ausgeben des Wertes reicht ein long.
433             nLongVal = (long)nBigVal;
434         }
435         else
436         {
437             BigInt nBigFac( nFac );
438             BigInt nBig10( 10 );
439             rOut += (long)(nBigVal / nBigFac);
440             if( !(nBigVal % nBigFac).IsZero() )
441             {
442                 rOut += '.';
443                 while( nFac > 1 && !(nBigVal % nBigFac).IsZero() )
444                 {
445                     nFac /= 10;
446                     nBigFac = nFac;
447                     rOut += (int)((nBigVal / nBigFac) % nBig10 );
448                 }
449             }
450             bOutLongVal = sal_False;
451         }
452 #else
453         sal_Int64 nBigVal( nVal );
454         nBigVal *= nMul;
455         nBigVal /= nDiv;
456         nBigVal += 5;
457         nBigVal /= 10;
458 
459         if( nBigVal <= LONG_MAX )
460         {
461             // Zum Ausgeben des Wertes reicht ein long.
462             nLongVal = (long)nBigVal;
463         }
464         else
465         {
466             rOut += ByteString::CreateFromInt64( nBigVal / (sal_Int64)nFac );
467             if( (nBigVal % (sal_Int64)nFac) != 0 )
468             {
469                 rOut += '.';
470                 while( nFac > 1 && (nBigVal % (sal_Int64)nFac) != 0 )
471                 {
472                     nFac /= 10;
473                     rOut += ByteString::CreateFromInt64(
474                                 (nBigVal / (sal_Int64)nFac) % (sal_Int64)10 );
475                 }
476             }
477             bOutLongVal = sal_False;
478         }
479 #endif
480     }
481     else
482     {
483         nLongVal = nVal * nMul;
484         nLongVal /= nDiv;
485         nLongVal += 5;
486         nLongVal /= 10;
487     }
488 
489     if( bOutLongVal )
490     {
491         rOut += ByteString::CreateFromInt32( nLongVal/nFac );
492         if( (nLongVal % nFac) != 0 )
493         {
494             rOut += '.';
495             while( nFac > 1 && (nLongVal % nFac) != 0 )
496             {
497                 nFac /= 10;
498                 rOut += ByteString::CreateFromInt32( (nLongVal / nFac) % 10 );
499             }
500         }
501     }
502 
503     rOut.Append( pUnit );
504 }
505 
OutCSS1_UnitProperty(const sal_Char * pProp,long nVal)506 void SwHTMLWriter::OutCSS1_UnitProperty( const sal_Char *pProp, long nVal )
507 {
508     ByteString sOut;
509     AddUnitPropertyValue( nVal, eCSS1Unit, sOut );
510     OutCSS1_PropertyAscii( pProp, sOut );
511 }
512 
OutCSS1_PixelProperty(const sal_Char * pProp,long nVal,sal_Bool bVert)513 void SwHTMLWriter::OutCSS1_PixelProperty( const sal_Char *pProp, long nVal,
514                                           sal_Bool bVert )
515 {
516     if( nVal && Application::GetDefaultDevice() )
517     {
518         Size aSz( bVert ? 0 : nVal, bVert ? nVal : 0 );
519         aSz = Application::GetDefaultDevice()->LogicToPixel( aSz, MapMode( MAP_TWIP) );
520         nVal = bVert ? aSz.Height() : aSz.Width();
521         if( !nVal )
522             nVal = 1;
523     }
524 
525     ByteString sOut( ByteString::CreateFromInt32( nVal ) );
526     sOut.Append( sCSS1_UNIT_px );
527     OutCSS1_PropertyAscii( pProp, sOut );
528 }
529 
OutCSS1_SfxItemSet(const SfxItemSet & rItemSet,sal_Bool bDeep)530 void SwHTMLWriter::OutCSS1_SfxItemSet( const SfxItemSet& rItemSet,
531                                        sal_Bool bDeep )
532 {
533     // den ItemSet ausgeben, und zwar inklusive aller Attribute
534     Out_SfxItemSet( aCSS1AttrFnTab, *this, rItemSet, bDeep );
535 
536     // ein par Attribute benoetigen eine Spezial-Behandlung
537     const SfxPoolItem *pItem = 0;
538 
539     // Underline, Overline, CrossedOut und Blink bilden zusammen eine CSS1-Property
540     // (geht natuerlich nicht bei Hints)
541     if( !IsCSS1Source(CSS1_OUTMODE_HINT) )
542     {
543         const SvxUnderlineItem *pUnderlineItem = 0;
544         if( SFX_ITEM_SET==rItemSet.GetItemState( RES_CHRATR_UNDERLINE, bDeep, &pItem ))
545             pUnderlineItem = (const SvxUnderlineItem *)pItem;
546 
547         const SvxOverlineItem *pOverlineItem = 0;
548         if( SFX_ITEM_SET==rItemSet.GetItemState( RES_CHRATR_OVERLINE, bDeep, &pItem ))
549             pOverlineItem = (const SvxOverlineItem *)pItem;
550 
551         const SvxCrossedOutItem *pCrossedOutItem = 0;
552         if( SFX_ITEM_SET==rItemSet.GetItemState( RES_CHRATR_CROSSEDOUT, bDeep, &pItem ))
553             pCrossedOutItem = (const SvxCrossedOutItem *)pItem;
554 
555         const SvxBlinkItem *pBlinkItem = 0;
556         if( SFX_ITEM_SET==rItemSet.GetItemState( RES_CHRATR_BLINK, bDeep, &pItem ))
557             pBlinkItem = (const SvxBlinkItem *)pItem;
558 
559         if( pUnderlineItem || pOverlineItem || pCrossedOutItem || pBlinkItem )
560             OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink( *this, pUnderlineItem,
561                                                  pOverlineItem,
562                                                  pCrossedOutItem,
563                                                  pBlinkItem );
564 
565         OutCSS1_SvxFmtBreak_SwFmtPDesc_SvxFmtKeep( *this, rItemSet, bDeep );
566     }
567 
568     if( !bFirstCSS1Property )
569     {
570         // wenn eine Property als Bestandteil einer Style-Option
571         // ausgegeben wurde, muss die Optiomn noch beendet werden
572         ByteString sOut;
573         switch( nCSS1OutMode & CSS1_OUTMODE_ANY_OFF )
574         {
575         case CSS1_OUTMODE_SPAN_TAG_OFF:
576             sOut = sCSS1_span_tag_end;
577             break;
578 
579         case CSS1_OUTMODE_STYLE_OPT_OFF:
580             sOut = cCSS1_style_opt_end;
581             break;
582 
583         case CSS1_OUTMODE_RULE_OFF:
584             sOut = sCSS1_rule_end;
585             break;
586         }
587         if( sOut.Len() )
588             Strm() << sOut.GetBuffer();
589     }
590 }
591 
OutStyleSheet(const SwPageDesc & rPageDesc,sal_Bool bUsed)592 void SwHTMLWriter::OutStyleSheet( const SwPageDesc& rPageDesc, sal_Bool bUsed )
593 {
594     bFirstCSS1Rule = sal_True;
595 
596 // Feature: PrintExt
597     if( IsHTMLMode(HTMLMODE_PRINT_EXT) )
598     {
599         const SwPageDesc *pFirstPageDesc = 0;
600         sal_uInt16 nFirstRefPoolId = RES_POOLPAGE_HTML;
601         bCSS1IgnoreFirstPageDesc = sal_True;
602 
603         // Erstmal versuchen wir zu erraten, wie das Dokument so augebaut ist.
604         // Erlaubt sind nur die Vorlagen HTML, erste Seite, linke Seite und
605         // rechte Seite.
606         // Eine erste Seite wird nur exportiert, wenn die erste Seite auch
607         // wirklich die Vorlage "erste Seite" ist.
608         // Linke und rechte Seiten werden nur exportiert, wenn diese beiden
609         // Vorlagen untereinander verkettet werden.
610         // Wenn andere Vorlagen verwendet werden, wird nur in sehr einfachen
611         // Faellen etwas exportiert.
612         const SwPageDesc *pPageDesc = &rPageDesc;
613         const SwPageDesc *pFollow = rPageDesc.GetFollow();
614         if( RES_POOLPAGE_FIRST == pPageDesc->GetPoolFmtId() &&
615             pFollow != pPageDesc &&
616             !IsPoolUserFmt( pFollow->GetPoolFmtId() ) )
617         {
618             // Das Dokument hat eine erste Seite
619             pFirstPageDesc = pPageDesc;
620             pPageDesc = pFollow;
621             pFollow = pPageDesc->GetFollow();
622         }
623 
624         IDocumentStylePoolAccess* pStylePoolAccess = getIDocumentStylePoolAccess();
625         if( pPageDesc == pFollow )
626         {
627             // Das Dokument ist einseitig. Egal welche Seite verwendet wird,
628             // es wird kein zweiseitiges Dokument daraus gemacht.
629             // Die Attributierung wird relativ zur HTML-Seitenvorlage
630             // aus der HTML-Vorlage exportiert.
631           OutCSS1_SwPageDesc( *this, *pPageDesc, pStylePoolAccess, pTemplate,
632                                 RES_POOLPAGE_HTML, sal_True, sal_False );
633             nFirstRefPoolId = pFollow->GetPoolFmtId();
634         }
635         else if( (RES_POOLPAGE_LEFT == pPageDesc->GetPoolFmtId() &&
636                   RES_POOLPAGE_RIGHT == pFollow->GetPoolFmtId()) ||
637                  (RES_POOLPAGE_RIGHT == pPageDesc->GetPoolFmtId() &&
638                   RES_POOLPAGE_LEFT == pFollow->GetPoolFmtId()) )
639         {
640             // Das Dokument ist zweiseitig
641           OutCSS1_SwPageDesc( *this, *pPageDesc, pStylePoolAccess, pTemplate,
642                                 RES_POOLPAGE_HTML, sal_True );
643           OutCSS1_SwPageDesc( *this, *pFollow, pStylePoolAccess, pTemplate,
644                                 RES_POOLPAGE_HTML, sal_True );
645             nFirstRefPoolId = RES_POOLPAGE_RIGHT;
646             bCSS1IgnoreFirstPageDesc = sal_False;
647         }
648         // Alles andere bekommen wir nicht hin.
649 
650         if( pFirstPageDesc )
651           OutCSS1_SwPageDesc( *this, *pFirstPageDesc, pStylePoolAccess, pTemplate,
652                                 nFirstRefPoolId, sal_False );
653     }
654 // /Feature: PrintExt
655 
656 
657     // The text body style has to be exported always (if it is changed compared
658     // to the template), because it is used as reference for any style
659     // that maps to <P>, and that's especially the standard style
660     getIDocumentStylePoolAccess()->GetTxtCollFromPool( RES_POOLCOLL_TEXT, false );
661 
662     // das Default-TextStyle wir nicht mit ausgegeben !!
663     // das 0-Style ist das Default, wird nie ausgegeben !!
664     sal_uInt16 nArrLen = pDoc->GetTxtFmtColls()->Count();
665     sal_uInt16 i;
666 
667     for( i = 1; i < nArrLen; i++ )
668     {
669         const SwTxtFmtColl* pColl = (*pDoc->GetTxtFmtColls())[i];
670         sal_uInt16 nPoolId = pColl->GetPoolFmtId();
671         if( !bUsed || nPoolId == RES_POOLCOLL_TEXT ||
672             pDoc->IsUsed( *pColl ) )
673             OutCSS1_SwFmt( *this, *pColl, pDoc, pTemplate );
674     }
675 
676     // das Default-TextStyle wir nicht mit ausgegeben !!
677     nArrLen = pDoc->GetCharFmts()->Count();
678     for( i=1; i<nArrLen; i++ )
679     {
680         const SwCharFmt *pCFmt = (*pDoc->GetCharFmts())[i];
681         sal_uInt16 nPoolId = pCFmt->GetPoolFmtId();
682         if( !bUsed || nPoolId == RES_POOLCHR_INET_NORMAL ||
683             nPoolId == RES_POOLCHR_INET_VISIT ||
684             pDoc->IsUsed( *pCFmt ) )
685             OutCSS1_SwFmt( *this, *pCFmt, pDoc, pTemplate );
686     }
687 
688     const SwFtnIdxs& rIdxs = pDoc->GetFtnIdxs();
689     nArrLen = rIdxs.Count();
690     sal_uInt16 nEnd = 0, nFtn = 0;
691     for( i=0; i < nArrLen; i++ )
692     {
693         if( rIdxs[i]->GetFtn().IsEndNote() )
694             nEnd++;
695         else
696             nFtn++;
697     }
698     OutCSS1_SwFtnInfo( *this, pDoc->GetFtnInfo(), pDoc, nFtn, sal_False );
699     OutCSS1_SwFtnInfo( *this, pDoc->GetEndNoteInfo(), pDoc, nEnd, sal_True );
700 
701     if( !bFirstCSS1Rule )
702     {
703         DecIndentLevel();
704         OutNewLine();
705         Strm() << "-->";
706 
707         OutNewLine();
708         HTMLOutFuncs::Out_AsciiTag( Strm(), OOO_STRING_SVTOOLS_HTML_style, sal_False );
709     }
710     else
711     {
712         bFirstCSS1Rule = sal_False;
713     }
714 
715     nDfltTopMargin = 0;
716     nDfltBottomMargin = 0;
717 }
718 
719 //-----------------------------------------------------------------------
720 
721 // wenn pPseudo gesetzt ist werden Styles-Sheets ausgegeben,
722 // sonst wird nur nach Token und Class fuer ein Format gesucht
GetCSS1Selector(const SwFmt * pFmt,ByteString & rToken,String & rClass,sal_uInt16 & rRefPoolId,String * pPseudo)723 sal_uInt16 SwHTMLWriter::GetCSS1Selector( const SwFmt *pFmt, ByteString& rToken,
724                                       String& rClass, sal_uInt16& rRefPoolId,
725                                       String *pPseudo )
726 {
727     sal_uInt16 nDeep = 0;
728     rToken.Erase(); rClass.Erase();
729     rRefPoolId = 0;
730     if( pPseudo )
731         pPseudo->Erase();
732 
733     sal_Bool bChrFmt = RES_CHRFMT==pFmt->Which();
734 
735     // Nach oben die Formate abklappern, bis man auf eine Standard-
736     // oder eine HTML-Tag-Vorlage trifft
737     const SwFmt *pPFmt = pFmt;
738     while( pPFmt && !pPFmt->IsDefault() )
739     {
740         sal_Bool bStop = sal_False;
741         sal_uInt16 nPoolId = pPFmt->GetPoolFmtId();
742         if( USER_FMT & nPoolId )
743         {
744             // Benutzer-Vorlagen
745             const String& rNm = pPFmt->GetName();
746             switch( rNm.GetChar(0) )
747             {
748                         // nicht mehr unterstuetzt:
749                         // OOO_STRING_SVTOOLS_HTML_author
750                         // OOO_STRING_SVTOOLS_HTML_acronym
751                         // OOO_STRING_SVTOOLS_HTML_abbreviation
752                         // OOO_STRING_SVTOOLS_HTML_deletedtext
753                         // OOO_STRING_SVTOOLS_HTML_insertedtext
754                         // OOO_STRING_SVTOOLS_HTML_language
755                         // OOO_STRING_SVTOOLS_HTML_person
756             case 'B':   if( !bChrFmt && rNm.EqualsAscii(OOO_STRING_SVTOOLS_HTML_blockquote) )
757                         {
758                             rRefPoolId = RES_POOLCOLL_HTML_BLOCKQUOTE;
759                             rToken.Assign( OOO_STRING_SVTOOLS_HTML_blockquote );
760                         }
761                         break;
762             case 'C':   if( bChrFmt )
763                         {
764                             if( rNm.EqualsAscii(OOO_STRING_SVTOOLS_HTML_citiation) )
765                             {
766                                 rRefPoolId = RES_POOLCHR_HTML_CITIATION;
767                                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_citiation );
768                             }
769                             else if( rNm.EqualsAscii(OOO_STRING_SVTOOLS_HTML_code) )
770                             {
771                                 rRefPoolId = RES_POOLCHR_HTML_CODE;
772                                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_code );
773                             }
774                         }
775                         break;
776             case 'D':   if( bChrFmt && rNm.EqualsAscii(OOO_STRING_SVTOOLS_HTML_definstance) )
777                         {
778                             rRefPoolId = RES_POOLCHR_HTML_DEFINSTANCE;
779                             rToken.Assign( OOO_STRING_SVTOOLS_HTML_definstance);
780                         }
781                         else if( !bChrFmt )
782                         {
783                             sal_uInt16 nDefListLvl = GetDefListLvl( rNm, nPoolId );
784                             // Die Vorlagen DD 1/DT 1 werden ausgegeben,
785                             // aber keine von ihnen abgeleiteten Vorlagen,
786                             // auch nicht DD 2/DT 2 etc.
787                             if( nDefListLvl )
788                             {
789                                 if( pPseudo &&
790                                     (nDeep || (nDefListLvl & 0x0fff) > 1) )
791                                 {
792                                     bStop = sal_True;
793                                 }
794                                 else if( nDefListLvl & HTML_DLCOLL_DD )
795                                 {
796                                     rRefPoolId = RES_POOLCOLL_HTML_DD;
797                                     rToken.Assign( OOO_STRING_SVTOOLS_HTML_dd );
798                                 }
799                                 else
800                                 {
801                                     rRefPoolId = RES_POOLCOLL_HTML_DT;
802                                     rToken.Assign( OOO_STRING_SVTOOLS_HTML_dt );
803                                 }
804                             }
805                         }
806                         break;
807             case 'E':   if( bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_emphasis ) )
808                         {
809                             rRefPoolId = RES_POOLCHR_HTML_EMPHASIS;
810                             rToken.Assign( OOO_STRING_SVTOOLS_HTML_emphasis );
811                         }
812                         break;
813             case 'H':   if( !bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_horzrule ) )
814                             // HR nicht ausgeben!
815                             bStop = (nDeep==0);
816                         break;
817             case 'K':   if( bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_keyboard ) )
818                         {
819                             rRefPoolId = RES_POOLCHR_HTML_KEYBOARD;
820                             rToken.Assign( OOO_STRING_SVTOOLS_HTML_keyboard );
821                         }
822                         break;
823             case 'L':   if( !bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_listing ) )
824                         {
825                             // Listing als PRE exportieren bzw. von
826                             // PRE abgeleitete Vorlage exportieren
827                             rToken.Assign( OOO_STRING_SVTOOLS_HTML_preformtxt );
828                             rRefPoolId = RES_POOLCOLL_HTML_PRE;
829                             nDeep = CSS1_FMT_CMPREF;
830                         }
831                         break;
832             case 'P':   if( !bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_preformtxt ) )
833                         {
834                             rRefPoolId = RES_POOLCOLL_HTML_PRE;
835                             rToken.Assign( OOO_STRING_SVTOOLS_HTML_preformtxt );
836                         }
837                         break;
838             case 'S':   if( bChrFmt )
839                         {
840                             if( rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_sample ) )
841                             {
842                                 rRefPoolId = RES_POOLCHR_HTML_SAMPLE;
843                                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_sample );
844                             }
845                             else if( rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_strong ) )
846                             {
847                                 rRefPoolId = RES_POOLCHR_HTML_STRONG;
848                                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_strong );
849                             }
850                         }
851                         break;
852             case 'T':   if( bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_teletype ) )
853                         {
854                             rRefPoolId = RES_POOLCHR_HTML_TELETYPE;
855                             rToken.Assign( OOO_STRING_SVTOOLS_HTML_teletype );
856                         }
857                         break;
858             case 'V':   if( bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_variable ) )
859                         {
860                             rRefPoolId = RES_POOLCHR_HTML_VARIABLE;
861                             rToken.Assign( OOO_STRING_SVTOOLS_HTML_variable );
862                         }
863                         break;
864             case 'X':   if( !bChrFmt && rNm.EqualsAscii( OOO_STRING_SVTOOLS_HTML_xmp ) )
865                         {
866                             // XMP als PRE exportieren (aber nicht die
867                             // Vorlage als Style)
868                             rToken.Assign( OOO_STRING_SVTOOLS_HTML_preformtxt );
869                             rRefPoolId = RES_POOLCOLL_HTML_PRE;
870                             nDeep = CSS1_FMT_CMPREF;
871                         }
872                         break;
873             }
874 
875             // Wenn eine PoolId gesetzt ist, entspricht der Name der
876             // Vorlage dem szugehoerigen Token
877             ASSERT( rRefPoolId != 0 == rToken.Len() > 0,
878                     "Token missing" );
879         }
880         else
881         {
882             // Pool-Vorlagen
883             switch( nPoolId )
884             {
885             // Absatz-Vorlagen
886             case RES_POOLCOLL_HEADLINE_BASE:
887             case RES_POOLCOLL_STANDARD:
888                 // diese Vorlagen nicht ausgeben
889                 bStop = (nDeep==0);
890                 break;
891             case RES_POOLCOLL_TEXT:
892                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_parabreak );
893                 break;
894             case RES_POOLCOLL_HEADLINE1:
895                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_head1 );
896                 break;
897             case RES_POOLCOLL_HEADLINE2:
898                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_head2 );
899                 break;
900             case RES_POOLCOLL_HEADLINE3:
901                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_head3 );
902                 break;
903             case RES_POOLCOLL_HEADLINE4:
904                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_head4 );
905                 break;
906             case RES_POOLCOLL_HEADLINE5:
907                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_head5 );
908                 break;
909             case RES_POOLCOLL_HEADLINE6:
910                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_head6 );
911                 break;
912             case RES_POOLCOLL_SENDADRESS:
913                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_address );
914                 break;
915             case RES_POOLCOLL_HTML_BLOCKQUOTE:
916                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_blockquote );
917                 break;
918             case RES_POOLCOLL_HTML_PRE:
919                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_preformtxt );
920                 break;
921 
922             case RES_POOLCOLL_HTML_DD:
923                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_dd );
924                 break;
925             case RES_POOLCOLL_HTML_DT:
926                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_dt );
927                 break;
928 
929             case RES_POOLCOLL_TABLE:
930                 if( pPseudo )
931                 {
932                     rToken.Assign( OOO_STRING_SVTOOLS_HTML_tabledata );
933                     rToken.Append( ' ' );
934                     rToken.Append( OOO_STRING_SVTOOLS_HTML_parabreak );
935                 }
936                 else
937                     rToken.Assign( OOO_STRING_SVTOOLS_HTML_parabreak );
938                 break;
939             case RES_POOLCOLL_TABLE_HDLN:
940                 if( pPseudo )
941                 {
942                     rToken.Assign( OOO_STRING_SVTOOLS_HTML_tableheader );
943                     rToken.Append( ' ' );
944                     rToken.Append( OOO_STRING_SVTOOLS_HTML_parabreak );
945                 }
946                 else
947                     rToken.Assign( OOO_STRING_SVTOOLS_HTML_parabreak );
948                 break;
949             case RES_POOLCOLL_HTML_HR:
950                 // HR nicht ausgeben!
951                 bStop = (nDeep==0);
952                 break;
953             case RES_POOLCOLL_FOOTNOTE:
954                 if( !nDeep )
955                 {
956                     rToken.Assign( OOO_STRING_SVTOOLS_HTML_parabreak );
957                     rClass.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote );
958                     rRefPoolId = RES_POOLCOLL_TEXT;
959                     nDeep = CSS1_FMT_CMPREF;
960                 }
961                 break;
962             case RES_POOLCOLL_ENDNOTE:
963                 if( !nDeep )
964                 {
965                     rToken.Assign( OOO_STRING_SVTOOLS_HTML_parabreak );
966                     rClass.AssignAscii( OOO_STRING_SVTOOLS_HTML_sdendnote );
967                     rRefPoolId = RES_POOLCOLL_TEXT;
968                     nDeep = CSS1_FMT_CMPREF;
969                 }
970                 break;
971 
972             // Zeichen-Vorlagen
973             case RES_POOLCHR_HTML_EMPHASIS:
974                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_emphasis );
975                 break;
976             case RES_POOLCHR_HTML_CITIATION:
977                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_citiation );
978                 break;
979             case RES_POOLCHR_HTML_STRONG:
980                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_strong );
981                 break;
982             case RES_POOLCHR_HTML_CODE:
983                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_code );
984                 break;
985             case RES_POOLCHR_HTML_SAMPLE:
986                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_sample );
987                 break;
988             case RES_POOLCHR_HTML_KEYBOARD:
989                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_keyboard );
990                 break;
991             case RES_POOLCHR_HTML_VARIABLE:
992                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_variable );
993                 break;
994             case RES_POOLCHR_HTML_DEFINSTANCE:
995                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_definstance );
996                 break;
997             case RES_POOLCHR_HTML_TELETYPE:
998                 rToken.Assign( OOO_STRING_SVTOOLS_HTML_teletype );
999                 break;
1000 
1001             case RES_POOLCHR_INET_NORMAL:
1002                 if( pPseudo )
1003                 {
1004                     rToken.Assign( OOO_STRING_SVTOOLS_HTML_anchor );
1005                     pPseudo->AssignAscii( sCSS1_link );
1006                 }
1007                 break;
1008             case RES_POOLCHR_INET_VISIT:
1009                 if( pPseudo )
1010                 {
1011                     rToken.Assign( OOO_STRING_SVTOOLS_HTML_anchor );
1012                     pPseudo->AssignAscii( sCSS1_visited );
1013                 }
1014                 break;
1015             }
1016 
1017             // Wenn ein Token gesetzt ist, enthaelt nPoolId die dazugehoerige
1018             // Vorlage
1019             if( rToken.Len() && !rRefPoolId )
1020                 rRefPoolId = nPoolId;
1021         }
1022 
1023         if( rToken.Len() || bStop )
1024         {
1025             // Anhalten wenn eine HTML-Tag-Vorlage gefunden wurde
1026             break;
1027         }
1028         else
1029         {
1030             // sonst weitersuchen
1031             nDeep++;
1032             pPFmt = pPFmt->DerivedFrom();
1033         }
1034     }
1035 
1036     if( rToken.Len() )
1037     {
1038         // Es ist eine HTML-Tag-Vorlage
1039         if( !nDeep )
1040             nDeep = CSS1_FMT_ISTAG;
1041     }
1042     else
1043     {
1044         // Es ist keine HTML-Tag-Vorlage und auch keine davon abgeleitete
1045         nDeep = 0;
1046     }
1047     if( nDeep > 0 && nDeep < CSS1_FMT_SPECIAL )
1048     {
1049         // Wenn die Vorlage von einer HTML-Vorlage abgeleitet ist,
1050         // wird sie als <TOKEN>.<CLASS> exportiert, sonst als .<CLASS>.
1051         // <CLASS> ergibt sich aus dem Namen der Vorlage durch entfernen
1052         // aller Zeichen vor und inklusive dem ersten '.'
1053         rClass = pFmt->GetName();
1054         xub_StrLen nPos = rClass.Search( '.' );
1055         if( nPos != STRING_NOTFOUND && rClass.Len() > nPos+1 )
1056         {
1057             rClass.Erase( 0, nPos+1 );
1058         }
1059 
1060         GetAppCharClass().toLower( rClass );
1061         while( STRING_NOTFOUND != rClass.SearchAndReplace( '.', '-' ) )
1062             ;
1063         while( STRING_NOTFOUND != rClass.SearchAndReplace( ' ', '-' ) )
1064             ;
1065         while( STRING_NOTFOUND != rClass.SearchAndReplace( '_', '-' ) )
1066             ;
1067     }
1068 
1069     return nDeep;
1070 }
1071 
GetCSS1Selector(const SwFmt * pFmt,String & rSelector,sal_uInt16 & rRefPoolId)1072 static sal_uInt16 GetCSS1Selector( const SwFmt *pFmt, String& rSelector,
1073                                sal_uInt16& rRefPoolId )
1074 {
1075     ByteString aToken;
1076     String aClass;
1077     String aPseudo;
1078 
1079     sal_uInt16 nDeep = SwHTMLWriter::GetCSS1Selector( pFmt, aToken, aClass,
1080                                                   rRefPoolId, &aPseudo );
1081     if( nDeep )
1082     {
1083         if( aToken.Len() )
1084             rSelector = String( aToken, RTL_TEXTENCODING_ASCII_US );
1085         else
1086             rSelector.Erase();
1087 
1088         if( aClass.Len() )
1089             (rSelector += '.') += aClass;
1090         if( aPseudo.Len() )
1091             (rSelector += ':') += aPseudo;
1092     }
1093 
1094     return nDeep;
1095 }
1096 
GetTemplateFmt(sal_uInt16 nPoolFmtId,IDocumentStylePoolAccess * pTemplate)1097 const SwFmt *SwHTMLWriter::GetTemplateFmt( sal_uInt16 nPoolFmtId,
1098                                            IDocumentStylePoolAccess* pTemplate /*SwDoc *pTemplate*/)
1099 {
1100     const SwFmt *pRefFmt = 0;
1101 
1102     if( pTemplate )
1103     {
1104         ASSERT( !(USER_FMT & nPoolFmtId),
1105                 "In der Dok-Vorlage gibt es keine Benutzer-Vorlagen" );
1106         if( POOLGRP_NOCOLLID & nPoolFmtId )
1107             pRefFmt = pTemplate->GetCharFmtFromPool( nPoolFmtId );
1108         else
1109             pRefFmt = pTemplate->GetTxtCollFromPool( nPoolFmtId, false );
1110     }
1111 
1112     return pRefFmt;
1113 }
1114 
GetParentFmt(const SwFmt & rFmt,sal_uInt16 nDeep)1115 const SwFmt *SwHTMLWriter::GetParentFmt( const SwFmt& rFmt, sal_uInt16 nDeep )
1116 {
1117     ASSERT( nDeep != USHRT_MAX, "GetParent fuer HTML-Vorlage aufgerufen!" );
1118     const SwFmt *pRefFmt = 0;
1119 
1120     if( nDeep > 0 )
1121     {
1122         // hier wird die HTML-Tag-Vorlage, von der die Vorlage abgeleitet
1123         // ist als Referenz geholt
1124         pRefFmt = &rFmt;
1125         for( sal_uInt16 i=nDeep; i>0; i-- )
1126             pRefFmt = pRefFmt->DerivedFrom();
1127 
1128         if( pRefFmt && pRefFmt->IsDefault() )
1129             pRefFmt = 0;
1130     }
1131 
1132     return pRefFmt;
1133 }
1134 
lcl_css1atr_equalFontItems(const SfxPoolItem & r1,const SfxPoolItem & r2)1135 sal_Bool lcl_css1atr_equalFontItems( const SfxPoolItem& r1, const SfxPoolItem& r2 )
1136 {
1137     return  ((const SvxFontItem &)r1).GetFamilyName() ==
1138                     ((const SvxFontItem &)r2).GetFamilyName() &&
1139             ((const SvxFontItem &)r1).GetFamily() ==
1140                     ((const SvxFontItem &)r2).GetFamily();
1141 }
1142 
SubtractItemSet(SfxItemSet & rItemSet,const SfxItemSet & rRefItemSet,sal_Bool bSetDefaults,sal_Bool bClearSame,const SfxItemSet * pRefScriptItemSet)1143 void SwHTMLWriter::SubtractItemSet( SfxItemSet& rItemSet,
1144                                     const SfxItemSet& rRefItemSet,
1145                                     sal_Bool bSetDefaults,
1146                                     sal_Bool bClearSame,
1147                                     const SfxItemSet *pRefScriptItemSet )
1148 {
1149     ASSERT( bSetDefaults || bClearSame,
1150             "SwHTMLWriter::SubtractItemSet: Bei diesen Flags passiert nix" );
1151     SfxItemSet aRefItemSet( *rRefItemSet.GetPool(), rRefItemSet.GetRanges() );
1152     aRefItemSet.Set( rRefItemSet );
1153 
1154     // und mit dem Attr-Set der Vorlage vergleichen
1155     SfxWhichIter aIter( rItemSet );
1156     sal_uInt16 nWhich = aIter.FirstWhich();
1157     while( nWhich )
1158     {
1159         const SfxPoolItem *pRefItem, *pItem;
1160         sal_Bool bItemSet = ( SFX_ITEM_SET ==
1161                 rItemSet.GetItemState( nWhich, sal_False, &pItem) );
1162         sal_Bool bRefItemSet;
1163 
1164         if( pRefScriptItemSet )
1165         {
1166             switch( nWhich )
1167             {
1168             case RES_CHRATR_FONT:
1169             case RES_CHRATR_FONTSIZE:
1170             case RES_CHRATR_LANGUAGE:
1171             case RES_CHRATR_POSTURE:
1172             case RES_CHRATR_WEIGHT:
1173             case RES_CHRATR_CJK_FONT:
1174             case RES_CHRATR_CJK_FONTSIZE:
1175             case RES_CHRATR_CJK_LANGUAGE:
1176             case RES_CHRATR_CJK_POSTURE:
1177             case RES_CHRATR_CJK_WEIGHT:
1178             case RES_CHRATR_CTL_FONT:
1179             case RES_CHRATR_CTL_FONTSIZE:
1180             case RES_CHRATR_CTL_LANGUAGE:
1181             case RES_CHRATR_CTL_POSTURE:
1182             case RES_CHRATR_CTL_WEIGHT:
1183                 bRefItemSet = ( SFX_ITEM_SET ==
1184                     pRefScriptItemSet->GetItemState( nWhich, sal_True, &pRefItem) );
1185                 break;
1186             default:
1187                 bRefItemSet = ( SFX_ITEM_SET ==
1188                     aRefItemSet.GetItemState( nWhich, sal_False, &pRefItem) );
1189                 break;
1190             }
1191         }
1192         else
1193         {
1194             bRefItemSet = ( SFX_ITEM_SET ==
1195                 aRefItemSet.GetItemState( nWhich, sal_False, &pRefItem) );
1196         }
1197 
1198         if( bItemSet )
1199         {
1200             if( (bClearSame || pRefScriptItemSet) && bRefItemSet &&
1201                 ( *pItem == *pRefItem ||
1202                   ((RES_CHRATR_FONT == nWhich ||
1203                     RES_CHRATR_CJK_FONT == nWhich ||
1204                     RES_CHRATR_CTL_FONT == nWhich)  &&
1205                    lcl_css1atr_equalFontItems( *pItem, *pRefItem )) ) )
1206             {
1207                 // das Attribut ist mit dem gleichen Wert in beiden
1208                 // Vorlagen vorhanden und muss nicht ausgegeben werden
1209                 rItemSet.ClearItem( nWhich );
1210             }
1211         }
1212         else
1213         {
1214             if( (bSetDefaults || pRefScriptItemSet) && bRefItemSet )
1215             {
1216                 // das Attribut ist nur in der Referenz vorhanden. Das
1217                 // Default muss ggf. ausgegeben werden
1218                 rItemSet.Put( rItemSet.GetPool()->GetDefaultItem(nWhich) );
1219             }
1220         }
1221 
1222         nWhich = aIter.NextWhich();
1223     }
1224 }
1225 
PrepareFontList(const SvxFontItem & rFontItem,String & rNames,sal_Unicode cQuote,sal_Bool bGeneric)1226 void SwHTMLWriter::PrepareFontList( const SvxFontItem& rFontItem,
1227                                     String& rNames,
1228                                     sal_Unicode cQuote, sal_Bool bGeneric )
1229 {
1230     rNames = aEmptyStr;
1231     const String& rName = rFontItem.GetFamilyName();
1232     sal_Bool bContainsKeyword = sal_False;
1233     if( rName.Len() )
1234     {
1235         xub_StrLen nStrPos = 0;
1236         while( nStrPos != STRING_NOTFOUND )
1237         {
1238             String aName = rName.GetToken( 0, ';', nStrPos );
1239             aName.EraseTrailingChars().EraseLeadingChars();
1240             if( !aName.Len() )
1241                 continue;
1242 
1243             sal_Bool bIsKeyword = sal_False;
1244             switch( aName.GetChar( 0 ) )
1245             {
1246             case 'c':
1247             case 'C':
1248                 bIsKeyword = aName.EqualsIgnoreCaseAscii( sCSS1_PV_cursive );
1249                 break;
1250 
1251             case 'f':
1252             case 'F':
1253                 bIsKeyword = aName.EqualsIgnoreCaseAscii( sCSS1_PV_fantasy );
1254                 break;
1255 
1256             case 'm':
1257             case 'M':
1258                 bIsKeyword = aName.EqualsIgnoreCaseAscii( sCSS1_PV_monospace );
1259                 break;
1260 
1261             case 's':
1262             case 'S':
1263                 bIsKeyword =
1264                     aName.EqualsIgnoreCaseAscii( sCSS1_PV_serif ) ||
1265                     aName.EqualsIgnoreCaseAscii( sCSS1_PV_sans_serif );
1266                 break;
1267             }
1268 
1269             bContainsKeyword |= bIsKeyword;
1270 
1271             if( rNames.Len() )
1272                 rNames.AppendAscii( ", " );
1273             if( cQuote && !bIsKeyword )
1274                 rNames += cQuote;
1275             rNames += aName;
1276             if( cQuote && !bIsKeyword )
1277                 rNames += cQuote;
1278         }
1279     }
1280 
1281     if( !bContainsKeyword && bGeneric )
1282     {
1283         const sal_Char *pStr = 0;
1284         switch( rFontItem.GetFamily() )
1285         {
1286         case FAMILY_ROMAN:      pStr = sCSS1_PV_serif;      break;
1287         case FAMILY_SWISS:      pStr = sCSS1_PV_sans_serif; break;
1288         case FAMILY_SCRIPT:     pStr = sCSS1_PV_cursive;    break;
1289         case FAMILY_DECORATIVE: pStr = sCSS1_PV_fantasy;    break;
1290         case FAMILY_MODERN:     pStr = sCSS1_PV_monospace;  break;
1291         default:
1292             ;
1293         }
1294 
1295         if( pStr )
1296         {
1297             if( rNames.Len() )
1298                 rNames.AppendAscii( ", " );
1299             rNames.AppendAscii( pStr );
1300         }
1301     }
1302 }
1303 
HasScriptDependentItems(const SfxItemSet & rItemSet,sal_Bool bCheckDropCap)1304 sal_Bool SwHTMLWriter::HasScriptDependentItems( const SfxItemSet& rItemSet,
1305                                                 sal_Bool bCheckDropCap )
1306 {
1307     static sal_uInt16 aWhichIds[] =
1308     {
1309         RES_CHRATR_FONT,        RES_CHRATR_CJK_FONT,        RES_CHRATR_CTL_FONT,
1310         RES_CHRATR_FONTSIZE,    RES_CHRATR_CJK_FONTSIZE,    RES_CHRATR_CTL_FONTSIZE,
1311         RES_CHRATR_LANGUAGE,    RES_CHRATR_CJK_LANGUAGE,    RES_CHRATR_CTL_LANGUAGE,
1312         RES_CHRATR_POSTURE,     RES_CHRATR_CJK_POSTURE,     RES_CHRATR_CTL_POSTURE,
1313         RES_CHRATR_WEIGHT,      RES_CHRATR_CJK_WEIGHT,      RES_CHRATR_CTL_WEIGHT,
1314         0,                      0,                          0
1315     };
1316 
1317     for( sal_uInt16 i=0; aWhichIds[i]; i += 3 )
1318     {
1319         const SfxPoolItem *pItem = 0, *pItemCJK = 0, *pItemCTL = 0, *pTmp;
1320         sal_uInt16 nItemCount = 0;
1321         if( SFX_ITEM_SET == rItemSet.GetItemState( aWhichIds[i], sal_False,
1322                                                    &pTmp ) )
1323         {
1324             pItem = pTmp;
1325             nItemCount++;
1326         }
1327         if( SFX_ITEM_SET == rItemSet.GetItemState( aWhichIds[i+1], sal_False,
1328                                                    &pTmp ) )
1329         {
1330             pItemCJK = pTmp;
1331             nItemCount++;
1332         }
1333         if( SFX_ITEM_SET == rItemSet.GetItemState( aWhichIds[i+2], sal_False,
1334                                                    &pTmp ) )
1335         {
1336             pItemCTL = pTmp;
1337             nItemCount++;
1338         }
1339 
1340         // If some of the items are set, but not all, we need script dependent
1341         // styles
1342         if( nItemCount > 0 && nItemCount < 3 )
1343             return sal_True;
1344 
1345         if( 3 == nItemCount )
1346         {
1347             // If all items are set, but some of them have different values,
1348             // we need script dependent styles, too. For font items, we have
1349             // to take care about their special HTML/CSS1 representation.
1350             if( RES_CHRATR_FONT == aWhichIds[i] )
1351             {
1352                 if( !lcl_css1atr_equalFontItems( *pItem, *pItemCJK ) ||
1353                     !lcl_css1atr_equalFontItems( *pItem, *pItemCTL ) ||
1354                     !lcl_css1atr_equalFontItems( *pItemCJK, *pItemCTL ) )
1355                     return sal_True;
1356             }
1357             else
1358             {
1359                 if( !( *pItem == *pItemCJK ) ||
1360                     !( *pItem == *pItemCTL ) ||
1361                     !( *pItemCJK == *pItemCTL ) )
1362                     return sal_True;
1363             }
1364         }
1365     }
1366 
1367     const SfxPoolItem *pItem;
1368     if( bCheckDropCap &&
1369         SFX_ITEM_SET == rItemSet.GetItemState( RES_PARATR_DROP, sal_True,
1370                 &pItem ) )
1371     {
1372         const SwFmtDrop *pDrop = (const SwFmtDrop *)pItem;
1373         const SwCharFmt *pDCCharFmt = pDrop->GetCharFmt();
1374         if( pDCCharFmt )
1375         {
1376             SfxItemSet aTstItemSet( *pDCCharFmt->GetAttrSet().GetPool(),
1377                 RES_CHRATR_FONT,        RES_CHRATR_FONT,
1378                 RES_CHRATR_POSTURE,     RES_CHRATR_POSTURE,
1379                 RES_CHRATR_WEIGHT,      RES_CHRATR_WEIGHT,
1380                 RES_CHRATR_CJK_FONT,    RES_CHRATR_CJK_FONT,
1381                 RES_CHRATR_CJK_POSTURE, RES_CHRATR_CJK_WEIGHT,
1382                 RES_CHRATR_CTL_FONT,    RES_CHRATR_CTL_FONT,
1383                 RES_CHRATR_CTL_POSTURE, RES_CHRATR_CTL_WEIGHT,
1384                 0 );
1385             aTstItemSet.Set( pDCCharFmt->GetAttrSet(), sal_True );
1386             return HasScriptDependentItems( aTstItemSet, sal_False );
1387         }
1388     }
1389 
1390     return sal_False;
1391 }
1392 
OutCSS1Rule(SwHTMLWriter & rHTMLWrt,const String & rSelector,const SfxItemSet & rItemSet,sal_Bool bHasClass,sal_Bool bCheckForPseudo)1393 static sal_Bool OutCSS1Rule( SwHTMLWriter& rHTMLWrt, const String& rSelector,
1394                     const SfxItemSet& rItemSet, sal_Bool bHasClass,
1395                     sal_Bool bCheckForPseudo  )
1396 {
1397     sal_Bool bScriptDependent = sal_False;
1398     if( SwHTMLWriter::HasScriptDependentItems( rItemSet,
1399                 rHTMLWrt.IsHTMLMode(HTMLMODE_DROPCAPS) && bHasClass ) )
1400     {
1401         bScriptDependent = sal_True;
1402         String aSelector( rSelector );
1403 
1404         String aPseudo;
1405         if( bCheckForPseudo )
1406         {
1407             xub_StrLen nPos = aSelector.SearchBackward( ':' );
1408             if( STRING_NOTFOUND != nPos )
1409             {
1410                 aPseudo = aSelector.Copy( nPos );
1411                 aSelector.Erase( nPos );
1412             }
1413         }
1414 
1415         if( !bHasClass )
1416         {
1417             // If we are exporting styles for a tag we have to export a tag
1418             // rule for all properties that aren't style dependent and
1419             // some class rule for the additional style dependen properties
1420             {
1421                 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_NO_SCRIPT|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
1422                                      sal_True, &rSelector );
1423                 rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, sal_False );
1424             }
1425 
1426             SfxItemSet aScriptItemSet( *rItemSet.GetPool(),
1427                                        RES_CHRATR_FONT, RES_CHRATR_FONTSIZE,
1428                                        RES_CHRATR_LANGUAGE, RES_CHRATR_POSTURE,
1429                                        RES_CHRATR_WEIGHT, RES_CHRATR_WEIGHT,
1430                                        RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_WEIGHT,
1431                                        0 );
1432             aScriptItemSet.Put( rItemSet );
1433 
1434             String aNewSelector( aSelector );
1435             aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM(".western") );
1436             aNewSelector.Append( aPseudo );
1437             {
1438                 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_WESTERN|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
1439                                      sal_True, &aNewSelector );
1440                 rHTMLWrt.OutCSS1_SfxItemSet( aScriptItemSet, sal_False );
1441             }
1442 
1443             aNewSelector = aSelector;
1444             aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM(".cjk") );
1445             aNewSelector.Append( aPseudo );
1446             {
1447                 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CJK|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
1448                                      sal_True, &aNewSelector );
1449                 rHTMLWrt.OutCSS1_SfxItemSet( aScriptItemSet, sal_False );
1450             }
1451 
1452             aNewSelector = aSelector;
1453             aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM(".ctl") );
1454             aNewSelector.Append( aPseudo );
1455             {
1456                 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CTL|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
1457                                      sal_True, &aNewSelector );
1458                 rHTMLWrt.OutCSS1_SfxItemSet( aScriptItemSet, sal_False );
1459             }
1460         }
1461         else
1462         {
1463             // If ther are script dependencies and we are derived from a tag,
1464             // when we have to export a style dependent class for all
1465             // scripts
1466             String aNewSelector( aSelector );
1467             aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-western") );
1468             aNewSelector.Append( aPseudo );
1469             {
1470                 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_WESTERN|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
1471                                      sal_True, &aNewSelector );
1472                 rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, sal_False );
1473             }
1474 
1475             aNewSelector = aSelector;
1476             aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-cjk") );
1477             aNewSelector.Append( aPseudo );
1478             {
1479                 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CJK|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
1480                                      sal_True, &aNewSelector );
1481                 rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, sal_False );
1482             }
1483 
1484             aNewSelector = aSelector;
1485             aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-ctl") );
1486             aNewSelector.Append( aPseudo );
1487             {
1488                 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CTL|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
1489                                      sal_True, &aNewSelector );
1490                 rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, sal_False );
1491             }
1492         }
1493     }
1494     else
1495     {
1496         // If there are no script dependencies, when all items are
1497         // exported in one step. For hyperlinks only, a script information
1498         // must be there, because these two chr formats don't support
1499         // script dependencies by now.
1500         SwCSS1OutMode aMode( rHTMLWrt,
1501                 rHTMLWrt.nCSS1Script|CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
1502                              sal_True, &rSelector );
1503         rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, sal_False );
1504     }
1505 
1506     return bScriptDependent;
1507 }
1508 
OutCSS1DropCapRule(SwHTMLWriter & rHTMLWrt,const String & rSelector,const SwFmtDrop & rDrop,sal_Bool bHasClass,sal_Bool bHasScriptDependencies)1509 static void OutCSS1DropCapRule(
1510                     SwHTMLWriter& rHTMLWrt, const String& rSelector,
1511                     const SwFmtDrop& rDrop, sal_Bool bHasClass,
1512                     sal_Bool bHasScriptDependencies  )
1513 {
1514     const SwCharFmt *pDCCharFmt = rDrop.GetCharFmt();
1515     if( (bHasScriptDependencies && bHasClass) ||
1516         (pDCCharFmt && SwHTMLWriter::HasScriptDependentItems( pDCCharFmt->GetAttrSet(), sal_False ) ) )
1517     {
1518         String aSelector( rSelector );
1519 
1520         String aPseudo;
1521         xub_StrLen nPos = aSelector.SearchBackward( ':' );
1522         if( STRING_NOTFOUND != nPos )
1523         {
1524             aPseudo = aSelector.Copy( nPos );
1525             aSelector.Erase( nPos );
1526         }
1527 
1528         if( !bHasClass )
1529         {
1530             // If we are exporting styles for a tag we have to export a tag
1531             // rule for all properties that aren't style dependent and
1532             // some class rule for the additional style dependen properties
1533             {
1534                 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_NO_SCRIPT|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
1535                                      sal_True, &rSelector );
1536                 OutCSS1_SwFmtDropAttrs( rHTMLWrt, rDrop );
1537             }
1538 
1539             SfxItemSet aScriptItemSet( rHTMLWrt.pDoc->GetAttrPool(),
1540                                        RES_CHRATR_FONT, RES_CHRATR_FONTSIZE,
1541                                        RES_CHRATR_LANGUAGE, RES_CHRATR_POSTURE,
1542                                        RES_CHRATR_WEIGHT, RES_CHRATR_WEIGHT,
1543                                        RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_WEIGHT,
1544                                        0 );
1545             if( pDCCharFmt )
1546                 aScriptItemSet.Set( pDCCharFmt->GetAttrSet(), sal_True );
1547 
1548             String aNewSelector( aSelector );
1549             aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM(".western") );
1550             aNewSelector.Append( aPseudo );
1551             {
1552                 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_WESTERN|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
1553                                      sal_True, &aNewSelector );
1554                 OutCSS1_SwFmtDropAttrs(  rHTMLWrt, rDrop, &aScriptItemSet );
1555             }
1556 
1557             aNewSelector = aSelector;
1558             aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM(".cjk") );
1559             aNewSelector.Append( aPseudo );
1560             {
1561                 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CJK|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
1562                                      sal_True, &aNewSelector );
1563                 OutCSS1_SwFmtDropAttrs(  rHTMLWrt, rDrop, &aScriptItemSet );
1564             }
1565 
1566             aNewSelector = aSelector;
1567             aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM(".ctl") );
1568             aNewSelector.Append( aPseudo );
1569             {
1570                 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CTL|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
1571                                      sal_True, &aNewSelector );
1572                 OutCSS1_SwFmtDropAttrs(  rHTMLWrt, rDrop, &aScriptItemSet );
1573             }
1574         }
1575         else
1576         {
1577             // If ther are script dependencies and we are derived from a tag,
1578             // when we have to export a style dependent class for all
1579             // scripts
1580             String aNewSelector( aSelector );
1581             aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-western") );
1582             aNewSelector.Append( aPseudo );
1583             {
1584                 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_WESTERN|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
1585                                      sal_True, &aNewSelector );
1586                 OutCSS1_SwFmtDropAttrs(  rHTMLWrt, rDrop );
1587             }
1588 
1589             aNewSelector = aSelector;
1590             aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-cjk") );
1591             aNewSelector.Append( aPseudo );
1592             {
1593                 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CJK|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
1594                                      sal_True, &aNewSelector );
1595                 OutCSS1_SwFmtDropAttrs(  rHTMLWrt, rDrop );
1596             }
1597 
1598             aNewSelector = aSelector;
1599             aNewSelector.AppendAscii( RTL_CONSTASCII_STRINGPARAM("-ctl") );
1600             aNewSelector.Append( aPseudo );
1601             {
1602                 SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_CTL|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
1603                                      sal_True, &aNewSelector );
1604                 OutCSS1_SwFmtDropAttrs(  rHTMLWrt, rDrop );
1605             }
1606         }
1607     }
1608     else
1609     {
1610         // If there are no script dependencies, when all items are
1611         // exported in one step. For hyperlinks only, a script information
1612         // must be there, because these two chr formats don't support
1613         // script dependencies by now.
1614         SwCSS1OutMode aMode( rHTMLWrt,
1615                 rHTMLWrt.nCSS1Script|CSS1_OUTMODE_RULE|CSS1_OUTMODE_DROPCAP,
1616                              sal_True, &rSelector );
1617                 OutCSS1_SwFmtDropAttrs( rHTMLWrt, rDrop );
1618     }
1619 }
1620 
OutCSS1_SwFmt(Writer & rWrt,const SwFmt & rFmt,IDocumentStylePoolAccess * pDoc,SwDoc * pTemplate)1621 static Writer& OutCSS1_SwFmt( Writer& rWrt, const SwFmt& rFmt,
1622                               IDocumentStylePoolAccess/*SwDoc*/ *pDoc, SwDoc *pTemplate )
1623 {
1624     SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
1625 
1626     sal_Bool bCharFmt = sal_False;
1627     switch( rFmt.Which() )
1628     {
1629     case RES_CHRFMT:
1630         bCharFmt = sal_True;
1631         break;
1632 
1633     case RES_TXTFMTCOLL:
1634     case RES_CONDTXTFMTCOLL:
1635         // diese Vorlagen-Typen koennen exportiert werden
1636         break;
1637 
1638     default:
1639         // und diese nicht
1640         return rWrt;
1641     }
1642 
1643     // den Selector und die auszugebende Attr-Set-Tiefe ermitteln
1644     String aSelector;
1645     sal_uInt16 nRefPoolId = 0;
1646     sal_uInt16 nDeep = GetCSS1Selector( &rFmt, aSelector, nRefPoolId );
1647     if( !nDeep )
1648         return rWrt;    // von keiner HTML-Vorlage abgeleitet
1649 
1650     sal_uInt16 nPoolFmtId = rFmt.GetPoolFmtId();
1651 
1652     // Den auszugebenden Attr-Set bestimmen. Hier muessen 3 Faelle
1653     // unterschieden werden:
1654     // - HTML-Tag-Vorlagen (nDeep==USHRT_MAX):
1655     //   Es werden die Attrs ausgegeben
1656     //     - die in der Vorlage gesetzt sind, aber nicht im Original aus
1657     //       der HTML-Vorlage
1658     //     - die Default-Attrs fuer die Attrs, die im Original aus der
1659     //       HTML-Vorlage gesetzt sind, aber nicht in der vorliegeden Vorlage.
1660     // - direkt von HTML-Vorlagen abgeleitete Vorlagen (nDeep==1):
1661     //   Es weren nur die Attribute des Vorlagen-Item-Set ohne seine
1662     //   Parents ausgegeben.
1663     // - indirekt von HTML-Tag-Vorlagen abgeleitete Vorlagen (nDeep>1)
1664     //   Es werden die Attribute des Vorlagen-Item-Sets inkl. seiner Parents,
1665     //   aber ohne die Attribute, die in der HTML-Tag-Vorlage gesetzt sind,
1666     //   ausgegeben.
1667 
1668     // einen Item-Set mit allen Attributen aus der Vorlage anlegen
1669     // (ausser fuer nDeep==1)
1670     const SfxItemSet& rFmtItemSet = rFmt.GetAttrSet();
1671     SfxItemSet aItemSet( *rFmtItemSet.GetPool(), rFmtItemSet.GetRanges() );
1672     aItemSet.Set( rFmtItemSet, sal_True ); // Was nDeep!=1 that is not working
1673                                        // for script dependent items buts should
1674                                        // not make a deifference for any other
1675 
1676     sal_Bool bSetDefaults = sal_True, bClearSame = sal_True;
1677     const SwFmt *pRefFmt = 0;
1678     const SwFmt *pRefFmtScript = 0;
1679     switch( nDeep )
1680     {
1681     case CSS1_FMT_ISTAG:
1682         pRefFmt = SwHTMLWriter::GetTemplateFmt( nRefPoolId, pTemplate );
1683         break;
1684     case CSS1_FMT_CMPREF:
1685         pRefFmt = SwHTMLWriter::GetTemplateFmt( nRefPoolId, pDoc );
1686         pRefFmtScript = SwHTMLWriter::GetTemplateFmt( nRefPoolId, pTemplate );
1687         bClearSame = sal_False;
1688         break;
1689     default:
1690         pRefFmt = SwHTMLWriter::GetParentFmt( rFmt, nDeep );
1691         pRefFmtScript = SwHTMLWriter::GetTemplateFmt( nRefPoolId, pTemplate );
1692         bSetDefaults = sal_False;
1693         break;
1694     }
1695 
1696     if( pRefFmt )
1697     {
1698         // Den Item-Set der Referenz-Vorlage (inkl. seiner Parents) vom
1699         // ItemSet abziehen
1700         SwHTMLWriter::SubtractItemSet( aItemSet, pRefFmt->GetAttrSet(),
1701                                        bSetDefaults, bClearSame,
1702                                        pRefFmtScript
1703                                             ? &pRefFmtScript->GetAttrSet()
1704                                             : 0  );
1705 
1706         if( !bCharFmt )
1707         {
1708             const SvxULSpaceItem& rULItem = pRefFmt->GetULSpace();
1709             rHTMLWrt.nDfltTopMargin = rULItem.GetUpper();
1710             rHTMLWrt.nDfltBottomMargin = rULItem.GetLower();
1711         }
1712     }
1713     else if( CSS1_FMT_ISTAG==nDeep && !bCharFmt )
1714     {
1715         // die Default-Abstaende nach oben und unten setzen (fuer den
1716         // Fall, dass es keine Vorlage als Referenz gibt)
1717         rHTMLWrt.nDfltTopMargin = 0;
1718         rHTMLWrt.nDfltBottomMargin = HTML_PARSPACE;
1719         if( USER_FMT & nPoolFmtId )
1720         {
1721             // Benutzer-Vorlagen
1722             const String& rNm = rFmt.GetName();
1723             switch( rNm.GetChar(0) )
1724             {
1725             case 'D':   if( rNm.EqualsAscii("DD 1") || rNm.EqualsAscii("DT 1") )
1726                             rHTMLWrt.nDfltBottomMargin = 0;
1727                         break;
1728             case 'L':   if(rNm.EqualsAscii(OOO_STRING_SVTOOLS_HTML_listing) )
1729                             rHTMLWrt.nDfltBottomMargin = 0;
1730                         break;
1731             case 'P':   if( rNm.EqualsAscii(OOO_STRING_SVTOOLS_HTML_preformtxt) )
1732                             rHTMLWrt.nDfltBottomMargin = 0;
1733                         break;
1734             case 'X':   if( rNm.EqualsAscii(OOO_STRING_SVTOOLS_HTML_xmp) )
1735                             rHTMLWrt.nDfltBottomMargin = 0;
1736                         break;
1737             }
1738         }
1739         else
1740         {
1741             // Pool-Vorlagen
1742             switch( nPoolFmtId )
1743             {
1744             case RES_POOLCOLL_HEADLINE1:
1745             case RES_POOLCOLL_HEADLINE2:
1746             case RES_POOLCOLL_HEADLINE3:
1747             case RES_POOLCOLL_HEADLINE4:
1748             case RES_POOLCOLL_HEADLINE5:
1749             case RES_POOLCOLL_HEADLINE6:
1750                 rHTMLWrt.nDfltTopMargin = HTML_HEADSPACE;
1751                 break;
1752             case RES_POOLCOLL_SENDADRESS:
1753             case RES_POOLCOLL_HTML_DT:
1754             case RES_POOLCOLL_HTML_DD:
1755             case RES_POOLCOLL_HTML_PRE:
1756                 rHTMLWrt.nDfltBottomMargin = 0;
1757                 break;
1758             }
1759         }
1760     }
1761 
1762     // wo nicht auszugeben ist ...
1763     if( !aItemSet.Count() )
1764         return rWrt;
1765 
1766     // There is no support for script dependent hyperlinks by now.
1767     sal_Bool bCheckForPseudo = sal_False;
1768     if( bCharFmt &&
1769         (RES_POOLCHR_INET_NORMAL==nRefPoolId ||
1770          RES_POOLCHR_INET_VISIT==nRefPoolId) )
1771         bCheckForPseudo = sal_True;
1772 
1773 
1774     // jetzt die Attribute (inkl. Selektor) ausgeben
1775     sal_Bool bHasScriptDependencies = sal_False;
1776     if( OutCSS1Rule( rHTMLWrt, aSelector, aItemSet, CSS1_FMT_ISTAG != nDeep,
1777                      bCheckForPseudo ) )
1778     {
1779         if( bCharFmt )
1780             rHTMLWrt.aScriptTextStyles.Insert( new String( rFmt.GetName() ) );
1781         else
1782         {
1783             if( nPoolFmtId==RES_POOLCOLL_TEXT )
1784                 rHTMLWrt.aScriptParaStyles.Insert
1785                     (new String( pDoc->GetTxtCollFromPool
1786                                  ( RES_POOLCOLL_STANDARD, false )->GetName()
1787                                  ) );
1788             rHTMLWrt.aScriptParaStyles.Insert( new String( rFmt.GetName() ) );
1789         }
1790         bHasScriptDependencies = sal_True;
1791     }
1792 
1793     if( nPoolFmtId==RES_POOLCOLL_TEXT && !rHTMLWrt.bFirstCSS1Property )
1794         rHTMLWrt.bPoolCollTextModified = sal_True;
1795 
1796     // Drop-Caps ausgeben
1797     const SfxPoolItem *pItem;
1798     if( rHTMLWrt.IsHTMLMode(HTMLMODE_DROPCAPS) &&
1799         SFX_ITEM_SET==aItemSet.GetItemState( RES_PARATR_DROP, sal_False, &pItem ))
1800     {
1801         String sOut( aSelector );
1802         sOut.Append( ':');
1803         sOut.AppendAscii( sCSS1_first_letter );
1804         const SwFmtDrop *pDrop = (const SwFmtDrop *)pItem;
1805         OutCSS1DropCapRule( rHTMLWrt, sOut, *pDrop, CSS1_FMT_ISTAG != nDeep, bHasScriptDependencies );
1806     }
1807 
1808     return rWrt;
1809 }
1810 
OutCSS1_SwPageDesc(Writer & rWrt,const SwPageDesc & rPageDesc,IDocumentStylePoolAccess * pDoc,SwDoc * pTemplate,sal_uInt16 nRefPoolId,sal_Bool bExtRef,sal_Bool bPseudo)1811 static Writer& OutCSS1_SwPageDesc( Writer& rWrt, const SwPageDesc& rPageDesc,
1812                                    IDocumentStylePoolAccess/*SwDoc*/ *pDoc, SwDoc *pTemplate,
1813                                    sal_uInt16 nRefPoolId, sal_Bool bExtRef,
1814                                    sal_Bool bPseudo )
1815 {
1816     SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
1817 
1818     const SwPageDesc* pRefPageDesc = 0;
1819     if( !bExtRef )
1820         pRefPageDesc = pDoc->GetPageDescFromPool( nRefPoolId, false );
1821     else if( pTemplate )
1822         pRefPageDesc = pTemplate->GetPageDescFromPool( nRefPoolId, false );
1823 
1824     String aSelector( '@' );
1825     aSelector.AppendAscii( sCSS1_page );
1826 
1827     if( bPseudo )
1828     {
1829         const sal_Char *pPseudo = 0;
1830         switch( rPageDesc.GetPoolFmtId() )
1831         {
1832         case RES_POOLPAGE_FIRST:    pPseudo = sCSS1_first;  break;
1833         case RES_POOLPAGE_LEFT:     pPseudo = sCSS1_left;   break;
1834         case RES_POOLPAGE_RIGHT:    pPseudo = sCSS1_right;  break;
1835         }
1836         if( pPseudo )
1837         {
1838             aSelector.Append( ':' );
1839             aSelector.AppendAscii( pPseudo );
1840         }
1841     }
1842 
1843     SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_RULE_ON|CSS1_OUTMODE_TEMPLATE,
1844                          sal_True, &aSelector );
1845 
1846     // Die Groesse: Wenn sie sich nur durch das Landscape-Flag unterscheidet,
1847     // wird nur Portrait oder Landscape exportiert. Sonst wird die Groesse
1848     // exportiert.
1849     sal_Bool bRefLandscape = pRefPageDesc ? pRefPageDesc->GetLandscape() : sal_False;
1850     Size aRefSz;
1851     const Size& rSz = rPageDesc.GetMaster().GetFrmSize().GetSize();
1852     if( pRefPageDesc )
1853     {
1854         aRefSz = pRefPageDesc->GetMaster().GetFrmSize().GetSize();
1855         if( bRefLandscape != rPageDesc.GetLandscape() )
1856         {
1857             long nTmp = aRefSz.Height();
1858             aRefSz.Height() = aRefSz.Width();
1859             aRefSz.Width() = nTmp;
1860         }
1861     }
1862 
1863     // Boeser uebler Hack: Auf der Seiten-Tabpage gibt es leichte
1864     // Rundungsfehler bei der Seitengroesse. Unter anderem wegen bug
1865     // 25535 wird dummerweise auch noch immer Size-Item vom Dialog geputtet,
1866     // auch wenn man gar nichts geaendert hat. Folge: Sobald man einmal im
1867     // Seiten-Dialog war und ihn mit OK verlassen hat, bekommt man eine
1868     // neue Seitengroesse, die dann hier exportiert wuerde. Um das
1869     // vermeiden erlauben wir hier kleine Abweichungen.
1870     if( Abs( rSz.Width() - aRefSz.Width() ) <= 2 &&
1871         Abs( rSz.Height() - aRefSz.Height() ) <= 2 )
1872     {
1873         if( bRefLandscape != rPageDesc.GetLandscape() )
1874         {
1875             rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_size,
1876                 rPageDesc.GetLandscape() ? sCSS1_PV_landscape
1877                                          : sCSS1_PV_portrait );
1878         }
1879     }
1880     else
1881     {
1882         ByteString sVal;
1883         AddUnitPropertyValue( rSz.Width(), rHTMLWrt.GetCSS1Unit(), sVal );
1884         sVal += ' ';
1885         AddUnitPropertyValue( rSz.Height(), rHTMLWrt.GetCSS1Unit(), sVal );
1886         rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_size, sVal );
1887     }
1888 
1889     // Die Abstand-Attribute koennen auf gwohnte Weise exportiert werden
1890     const SwFrmFmt &rMaster = rPageDesc.GetMaster();
1891     SfxItemSet aItemSet( *rMaster.GetAttrSet().GetPool(),
1892                          RES_LR_SPACE, RES_UL_SPACE );
1893     aItemSet.Set( rMaster.GetAttrSet(), sal_True );
1894 
1895     if( pRefPageDesc )
1896     {
1897         SwHTMLWriter::SubtractItemSet( aItemSet,
1898                                        pRefPageDesc->GetMaster().GetAttrSet(),
1899                                        sal_True );
1900     }
1901 
1902     OutCSS1_SvxULSpace_SvxLRSpace( rWrt, aItemSet, sal_False );
1903 
1904     // Wenn fuer einen Pseudo-Selektor keine Property ausgegeben wurde, muessen
1905     // wir trotzdem etwas ausgeben, damit beim Import die entsprechende
1906     // Vorlage angelegt wird.
1907     if( rHTMLWrt.bFirstCSS1Property && bPseudo )
1908     {
1909         rHTMLWrt.OutNewLine();
1910         ByteString sTmp( aSelector, rHTMLWrt.eDestEnc );
1911         rWrt.Strm() << sTmp.GetBuffer() << " {";
1912         rHTMLWrt.bFirstCSS1Property = sal_False;
1913     }
1914 
1915     if( !rHTMLWrt.bFirstCSS1Property )
1916         rWrt.Strm() << sCSS1_rule_end;
1917 
1918     return rWrt;
1919 }
1920 
OutCSS1_SwFtnInfo(Writer & rWrt,const SwEndNoteInfo & rInfo,SwDoc * pDoc,sal_uInt16 nNotes,sal_Bool bEndNote)1921 static Writer& OutCSS1_SwFtnInfo( Writer& rWrt, const SwEndNoteInfo& rInfo,
1922                                   SwDoc *pDoc, sal_uInt16 nNotes, sal_Bool bEndNote )
1923 {
1924     SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
1925 
1926     String aSelector;
1927 
1928     if( nNotes > 0 )
1929     {
1930         aSelector.AssignAscii( OOO_STRING_SVTOOLS_HTML_anchor );
1931         aSelector.Append( '.');
1932         aSelector.AppendAscii( bEndNote ? OOO_STRING_SVTOOLS_HTML_sdendnote_anc
1933                                         : OOO_STRING_SVTOOLS_HTML_sdfootnote_anc );
1934         SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_RULE|CSS1_OUTMODE_TEMPLATE,
1935                              sal_True, &aSelector );
1936         rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_size,
1937                                         sHTML_FTN_fontheight );
1938         rHTMLWrt.Strm() << sCSS1_rule_end;
1939     }
1940 
1941     const SwCharFmt *pSymCharFmt = rInfo.GetCharFmt( *pDoc );
1942     if( pSymCharFmt )
1943     {
1944         const SfxItemSet& rFmtItemSet = pSymCharFmt->GetAttrSet();
1945         SfxItemSet aItemSet( *rFmtItemSet.GetPool(), rFmtItemSet.GetRanges() );
1946         aItemSet.Set( rFmtItemSet, sal_True );
1947 
1948         // Wenn es Fuss- bzw. Endnoten gibt, dann muessen alles Attribute
1949         // ausgegeben werden, damit Netscape das Dokument richtig anzeigt.
1950         // Anderenfalls genuegt es, die Unterschiede zur Fuss-/Endnoten
1951         // Vorlage rauszuschreiben.
1952         if( nNotes == 0 && rHTMLWrt.pTemplate )
1953         {
1954             SwFmt *pRefFmt = rHTMLWrt.pTemplate->GetCharFmtFromPool(
1955                         static_cast< sal_uInt16 >(bEndNote ? RES_POOLCHR_ENDNOTE : RES_POOLCHR_FOOTNOTE) );
1956             if( pRefFmt )
1957                 SwHTMLWriter::SubtractItemSet( aItemSet, pRefFmt->GetAttrSet(),
1958                                                sal_True );
1959         }
1960         if( aItemSet.Count() )
1961         {
1962             aSelector.AssignAscii( OOO_STRING_SVTOOLS_HTML_anchor );
1963             aSelector.Append( '.');
1964             aSelector.AppendAscii( bEndNote ? OOO_STRING_SVTOOLS_HTML_sdendnote_sym
1965                                         : OOO_STRING_SVTOOLS_HTML_sdfootnote_sym );
1966             if( OutCSS1Rule( rHTMLWrt, aSelector, aItemSet, sal_True, sal_False ))
1967                 rHTMLWrt.aScriptTextStyles.Insert( new String( pSymCharFmt->GetName() ) );
1968         }
1969     }
1970 
1971     return rWrt;
1972 }
1973 
OutCSS1_BodyTagStyleOpt(Writer & rWrt,const SfxItemSet & rItemSet,String aEmbBGGrfName)1974 Writer& OutCSS1_BodyTagStyleOpt( Writer& rWrt, const SfxItemSet& rItemSet,
1975                                  String aEmbBGGrfName )
1976 {
1977     SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
1978 
1979     SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_STYLE_OPT_ON |
1980                                    CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_BODY );
1981 
1982 
1983     // Es werden nur die Attribute der Seiten-Vorlage ausgegeben.
1984     // Die Attribute der Standard-Absatz-Vorlage werden schon beim
1985     // Export der Absatz-Vorlagen beruecksichtigt.
1986 
1987     const SfxPoolItem *pItem;
1988     if( SFX_ITEM_SET == rItemSet.GetItemState( RES_BACKGROUND, sal_False,
1989                                                &pItem ) )
1990     {
1991         OutCSS1_SvxBrush( rWrt, *pItem, CSS1_BACKGROUND_PAGE,
1992                           &aEmbBGGrfName );
1993     }
1994 
1995     if( SFX_ITEM_SET == rItemSet.GetItemState( RES_BOX, sal_False,
1996                                                &pItem ))
1997     {
1998         OutCSS1_SvxBox( rWrt, *pItem );
1999     }
2000 
2001     if( !rHTMLWrt.bFirstCSS1Property )
2002     {
2003         // wenn eine Property als Bestandteil einer Style-Option
2004         // ausgegeben wurde, muss die Optiomn noch beendet werden
2005         rWrt.Strm() << '\"';
2006     }
2007 
2008     return rWrt;
2009 }
2010 
OutCSS1_ParaTagStyleOpt(Writer & rWrt,const SfxItemSet & rItemSet)2011 Writer& OutCSS1_ParaTagStyleOpt( Writer& rWrt, const SfxItemSet& rItemSet )
2012 {
2013     SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
2014 
2015     SwCSS1OutMode aMode( rHTMLWrt, rHTMLWrt.nCSS1Script|CSS1_OUTMODE_STYLE_OPT |
2016                                    CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_PARA );
2017     rHTMLWrt.OutCSS1_SfxItemSet( rItemSet, sal_False );
2018 
2019     return rWrt;
2020 }
2021 
OutCSS1_HintSpanTag(Writer & rWrt,const SfxPoolItem & rHt)2022 Writer& OutCSS1_HintSpanTag( Writer& rWrt, const SfxPoolItem& rHt )
2023 {
2024     SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
2025 
2026     SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_SPAN_TAG |
2027                                    CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_HINT );
2028 
2029     Out( aCSS1AttrFnTab, rHt, rWrt );
2030 
2031     if( !rHTMLWrt.bFirstCSS1Property  && rHTMLWrt.bTagOn )
2032         rWrt.Strm() << sCSS1_span_tag_end;
2033 
2034     return rWrt;
2035 }
2036 
OutCSS1_HintStyleOpt(Writer & rWrt,const SfxPoolItem & rHt)2037 Writer& OutCSS1_HintStyleOpt( Writer& rWrt, const SfxPoolItem& rHt )
2038 {
2039     SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
2040 
2041     SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_STYLE_OPT_ON |
2042                                    CSS1_OUTMODE_ENCODE|
2043                                    CSS1_OUTMODE_HINT );
2044 
2045     Out( aCSS1AttrFnTab, rHt, rWrt );
2046 
2047     if( !rHTMLWrt.bFirstCSS1Property )
2048         rWrt.Strm() << '\"';
2049 
2050     return rWrt;
2051 }
2052 
2053 // Wrapper fuer die Ausgabe von Tabellen-Hintergruenden
OutCSS1_TableBGStyleOpt(Writer & rWrt,const SfxPoolItem & rHt)2054 Writer& OutCSS1_TableBGStyleOpt( Writer& rWrt, const SfxPoolItem& rHt )
2055 {
2056     SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
2057 
2058     SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_STYLE_OPT_ON |
2059                                    CSS1_OUTMODE_ENCODE|
2060                                    CSS1_OUTMODE_TABLEBOX );
2061     OutCSS1_SvxBrush( rWrt, rHt, CSS1_BACKGROUND_TABLE, 0 );
2062 
2063     if( !rHTMLWrt.bFirstCSS1Property )
2064         rWrt.Strm() << '\"';
2065 
2066     return rWrt;
2067 }
2068 
2069 
OutCSS1_NumBulListStyleOpt(Writer & rWrt,const SwNumRule & rNumRule,sal_uInt8 nLevel)2070 Writer& OutCSS1_NumBulListStyleOpt( Writer& rWrt, const SwNumRule& rNumRule,
2071                                     sal_uInt8 nLevel )
2072 {
2073     SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
2074 
2075     SwCSS1OutMode aMode( rHTMLWrt, CSS1_OUTMODE_STYLE_OPT |
2076                                    CSS1_OUTMODE_ENCODE|CSS1_OUTMODE_PARA );
2077 
2078     const SwNumFmt& rNumFmt = rNumRule.Get( nLevel );
2079 
2080     long nLSpace = rNumFmt.GetAbsLSpace();
2081     long nFirstLineOffset = rNumFmt.GetFirstLineOffset();
2082     long nDfltFirstLineOffset = HTML_NUMBUL_INDENT;
2083     if( nLevel > 0 )
2084     {
2085         const SwNumFmt& rPrevNumFmt = rNumRule.Get( nLevel-1 );
2086         nLSpace -= rPrevNumFmt.GetAbsLSpace();
2087         nDfltFirstLineOffset = rPrevNumFmt.GetFirstLineOffset();
2088     }
2089 
2090     if( rHTMLWrt.IsHTMLMode(HTMLMODE_LSPACE_IN_NUMBUL) &&
2091         nLSpace != HTML_NUMBUL_MARGINLEFT )
2092         rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_left, nLSpace );
2093 
2094     if( rHTMLWrt.IsHTMLMode(HTMLMODE_FRSTLINE_IN_NUMBUL) &&
2095         nFirstLineOffset != nDfltFirstLineOffset )
2096         rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_text_indent, nFirstLineOffset );
2097 
2098     if( !rHTMLWrt.bFirstCSS1Property )
2099         rWrt.Strm() << '\"';
2100 
2101     return rWrt;
2102 }
2103 
2104 //-----------------------------------------------------------------------
2105 
OutCSS1_FrmFmtOptions(const SwFrmFmt & rFrmFmt,sal_uInt32 nFrmOpts,const SdrObject * pSdrObj,const SfxItemSet * pItemSet)2106 void SwHTMLWriter::OutCSS1_FrmFmtOptions( const SwFrmFmt& rFrmFmt,
2107                                           sal_uInt32 nFrmOpts,
2108                                           const SdrObject *pSdrObj,
2109                                           const SfxItemSet *pItemSet )
2110 {
2111     SwCSS1OutMode aMode( *this, CSS1_OUTMODE_STYLE_OPT_ON |
2112                                 CSS1_OUTMODE_ENCODE|
2113                                 CSS1_OUTMODE_FRAME );
2114 
2115     const SwFmtHoriOrient& rHoriOri = rFrmFmt.GetHoriOrient();
2116     SvxLRSpaceItem aLRItem( rFrmFmt.GetLRSpace() );
2117     SvxULSpaceItem aULItem( rFrmFmt.GetULSpace() );
2118     if( nFrmOpts & HTML_FRMOPT_S_ALIGN )
2119     {
2120         const SwFmtAnchor& rAnchor = rFrmFmt.GetAnchor();
2121         switch( rAnchor.GetAnchorId() )
2122         {
2123         case FLY_AT_PARA:
2124         case FLY_AT_CHAR:
2125             if( text::RelOrientation::FRAME == rHoriOri.GetRelationOrient() ||
2126                 text::RelOrientation::PRINT_AREA == rHoriOri.GetRelationOrient() )
2127             {
2128                 if( !(nFrmOpts & HTML_FRMOPT_ALIGN) )
2129                 {
2130                     // float
2131                     const sal_Char *pStr = text::HoriOrientation::RIGHT==rHoriOri.GetHoriOrient()
2132                             ? sCSS1_PV_right
2133                             : sCSS1_PV_left;
2134                     OutCSS1_PropertyAscii( sCSS1_P_float, pStr );
2135                 }
2136                 break;
2137             }
2138 
2139         case FLY_AT_PAGE:
2140         case FLY_AT_FLY:
2141             {
2142                 // position
2143                 OutCSS1_PropertyAscii( sCSS1_P_position, sCSS1_PV_absolute );
2144 
2145                 // Fuer top/left muessen die Abstaende des Rahmens von
2146                 // der Position abgezogen werden, da sie in CSS1 noch
2147                 // zur Position addiert werden.
2148                 // Das funktioniert auch fuer automatisch ausgerichtete
2149                 // Rahmen, obwohl der Abstand da ja auch im Writer noch
2150                 // addiert wird. Denn auch in diesem Fall enthalten
2151                 // die Orient-Attribute die korrekte Position
2152 
2153                 // top
2154                 long nXPos=0, nYPos=0;
2155                 sal_Bool bOutXPos = sal_False, bOutYPos = sal_False;
2156                 if( RES_DRAWFRMFMT == rFrmFmt.Which() )
2157                 {
2158                     ASSERT( pSdrObj, "Kein SdrObject uebergeben. Ineffizient" );
2159                     if( !pSdrObj )
2160                         pSdrObj = rFrmFmt.FindSdrObject();
2161                     ASSERT( pSdrObj, "Wo ist das SdrObject" );
2162                     if( pSdrObj )
2163                     {
2164                         Point aPos( pSdrObj->GetRelativePos() );
2165                         nXPos = aPos.A();
2166                         nYPos = aPos.B();
2167                     }
2168                     bOutXPos = bOutYPos = sal_True;
2169                 }
2170                 else
2171                 {
2172                     bOutXPos = text::RelOrientation::CHAR != rHoriOri.GetRelationOrient();
2173                     nXPos = text::HoriOrientation::NONE == rHoriOri.GetHoriOrient()
2174                                 ? rHoriOri.GetPos() : 0;
2175 
2176                     const SwFmtVertOrient& rVertOri = rFrmFmt.GetVertOrient();
2177                     bOutYPos = text::RelOrientation::CHAR != rVertOri.GetRelationOrient();
2178                     nYPos = text::VertOrientation::NONE == rVertOri.GetVertOrient()
2179                                  ? rVertOri.GetPos() : 0;
2180                 }
2181 
2182                 if( bOutYPos )
2183                 {
2184                     if( IsHTMLMode( HTMLMODE_FLY_MARGINS) )
2185                     {
2186                         nYPos -= aULItem.GetUpper();
2187                         if( nYPos < 0 )
2188                         {
2189                             aULItem.SetUpper( (sal_uInt16)(aULItem.GetUpper() + nYPos) );
2190                             nYPos = 0;
2191                         }
2192                     }
2193 
2194                     OutCSS1_UnitProperty( sCSS1_P_top, nYPos );
2195                 }
2196 
2197                 if( bOutXPos )
2198                 {
2199                     // left
2200                     if( IsHTMLMode( HTMLMODE_FLY_MARGINS) )
2201                     {
2202                         nXPos -= aLRItem.GetLeft();
2203                         if( nXPos < 0 )
2204                         {
2205                             aLRItem.SetLeft( (sal_uInt16)(aLRItem.GetLeft() + nXPos) );
2206                             nXPos = 0;
2207                         }
2208                     }
2209 
2210                     OutCSS1_UnitProperty( sCSS1_P_left, nXPos );
2211                 }
2212             }
2213             break;
2214 
2215         default:
2216             ;
2217         }
2218     }
2219 
2220     // width/height
2221     if( nFrmOpts & HTML_FRMOPT_S_SIZE )
2222     {
2223         if( RES_DRAWFRMFMT == rFrmFmt.Which() )
2224         {
2225             ASSERT( pSdrObj, "Kein SdrObject uebergeben. Ineffizient" );
2226             if( !pSdrObj )
2227                 pSdrObj = rFrmFmt.FindSdrObject();
2228             ASSERT( pSdrObj, "Wo ist das SdrObject" );
2229             if( pSdrObj )
2230             {
2231                 Size aTwipSz( pSdrObj->GetLogicRect().GetSize() );
2232                 if( nFrmOpts & HTML_FRMOPT_S_WIDTH )
2233                 {
2234                     if( nFrmOpts & HTML_FRMOPT_S_PIXSIZE )
2235                         OutCSS1_PixelProperty( sCSS1_P_width, aTwipSz.Width(),
2236                                                sal_False );
2237                     else
2238                         OutCSS1_UnitProperty( sCSS1_P_width, aTwipSz.Width() );
2239                 }
2240                 if( nFrmOpts & HTML_FRMOPT_S_HEIGHT )
2241                 {
2242                     if( nFrmOpts & HTML_FRMOPT_S_PIXSIZE )
2243                         OutCSS1_PixelProperty( sCSS1_P_height, aTwipSz.Height(),
2244                                                sal_True );
2245                     else
2246                         OutCSS1_UnitProperty( sCSS1_P_height, aTwipSz.Height() );
2247                 }
2248             }
2249         }
2250         else
2251         {
2252             ASSERT( HTML_FRMOPT_ABSSIZE & nFrmOpts,
2253                     "Absolute Groesse wird exportiert" );
2254             ASSERT( HTML_FRMOPT_ANYSIZE & nFrmOpts,
2255                     "Jede Groesse wird exportiert" );
2256             sal_uInt16 nMode = 0;
2257             if( nFrmOpts & HTML_FRMOPT_S_WIDTH )
2258                 nMode |= CSS1_FRMSIZE_WIDTH;
2259             if( nFrmOpts & HTML_FRMOPT_S_HEIGHT )
2260                 nMode |= (CSS1_FRMSIZE_MINHEIGHT|CSS1_FRMSIZE_FIXHEIGHT);
2261             if( nFrmOpts & HTML_FRMOPT_S_PIXSIZE )
2262                 nMode |= CSS1_FRMSIZE_PIXEL;
2263 
2264             OutCSS1_SwFmtFrmSize( *this, rFrmFmt.GetFrmSize(), nMode );
2265         }
2266     }
2267 
2268     const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet();
2269     // margin-*
2270     if( (nFrmOpts & HTML_FRMOPT_S_SPACE) &&
2271         IsHTMLMode( HTMLMODE_FLY_MARGINS) )
2272     {
2273         const SvxLRSpaceItem *pLRItem = 0;
2274         const SvxULSpaceItem *pULItem = 0;
2275         if( SFX_ITEM_SET == rItemSet.GetItemState( RES_LR_SPACE, sal_True ) )
2276             pLRItem = &aLRItem;
2277         if( SFX_ITEM_SET == rItemSet.GetItemState( RES_UL_SPACE, sal_True ) )
2278             pULItem = &aULItem;
2279         if( pLRItem || pULItem )
2280             OutCSS1_SvxULSpace_SvxLRSpace( *this, pULItem, pLRItem );
2281     }
2282 
2283     // border
2284     if( nFrmOpts & HTML_FRMOPT_S_BORDER )
2285     {
2286         const SfxPoolItem* pItem;
2287         if( nFrmOpts & HTML_FRMOPT_S_NOBORDER )
2288             OutCSS1_SvxBox( *this, rFrmFmt.GetBox() );
2289         else if( SFX_ITEM_SET==rItemSet.GetItemState( RES_BOX, sal_True, &pItem ) )
2290             OutCSS1_SvxBox( *this, *pItem );
2291     }
2292 
2293     // background (wenn, dann muss auch eine Farbe ausgegeben werden)
2294     if( nFrmOpts & HTML_FRMOPT_S_BACKGROUND )
2295         OutCSS1_FrmFmtBackground( rFrmFmt );
2296 
2297     if( pItemSet )
2298         OutCSS1_SfxItemSet( *pItemSet, sal_False );
2299 
2300     if( !bFirstCSS1Property )
2301         Strm() << '\"';
2302 }
2303 
OutCSS1_TableFrmFmtOptions(const SwFrmFmt & rFrmFmt)2304 void SwHTMLWriter::OutCSS1_TableFrmFmtOptions( const SwFrmFmt& rFrmFmt )
2305 {
2306     SwCSS1OutMode aMode( *this, CSS1_OUTMODE_STYLE_OPT_ON |
2307                                 CSS1_OUTMODE_ENCODE|
2308                                 CSS1_OUTMODE_TABLE );
2309 
2310     const SfxPoolItem *pItem;
2311     const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet();
2312     if( SFX_ITEM_SET==rItemSet.GetItemState( RES_BACKGROUND, sal_False, &pItem ) )
2313         OutCSS1_SvxBrush( *this, *pItem, CSS1_BACKGROUND_TABLE, 0 );
2314 
2315     if( IsHTMLMode( HTMLMODE_PRINT_EXT ) )
2316         OutCSS1_SvxFmtBreak_SwFmtPDesc_SvxFmtKeep( *this, rItemSet, sal_False );
2317 
2318     if( SFX_ITEM_SET==rItemSet.GetItemState( RES_LAYOUT_SPLIT, sal_False, &pItem ) )
2319         OutCSS1_SwFmtLayoutSplit( *this, *pItem );
2320 
2321     if( !bFirstCSS1Property )
2322         Strm() << '\"';
2323 }
2324 
OutCSS1_SectionFmtOptions(const SwFrmFmt & rFrmFmt)2325 void SwHTMLWriter::OutCSS1_SectionFmtOptions( const SwFrmFmt& rFrmFmt )
2326 {
2327     SwCSS1OutMode aMode( *this, CSS1_OUTMODE_STYLE_OPT_ON |
2328                                 CSS1_OUTMODE_ENCODE|
2329                                 CSS1_OUTMODE_SECTION );
2330 
2331     const SfxPoolItem *pItem;
2332     const SfxItemSet& rItemSet = rFrmFmt.GetAttrSet();
2333     if( SFX_ITEM_SET==rItemSet.GetItemState( RES_BACKGROUND, sal_False, &pItem ) )
2334         OutCSS1_SvxBrush( *this, *pItem, CSS1_BACKGROUND_SECTION, 0 );
2335 
2336     if( !bFirstCSS1Property )
2337         Strm() << '\"';
2338 }
2339 
OutCSS1_FrmFmtBrush(SwHTMLWriter & rWrt,const SvxBrushItem & rBrushItem)2340 static sal_Bool OutCSS1_FrmFmtBrush( SwHTMLWriter& rWrt,
2341                                  const SvxBrushItem& rBrushItem )
2342 {
2343     sal_Bool bWritten = sal_False;
2344     /// OD 02.09.2002 #99657#
2345     /// output brush of frame format, if its background color is not "no fill"/"auto fill"
2346     /// or it has a background graphic.
2347     if( rBrushItem.GetColor() != COL_TRANSPARENT ||
2348         0 != rBrushItem.GetGraphicLink() ||
2349         0 != rBrushItem.GetGraphicPos() )
2350     {
2351         OutCSS1_SvxBrush( rWrt, rBrushItem, CSS1_BACKGROUND_FLY, 0 );
2352         bWritten = sal_True;
2353     }
2354     return bWritten;
2355 }
2356 
OutCSS1_FrmFmtBackground(const SwFrmFmt & rFrmFmt)2357 void SwHTMLWriter::OutCSS1_FrmFmtBackground( const SwFrmFmt& rFrmFmt )
2358 {
2359     // Wenn der Rahmen selbst einen Hintergrund hat, wird der ausgegeben.
2360     if( OutCSS1_FrmFmtBrush( *this, rFrmFmt.GetBackground() ) )
2361         return;
2362 
2363     // Wenn der Rahmen nicht seitengebunden ist, wird sonst muss der
2364     // Hintergrund vom Anker betrachtet
2365     const SwFmtAnchor& rAnchor = rFrmFmt.GetAnchor();
2366     RndStdIds eAnchorId = rAnchor.GetAnchorId();
2367     const SwPosition *pAnchorPos = rAnchor.GetCntntAnchor();
2368     if (FLY_AT_PAGE != eAnchorId && pAnchorPos)
2369     {
2370         const SwNode& rNode = pAnchorPos->nNode.GetNode();
2371         if( rNode.IsCntntNode() )
2372         {
2373             // Wenn der Rahmen in einem Content-Node verankert ist,
2374             // wird der Hintergrund von Content-Node ausgegeben, wenn
2375             // der einen hat.
2376             if( OutCSS1_FrmFmtBrush( *this,
2377                     rNode.GetCntntNode()->GetSwAttrSet().GetBackground()) )
2378                 return;
2379 
2380             // Sonst koennen wir evtl. auch in einer Tabelle stehen
2381             const SwTableNode *pTableNd = rNode.FindTableNode();
2382             if( pTableNd )
2383             {
2384                 const SwStartNode *pBoxSttNd = rNode.FindTableBoxStartNode();
2385                 const SwTableBox *pBox =
2386                     pTableNd->GetTable().GetTblBox( pBoxSttNd->GetIndex() );
2387 
2388                 // Wenn die Box einen Hintergrund hat, nehmen wir den.
2389                 if( OutCSS1_FrmFmtBrush( *this,
2390                         pBox->GetFrmFmt()->GetBackground() ) )
2391                     return;
2392 
2393                 // Sonst betrachten wir den der Lines
2394                 const SwTableLine *pLine = pBox->GetUpper();
2395                 while( pLine )
2396                 {
2397                     if( OutCSS1_FrmFmtBrush( *this,
2398                             pLine->GetFrmFmt()->GetBackground() ) )
2399                         return;
2400                     pBox = pLine->GetUpper();
2401                     pLine = pBox ? pBox->GetUpper() : 0;
2402                 }
2403 
2404                 // Wenn da auch nichts war den der Tabelle.
2405                 if( OutCSS1_FrmFmtBrush( *this,
2406                         pTableNd->GetTable().GetFrmFmt()->GetBackground() ) )
2407                     return;
2408             }
2409 
2410         }
2411 
2412         // Wenn der Anker wieder in einem Fly-Frame steht, dann
2413         // wird der Hintergrund des Fly-Frames ausgegeben.
2414         const SwFrmFmt *pFrmFmt = rNode.GetFlyFmt();
2415         if( pFrmFmt )
2416         {
2417             OutCSS1_FrmFmtBackground( *pFrmFmt );
2418             return;
2419         }
2420     }
2421 
2422     // Schliesslich bleibt noch der Hintergrund der Seite uebrig und als
2423     // letzte Rettung das Item der Config.
2424     ASSERT( pCurrPageDesc, "Keine Seiten-Vorlage gemerkt" );
2425     if( !OutCSS1_FrmFmtBrush( *this,
2426                               pCurrPageDesc->GetMaster().GetBackground() ) )
2427     {
2428         Color aColor( COL_WHITE );
2429 
2430         // Die Hintergrund-Farbe wird normalerweise nur in Browse-Mode
2431         // benutzt. Wir benutzen si bei einem HTML-Dokument immer und
2432         // bei einem Text-Dokument nur, wenn es im Browse-Mode angezeigt
2433         // wird.
2434         if( pDoc->get(IDocumentSettingAccess::HTML_MODE) ||
2435             pDoc->get(IDocumentSettingAccess::BROWSE_MODE))
2436         {
2437             ViewShell *pVSh = 0;
2438             pDoc->GetEditShell( &pVSh );
2439             if ( pVSh &&
2440                  COL_TRANSPARENT != pVSh->GetViewOptions()->GetRetoucheColor().GetColor())
2441                 aColor = pVSh->GetViewOptions()->GetRetoucheColor().GetColor();
2442         }
2443 
2444         ByteString sOut;
2445         GetCSS1Color( aColor, sOut );
2446         OutCSS1_PropertyAscii( sCSS1_P_background, sOut );
2447     }
2448 }
2449 
2450 //-----------------------------------------------------------------------
2451 
OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink(Writer & rWrt,const SvxUnderlineItem * pUItem,const SvxOverlineItem * pOItem,const SvxCrossedOutItem * pCOItem,const SvxBlinkItem * pBItem)2452 static Writer& OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink( Writer& rWrt,
2453                     const SvxUnderlineItem *pUItem,
2454                     const SvxOverlineItem *pOItem,
2455                     const SvxCrossedOutItem *pCOItem,
2456                     const SvxBlinkItem *pBItem )
2457 {
2458     SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
2459     sal_Bool bNone = sal_False;
2460 
2461     const sal_Char *pUStr = 0;
2462     if( pUItem )
2463     {
2464         switch( pUItem->GetLineStyle() )
2465         {
2466         case UNDERLINE_NONE:
2467             bNone = sal_True;
2468             break;
2469         case UNDERLINE_DONTKNOW:
2470             break;
2471         default:
2472             if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
2473             {
2474                 // das geht auch in HTML und muss nicht als STYLE-Option
2475                 // und darf nicht als Hint geschrieben werden
2476                 ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
2477                         "Underline als Hint schreiben?" );
2478                 pUStr = sCSS1_PV_underline;
2479             }
2480             break;
2481         }
2482     }
2483 
2484     const sal_Char *pOStr = 0;
2485     if( pOItem )
2486     {
2487         switch( pOItem->GetLineStyle() )
2488         {
2489         case UNDERLINE_NONE:
2490             bNone = sal_True;
2491             break;
2492         case UNDERLINE_DONTKNOW:
2493             break;
2494         default:
2495             if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
2496             {
2497                 // das geht auch in HTML und muss nicht als STYLE-Option
2498                 // und darf nicht als Hint geschrieben werden
2499                 ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
2500                         "Overline als Hint schreiben?" );
2501                 pOStr = sCSS1_PV_overline;
2502             }
2503             break;
2504         }
2505     }
2506 
2507     const sal_Char *pCOStr = 0;
2508     if( pCOItem )
2509     {
2510         switch( pCOItem->GetStrikeout() )
2511         {
2512         case STRIKEOUT_NONE:
2513             bNone = sal_True;
2514             break;
2515         case STRIKEOUT_DONTKNOW:
2516             break;
2517         default:
2518             if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
2519             {
2520                 // das geht auch in HTML und muss nicht als STYLE-Option
2521                 // und darf nicht als Hint geschrieben werden
2522                 ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
2523                         "CrossedOut als Hint schreiben?" );
2524                 pCOStr = sCSS1_PV_line_through;
2525             }
2526             break;
2527         }
2528     }
2529 
2530     const sal_Char *pBStr = 0;
2531     if( pBItem && rHTMLWrt.IsHTMLMode(HTMLMODE_BLINK) )
2532     {
2533         if( !pBItem->GetValue() )
2534         {
2535             bNone = sal_True;
2536         }
2537         else if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
2538         {
2539             // das geht auch in HTML und muss nicht als STYLE-Option
2540             // und darf nicht als Hint geschrieben werden
2541             ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
2542                     "Blink als Hint schreiben?" );
2543             pBStr = sCSS1_PV_blink;
2544         }
2545     }
2546 
2547     ByteString sOut;
2548     if( pUStr )
2549         sOut.Append( pUStr );
2550 
2551     if( pOStr )
2552     {
2553         if( sOut.Len() )
2554             sOut += ' ';
2555 
2556         sOut.Append( pOStr );
2557     }
2558 
2559     if( pCOStr )
2560     {
2561         if( sOut.Len() )
2562             sOut += ' ';
2563 
2564         sOut.Append( pCOStr );
2565     }
2566 
2567     if( pBStr )
2568     {
2569         if( sOut.Len() )
2570             sOut += ' ';
2571 
2572         sOut.Append( pBStr );
2573     }
2574 
2575     if( sOut.Len() )
2576         rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_decoration, sOut );
2577     else if( bNone )
2578         rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_decoration, sCSS1_PV_none );
2579 
2580     return rWrt;
2581 }
2582 
2583 
OutCSS1_SvxCaseMap(Writer & rWrt,const SfxPoolItem & rHt)2584 static Writer& OutCSS1_SvxCaseMap( Writer& rWrt, const SfxPoolItem& rHt )
2585 {
2586     SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
2587 
2588     if( !rHTMLWrt.IsHTMLMode(HTMLMODE_SMALL_CAPS) )
2589         return rWrt;
2590 
2591     const sal_Char *pStr = 0;
2592     switch( ((const SvxCaseMapItem&)rHt).GetCaseMap() )
2593     {
2594     case SVX_CASEMAP_NOT_MAPPED:    pStr = sCSS1_PV_normal;     break;
2595     case SVX_CASEMAP_KAPITAELCHEN:  pStr = sCSS1_PV_small_caps; break;
2596     default:
2597         ;
2598     }
2599 
2600     if( pStr )
2601         rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_variant, pStr );
2602 
2603     return rWrt;
2604 }
2605 
2606 
OutCSS1_SvxColor(Writer & rWrt,const SfxPoolItem & rHt)2607 static Writer& OutCSS1_SvxColor( Writer& rWrt, const SfxPoolItem& rHt )
2608 {
2609     SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
2610 
2611     // Farben muessen nicht in der Style-Option ausgegeben werden.
2612     if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) &&
2613         !rHTMLWrt.bCfgPreferStyles )
2614         return rWrt;
2615     ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
2616             "Farbe wirklich als Hint ausgeben?" );
2617 
2618     Color aColor( ((const SvxColorItem&)rHt).GetValue() );
2619     if( COL_AUTO == aColor.GetColor() )
2620         aColor.SetColor( COL_BLACK );
2621 
2622     ByteString sOut;
2623     GetCSS1Color( aColor, sOut );
2624 
2625     rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_color, sOut );
2626 
2627     return rWrt;
2628 }
2629 
2630 
OutCSS1_SvxCrossedOut(Writer & rWrt,const SfxPoolItem & rHt)2631 static Writer& OutCSS1_SvxCrossedOut( Writer& rWrt, const SfxPoolItem& rHt )
2632 {
2633     // Mit dieser Methode werden nur Hints ausgegeben!
2634     // Sonst wird OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink() direkt aufgerufen.
2635 
2636     if( ((SwHTMLWriter&)rWrt).IsCSS1Source(CSS1_OUTMODE_HINT) )
2637         OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink( rWrt,
2638                 0, 0, (const SvxCrossedOutItem *)&rHt, 0 );
2639 
2640     return rWrt;
2641 }
2642 
OutCSS1_SvxFont(Writer & rWrt,const SfxPoolItem & rHt)2643 static Writer& OutCSS1_SvxFont( Writer& rWrt, const SfxPoolItem& rHt )
2644 {
2645     SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
2646 
2647     // Fonts muessen nicht in der Style-Option ausgegeben werden.
2648     if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
2649         return rWrt;
2650 
2651     sal_uInt16 nScript = CSS1_OUTMODE_WESTERN;
2652     switch( rHt.Which() )
2653     {
2654     case RES_CHRATR_CJK_FONT:   nScript = CSS1_OUTMODE_CJK; break;
2655     case RES_CHRATR_CTL_FONT:   nScript = CSS1_OUTMODE_CTL; break;
2656     }
2657     if( !rHTMLWrt.IsCSS1Script( nScript ) )
2658         return rWrt;
2659 
2660     ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
2661             "Font wirklich als Hint ausgeben?" );
2662 
2663     String sOut;
2664     // MS IE3b1 hat mit einfachen Haekchen Probleme
2665     sal_uInt16 nMode = rHTMLWrt.nCSS1OutMode & CSS1_OUTMODE_ANY_ON;
2666     sal_Unicode cQuote = nMode == CSS1_OUTMODE_RULE_ON ? '\"' : '\'';
2667     SwHTMLWriter::PrepareFontList( ((const SvxFontItem&)rHt), sOut, cQuote,
2668                                    sal_True );
2669 
2670     rHTMLWrt.OutCSS1_Property( sCSS1_P_font_family, sOut );
2671 
2672     return rWrt;
2673 }
2674 
OutCSS1_SvxFontHeight(Writer & rWrt,const SfxPoolItem & rHt)2675 static Writer& OutCSS1_SvxFontHeight( Writer& rWrt, const SfxPoolItem& rHt )
2676 {
2677     SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
2678 
2679     // Font-Hoehen muessen nicht in der Style-Option ausgegeben werden.
2680     // Fuer Drop-Caps wird ein andewres font-size ausgegeben
2681     if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) ||
2682         rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_DROPCAP ) )
2683         return rWrt;
2684 
2685     sal_uInt16 nScript = CSS1_OUTMODE_WESTERN;
2686     switch( rHt.Which() )
2687     {
2688     case RES_CHRATR_CJK_FONTSIZE:   nScript = CSS1_OUTMODE_CJK; break;
2689     case RES_CHRATR_CTL_FONTSIZE:   nScript = CSS1_OUTMODE_CTL; break;
2690     }
2691     if( !rHTMLWrt.IsCSS1Script( nScript ) )
2692         return rWrt;
2693 
2694     sal_uInt32 nHeight = ((const SvxFontHeightItem&)rHt).GetHeight();
2695     if( rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT) )
2696     {
2697         // einen Hint nur dann ausgeben wenn es auch was bringt
2698         sal_uInt16 nSize = rHTMLWrt.GetHTMLFontSize( nHeight );
2699         if( rHTMLWrt.aFontHeights[nSize-1] == nHeight )
2700             return rWrt;
2701     }
2702     ByteString sHeight( ByteString::CreateFromInt32(
2703                                             (sal_Int32)(nHeight/20) ) );
2704     sHeight.Append( sCSS1_UNIT_pt );
2705 
2706     rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_size, sHeight );
2707 
2708     return rWrt;
2709 }
2710 
OutCSS1_SvxPosture(Writer & rWrt,const SfxPoolItem & rHt)2711 static Writer& OutCSS1_SvxPosture( Writer& rWrt, const SfxPoolItem& rHt )
2712 {
2713     SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
2714 
2715     sal_uInt16 nScript = CSS1_OUTMODE_WESTERN;
2716     switch( rHt.Which() )
2717     {
2718     case RES_CHRATR_CJK_POSTURE:    nScript = CSS1_OUTMODE_CJK; break;
2719     case RES_CHRATR_CTL_POSTURE:    nScript = CSS1_OUTMODE_CTL; break;
2720     }
2721     if( !rHTMLWrt.IsCSS1Script( nScript ) )
2722         return rWrt;
2723 
2724     const sal_Char *pStr = 0;
2725     switch( ((const SvxPostureItem&)rHt).GetPosture() )
2726     {
2727     case ITALIC_NONE:       pStr = sCSS1_PV_normal;     break;
2728     case ITALIC_OBLIQUE:    pStr = sCSS1_PV_oblique;    break;
2729     case ITALIC_NORMAL:
2730         if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
2731         {
2732             // das geht auch in HTML und muss nicht als STYLE-Option
2733             // und darf nicht als Hint geschrieben werden
2734             ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
2735                     "Italic als Hint schreiben?" );
2736             pStr = sCSS1_PV_italic;
2737         }
2738         break;
2739     default:
2740         ;
2741     }
2742 
2743     if( pStr )
2744         rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_style, pStr );
2745 
2746     return rWrt;
2747 }
2748 
OutCSS1_SvxKerning(Writer & rWrt,const SfxPoolItem & rHt)2749 static Writer& OutCSS1_SvxKerning( Writer& rWrt, const SfxPoolItem& rHt )
2750 {
2751     SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
2752 
2753     // Kerning-Item nur ausgeben, wenn volle Style-Unterst?tzung da ist
2754     if( !rHTMLWrt.IsHTMLMode(HTMLMODE_FULL_STYLES) )
2755         return rWrt;
2756 
2757     sal_Int16 nValue = ((const SvxKerningItem&)rHt).GetValue();
2758     if( nValue )
2759     {
2760         ByteString sOut;
2761         if( nValue < 0 )
2762         {
2763             sOut = '-';
2764             nValue = -nValue;
2765         }
2766 
2767         // Breite als n.n pt
2768         nValue = (nValue + 1) / 2;  // 1/10pt
2769         sOut.Append( ByteString::CreateFromInt32( (sal_Int32)(nValue  / 10) ) );
2770         sOut.Append( '.' );
2771         sOut.Append( ByteString::CreateFromInt32( (sal_Int32)(nValue % 10) ) );
2772         sOut.Append( sCSS1_UNIT_pt );
2773 
2774         rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_letter_spacing, sOut );
2775     }
2776     else
2777     {
2778         rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_letter_spacing,
2779                                         sCSS1_PV_normal );
2780     }
2781 
2782     return rWrt;
2783 }
2784 
OutCSS1_SvxLanguage(Writer & rWrt,const SfxPoolItem & rHt)2785 static Writer& OutCSS1_SvxLanguage( Writer& rWrt, const SfxPoolItem& rHt )
2786 {
2787     SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
2788 
2789     // Language will be exported rules only
2790     if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
2791         return rWrt;
2792 
2793     sal_uInt16 nScript = CSS1_OUTMODE_WESTERN;
2794     switch( rHt.Which() )
2795     {
2796     case RES_CHRATR_CJK_LANGUAGE:   nScript = CSS1_OUTMODE_CJK; break;
2797     case RES_CHRATR_CTL_LANGUAGE:   nScript = CSS1_OUTMODE_CTL; break;
2798     }
2799     if( !rHTMLWrt.IsCSS1Script( nScript ) )
2800         return rWrt;
2801 
2802     ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
2803             "Language wirklich als Hint ausgeben?" );
2804 
2805     LanguageType eLang = ((const SvxLanguageItem &)rHt).GetLanguage();
2806     if( LANGUAGE_DONTKNOW == eLang )
2807         return rWrt;
2808 
2809     String sOut = MsLangId::convertLanguageToIsoString( eLang );
2810 
2811     rHTMLWrt.OutCSS1_Property( sCSS1_P_so_language, sOut );
2812 
2813     return rWrt;
2814 }
2815 
OutCSS1_SvxUnderline(Writer & rWrt,const SfxPoolItem & rHt)2816 static Writer& OutCSS1_SvxUnderline( Writer& rWrt, const SfxPoolItem& rHt )
2817 {
2818     // Mit dieser Methode werden nur Hints ausgegeben!
2819     // Sonst wird OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink() direkt aufgerufen.
2820 
2821     if( ((SwHTMLWriter&)rWrt).IsCSS1Source(CSS1_OUTMODE_HINT) )
2822         OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink( rWrt,
2823                 (const SvxUnderlineItem *)&rHt, 0, 0, 0 );
2824 
2825     return rWrt;
2826 }
2827 
2828 
OutCSS1_SvxOverline(Writer & rWrt,const SfxPoolItem & rHt)2829 static Writer& OutCSS1_SvxOverline( Writer& rWrt, const SfxPoolItem& rHt )
2830 {
2831     // Mit dieser Methode werden nur Hints ausgegeben!
2832     // Sonst wird OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink() direkt aufgerufen.
2833 
2834     if( ((SwHTMLWriter&)rWrt).IsCSS1Source(CSS1_OUTMODE_HINT) )
2835         OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink( rWrt,
2836                 0, (const SvxOverlineItem *)&rHt, 0, 0 );
2837 
2838     return rWrt;
2839 }
2840 
2841 
OutCSS1_SvxFontWeight(Writer & rWrt,const SfxPoolItem & rHt)2842 static Writer& OutCSS1_SvxFontWeight( Writer& rWrt, const SfxPoolItem& rHt )
2843 {
2844     SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
2845 
2846     sal_uInt16 nScript = CSS1_OUTMODE_WESTERN;
2847     switch( rHt.Which() )
2848     {
2849     case RES_CHRATR_CJK_WEIGHT: nScript = CSS1_OUTMODE_CJK; break;
2850     case RES_CHRATR_CTL_WEIGHT: nScript = CSS1_OUTMODE_CTL; break;
2851     }
2852     if( !rHTMLWrt.IsCSS1Script( nScript ) )
2853         return rWrt;
2854 
2855     const sal_Char *pStr = 0;
2856     switch( ((const SvxWeightItem&)rHt).GetWeight() )
2857     {
2858     case WEIGHT_ULTRALIGHT: pStr = sCSS1_PV_extra_light;    break;
2859     case WEIGHT_LIGHT:      pStr = sCSS1_PV_light;          break;
2860     case WEIGHT_SEMILIGHT:  pStr = sCSS1_PV_demi_light;     break;
2861     case WEIGHT_NORMAL:     pStr = sCSS1_PV_normal;         break;
2862     case WEIGHT_SEMIBOLD:   pStr = sCSS1_PV_demi_bold;      break;
2863     case WEIGHT_BOLD:
2864         if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
2865         {
2866             // das geht auch in HTML und muss nicht als STYLE-Option
2867             // und darf nicht als Hint geschrieben werden
2868             ASSERT( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT),
2869                     "Fett als Hint schreiben?" );
2870             pStr = sCSS1_PV_bold;
2871         }
2872         break;
2873     case WEIGHT_ULTRABOLD:  pStr = sCSS1_PV_extra_bold;     break;
2874     default:
2875         pStr = sCSS1_PV_normal;;
2876     }
2877 
2878     if( pStr )
2879         rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_font_weight, pStr );
2880 
2881     return rWrt;
2882 }
2883 
OutCSS1_SvxBlink(Writer & rWrt,const SfxPoolItem & rHt)2884 static Writer& OutCSS1_SvxBlink( Writer& rWrt, const SfxPoolItem& rHt )
2885 {
2886     // Mit dieser Methode werden nur Hints ausgegeben!
2887     // Sonst wird OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink() direkt aufgerufen.
2888 
2889     if( ((SwHTMLWriter&)rWrt).IsCSS1Source(CSS1_OUTMODE_HINT) )
2890         OutCSS1_SvxTxtLn_SvxCrOut_SvxBlink( rWrt,
2891                 0, 0, 0, (const SvxBlinkItem *)&rHt );
2892 
2893     return rWrt;
2894 }
2895 
OutCSS1_SvxLineSpacing(Writer & rWrt,const SfxPoolItem & rHt)2896 static Writer& OutCSS1_SvxLineSpacing( Writer& rWrt, const SfxPoolItem& rHt )
2897 {
2898     SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
2899 
2900     // #60393#: Netscape4 hat massive Probleme mit den Zellenhoehen
2901     // wenn der Zeilenabstand innerhalb einer Tabelle geaendert wird
2902     // und die Breite der Tabelle nicht automatisch berechnet wird
2903     // (also wenn eine WIDTH-Option vorhanden ist).
2904     if( rHTMLWrt.bOutTable && rHTMLWrt.bCfgNetscape4 )
2905         return rWrt;
2906 
2907     const SvxLineSpacingItem& rLSItem = (const SvxLineSpacingItem&)rHt;
2908 
2909     sal_uInt16 nHeight = 0;
2910     sal_uInt16 nPrcHeight = 0;
2911     SvxLineSpace eLineSpace = rLSItem.GetLineSpaceRule();
2912     switch( rLSItem.GetInterLineSpaceRule() )
2913     {
2914     case SVX_INTER_LINE_SPACE_OFF:
2915     case SVX_INTER_LINE_SPACE_FIX:
2916         {
2917             switch( eLineSpace )
2918             {
2919             case SVX_LINE_SPACE_MIN:
2920             case SVX_LINE_SPACE_FIX:
2921                 nHeight = rLSItem.GetLineHeight();
2922                 break;
2923             case SVX_LINE_SPACE_AUTO:
2924                 nPrcHeight = 100;
2925                 break;
2926             default:
2927                 ;
2928             }
2929         }
2930         break;
2931     case SVX_INTER_LINE_SPACE_PROP:
2932         nPrcHeight = rLSItem.GetPropLineSpace();
2933         break;
2934 
2935     default:
2936         ;
2937     }
2938 
2939     if( nHeight )
2940         rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_line_height, (long)nHeight );
2941     else if( nPrcHeight )
2942     {
2943         ByteString sHeight(
2944                 ByteString::CreateFromInt32( (sal_Int32)nPrcHeight ) );
2945         sHeight += '%';
2946         rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_line_height, sHeight );
2947     }
2948 
2949     return rWrt;
2950 
2951 }
2952 
OutCSS1_SvxAdjust(Writer & rWrt,const SfxPoolItem & rHt)2953 static Writer& OutCSS1_SvxAdjust( Writer& rWrt, const SfxPoolItem& rHt )
2954 {
2955     SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
2956 
2957     // Alignment in Style-Option nur ausgeben, wenn das Tag kein
2958     // ALIGN=xxx zulaesst
2959     if( rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) &&
2960         !rHTMLWrt.bNoAlign)
2961         return rWrt;
2962 
2963     const sal_Char* pStr = 0;
2964     switch( ((const SvxAdjustItem&)rHt).GetAdjust() )
2965     {
2966     case SVX_ADJUST_LEFT:   pStr = sCSS1_PV_left;       break;
2967     case SVX_ADJUST_RIGHT:  pStr = sCSS1_PV_right;      break;
2968     case SVX_ADJUST_BLOCK:  pStr = sCSS1_PV_justify;    break;
2969     case SVX_ADJUST_CENTER: pStr = sCSS1_PV_center;     break;
2970     default:
2971         ;
2972     }
2973 
2974     if( pStr )
2975         rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_text_align, pStr );
2976 
2977     return rWrt;
2978 }
2979 
OutCSS1_SvxFmtSplit(Writer & rWrt,const SfxPoolItem & rHt)2980 static Writer& OutCSS1_SvxFmtSplit( Writer& rWrt, const SfxPoolItem& rHt )
2981 {
2982     SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
2983 
2984     const sal_Char *pStr = ((const SvxFmtSplitItem&)rHt).GetValue()
2985                             ? sCSS1_PV_auto
2986                             : sCSS1_PV_avoid;
2987     rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_page_break_inside, pStr );
2988 
2989     return rWrt;
2990 }
2991 
OutCSS1_SwFmtLayoutSplit(Writer & rWrt,const SfxPoolItem & rHt)2992 static Writer& OutCSS1_SwFmtLayoutSplit( Writer& rWrt, const SfxPoolItem& rHt )
2993 {
2994     SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
2995 
2996     const sal_Char *pStr = ((const SwFmtLayoutSplit&)rHt).GetValue()
2997                             ? sCSS1_PV_auto
2998                             : sCSS1_PV_avoid;
2999     rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_page_break_inside, pStr );
3000 
3001     return rWrt;
3002 }
3003 
OutCSS1_SvxWidows(Writer & rWrt,const SfxPoolItem & rHt)3004 static Writer& OutCSS1_SvxWidows( Writer& rWrt, const SfxPoolItem& rHt )
3005 {
3006     SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
3007 
3008     ByteString aStr(
3009         ByteString::CreateFromInt32( ((const SvxWidowsItem&)rHt).GetValue() ) );
3010     rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_widows, aStr );
3011 
3012     return rWrt;
3013 }
3014 
OutCSS1_SvxOrphans(Writer & rWrt,const SfxPoolItem & rHt)3015 static Writer& OutCSS1_SvxOrphans( Writer& rWrt, const SfxPoolItem& rHt )
3016 {
3017     SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
3018 
3019     ByteString aStr(
3020        ByteString::CreateFromInt32( ((const SvxOrphansItem&)rHt).GetValue() ) );
3021     rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_orphans, aStr );
3022 
3023     return rWrt;
3024 }
3025 
OutCSS1_SwFmtDropAttrs(SwHTMLWriter & rHWrt,const SwFmtDrop & rDrop,const SfxItemSet * pCharFmtItemSet)3026 static void OutCSS1_SwFmtDropAttrs( SwHTMLWriter& rHWrt,
3027                                     const SwFmtDrop& rDrop,
3028                                     const SfxItemSet *pCharFmtItemSet )
3029 {
3030     // Text fliesst rechts drumrum
3031     rHWrt.OutCSS1_PropertyAscii( sCSS1_P_float, sCSS1_PV_left );
3032 
3033     // Anzahl der Zeilen -> %-Angabe fuer Font-Hoehe!
3034     ByteString sOut( ByteString::CreateFromInt32( rDrop.GetLines()*100 ) );
3035     sOut += '%';
3036     rHWrt.OutCSS1_PropertyAscii( sCSS1_P_font_size, sOut );
3037 
3038     // Abstand zum Text = rechter Rand
3039     sal_uInt16 nDistance = rDrop.GetDistance();
3040     if( nDistance > 0 )
3041         rHWrt.OutCSS1_UnitProperty( sCSS1_P_margin_right, nDistance );
3042 
3043     const SwCharFmt *pDCCharFmt = rDrop.GetCharFmt();
3044     if( pCharFmtItemSet )
3045         rHWrt.OutCSS1_SfxItemSet( *pCharFmtItemSet );
3046     else if( pDCCharFmt )
3047         rHWrt.OutCSS1_SfxItemSet( pDCCharFmt->GetAttrSet() );
3048     else if( (rHWrt.nCSS1OutMode & CSS1_OUTMODE_ANY_OFF) == CSS1_OUTMODE_RULE_OFF )
3049         rHWrt.Strm() << sCSS1_rule_end;
3050 
3051 }
3052 
OutCSS1_SwFmtDrop(Writer & rWrt,const SfxPoolItem & rHt)3053 static Writer& OutCSS1_SwFmtDrop( Writer& rWrt, const SfxPoolItem& rHt )
3054 {
3055     SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
3056 
3057     // nie als Option eines Absatzes ausgeben, sondern nur als Hints
3058     if( !rHTMLWrt.IsCSS1Source(CSS1_OUTMODE_HINT) )
3059         return rWrt;
3060 
3061     if( rHTMLWrt.bTagOn )
3062     {
3063         SwCSS1OutMode aMode( rHTMLWrt,
3064                              rHTMLWrt.nCSS1Script|CSS1_OUTMODE_SPAN_TAG1_ON|CSS1_OUTMODE_ENCODE|
3065                              CSS1_OUTMODE_DROPCAP );
3066 
3067         OutCSS1_SwFmtDropAttrs( rHTMLWrt, (const SwFmtDrop&)rHt );
3068         // Ein "> wird schon vom aufrufenden OutCSS1_HintAsSpanTag geschrieben.
3069     }
3070     else
3071     {
3072         HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_span, sal_False );
3073     }
3074 
3075     return rWrt;
3076 }
3077 
OutCSS1_SwFmtFrmSize(Writer & rWrt,const SfxPoolItem & rHt,sal_uInt16 nMode)3078 static Writer& OutCSS1_SwFmtFrmSize( Writer& rWrt, const SfxPoolItem& rHt,
3079                                      sal_uInt16 nMode )
3080 {
3081     SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
3082 
3083     ByteString sOut;
3084     const SwFmtFrmSize& rFSItem = (const SwFmtFrmSize&)rHt;
3085 
3086     if( nMode & CSS1_FRMSIZE_WIDTH )
3087     {
3088         sal_uInt8 nPrcWidth = rFSItem.GetWidthPercent();
3089         if( nPrcWidth )
3090         {
3091             (sOut = ByteString::CreateFromInt32( nPrcWidth) ) += '%';
3092             rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_width, sOut );
3093         }
3094         else if( nMode & CSS1_FRMSIZE_PIXEL )
3095         {
3096             rHTMLWrt.OutCSS1_PixelProperty( sCSS1_P_width,
3097                                             rFSItem.GetSize().Width(), sal_False );
3098         }
3099         else
3100         {
3101             rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_width,
3102                                            rFSItem.GetSize().Width() );
3103         }
3104     }
3105 
3106     if( nMode & CSS1_FRMSIZE_ANYHEIGHT )
3107     {
3108         sal_Bool bOutHeight = sal_False;
3109         switch( rFSItem.GetHeightSizeType() )
3110         {
3111         case ATT_FIX_SIZE:
3112             bOutHeight = (nMode & CSS1_FRMSIZE_FIXHEIGHT) != 0;
3113             break;
3114         case ATT_MIN_SIZE:
3115             bOutHeight = (nMode & CSS1_FRMSIZE_MINHEIGHT) != 0;
3116             break;
3117         case ATT_VAR_SIZE:
3118             bOutHeight = (nMode & CSS1_FRMSIZE_VARHEIGHT) != 0;
3119             break;
3120         default:
3121             ASSERT( bOutHeight, "Hoehe wird nicht exportiert" );
3122             break;
3123         }
3124 
3125         if( bOutHeight )
3126         {
3127             sal_uInt8 nPrcHeight = rFSItem.GetHeightPercent();
3128             if( nPrcHeight )
3129             {
3130                 (sOut = ByteString::CreateFromInt32( nPrcHeight ) ) += '%';
3131                 rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_height, sOut );
3132             }
3133             else if( nMode & CSS1_FRMSIZE_PIXEL )
3134             {
3135                 rHTMLWrt.OutCSS1_PixelProperty( sCSS1_P_height,
3136                                                 rFSItem.GetSize().Width(),
3137                                                 sal_True );
3138             }
3139             else
3140             {
3141                 rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_height,
3142                                                rFSItem.GetSize().Height() );
3143             }
3144         }
3145     }
3146 
3147     return rWrt;
3148 }
3149 
OutCSS1_SvxLRSpace(Writer & rWrt,const SfxPoolItem & rHt)3150 static Writer& OutCSS1_SvxLRSpace( Writer& rWrt, const SfxPoolItem& rHt )
3151 {
3152     SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
3153 
3154     const SvxLRSpaceItem& rLRItem = (const SvxLRSpaceItem&)rHt;
3155 
3156     // Der Export der harten Attributierung ist unnoetig, wenn die
3157     // neuen Werte denen der aktuellen Vorlage entsprechen
3158 
3159     // Einen linken Rand kann es durch eine Liste bereits in der
3160     // Umgebung geben
3161     long nLeftMargin = (long)rLRItem.GetTxtLeft() - rHTMLWrt.nLeftMargin;
3162     if( rHTMLWrt.nDfltLeftMargin != nLeftMargin )
3163     {
3164         rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_left, nLeftMargin );
3165     }
3166 
3167     if( rHTMLWrt.nDfltRightMargin != rLRItem.GetRight() )
3168     {
3169         rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_right,
3170                                  (long)rLRItem.GetRight() );
3171     }
3172 
3173     // Der Erstzeilen-Einzug kann den Platz fuer eine Numerierung
3174     // enthalten
3175     long nFirstLineIndent = (long)rLRItem.GetTxtFirstLineOfst() -
3176         rHTMLWrt.nFirstLineIndent;
3177     if( rHTMLWrt.nDfltFirstLineIndent != nFirstLineIndent )
3178     {
3179         rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_text_indent,
3180                                      nFirstLineIndent );
3181     }
3182 
3183     return rWrt;
3184 }
3185 
OutCSS1_SvxULSpace(Writer & rWrt,const SfxPoolItem & rHt)3186 static Writer& OutCSS1_SvxULSpace( Writer& rWrt, const SfxPoolItem& rHt )
3187 {
3188     SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
3189 
3190     const SvxULSpaceItem& rULItem = (const SvxULSpaceItem&)rHt;
3191 
3192     if( rHTMLWrt.nDfltTopMargin != rULItem.GetUpper() )
3193     {
3194         rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_top,
3195                                      (long)rULItem.GetUpper() );
3196     }
3197 
3198     if( rHTMLWrt.nDfltBottomMargin != rULItem.GetLower() )
3199     {
3200         rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin_bottom,
3201                                      (long)rULItem.GetLower() );
3202     }
3203 
3204     return rWrt;
3205 }
3206 
OutCSS1_SvxULSpace_SvxLRSpace(Writer & rWrt,const SvxULSpaceItem * pULItem,const SvxLRSpaceItem * pLRItem)3207 static Writer& OutCSS1_SvxULSpace_SvxLRSpace( Writer& rWrt,
3208                                         const SvxULSpaceItem *pULItem,
3209                                         const SvxLRSpaceItem *pLRItem )
3210 {
3211     SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
3212 
3213     if( pLRItem && pULItem &&
3214         pLRItem->GetLeft() == pLRItem->GetRight() &&
3215         pLRItem->GetLeft() == pULItem->GetUpper() &&
3216         pLRItem->GetLeft() == pULItem->GetLower() &&
3217         pLRItem->GetLeft() != rHTMLWrt.nDfltLeftMargin &&
3218         pLRItem->GetRight() != rHTMLWrt.nDfltRightMargin &&
3219         pULItem->GetUpper() != rHTMLWrt.nDfltTopMargin &&
3220         pULItem->GetLower() != rHTMLWrt.nDfltBottomMargin )
3221     {
3222         rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_margin, (long)pLRItem->GetLeft() );
3223     }
3224     else
3225     {
3226         if( pLRItem )
3227             OutCSS1_SvxLRSpace( rWrt, *pLRItem );
3228         if( pULItem )
3229             OutCSS1_SvxULSpace( rWrt, *pULItem );
3230     }
3231 
3232     return rWrt;
3233 }
3234 
OutCSS1_SvxULSpace_SvxLRSpace(Writer & rWrt,const SfxItemSet & rItemSet,sal_Bool bDeep)3235 static Writer& OutCSS1_SvxULSpace_SvxLRSpace( Writer& rWrt,
3236                                         const SfxItemSet& rItemSet,
3237                                         sal_Bool bDeep )
3238 {
3239     const SvxULSpaceItem *pULSpace = 0;
3240     const SvxLRSpaceItem *pLRSpace = 0;
3241     const SfxPoolItem *pItem;
3242     if( SFX_ITEM_SET == rItemSet.GetItemState( RES_LR_SPACE, bDeep, &pItem ) )
3243         pLRSpace = (const SvxLRSpaceItem *)pItem;
3244 
3245     if( SFX_ITEM_SET == rItemSet.GetItemState( RES_UL_SPACE, bDeep, &pItem ) )
3246         pULSpace = (const SvxULSpaceItem *)pItem;
3247 
3248     if( pLRSpace || pULSpace )
3249         OutCSS1_SvxULSpace_SvxLRSpace( rWrt, pULSpace, pLRSpace );
3250 
3251     return rWrt;
3252 }
3253 
OutCSS1_SvxFmtBreak_SwFmtPDesc_SvxFmtKeep(Writer & rWrt,const SvxFmtBreakItem * pBreakItem,const SwFmtPageDesc * pPDescItem,const SvxFmtKeepItem * pKeepItem)3254 static Writer& OutCSS1_SvxFmtBreak_SwFmtPDesc_SvxFmtKeep( Writer& rWrt,
3255                                         const SvxFmtBreakItem *pBreakItem,
3256                                         const SwFmtPageDesc *pPDescItem,
3257                                         const SvxFmtKeepItem *pKeepItem )
3258 {
3259     SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
3260 
3261     if( !rHTMLWrt.IsHTMLMode(HTMLMODE_PRINT_EXT) )
3262         return rWrt;
3263 
3264     const sal_Char *pBreakBefore = 0;
3265     const sal_Char *pBreakAfter = 0;
3266 
3267     if( pKeepItem )
3268     {
3269         pBreakAfter = pKeepItem->GetValue() ? sCSS1_PV_avoid : sCSS1_PV_auto;
3270     }
3271     if( pBreakItem )
3272     {
3273         switch( pBreakItem->GetBreak() )
3274         {
3275         case SVX_BREAK_NONE:
3276             pBreakBefore = sCSS1_PV_auto;
3277             if( !pBreakAfter )
3278                 pBreakAfter = sCSS1_PV_auto;
3279             break;
3280 
3281         case SVX_BREAK_PAGE_BEFORE:
3282             pBreakBefore = sCSS1_PV_always;
3283             break;
3284 
3285         case SVX_BREAK_PAGE_AFTER:
3286             pBreakAfter= sCSS1_PV_always;
3287             break;
3288 
3289         default:
3290             ;
3291         }
3292     }
3293     if( pPDescItem )
3294     {
3295         const SwPageDesc *pPDesc = pPDescItem->GetPageDesc();
3296         if( pPDesc )
3297         {
3298             switch( pPDesc->GetPoolFmtId() )
3299             {
3300             case RES_POOLPAGE_LEFT:     pBreakBefore = sCSS1_PV_left;   break;
3301             case RES_POOLPAGE_RIGHT:    pBreakBefore = sCSS1_PV_right;  break;
3302             default:                    pBreakBefore = sCSS1_PV_always; break;
3303             }
3304         }
3305         else if( !pBreakBefore )
3306         {
3307             pBreakBefore = sCSS1_PV_auto;
3308         }
3309     }
3310 
3311     if( pBreakBefore )
3312         rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_page_break_before,
3313                                         pBreakBefore );
3314     if( pBreakAfter )
3315         rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_page_break_after,
3316                                         pBreakAfter );
3317 
3318     return rWrt;
3319 }
3320 
OutCSS1_SvxFmtBreak_SwFmtPDesc_SvxFmtKeep(Writer & rWrt,const SfxItemSet & rItemSet,sal_Bool bDeep)3321 static Writer& OutCSS1_SvxFmtBreak_SwFmtPDesc_SvxFmtKeep( Writer& rWrt,
3322                                         const SfxItemSet& rItemSet,
3323                                         sal_Bool bDeep )
3324 {
3325     SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
3326     const SfxPoolItem *pItem;
3327     const SvxFmtBreakItem *pBreakItem = 0;
3328     if( SFX_ITEM_SET==rItemSet.GetItemState( RES_BREAK, bDeep, &pItem ))
3329         pBreakItem = (const SvxFmtBreakItem *)pItem;
3330 
3331     const SwFmtPageDesc *pPDescItem = 0;
3332     if( ( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) ||
3333           !rHTMLWrt.bCSS1IgnoreFirstPageDesc ||
3334           rHTMLWrt.pStartNdIdx->GetIndex() !=
3335                       rHTMLWrt.pCurPam->GetPoint()->nNode.GetIndex() ) &&
3336         SFX_ITEM_SET==rItemSet.GetItemState( RES_PAGEDESC, bDeep, &pItem ))
3337         pPDescItem = (const SwFmtPageDesc*)pItem;
3338 
3339     const SvxFmtKeepItem *pKeepItem = 0;
3340     if( SFX_ITEM_SET==rItemSet.GetItemState( RES_KEEP, bDeep, &pItem ))
3341         pKeepItem = (const SvxFmtKeepItem *)pItem;
3342 
3343     if( pBreakItem || pPDescItem || pKeepItem )
3344         OutCSS1_SvxFmtBreak_SwFmtPDesc_SvxFmtKeep( rWrt, pBreakItem,
3345                                                    pPDescItem, pKeepItem );
3346 
3347     return rWrt;
3348 }
3349 
3350 // Wrapper fuer OutCSS1_SfxItemSet etc.
OutCSS1_SvxBrush(Writer & rWrt,const SfxPoolItem & rHt)3351 static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt )
3352 {
3353     OutCSS1_SvxBrush( rWrt, rHt, CSS1_BACKGROUND_ATTR, 0 );
3354     return rWrt;
3355 }
3356 
3357 
OutCSS1_SvxBrush(Writer & rWrt,const SfxPoolItem & rHt,sal_uInt16 nMode,const String * pGrfName)3358 static Writer& OutCSS1_SvxBrush( Writer& rWrt, const SfxPoolItem& rHt,
3359                                  sal_uInt16 nMode, const String *pGrfName )
3360 {
3361     SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
3362 
3363     // Das Zeichen-Attribut wird nicht ausgegeben, wenn gerade
3364     // Optionen ausgegeben werden
3365     if( rHt.Which() < RES_CHRATR_END &&
3366         rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_PARA ) )
3367         return rWrt;
3368 
3369     // Erstmal ein par Werte holen
3370 //  const Brush &rBrush = ((const SvxBrushItem &)rHt).GetBrush();
3371     const Color & rColor = ((const SvxBrushItem &)rHt).GetColor();
3372     const String *pLink = pGrfName ? pGrfName
3373                             : ((const SvxBrushItem &)rHt).GetGraphicLink();
3374     SvxGraphicPosition ePos = ((const SvxBrushItem &)rHt).GetGraphicPos();
3375 
3376     if( CSS1_BACKGROUND_PAGE==nMode )
3377     {
3378         // Fuer Seitenvorlagen wurde der Grafik-Name uebergeben. Es wird
3379         // nur ein Attribut ausgegeben, wenn die Grafik nicht gekachelt ist.
3380         ASSERT( pLink, "Wo ist der Grafik-Name der Seitenvorlage?" );
3381         if( !pLink || !pLink->Len() || GPOS_TILED==ePos )
3382             return rWrt;
3383     }
3384 
3385     // Erstmal die Farbe holen
3386     sal_Bool bColor = sal_False;
3387     /// OD 02.09.2002 #99657#
3388     /// set <bTransparent> to sal_True, if color is "no fill"/"auto fill"
3389     sal_Bool bTransparent = (rColor.GetColor() == COL_TRANSPARENT);
3390     Color aColor;
3391     if( !bTransparent )
3392     {
3393         aColor = rColor;
3394         bColor = sal_True;
3395     }
3396 
3397     // und jetzt eine Grafik
3398     String sGrfNm;
3399 
3400     if( !pLink )
3401     {
3402         // embeddete Grafik -> WriteEmbedded schreiben
3403         const Graphic* pGrf = ((const SvxBrushItem &)rHt).GetGraphic();
3404         if( pGrf )
3405         {
3406             // Grafik als (JPG-)File speichern
3407             const String* pTempFileName = rHTMLWrt.GetOrigFileName();
3408             if( pTempFileName )
3409                 sGrfNm = *pTempFileName;
3410             sal_uInt16 nErr = XOutBitmap::WriteGraphic( *pGrf, sGrfNm,
3411                         String::CreateFromAscii("JPG"),
3412                         XOUTBMP_USE_NATIVE_IF_POSSIBLE );
3413             if( !nErr )     // fehlerhaft, da ist nichts auszugeben
3414             {
3415                 sGrfNm = URIHelper::SmartRel2Abs(
3416                     INetURLObject(rWrt.GetBaseURL()), sGrfNm,
3417                     URIHelper::GetMaybeFileHdl() );
3418                 pLink = &sGrfNm;
3419             }
3420             else
3421             {
3422                 rHTMLWrt.nWarn = WARN_SWG_POOR_LOAD | WARN_SW_WRITE_BASE;
3423             }
3424         }
3425     }
3426     else if( !pGrfName && rHTMLWrt.bCfgCpyLinkedGrfs )
3427     {
3428         sGrfNm = *pLink;
3429         rWrt.CopyLocalFileToINet( sGrfNm );
3430         pLink = &sGrfNm;
3431     }
3432 
3433     // In Tabellen wird nur dann etwas exportiert, wenn eine Grafik
3434     // existiert.
3435     if( CSS1_BACKGROUND_TABLE==nMode && !pLink )
3436         return rWrt;
3437 
3438     // ggf. noch die Ausrichtung der Grafik
3439     const sal_Char *pRepeat = 0, *pHori = 0, *pVert = 0;
3440     if( pLink )
3441     {
3442         if( GPOS_TILED==ePos )
3443         {
3444             pRepeat = sCSS1_PV_repeat;
3445         }
3446         else
3447         {
3448             switch( ePos )
3449             {
3450             case GPOS_LT:
3451             case GPOS_MT:
3452             case GPOS_RT:
3453                 pHori = sCSS1_PV_top;
3454                 break;
3455 
3456             case GPOS_LM:
3457             case GPOS_MM:
3458             case GPOS_RM:
3459                 pHori = sCSS1_PV_middle;
3460                 break;
3461 
3462             case GPOS_LB:
3463             case GPOS_MB:
3464             case GPOS_RB:
3465                 pHori = sCSS1_PV_bottom;
3466                 break;
3467 
3468             default:
3469                 ;
3470             }
3471 
3472             switch( ePos )
3473             {
3474             case GPOS_LT:
3475             case GPOS_LM:
3476             case GPOS_LB:
3477                 pVert = sCSS1_PV_left;
3478                 break;
3479 
3480             case GPOS_MT:
3481             case GPOS_MM:
3482             case GPOS_MB:
3483                 pVert = sCSS1_PV_center;
3484                 break;
3485 
3486             case GPOS_RT:
3487             case GPOS_RM:
3488             case GPOS_RB:
3489                 pVert = sCSS1_PV_right;
3490                 break;
3491 
3492             default:
3493                 ;
3494             }
3495 
3496             if( pHori || pVert )
3497                 pRepeat = sCSS1_PV_no_repeat;
3498         }
3499     }
3500 
3501     // jetzt den String zusammen bauen
3502     String sOut;
3503     if( !pLink && !bColor )
3504     {
3505         // keine Farbe und kein Link, aber ein transparenter Brush
3506         if( bTransparent && CSS1_BACKGROUND_FLY != nMode )
3507             sOut.AssignAscii( sCSS1_PV_transparent );
3508     }
3509     else
3510     {
3511         if( bColor )
3512         {
3513             ByteString sTmp;
3514             GetCSS1Color( aColor, sTmp );
3515             sOut += String( sTmp, RTL_TEXTENCODING_ASCII_US );
3516         }
3517 
3518         if( pLink )
3519         {
3520             if( bColor )
3521                 sOut += ' ';
3522 
3523             sOut.AppendAscii( sCSS1_url );
3524             sOut.Append( '(' );
3525             sOut.Append( String(URIHelper::simpleNormalizedMakeRelative(rWrt.GetBaseURL(),
3526               *pLink)));
3527 
3528             sOut.Append( ')' );
3529 
3530             if( pRepeat )
3531             {
3532                 sOut.Append( ' ' );
3533                 sOut.AppendAscii( pRepeat );
3534             }
3535 
3536             if( pHori )
3537             {
3538                 sOut.Append( ' ' );
3539                 sOut.AppendAscii( pHori );
3540             }
3541             if( pVert )
3542             {
3543                 sOut.Append( ' ' );
3544                 sOut.AppendAscii( pVert );
3545             }
3546 
3547             sOut.Append( ' ' );
3548             sOut.AppendAscii( sCSS1_PV_scroll );
3549         }
3550     }
3551 
3552     if( sOut.Len() )
3553         rHTMLWrt.OutCSS1_Property( sCSS1_P_background, sOut );
3554 
3555     return rWrt;
3556 }
3557 
OutCSS1_SvxBorderLine(SwHTMLWriter & rHTMLWrt,const sal_Char * pProperty,const SvxBorderLine * pLine)3558 static void OutCSS1_SvxBorderLine( SwHTMLWriter& rHTMLWrt,
3559                                    const sal_Char *pProperty,
3560                                    const SvxBorderLine *pLine )
3561 {
3562     if( !pLine )
3563     {
3564         rHTMLWrt.OutCSS1_PropertyAscii( pProperty, sCSS1_PV_none );
3565         return;
3566     }
3567 
3568     sal_Bool bDouble = sal_False;
3569     sal_Int32 nWidth = pLine->GetOutWidth();
3570     if( pLine->GetInWidth() )
3571     {
3572         nWidth += pLine->GetDistance();
3573         nWidth += pLine->GetInWidth();
3574         bDouble = sal_True;
3575     }
3576 
3577     ByteString sOut;
3578     if( Application::GetDefaultDevice() &&
3579         nWidth <= Application::GetDefaultDevice()->PixelToLogic(
3580                     Size( 1, 1 ), MapMode( MAP_TWIP) ).Width() )
3581     {
3582         // Wenn die Breite kleiner ist als ein Pixel, dann als 1px
3583         // ausgeben, damit Netscape und IE die Linie auch darstellen.
3584         sOut += "1px";
3585     }
3586     else
3587     {
3588         nWidth *= 5;    // 1/100pt
3589 
3590         // Breite als n.nn pt
3591         sOut += ByteString::CreateFromInt32( nWidth / 100 );
3592         (((sOut += '.')
3593             += ByteString::CreateFromInt32((nWidth/10) % 10))
3594             += ByteString::CreateFromInt32(nWidth % 10)) += sCSS1_UNIT_pt;
3595     }
3596 
3597     // Linien-Stil: solid oder double
3598     ((sOut += ' ')
3599         += (bDouble ? sCSS1_PV_double : sCSS1_PV_solid)) += ' ';
3600 
3601     // und noch die Farbe
3602     GetCSS1Color( pLine->GetColor(), sOut );
3603 
3604     rHTMLWrt.OutCSS1_PropertyAscii( pProperty, sOut );
3605 }
3606 
OutCSS1_SvxBox(Writer & rWrt,const SfxPoolItem & rHt)3607 static Writer& OutCSS1_SvxBox( Writer& rWrt, const SfxPoolItem& rHt )
3608 {
3609     SwHTMLWriter& rHTMLWrt = (SwHTMLWriter&)rWrt;
3610 
3611     // Das Zeichen-Attribut wird nicht ausgegeben, wenn gerade
3612     // Optionen ausgegeben werden
3613     if( !rHTMLWrt.IsHTMLMode(HTMLMODE_PARA_BORDER))
3614         return rWrt;
3615 
3616     const SvxBoxItem& rBoxItem = (const SvxBoxItem&)rHt;
3617     const SvxBorderLine *pTop = rBoxItem.GetTop();
3618     const SvxBorderLine *pBottom = rBoxItem.GetBottom();
3619     const SvxBorderLine *pLeft = rBoxItem.GetLeft();
3620     const SvxBorderLine *pRight = rBoxItem.GetRight();
3621 
3622     if( (pTop && pBottom && pLeft && pRight &&
3623          *pTop == *pBottom && *pTop == *pLeft && *pTop == *pRight) ||
3624          (!pTop && !pBottom && !pLeft && !pRight) )
3625     {
3626         // alle Linien gesetzt und gleich oder alle Linien nicht gesetzt
3627         // => border : ...
3628         OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border, pTop );
3629     }
3630     else
3631     {
3632         // sonst alle Linien individuell ausgeben
3633         OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border_top, pTop );
3634         OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border_bottom, pBottom );
3635         OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border_left, pLeft );
3636         OutCSS1_SvxBorderLine( rHTMLWrt, sCSS1_P_border_right, pRight );
3637     }
3638 
3639     long nTopDist = pTop ? rBoxItem.GetDistance( BOX_LINE_TOP ) : 0;
3640     long nBottomDist = pBottom ? rBoxItem.GetDistance( BOX_LINE_BOTTOM ) : 0;
3641     long nLeftDist = pLeft ? rBoxItem.GetDistance( BOX_LINE_LEFT ) : 0;
3642     long nRightDist = pRight ? rBoxItem.GetDistance( BOX_LINE_RIGHT ) : 0;
3643 
3644     if( nTopDist == nBottomDist && nLeftDist == nRightDist )
3645     {
3646         ByteString sVal;
3647         AddUnitPropertyValue( nTopDist, rHTMLWrt.GetCSS1Unit(), sVal );
3648         if( nTopDist != nLeftDist )
3649         {
3650             sVal += ' ';
3651             AddUnitPropertyValue( nLeftDist, rHTMLWrt.GetCSS1Unit(), sVal );
3652         }
3653         rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_padding, sVal );
3654     }
3655     else
3656     {
3657         rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_padding_top, nTopDist );
3658         rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_padding_bottom, nBottomDist );
3659         rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_padding_left, nLeftDist );
3660         rHTMLWrt.OutCSS1_UnitProperty( sCSS1_P_padding_right, nRightDist );
3661     }
3662 
3663     return rWrt;
3664 }
3665 
OutCSS1_SvxFrameDirection(Writer & rWrt,const SfxPoolItem & rHt)3666 static Writer& OutCSS1_SvxFrameDirection( Writer& rWrt, const SfxPoolItem& rHt )
3667 {
3668     SwHTMLWriter& rHTMLWrt = static_cast< SwHTMLWriter& >( rWrt  );
3669 
3670     // Language will be exported rules only
3671     if( !rHTMLWrt.IsCSS1Source( CSS1_OUTMODE_TEMPLATE ) )
3672         return rWrt;
3673 
3674     sal_uInt16 nDir =
3675         static_cast< const SvxFrameDirectionItem& >( rHt ).GetValue();
3676     sal_Char *pStr = 0;
3677     switch( nDir )
3678     {
3679     case FRMDIR_HORI_LEFT_TOP:
3680     case FRMDIR_VERT_TOP_LEFT:
3681         pStr = sCSS1_PV_ltr;
3682         break;
3683     case FRMDIR_HORI_RIGHT_TOP:
3684     case FRMDIR_VERT_TOP_RIGHT:
3685         pStr = sCSS1_PV_rtl;
3686         break;
3687     case FRMDIR_ENVIRONMENT:
3688         pStr = sCSS1_PV_inherit;
3689         break;
3690     }
3691 
3692     if( pStr )
3693         rHTMLWrt.OutCSS1_PropertyAscii( sCSS1_P_direction, pStr );
3694 
3695     return rWrt;
3696 }
3697 
3698 /*
3699  * lege hier die Tabellen fuer die HTML-Funktions-Pointer auf
3700  * die Ausgabe-Funktionen an.
3701  * Es sind lokale Strukturen, die nur innerhalb der HTML-DLL
3702  * bekannt sein muessen.
3703  */
3704 
3705 
3706 SwAttrFnTab aCSS1AttrFnTab = {
3707 /* RES_CHRATR_CASEMAP   */          OutCSS1_SvxCaseMap,
3708 /* RES_CHRATR_CHARSETCOLOR  */      0,
3709 /* RES_CHRATR_COLOR */              OutCSS1_SvxColor,
3710 /* RES_CHRATR_CONTOUR   */          0,
3711 /* RES_CHRATR_CROSSEDOUT    */      OutCSS1_SvxCrossedOut,
3712 /* RES_CHRATR_ESCAPEMENT    */      0,
3713 /* RES_CHRATR_FONT  */              OutCSS1_SvxFont,
3714 /* RES_CHRATR_FONTSIZE  */          OutCSS1_SvxFontHeight,
3715 /* RES_CHRATR_KERNING   */          OutCSS1_SvxKerning,
3716 /* RES_CHRATR_LANGUAGE  */          OutCSS1_SvxLanguage,
3717 /* RES_CHRATR_POSTURE   */          OutCSS1_SvxPosture,
3718 /* RES_CHRATR_PROPORTIONALFONTSIZE*/0,
3719 /* RES_CHRATR_SHADOWED  */          0,
3720 /* RES_CHRATR_UNDERLINE */          OutCSS1_SvxUnderline,
3721 /* RES_CHRATR_WEIGHT    */          OutCSS1_SvxFontWeight,
3722 /* RES_CHRATR_WORDLINEMODE  */      0,
3723 /* RES_CHRATR_AUTOKERN  */          0,
3724 /* RES_CHRATR_BLINK */              OutCSS1_SvxBlink,
3725 /* RES_CHRATR_NOHYPHEN  */          0, // Neu: nicht trennen
3726 /* RES_CHRATR_NOLINEBREAK */        0, // Neu: nicht umbrechen
3727 /* RES_CHRATR_BACKGROUND */         OutCSS1_SvxBrush, // Neu: Zeichenhintergrund
3728 /* RES_CHRATR_CJK_FONT */           OutCSS1_SvxFont,
3729 /* RES_CHRATR_CJK_FONTSIZE */       OutCSS1_SvxFontHeight,
3730 /* RES_CHRATR_CJK_LANGUAGE */       OutCSS1_SvxLanguage,
3731 /* RES_CHRATR_CJK_POSTURE */        OutCSS1_SvxPosture,
3732 /* RES_CHRATR_CJK_WEIGHT */         OutCSS1_SvxFontWeight,
3733 /* RES_CHRATR_CTL_FONT */           OutCSS1_SvxFont,
3734 /* RES_CHRATR_CTL_FONTSIZE */       OutCSS1_SvxFontHeight,
3735 /* RES_CHRATR_CTL_LANGUAGE */       OutCSS1_SvxLanguage,
3736 /* RES_CHRATR_CTL_POSTURE */        OutCSS1_SvxPosture,
3737 /* RES_CHRATR_CTL_WEIGHT */         OutCSS1_SvxFontWeight,
3738 /* RES_CHRATR_ROTATE */             0,
3739 /* RES_CHRATR_EMPHASIS_MARK */      0,
3740 /* RES_CHRATR_TWO_LINES */          0,
3741 /* RES_CHRATR_SCALEW */             0,
3742 /* RES_CHRATR_RELIEF */             0,
3743 /* RES_CHRATR_HIDDEN */             0,
3744 /* RES_CHRATR_OVERLINE */           OutCSS1_SvxOverline,
3745 /* RES_CHRATR_DUMMY1 */             0,
3746 /* RES_CHRATR_DUMMY2 */             0,
3747 /* RES_CHRATR_BIDIRTL */            0,
3748 /* RES_CHRATR_IDCTHINT */           0,
3749 
3750 /* RES_TXTATR_REFMARK */            0,
3751 /* RES_TXTATR_TOXMARK */            0,
3752 /* RES_TXTATR_META */               0,
3753 /* RES_TXTATR_METAFIELD */          0,
3754 /* RES_TXTATR_AUTOFMT */            0,
3755 /* RES_TXTATR_INETFMT */            0,
3756 /* RES_TXTATR_CHARFMT */            0,
3757 /* RES_TXTATR_CJK_RUBY */           0,
3758 /* RES_TXTATR_UNKNOWN_CONTAINER */  0,
3759 /* RES_TXTATR_INPUTFIELD */         0,
3760 
3761 /* RES_TXTATR_FIELD */              0,
3762 /* RES_TXTATR_FLYCNT */             0,
3763 /* RES_TXTATR_FTN */                0,
3764 /* RES_TXTATR_ANNOTATION */         0,
3765 /* RES_TXTATR_DUMMY3 */             0,
3766 /* RES_TXTATR_DUMMY1 */             0, // Dummy:
3767 /* RES_TXTATR_DUMMY2 */             0, // Dummy:
3768 
3769 /* RES_PARATR_LINESPACING   */      OutCSS1_SvxLineSpacing,
3770 /* RES_PARATR_ADJUST    */          OutCSS1_SvxAdjust,
3771 /* RES_PARATR_SPLIT */              OutCSS1_SvxFmtSplit,
3772 /* RES_PARATR_WIDOWS    */          OutCSS1_SvxWidows,
3773 /* RES_PARATR_ORPHANS   */          OutCSS1_SvxOrphans,
3774 /* RES_PARATR_TABSTOP   */          0,
3775 /* RES_PARATR_HYPHENZONE*/          0,
3776 /* RES_PARATR_DROP */               OutCSS1_SwFmtDrop,
3777 /* RES_PARATR_REGISTER */           0, // neu:  Registerhaltigkeit
3778 /* RES_PARATR_NUMRULE */            0,
3779 /* RES_PARATR_SCRIPTSPACE */        0,
3780 /* RES_PARATR_HANGINGPUNCTUATION */ 0,
3781 /* RES_PARATR_FORBIDDEN_RULES */    0, // new
3782 /* RES_PARATR_VERTALIGN */          0, // new
3783 /* RES_PARATR_SNAPTOGRID*/          0, // new
3784 /* RES_PARATR_CONNECT_TO_BORDER */  0, // new
3785 /* RES_PARATR_OUTLINELEVEL */       0, // new since cws outlinelevel
3786 
3787 /* RES_PARATR_LIST_ID */            0, // new
3788 /* RES_PARATR_LIST_LEVEL */         0, // new
3789 /* RES_PARATR_LIST_ISRESTART */     0, // new
3790 /* RES_PARATR_LIST_RESTARTVALUE */  0, // new
3791 /* RES_PARATR_LIST_ISCOUNTED */     0, // new
3792 
3793 /* RES_FILL_ORDER   */              0,
3794 /* RES_FRM_SIZE */                  0,
3795 /* RES_PAPER_BIN    */              0,
3796 /* RES_LR_SPACE */                  OutCSS1_SvxLRSpace,
3797 /* RES_UL_SPACE */                  OutCSS1_SvxULSpace,
3798 /* RES_PAGEDESC */                  0,
3799 /* RES_BREAK */                     0,
3800 /* RES_CNTNT */                     0,
3801 /* RES_HEADER */                    0,
3802 /* RES_FOOTER */                    0,
3803 /* RES_PRINT */                     0,
3804 /* RES_OPAQUE */                    0,
3805 /* RES_PROTECT */                   0,
3806 /* RES_SURROUND */                  0,
3807 /* RES_VERT_ORIENT */               0,
3808 /* RES_HORI_ORIENT */               0,
3809 /* RES_ANCHOR */                    0,
3810 /* RES_BACKGROUND */                OutCSS1_SvxBrush,
3811 /* RES_BOX  */                      OutCSS1_SvxBox,
3812 /* RES_SHADOW */                    0,
3813 /* RES_FRMMACRO */                  0,
3814 /* RES_COL */                       0,
3815 /* RES_KEEP */                      0,
3816 /* RES_URL */                       0,
3817 /* RES_EDIT_IN_READONLY */          0,
3818 /* RES_LAYOUT_SPLIT */              0,
3819 /* RES_CHAIN */                     0,
3820 /* RES_TEXTGRID */                  0,
3821 /* RES_LINENUMBER */                0,
3822 /* RES_FTN_AT_TXTEND */             0,
3823 /* RES_END_AT_TXTEND */             0,
3824 /* RES_COLUMNBALANCE */             0,
3825 /* RES_FRAMEDIR */                  OutCSS1_SvxFrameDirection,
3826 /* RES_HEADER_FOOTER_EAT_SPACING */ 0,
3827 /* RES_ROW_SPLIT */                 0,
3828 /* RES_FOLLOW_TEXT_FLOW */          0,
3829 /* RES_COLLAPSING_BORDERS */        0,
3830 /* RES_WRAP_INFLUENCE_ON_OBJPOS */  0,
3831 /* RES_AUTO_STYLE */                0,
3832 /* RES_FRMATR_STYLE_NAME */         0,
3833 /* RES_FRMATR_CONDITIONAL_STYLE_NAME */  0,
3834 
3835 /* RES_GRFATR_MIRRORGRF */          0,
3836 /* RES_GRFATR_CROPGRF   */          0,
3837 /* RES_GRFATR_ROTATION */           0,
3838 /* RES_GRFATR_LUMINANCE */          0,
3839 /* RES_GRFATR_CONTRAST */           0,
3840 /* RES_GRFATR_CHANNELR */           0,
3841 /* RES_GRFATR_CHANNELG */           0,
3842 /* RES_GRFATR_CHANNELB */           0,
3843 /* RES_GRFATR_GAMMA */              0,
3844 /* RES_GRFATR_INVERT */             0,
3845 /* RES_GRFATR_TRANSPARENCY */       0,
3846 /* RES_GRFATR_DRWAMODE */           0,
3847 /* RES_GRFATR_DUMMY1 */             0,
3848 /* RES_GRFATR_DUMMY2 */             0,
3849 /* RES_GRFATR_DUMMY3 */             0,
3850 /* RES_GRFATR_DUMMY4 */             0,
3851 /* RES_GRFATR_DUMMY5 */             0,
3852 
3853 /* RES_BOXATR_FORMAT */             0,
3854 /* RES_BOXATR_FORMULA */            0,
3855 /* RES_BOXATR_VALUE */              0
3856 };
3857