xref: /AOO41X/main/sw/source/filter/html/svxcss1.cxx (revision efeef26f81c84063fb0a91bde3856d4a51172d90) !
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 
28 #include <stdlib.h>
29 
30 #ifndef _SVX_SVXIDS_HRC
31 #include <svx/svxids.hrc>
32 #endif
33 #include <i18npool/mslangid.hxx>
34 #include <svtools/ctrltool.hxx>
35 #include <svl/urihelper.hxx>
36 #include <editeng/udlnitem.hxx>
37 #include <editeng/adjitem.hxx>
38 #include <editeng/blnkitem.hxx>
39 #include <editeng/crsditem.hxx>
40 #include <editeng/kernitem.hxx>
41 #include <editeng/lspcitem.hxx>
42 #include <editeng/fontitem.hxx>
43 #include <editeng/postitem.hxx>
44 #include <editeng/colritem.hxx>
45 #include <editeng/cmapitem.hxx>
46 #include <editeng/brshitem.hxx>
47 #include <editeng/wghtitem.hxx>
48 #include <editeng/fhgtitem.hxx>
49 #include <editeng/boxitem.hxx>
50 #include <editeng/ulspitem.hxx>
51 #include <editeng/lrspitem.hxx>
52 #include <editeng/langitem.hxx>
53 #include <svl/itempool.hxx>
54 #include <editeng/spltitem.hxx>
55 #include <editeng/widwitem.hxx>
56 #include <editeng/frmdiritem.hxx>
57 #include <editeng/orphitem.hxx>
58 #include <svtools/svparser.hxx>
59 #include <vcl/svapp.hxx>
60 #include <vcl/wrkwin.hxx>
61 
62 #include "css1kywd.hxx"
63 #include "svxcss1.hxx"
64 
65 // die Funktionen zum Parsen einer CSS1-Property sind von folgendem Typ:
66 typedef void (*FnParseCSS1Prop)( const CSS1Expression *pExpr,
67                                  SfxItemSet& rItemSet,
68                                  SvxCSS1PropertyInfo& rPropInfo,
69                                  const SvxCSS1Parser& rParser );
70 
71 SV_IMPL_PTRARR( CSS1Selectors, CSS1Selector* )
72 
73 
74 /*  */
75 
76 static CSS1PropertyEnum __READONLY_DATA aFontSizeTable[] =
77 {
78     { sCSS1_PV_xx_small,    0                   },
79     { sCSS1_PV_x_small,     1                   },
80     { sCSS1_PV_small,       2                   },
81     { sCSS1_PV_medium,      3                   },
82     { sCSS1_PV_large,       4                   },
83     { sCSS1_PV_x_large,     5                   },
84     { sCSS1_PV_xx_large,    6                   },
85     { 0,                    0                   }
86 };
87 
88 static CSS1PropertyEnum __READONLY_DATA aFontFamilyTable[] =
89 {
90     { sCSS1_PV_serif,       FAMILY_ROMAN        },
91     { sCSS1_PV_sans_serif,  FAMILY_SWISS        },
92     { sCSS1_PV_cursive,     FAMILY_SCRIPT       },
93     { sCSS1_PV_fantasy,     FAMILY_DECORATIVE   },
94     { sCSS1_PV_monospace,   FAMILY_MODERN       },
95     { 0,                    0                   }
96 };
97 
98 static CSS1PropertyEnum __READONLY_DATA aFontWeightTable[] =
99 {
100     { sCSS1_PV_extra_light, WEIGHT_NORMAL       }, // WEIGHT_ULTRALIGHT (OBS)
101     { sCSS1_PV_light,       WEIGHT_NORMAL       }, // WEIGHT_LIGHT (OBSOLETE)
102     { sCSS1_PV_demi_light,  WEIGHT_NORMAL       }, // WEIGHT_SEMILIGHT (OBS)
103     { sCSS1_PV_medium,      WEIGHT_NORMAL       }, // WEIGHT_MEDIUM (OBS)
104     { sCSS1_PV_normal,      WEIGHT_NORMAL       }, // WEIGHT_MEDIUM
105     { sCSS1_PV_demi_bold,   WEIGHT_NORMAL       }, // WEIGHT_SEMIBOLD (OBS)
106     { sCSS1_PV_bold,        WEIGHT_BOLD         }, // WEIGHT_BOLD (OBSOLETE)
107     { sCSS1_PV_extra_bold,  WEIGHT_BOLD         }, // WEIGHT_ULTRABOLD (OBS)
108     { sCSS1_PV_bolder,      WEIGHT_BOLD         },
109     { sCSS1_PV_lighter,     WEIGHT_NORMAL       },
110     { 0,                    0                   }
111 };
112 
113 static CSS1PropertyEnum __READONLY_DATA aFontStyleTable[] =
114 {
115     { sCSS1_PV_normal,      ITALIC_NONE         },
116     { sCSS1_PV_italic,      ITALIC_NORMAL       },
117     { sCSS1_PV_oblique,     ITALIC_NORMAL       },
118     { 0,                    0                   }
119 };
120 
121 static CSS1PropertyEnum __READONLY_DATA aFontVariantTable[] =
122 {
123     { sCSS1_PV_normal,      SVX_CASEMAP_NOT_MAPPED      },
124     { sCSS1_PV_small_caps,  SVX_CASEMAP_KAPITAELCHEN    },
125     { 0,                    0                   }
126 };
127 
128 static CSS1PropertyEnum __READONLY_DATA aDirectionTable[] =
129 {
130     { sCSS1_PV_ltr,         FRMDIR_HORI_LEFT_TOP        },
131     { sCSS1_PV_rtl,         FRMDIR_HORI_RIGHT_TOP       },
132     { sCSS1_PV_inherit,     FRMDIR_ENVIRONMENT          },
133     { 0,                    0                   }
134 };
135 
136 /*  */
137 
138 static CSS1PropertyEnum __READONLY_DATA aBGRepeatTable[] =
139 {
140     { sCSS1_PV_repeat,      GPOS_TILED                  },
141     { sCSS1_PV_repeat_x,    GPOS_TILED                  },
142     { sCSS1_PV_repeat_y,    GPOS_TILED                  },
143     { sCSS1_PV_no_repeat,   GPOS_NONE                   },
144     { 0,                    0                           }
145 };
146 
147 static CSS1PropertyEnum __READONLY_DATA aBGHoriPosTable[] =
148 {
149     { sCSS1_PV_left,        GPOS_LT                 },
150     { sCSS1_PV_center,      GPOS_MT                 },
151     { sCSS1_PV_right,       GPOS_RT                 },
152     { 0,                    0                       }
153 };
154 
155 static CSS1PropertyEnum __READONLY_DATA aBGVertPosTable[] =
156 {
157     { sCSS1_PV_top,         GPOS_LT                 },
158     { sCSS1_PV_middle,      GPOS_LM                 },
159     { sCSS1_PV_bottom,      GPOS_LB                 },
160     { 0,                    0                       }
161 };
162 
163 /*  */
164 
165 static CSS1PropertyEnum __READONLY_DATA aTextAlignTable[] =
166 {
167     { sCSS1_PV_left,        SVX_ADJUST_LEFT     },
168     { sCSS1_PV_center,      SVX_ADJUST_CENTER   },
169     { sCSS1_PV_right,       SVX_ADJUST_RIGHT    },
170     { sCSS1_PV_justify,     SVX_ADJUST_BLOCK    },
171     { 0,                    0                   }
172 };
173 
174 /*  */
175 
176 static CSS1PropertyEnum __READONLY_DATA aBorderWidthTable[] =
177 {
178     { sCSS1_PV_thin,        0   },  // DEF_LINE_WIDTH_0 / DEF_DOUBLE_LINE0
179     { sCSS1_PV_medium,      1   },  // DEF_LINE_WIDTH_1 / DEF_DOUBLE_LINE1
180     { sCSS1_PV_thick,       2   },  // DEF_LINE_WIDTH_2 / DEF_DOUBLE_LINE2
181     { 0,                    0   }
182 };
183 
184 enum CSS1BorderStyle { CSS1_BS_NONE, CSS1_BS_SINGLE, CSS1_BS_DOUBLE };
185 
186 static CSS1PropertyEnum __READONLY_DATA aBorderStyleTable[] =
187 {
188     { sCSS1_PV_none,        CSS1_BS_NONE        },
189     { sCSS1_PV_dotted,      CSS1_BS_SINGLE      },
190     { sCSS1_PV_dashed,      CSS1_BS_SINGLE      },
191     { sCSS1_PV_solid,       CSS1_BS_SINGLE      },
192     { sCSS1_PV_double,      CSS1_BS_DOUBLE      },
193     { sCSS1_PV_groove,      CSS1_BS_SINGLE      },
194     { sCSS1_PV_ridge,       CSS1_BS_SINGLE      },
195     { sCSS1_PV_inset,       CSS1_BS_SINGLE      },
196     { sCSS1_PV_outset,      CSS1_BS_SINGLE      },
197     { 0,                    0                   }
198 };
199 
200 static CSS1PropertyEnum __READONLY_DATA aFloatTable[] =
201 {
202     { sCSS1_PV_left,    SVX_ADJUST_LEFT         },
203     { sCSS1_PV_right,   SVX_ADJUST_RIGHT        },
204     { sCSS1_PV_none,    SVX_ADJUST_END          },
205     { 0,                0                       }
206 };
207 
208 static CSS1PropertyEnum __READONLY_DATA aPositionTable[] =
209 {
210     { sCSS1_PV_absolute,    SVX_CSS1_POS_ABSOLUTE   },
211     { sCSS1_PV_relative,    SVX_CSS1_POS_RELATIVE   },
212     { sCSS1_PV_static,      SVX_CSS1_POS_STATIC     },
213     { 0,                    0                       }
214 };
215 
216 // Feature: PrintExt
217 static CSS1PropertyEnum __READONLY_DATA aSizeTable[] =
218 {
219     { sCSS1_PV_auto,        SVX_CSS1_STYPE_AUTO         },
220     { sCSS1_PV_landscape,   SVX_CSS1_STYPE_LANDSCAPE    },
221     { sCSS1_PV_portrait,    SVX_CSS1_STYPE_PORTRAIT     },
222     { 0,                    0                           }
223 };
224 
225 static CSS1PropertyEnum __READONLY_DATA aPageBreakTable[] =
226 {
227     { sCSS1_PV_auto,        SVX_CSS1_PBREAK_AUTO        },
228     { sCSS1_PV_always,      SVX_CSS1_PBREAK_ALWAYS      },
229     { sCSS1_PV_avoid,       SVX_CSS1_PBREAK_AVOID       },
230     { sCSS1_PV_left,        SVX_CSS1_PBREAK_LEFT        },
231     { sCSS1_PV_right,       SVX_CSS1_PBREAK_RIGHT       },
232     { 0,                    0                           }
233 };
234 
235 // /Feature: PrintExt
236 
237 /*  */
238 
239 // Ein Eintrag besteht aus vier USHORTs. Der erste ist die Gesamtbreite,
240 // die anderen sind die 3 Einzelbreiten
241 
242 #define SBORDER_ENTRY( n ) \
243     DEF_LINE_WIDTH_##n, DEF_LINE_WIDTH_##n, 0, 0
244 
245 #define DBORDER_ENTRY( n ) \
246     DEF_DOUBLE_LINE##n##_OUT + DEF_DOUBLE_LINE##n##_IN + \
247     DEF_DOUBLE_LINE##n##_DIST, \
248     DEF_DOUBLE_LINE##n##_OUT, \
249     DEF_DOUBLE_LINE##n##_IN, \
250     DEF_DOUBLE_LINE##n##_DIST
251 
252 #define TDBORDER_ENTRY( n ) \
253     DEF_DOUBLE_LINE##n##_OUT, \
254     DEF_DOUBLE_LINE##n##_OUT, \
255     DEF_DOUBLE_LINE##n##_IN, \
256     DEF_DOUBLE_LINE##n##_DIST
257 
258 
259 static sal_uInt16 __READONLY_DATA aSBorderWidths[] =
260 {
261     SBORDER_ENTRY( 0 ), SBORDER_ENTRY( 1 ), SBORDER_ENTRY( 2 ),
262     SBORDER_ENTRY( 3 ), SBORDER_ENTRY( 4 )
263 };
264 
265 static sal_uInt16 __READONLY_DATA aDBorderWidths[] =
266 {
267     DBORDER_ENTRY( 0 ),
268     DBORDER_ENTRY( 7 ),
269     DBORDER_ENTRY( 1 ),
270     DBORDER_ENTRY( 8 ),
271     DBORDER_ENTRY( 4 ),
272     DBORDER_ENTRY( 9 ),
273     DBORDER_ENTRY( 3 ),
274     DBORDER_ENTRY( 10 ),
275     DBORDER_ENTRY( 2 ),
276     DBORDER_ENTRY( 5 )
277 };
278 
279 static sal_uInt16 __READONLY_DATA aTDBorderWidths[] =
280 {
281     TDBORDER_ENTRY( 7 ), TDBORDER_ENTRY( 8 ), TDBORDER_ENTRY( 9 ),
282     TDBORDER_ENTRY( 10 )
283 };
284 
285 #undef SBORDER_ENTRY
286 #undef DBORDER_ENTRY
287 
288 /*  */
289 
290 struct SvxCSS1ItemIds
291 {
292     sal_uInt16 nFont;
293     sal_uInt16 nFontCJK;
294     sal_uInt16 nFontCTL;
295     sal_uInt16 nPosture;
296     sal_uInt16 nPostureCJK;
297     sal_uInt16 nPostureCTL;
298     sal_uInt16 nWeight;
299     sal_uInt16 nWeightCJK;
300     sal_uInt16 nWeightCTL;
301     sal_uInt16 nFontHeight;
302     sal_uInt16 nFontHeightCJK;
303     sal_uInt16 nFontHeightCTL;
304     sal_uInt16 nUnderline;
305     sal_uInt16 nOverline;
306     sal_uInt16 nCrossedOut;
307     sal_uInt16 nColor;
308     sal_uInt16 nKerning;
309     sal_uInt16 nCaseMap;
310     sal_uInt16 nBlink;
311 
312     sal_uInt16 nLineSpacing;
313     sal_uInt16 nAdjust;
314     sal_uInt16 nWidows;
315     sal_uInt16 nOrphans;
316     sal_uInt16 nFmtSplit;
317 
318     sal_uInt16 nLRSpace;
319     sal_uInt16 nULSpace;
320     sal_uInt16 nBox;
321     sal_uInt16 nBrush;
322 
323     sal_uInt16 nLanguage;
324     sal_uInt16 nLanguageCJK;
325     sal_uInt16 nLanguageCTL;
326     sal_uInt16 nDirection;
327 };
328 
329 
330 static SvxCSS1ItemIds aItemIds;
331 
332 
333 /*  */
334 
335 struct SvxCSS1BorderInfo
336 {
337     Color aColor;
338     sal_uInt16 nAbsWidth;
339     sal_uInt16 nNamedWidth;
340     CSS1BorderStyle eStyle;
341 
SvxCSS1BorderInfoSvxCSS1BorderInfo342     SvxCSS1BorderInfo() :
343         aColor( COL_BLACK ), nAbsWidth( USHRT_MAX ),
344         nNamedWidth( USHRT_MAX ), eStyle( CSS1_BS_NONE )
345     {}
346 
SvxCSS1BorderInfoSvxCSS1BorderInfo347     SvxCSS1BorderInfo( const SvxCSS1BorderInfo& rInfo ) :
348         aColor( rInfo.aColor ), nAbsWidth( rInfo.nAbsWidth ),
349         nNamedWidth( rInfo.nNamedWidth ), eStyle( rInfo.eStyle )
350     {}
351 
352     void SetBorderLine( sal_uInt16 nLine, SvxBoxItem &rBoxItem ) const;
353 };
354 
SetBorderLine(sal_uInt16 nLine,SvxBoxItem & rBoxItem) const355 void SvxCSS1BorderInfo::SetBorderLine( sal_uInt16 nLine, SvxBoxItem &rBoxItem ) const
356 {
357     if( CSS1_BS_NONE==eStyle || nAbsWidth==0 ||
358         (nAbsWidth==USHRT_MAX && nNamedWidth==USHRT_MAX) )
359     {
360         rBoxItem.SetLine( 0, nLine );
361         return;
362     }
363 
364     SvxBorderLine aBorderLine( &aColor );
365 
366     // Linien-Stil doppelt oder einfach?
367     sal_Bool bDouble = eStyle == CSS1_BS_DOUBLE;
368 
369     // benannte Breite umrechnenen, wenn keine absolute gegeben ist
370     if( nAbsWidth==USHRT_MAX )
371     {
372         const sal_uInt16 *aWidths = bDouble ? aDBorderWidths : aSBorderWidths;
373         sal_uInt16 nNWidth = nNamedWidth * 4;
374         aBorderLine.SetOutWidth( aWidths[nNWidth+1] );
375         aBorderLine.SetInWidth( aWidths[nNWidth+2] );
376         aBorderLine.SetDistance( aWidths[nNWidth+3] );
377     }
378     else
379     {
380         SvxCSS1Parser::SetBorderWidth( aBorderLine, nAbsWidth, bDouble );
381     }
382 
383     rBoxItem.SetLine( &aBorderLine, nLine );
384 }
385 
386 
387 /*  */
388 
SvxCSS1PropertyInfo()389 SvxCSS1PropertyInfo::SvxCSS1PropertyInfo()
390 {
391     for( sal_uInt16 i=0; i<4; i++ )
392         aBorderInfos[i] = 0;
393 
394     Clear();
395 }
396 
SvxCSS1PropertyInfo(const SvxCSS1PropertyInfo & rProp)397 SvxCSS1PropertyInfo::SvxCSS1PropertyInfo( const SvxCSS1PropertyInfo& rProp ) :
398     aId( rProp.aId ),
399     bTopMargin( rProp.bTopMargin ),
400     bBottomMargin( rProp.bBottomMargin ),
401     bLeftMargin( rProp.bLeftMargin ),
402     bRightMargin( rProp.bRightMargin ),
403     bTextIndent( rProp.bTextIndent ),
404     eFloat( rProp.eFloat ),
405     ePosition( rProp.ePosition ),
406     nTopBorderDistance( rProp.nTopBorderDistance ),
407     nBottomBorderDistance( rProp.nBottomBorderDistance ),
408     nLeftBorderDistance( rProp.nLeftBorderDistance ),
409     nRightBorderDistance( rProp.nRightBorderDistance ),
410     nLeft( rProp.nLeft ),
411     nTop( rProp.nTop ),
412     nWidth( rProp.nWidth ),
413     nHeight( rProp.nHeight ),
414     nLeftMargin( rProp.nLeftMargin ),
415     nRightMargin( rProp.nRightMargin ),
416     eLeftType( rProp.eLeftType ),
417     eTopType( rProp.eTopType ),
418     eWidthType( rProp.eWidthType ),
419     eHeightType( rProp.eHeightType ),
420 // Feature: PrintExt
421     eSizeType( rProp.eSizeType ),
422     ePageBreakBefore( rProp.ePageBreakBefore ),
423     ePageBreakAfter( rProp.ePageBreakAfter )
424 // /Feature: PrintExt
425 {
426     for( sal_uInt16 i=0; i<4; i++ )
427         aBorderInfos[i] = rProp.aBorderInfos[i]
428                             ? new SvxCSS1BorderInfo( *rProp.aBorderInfos[i] )
429                             : 0;
430 }
431 
~SvxCSS1PropertyInfo()432 SvxCSS1PropertyInfo::~SvxCSS1PropertyInfo()
433 {
434     DestroyBorderInfos();
435 }
436 
DestroyBorderInfos()437 void SvxCSS1PropertyInfo::DestroyBorderInfos()
438 {
439     for( sal_uInt16 i=0; i<4; i++ )
440     {
441         delete aBorderInfos[i];
442         aBorderInfos[i] = 0;
443     }
444 }
445 
Clear()446 void SvxCSS1PropertyInfo::Clear()
447 {
448     aId.Erase();
449     bTopMargin = bBottomMargin = sal_False;
450     bLeftMargin = bRightMargin = bTextIndent = sal_False;
451     nLeftMargin = nRightMargin = 0;
452     eFloat = SVX_ADJUST_END;
453 
454     ePosition = SVX_CSS1_POS_NONE;
455     nTopBorderDistance = nBottomBorderDistance =
456     nLeftBorderDistance = nRightBorderDistance = USHRT_MAX;
457     nLeft = nTop = nWidth = nHeight = 0;
458     eLeftType = eTopType = eWidthType = eHeightType = SVX_CSS1_LTYPE_NONE;
459 
460 // Feature: PrintExt
461     eSizeType = SVX_CSS1_STYPE_NONE;
462     ePageBreakBefore = SVX_CSS1_PBREAK_NONE;
463     ePageBreakAfter = SVX_CSS1_PBREAK_NONE;
464 
465     DestroyBorderInfos();
466 }
467 
Merge(const SvxCSS1PropertyInfo & rProp)468 void SvxCSS1PropertyInfo::Merge( const SvxCSS1PropertyInfo& rProp )
469 {
470     if( rProp.bTopMargin )
471         bTopMargin = sal_True;
472     if( rProp.bBottomMargin )
473         bBottomMargin = sal_True;
474 
475     if( rProp.bLeftMargin )
476     {
477         bLeftMargin = sal_True;
478         nLeftMargin = rProp.nLeftMargin;
479     }
480     if( rProp.bRightMargin )
481     {
482         bRightMargin = sal_True;
483         nRightMargin = rProp.nRightMargin;
484     }
485     if( rProp.bTextIndent )
486         bTextIndent = sal_True;
487 
488     for( sal_uInt16 i=0; i<4; i++ )
489     {
490         if( rProp.aBorderInfos[i] )
491         {
492             if( aBorderInfos[i] )
493                 delete aBorderInfos[i];
494 
495             aBorderInfos[i] = new SvxCSS1BorderInfo( *rProp.aBorderInfos[i] );
496         }
497     }
498 
499     if( USHRT_MAX != rProp.nTopBorderDistance )
500         nTopBorderDistance = rProp.nTopBorderDistance;
501     if( USHRT_MAX != rProp.nBottomBorderDistance )
502         nBottomBorderDistance = rProp.nBottomBorderDistance;
503     if( USHRT_MAX != rProp.nLeftBorderDistance )
504         nLeftBorderDistance = rProp.nLeftBorderDistance;
505     if( USHRT_MAX != rProp.nRightBorderDistance )
506         nRightBorderDistance = rProp.nRightBorderDistance;
507 
508     if( rProp.eFloat != SVX_ADJUST_END )
509         eFloat = rProp.eFloat;
510 
511     if( rProp.ePosition != SVX_CSS1_POS_NONE )
512         ePosition = rProp.ePosition;
513 
514 // Feature: PrintExt
515     if( rProp.eSizeType != SVX_CSS1_STYPE_NONE )
516     {
517         eSizeType = rProp.eSizeType;
518         nWidth = rProp.nWidth;
519         nHeight = rProp.nHeight;
520     }
521 
522     if( rProp.ePageBreakBefore != SVX_CSS1_PBREAK_NONE )
523         ePageBreakBefore = rProp.ePageBreakBefore;
524 
525     if( rProp.ePageBreakAfter != SVX_CSS1_PBREAK_NONE )
526         ePageBreakAfter = rProp.ePageBreakAfter;
527 
528 // /Feature: PrintExt
529 
530     if( rProp.eLeftType != SVX_CSS1_LTYPE_NONE )
531     {
532         eLeftType = rProp.eLeftType;
533         nLeft = rProp.nLeft;
534     }
535 
536     if( rProp.eTopType != SVX_CSS1_LTYPE_NONE )
537     {
538         eTopType = rProp.eTopType;
539         nTop = rProp.nTop;
540     }
541 
542     if( rProp.eWidthType != SVX_CSS1_LTYPE_NONE )
543     {
544         eWidthType = rProp.eWidthType;
545         nWidth = rProp.nWidth;
546     }
547 
548     if( rProp.eHeightType != SVX_CSS1_LTYPE_NONE )
549     {
550         eHeightType = rProp.eHeightType;
551         nHeight = rProp.nHeight;
552     }
553 }
554 
GetBorderInfo(sal_uInt16 nLine,sal_Bool bCreate)555 SvxCSS1BorderInfo *SvxCSS1PropertyInfo::GetBorderInfo( sal_uInt16 nLine, sal_Bool bCreate )
556 {
557     sal_uInt16 nPos = 0;
558     switch( nLine )
559     {
560     case BOX_LINE_TOP:      nPos = 0;   break;
561     case BOX_LINE_BOTTOM:   nPos = 1;   break;
562     case BOX_LINE_LEFT:     nPos = 2;   break;
563     case BOX_LINE_RIGHT:    nPos = 3;   break;
564     }
565 
566     if( !aBorderInfos[nPos] && bCreate )
567         aBorderInfos[nPos] = new SvxCSS1BorderInfo;
568 
569     return aBorderInfos[nPos];
570 }
571 
CopyBorderInfo(sal_uInt16 nSrcLine,sal_uInt16 nDstLine,sal_uInt16 nWhat)572 void SvxCSS1PropertyInfo::CopyBorderInfo( sal_uInt16 nSrcLine, sal_uInt16 nDstLine,
573                                           sal_uInt16 nWhat )
574 {
575     SvxCSS1BorderInfo *pSrcInfo = GetBorderInfo( nSrcLine, sal_False );
576     if( !pSrcInfo )
577         return;
578 
579     SvxCSS1BorderInfo *pDstInfo = GetBorderInfo( nDstLine );
580     if( (nWhat & SVX_CSS1_BORDERINFO_WIDTH) != 0 )
581     {
582         pDstInfo->nAbsWidth = pSrcInfo->nAbsWidth;
583         pDstInfo->nNamedWidth = pSrcInfo->nNamedWidth;
584     }
585 
586     if( (nWhat & SVX_CSS1_BORDERINFO_COLOR) != 0 )
587         pDstInfo->aColor = pSrcInfo->aColor;
588 
589     if( (nWhat & SVX_CSS1_BORDERINFO_STYLE) != 0 )
590         pDstInfo->eStyle = pSrcInfo->eStyle;
591 }
592 
CopyBorderInfo(sal_uInt16 nCount,sal_uInt16 nWhat)593 void SvxCSS1PropertyInfo::CopyBorderInfo( sal_uInt16 nCount, sal_uInt16 nWhat )
594 {
595     if( nCount==0 )
596     {
597         CopyBorderInfo( BOX_LINE_BOTTOM, BOX_LINE_TOP, nWhat );
598         CopyBorderInfo( BOX_LINE_TOP, BOX_LINE_LEFT, nWhat );
599     }
600     if( nCount<=1 )
601     {
602         CopyBorderInfo( BOX_LINE_LEFT, BOX_LINE_RIGHT, nWhat );
603     }
604 }
605 
SetBoxItem(SfxItemSet & rItemSet,sal_uInt16 nMinBorderDist,const SvxBoxItem * pDfltItem,sal_Bool bTable)606 void SvxCSS1PropertyInfo::SetBoxItem( SfxItemSet& rItemSet,
607                                       sal_uInt16 nMinBorderDist,
608                                       const SvxBoxItem *pDfltItem,
609                                       sal_Bool bTable )
610 {
611     sal_Bool bChg = nTopBorderDistance != USHRT_MAX ||
612                 nBottomBorderDistance != USHRT_MAX ||
613                 nLeftBorderDistance != USHRT_MAX ||
614                 nRightBorderDistance != USHRT_MAX;
615     sal_uInt16 i;
616 
617     for( i = 0; !bChg && i < 4; i++ )
618         bChg = aBorderInfos[i]!=0;
619 
620     if( !bChg )
621         return;
622 
623     SvxBoxItem aBoxItem( aItemIds.nBox );
624     if( pDfltItem )
625         aBoxItem = *pDfltItem;
626 
627     SvxCSS1BorderInfo *pInfo = GetBorderInfo( BOX_LINE_TOP, sal_False );
628     if( pInfo )
629         pInfo->SetBorderLine( BOX_LINE_TOP, aBoxItem );
630 
631     pInfo = GetBorderInfo( BOX_LINE_BOTTOM, sal_False );
632     if( pInfo )
633         pInfo->SetBorderLine( BOX_LINE_BOTTOM, aBoxItem );
634 
635     pInfo = GetBorderInfo( BOX_LINE_LEFT, sal_False );
636     if( pInfo )
637         pInfo->SetBorderLine( BOX_LINE_LEFT, aBoxItem );
638 
639     pInfo = GetBorderInfo( BOX_LINE_RIGHT, sal_False );
640     if( pInfo )
641         pInfo->SetBorderLine( BOX_LINE_RIGHT, aBoxItem );
642 
643     for( i=0; i<4; i++ )
644     {
645         sal_uInt16 nLine = BOX_LINE_TOP, nDist = 0;
646         switch( i )
647         {
648         case 0: nLine = BOX_LINE_TOP;
649                 nDist = nTopBorderDistance;
650                 nTopBorderDistance = USHRT_MAX;
651                 break;
652         case 1: nLine = BOX_LINE_BOTTOM;
653                 nDist = nBottomBorderDistance;
654                 nBottomBorderDistance = USHRT_MAX;
655                 break;
656         case 2: nLine = BOX_LINE_LEFT;
657                 nDist = nLeftBorderDistance;
658                 nLeftBorderDistance = USHRT_MAX;
659                 break;
660         case 3: nLine = BOX_LINE_RIGHT;
661                 nDist = nRightBorderDistance;
662                 nRightBorderDistance = USHRT_MAX;
663                 break;
664         }
665 
666         if( aBoxItem.GetLine( nLine ) )
667         {
668             if( USHRT_MAX == nDist )
669                 nDist = aBoxItem.GetDistance( nLine );
670 
671             if( nDist < nMinBorderDist )
672                 nDist = nMinBorderDist;
673         }
674         else
675         {
676             if( USHRT_MAX == nDist )
677                 nDist = aBoxItem.GetDistance( nLine );
678 
679             if( !bTable )
680                 nDist = 0U;
681             else if( nDist && nDist < nMinBorderDist )
682                 nDist = nMinBorderDist;
683         }
684 
685         aBoxItem.SetDistance( nDist, nLine );
686     }
687 
688     rItemSet.Put( aBoxItem );
689 
690     DestroyBorderInfos();
691 }
692 
693 
694 /*  */
695 
SvxCSS1MapEntry(const String & rKey,const SfxItemSet & rItemSet,const SvxCSS1PropertyInfo & rProp)696 SvxCSS1MapEntry::SvxCSS1MapEntry( const String& rKey, const SfxItemSet& rItemSet,
697                                   const SvxCSS1PropertyInfo& rProp ) :
698     aKey( rKey ),
699     aItemSet( rItemSet ),
700     aPropInfo( rProp )
701 {
702     // TODO: ToUpperAscii
703     aKey.ToUpperAscii();
704 }
705 
706 #if defined( ICC ) || defined( BLC )
operator ==(const SvxCSS1MapEntry & rE1,const SvxCSS1MapEntry & rE2)707 sal_Bool operator==( const SvxCSS1MapEntry& rE1, const SvxCSS1MapEntry& rE2 )
708 {
709     return  rE1.aKey==rE2.aKey;
710 }
711 
operator <(const SvxCSS1MapEntry & rE1,const SvxCSS1MapEntry & rE2)712 sal_Bool operator<( const SvxCSS1MapEntry& rE1, const SvxCSS1MapEntry& rE2 )
713 {
714     return  rE1.aKey<rE2.aKey;
715 }
716 #endif
717 
SV_IMPL_OP_PTRARR_SORT(SvxCSS1Map,SvxCSS1MapEntryPtr)718 SV_IMPL_OP_PTRARR_SORT( SvxCSS1Map, SvxCSS1MapEntryPtr )
719 
720 /*  */
721 
722 sal_Bool SvxCSS1Parser::StyleParsed( const CSS1Selector * /*pSelector*/,
723                                  SfxItemSet& /*rItemSet*/,
724                                  SvxCSS1PropertyInfo& /*rPropInfo*/ )
725 {
726     // wie man sieht passiert hier gar nichts
727     return sal_True;
728 }
729 
SelectorParsed(const CSS1Selector * pSelector,sal_Bool bFirst)730 sal_Bool SvxCSS1Parser::SelectorParsed( const CSS1Selector *pSelector,
731                                     sal_Bool bFirst )
732 {
733     if( bFirst )
734     {
735         DBG_ASSERT( pSheetItemSet, "Wo ist der Item-Set fuer Style-Sheets?" );
736 
737         // Dieses ist der erste Selektor einer Rule, also muessen
738         // die bisher geparsten Items auf die Styles verteilt werden
739 //      pSheetPropInfo->CreateBoxItem( *pSheetItemSet, GetDfltBorderDist() );
740         for( sal_uInt16 i=0; i<aSelectors.Count(); i++ )
741         {
742             StyleParsed( aSelectors[i], *pSheetItemSet, *pSheetPropInfo );
743         }
744         pSheetItemSet->ClearItem();
745         pSheetPropInfo->Clear();
746 
747         // und die naechste Rule vorbereiten
748         if( aSelectors.Count() )
749             aSelectors.DeleteAndDestroy( 0, aSelectors.Count() );
750     }
751 
752     aSelectors.C40_INSERT( CSS1Selector, pSelector, aSelectors.Count() );
753 
754     return sal_False; // den Selektor haben wir gespeichert. Loeschen toedlich!
755 }
756 
757 
DeclarationParsed(const String & rProperty,const CSS1Expression * pExpr)758 sal_Bool SvxCSS1Parser::DeclarationParsed( const String& rProperty,
759                                        const CSS1Expression *pExpr )
760 {
761     DBG_ASSERT( pExpr, "DeclarationParsed() ohne Expression" );
762 
763     if( !pExpr )
764         return sal_True;
765 
766     ParseProperty( rProperty, pExpr );
767 
768     return sal_True;    // die Deklaration brauchen wir nicht mehr. Loeschen!
769 }
770 
771 /*  */
772 
SvxCSS1Parser(SfxItemPool & rPool,const String & rBaseURL,sal_uInt16 nMinFixLineSp,sal_uInt16 * pWhichIds,sal_uInt16 nWhichIds)773 SvxCSS1Parser::SvxCSS1Parser( SfxItemPool& rPool, const String& rBaseURL, sal_uInt16 nMinFixLineSp,
774                               sal_uInt16 *pWhichIds, sal_uInt16 nWhichIds ) :
775     CSS1Parser(),
776     sBaseURL( rBaseURL ),
777     pSheetItemSet(0),
778     pItemSet(0),
779     pSearchEntry( 0 ),
780     nMinFixLineSpace( nMinFixLineSp ),
781     eDfltEnc( RTL_TEXTENCODING_DONTKNOW ),
782     nScriptFlags( CSS1_SCRIPT_ALL ),
783     bIgnoreFontFamily( sal_False )
784 {
785     // Item-Ids auch initialisieren
786     aItemIds.nFont = rPool.GetTrueWhich( SID_ATTR_CHAR_FONT, sal_False );
787     aItemIds.nFontCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_FONT, sal_False );
788     aItemIds.nFontCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_FONT, sal_False );
789     aItemIds.nPosture = rPool.GetTrueWhich( SID_ATTR_CHAR_POSTURE, sal_False );
790     aItemIds.nPostureCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_POSTURE, sal_False );
791     aItemIds.nPostureCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_POSTURE, sal_False );
792     aItemIds.nWeight = rPool.GetTrueWhich( SID_ATTR_CHAR_WEIGHT, sal_False );
793     aItemIds.nWeightCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_WEIGHT, sal_False );
794     aItemIds.nWeightCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_WEIGHT, sal_False );
795     aItemIds.nFontHeight = rPool.GetTrueWhich( SID_ATTR_CHAR_FONTHEIGHT, sal_False );
796     aItemIds.nFontHeightCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT, sal_False );
797     aItemIds.nFontHeightCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT, sal_False );
798     aItemIds.nUnderline = rPool.GetTrueWhich( SID_ATTR_CHAR_UNDERLINE, sal_False );
799     aItemIds.nOverline = rPool.GetTrueWhich( SID_ATTR_CHAR_OVERLINE, sal_False );
800     aItemIds.nCrossedOut = rPool.GetTrueWhich( SID_ATTR_CHAR_STRIKEOUT, sal_False );
801     aItemIds.nColor = rPool.GetTrueWhich( SID_ATTR_CHAR_COLOR, sal_False );
802     aItemIds.nKerning = rPool.GetTrueWhich( SID_ATTR_CHAR_KERNING, sal_False );
803     aItemIds.nCaseMap = rPool.GetTrueWhich( SID_ATTR_CHAR_CASEMAP, sal_False );
804     aItemIds.nBlink = rPool.GetTrueWhich( SID_ATTR_FLASH, sal_False );
805 
806     aItemIds.nLineSpacing = rPool.GetTrueWhich( SID_ATTR_PARA_LINESPACE, sal_False );
807     aItemIds.nAdjust = rPool.GetTrueWhich( SID_ATTR_PARA_ADJUST, sal_False );
808     aItemIds.nWidows = rPool.GetTrueWhich( SID_ATTR_PARA_WIDOWS, sal_False );
809     aItemIds.nOrphans = rPool.GetTrueWhich( SID_ATTR_PARA_ORPHANS, sal_False );
810     aItemIds.nFmtSplit = rPool.GetTrueWhich( SID_ATTR_PARA_SPLIT, sal_False );
811 
812     aItemIds.nLRSpace = rPool.GetTrueWhich( SID_ATTR_LRSPACE, sal_False );
813     aItemIds.nULSpace = rPool.GetTrueWhich( SID_ATTR_ULSPACE, sal_False );
814     aItemIds.nBox = rPool.GetTrueWhich( SID_ATTR_BORDER_OUTER, sal_False );
815     aItemIds.nBrush = rPool.GetTrueWhich( SID_ATTR_BRUSH, sal_False );
816 
817     aItemIds.nLanguage = rPool.GetTrueWhich( SID_ATTR_CHAR_LANGUAGE, sal_False );
818     aItemIds.nLanguageCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_LANGUAGE, sal_False );
819     aItemIds.nLanguageCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_LANGUAGE, sal_False );
820     aItemIds.nDirection = rPool.GetTrueWhich( SID_ATTR_FRAMEDIRECTION, sal_False );
821 
822     aWhichMap.Insert( (sal_uInt16)0, (sal_uInt16)0 );
823     SvParser::BuildWhichTbl( aWhichMap, (sal_uInt16 *)&aItemIds,
824                              sizeof(aItemIds) / sizeof(sal_uInt16) );
825     if( pWhichIds && nWhichIds )
826         SvParser::BuildWhichTbl( aWhichMap, pWhichIds, nWhichIds );
827 
828     pSheetItemSet = new SfxItemSet( rPool, aWhichMap.GetData() );
829     pSheetPropInfo = new SvxCSS1PropertyInfo;
830     pSearchEntry = new SvxCSS1MapEntry( rPool, aWhichMap.GetData() );
831 }
832 
~SvxCSS1Parser()833 SvxCSS1Parser::~SvxCSS1Parser()
834 {
835     delete pSheetItemSet;
836     delete pSheetPropInfo;
837     delete pSearchEntry;
838 }
839 
840 
841 /*  */
842 
ParseStyleSheet(const String & rIn)843 sal_Bool SvxCSS1Parser::ParseStyleSheet( const String& rIn )
844 {
845     pItemSet = pSheetItemSet;
846     pPropInfo = pSheetPropInfo;
847 
848     sal_Bool bSuccess = CSS1Parser::ParseStyleSheet( rIn );
849 
850     // die bisher geparsten Items auf die Styles verteilt werden
851 //  pSheetPropInfo->CreateBoxItem( *pSheetItemSet, GetDfltBorderDist() );
852     for( sal_uInt16 i=0; i<aSelectors.Count(); i++ )
853     {
854         StyleParsed( aSelectors[i], *pSheetItemSet, *pSheetPropInfo );
855     }
856 
857     // und etwas aufrauemen
858     if( aSelectors.Count() )
859         aSelectors.DeleteAndDestroy( 0, aSelectors.Count() );
860     pSheetItemSet->ClearItem();
861     pSheetPropInfo->Clear();
862 
863     pItemSet = 0;
864     pPropInfo = 0;
865 
866     return bSuccess;
867 }
868 
ParseStyleOption(const String & rIn,SfxItemSet & rItemSet,SvxCSS1PropertyInfo & rPropInfo)869 sal_Bool SvxCSS1Parser::ParseStyleOption( const String& rIn,
870                                       SfxItemSet& rItemSet,
871                                       SvxCSS1PropertyInfo& rPropInfo )
872 {
873     pItemSet = &rItemSet;
874     pPropInfo = &rPropInfo;
875 
876     sal_Bool bSuccess = CSS1Parser::ParseStyleOption( rIn );
877     rItemSet.ClearItem( aItemIds.nDirection );
878 //  pPropInfo->CreateBoxItem( *pItemSet, GetDfltBorderDist() );
879 
880     pItemSet = 0;
881     pPropInfo = 0;
882 
883     return bSuccess;
884 }
885 
886 /*  */
887 
GetEnum(const CSS1PropertyEnum * pPropTable,const String & rValue,sal_uInt16 & rEnum)888 sal_Bool SvxCSS1Parser::GetEnum( const CSS1PropertyEnum *pPropTable,
889                           const String &rValue, sal_uInt16& rEnum )
890 {
891     String aValue( rValue );
892     aValue.ToLowerAscii();
893     while( pPropTable->pName )
894     {
895         if( !rValue.EqualsIgnoreCaseAscii( pPropTable->pName ) )
896             pPropTable++;
897         else
898             break;
899     }
900 
901     if( pPropTable->pName )
902         rEnum = pPropTable->nEnum;
903 
904     return (pPropTable->pName != 0);
905 }
906 
PixelToTwip(long & rWidth,long & rHeight)907 void SvxCSS1Parser::PixelToTwip( long &rWidth, long &rHeight )
908 {
909     if( Application::GetDefaultDevice() )
910     {
911         Size aTwipSz( rWidth, rHeight );
912         aTwipSz = Application::GetDefaultDevice()->PixelToLogic( aTwipSz,
913                                                           MapMode(MAP_TWIP) );
914 
915         rWidth = aTwipSz.Width();
916         rHeight = aTwipSz.Height();
917     }
918 }
919 
SetBorderWidth(SvxBorderLine & aBorderLine,sal_uInt16 nWidth,sal_Bool bDouble,sal_Bool bTable)920 void SvxCSS1Parser::SetBorderWidth( SvxBorderLine& aBorderLine, sal_uInt16 nWidth,
921                                     sal_Bool bDouble, sal_Bool bTable )
922 {
923     const sal_uInt16 *aWidths;
924     sal_uInt16 nSize;
925     if( !bDouble )
926     {
927         aWidths = aSBorderWidths;
928         nSize = sizeof( aSBorderWidths );
929     }
930     else if( bTable )
931     {
932         aWidths = aTDBorderWidths;
933         nSize = sizeof( aTDBorderWidths );
934     }
935     else
936     {
937         aWidths = aDBorderWidths;
938         nSize = sizeof( aDBorderWidths );
939     }
940 
941     sal_uInt16 i = (nSize / sizeof(sal_uInt16)) - 4;
942     while( i>0 &&
943            nWidth <= ((aWidths[i] + aWidths[i-4]) / 2)  )
944     {
945         DBG_ASSERT( aWidths[i] > aWidths[i-4],
946                 "Linienbreiten sind nicht sortiert!" );
947         i -= 4;
948     }
949 
950     aBorderLine.SetOutWidth( aWidths[i+1] );
951     aBorderLine.SetInWidth( aWidths[i+2] );
952     aBorderLine.SetDistance( aWidths[i+3] );
953 }
954 
GetFontHeight(sal_uInt16 nSize) const955 sal_uInt32 SvxCSS1Parser::GetFontHeight( sal_uInt16 nSize ) const
956 {
957     sal_uInt16 nHeight;
958 
959     switch( nSize )
960     {
961     case 0:     nHeight =  8*20;    break;
962     case 1:     nHeight = 10*20;    break;
963     case 2:     nHeight = 11*20;    break;
964     case 3:     nHeight = 12*20;    break;
965     case 4:     nHeight = 17*20;    break;
966     case 5:     nHeight = 20*20;    break;
967     case 6:
968     default:    nHeight = 32*20;    break;
969     }
970 
971     return nHeight;
972 }
973 
GetFontList() const974 const FontList *SvxCSS1Parser::GetFontList() const
975 {
976         return 0;
977 }
978 
GetMapEntry(const String & rKey,const SvxCSS1Map & rMap) const979 SvxCSS1MapEntry *SvxCSS1Parser::GetMapEntry( const String& rKey,
980                                              const SvxCSS1Map& rMap ) const
981 {
982     pSearchEntry->SetKey( rKey );
983 
984     SvxCSS1MapEntry *pRet = 0;
985     sal_uInt16 nPos;
986     if( rMap.Seek_Entry( pSearchEntry, &nPos ) )
987         pRet = rMap[nPos];
988 
989     return pRet;
990 }
991 
InsertMapEntry(const String & rKey,const SfxItemSet & rItemSet,const SvxCSS1PropertyInfo & rProp,SvxCSS1Map & rMap)992 void SvxCSS1Parser::InsertMapEntry( const String& rKey,
993                                     const SfxItemSet& rItemSet,
994                                     const SvxCSS1PropertyInfo& rProp,
995                                     SvxCSS1Map& rMap )
996 {
997     SvxCSS1MapEntry *pEntry = GetMapEntry( rKey, rMap );
998     if( pEntry )
999     {
1000         MergeStyles( rItemSet, rProp,
1001                      pEntry->GetItemSet(), pEntry->GetPropertyInfo(), sal_True );
1002     }
1003     else
1004     {
1005         rMap.Insert( new SvxCSS1MapEntry( rKey, rItemSet, rProp ) );
1006     }
1007 }
1008 
1009 
MergeStyles(const SfxItemSet & rSrcSet,const SvxCSS1PropertyInfo & rSrcInfo,SfxItemSet & rTargetSet,SvxCSS1PropertyInfo & rTargetInfo,sal_Bool bSmart)1010 void SvxCSS1Parser::MergeStyles( const SfxItemSet& rSrcSet,
1011                                  const SvxCSS1PropertyInfo& rSrcInfo,
1012                                  SfxItemSet& rTargetSet,
1013                                  SvxCSS1PropertyInfo& rTargetInfo,
1014                                  sal_Bool bSmart )
1015 {
1016     if( !bSmart )
1017     {
1018         rTargetSet.Put( rSrcSet );
1019     }
1020     else
1021     {
1022         SvxLRSpaceItem aLRSpace( (const SvxLRSpaceItem&)rTargetSet.Get(aItemIds.nLRSpace) );
1023         SvxULSpaceItem aULSpace( (const SvxULSpaceItem&)rTargetSet.Get(aItemIds.nULSpace) );
1024         SvxBoxItem aBox( (const SvxBoxItem&)rTargetSet.Get(aItemIds.nBox) );
1025 
1026         rTargetSet.Put( rSrcSet );
1027 
1028         if( rSrcInfo.bLeftMargin || rSrcInfo.bRightMargin ||
1029             rSrcInfo.bTextIndent )
1030         {
1031             const SvxLRSpaceItem& rNewLRSpace =
1032                 (const SvxLRSpaceItem&)rSrcSet.Get( aItemIds.nLRSpace );
1033 
1034             if( rSrcInfo.bLeftMargin )
1035                 aLRSpace.SetLeft( rNewLRSpace.GetLeft() );
1036             if( rSrcInfo.bRightMargin )
1037                 aLRSpace.SetRight( rNewLRSpace.GetRight() );
1038             if( rSrcInfo.bTextIndent )
1039                 aLRSpace.SetTxtFirstLineOfst( rNewLRSpace.GetTxtFirstLineOfst() );
1040 
1041             rTargetSet.Put( aLRSpace );
1042         }
1043 
1044         if( rSrcInfo.bTopMargin || rSrcInfo.bBottomMargin )
1045         {
1046             const SvxULSpaceItem& rNewULSpace =
1047                 (const SvxULSpaceItem&)rSrcSet.Get( aItemIds.nULSpace );
1048 
1049             if( rSrcInfo.bTopMargin )
1050                 aULSpace.SetUpper( rNewULSpace.GetUpper() );
1051             if( rSrcInfo.bBottomMargin )
1052                 aULSpace.SetLower( rNewULSpace.GetLower() );
1053 
1054             rTargetSet.Put( aULSpace );
1055         }
1056     }
1057 
1058     rTargetInfo.Merge( rSrcInfo );
1059 }
1060 
SetDfltEncoding(rtl_TextEncoding eEnc)1061 void SvxCSS1Parser::SetDfltEncoding( rtl_TextEncoding eEnc )
1062 {
1063     eDfltEnc = eEnc;
1064 }
1065 
1066 /*  */
1067 
ParseCSS1_font_size(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo &,const SvxCSS1Parser & rParser)1068 static void ParseCSS1_font_size( const CSS1Expression *pExpr,
1069                                  SfxItemSet &rItemSet,
1070                                  SvxCSS1PropertyInfo& /*rPropInfo*/,
1071                                  const SvxCSS1Parser& rParser )
1072 {
1073     DBG_ASSERT( pExpr, "kein Ausdruck" );
1074 
1075     sal_uLong nHeight = 0;
1076     sal_uInt16 nPropHeight = 100;
1077 
1078     switch( pExpr->GetType() )
1079     {
1080     case CSS1_LENGTH:
1081         nHeight = pExpr->GetULength();
1082         break;
1083     case CSS1_PIXLENGTH:
1084         {
1085             long nPWidth = 0;
1086             long nPHeight = (long)pExpr->GetNumber();
1087             SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
1088             nHeight = (sal_uLong)nPHeight;
1089         }
1090         break;
1091 //#ifdef PERCENTAGE_POSSIBLE
1092     case CSS1_PERCENTAGE:
1093         // nur fuer Drop-Caps!
1094         nPropHeight = (sal_uInt16)pExpr->GetNumber();
1095         break;
1096 //#endif
1097     case CSS1_IDENT:
1098         {
1099             sal_uInt16 nSize;
1100 #ifdef PERCENTAGE_POSSIBLE
1101             const String& rValue = pExpr->GetString();
1102 #endif
1103             if( SvxCSS1Parser::GetEnum( aFontSizeTable, pExpr->GetString(),
1104                                         nSize ) )
1105             {
1106                 nHeight = rParser.GetFontHeight( nSize );
1107             }
1108 #ifdef PERCENTAGE_POSSIBLE
1109             else if( rValue.EqualsIgnoreCaseAscii( sCSS1_PV_larger ) )
1110             {
1111                 nPropHeight = 150;
1112             }
1113             else if( rValue.EqualsIgnoreCaseAscii( sCSS1_PV_smaller ) )
1114             {
1115                 nPropHeight = 67;
1116             }
1117 #endif
1118         }
1119         break;
1120 
1121     default:
1122         ;
1123     }
1124 
1125     if( nHeight || nPropHeight!=100 )
1126     {
1127         SvxFontHeightItem aFontHeight( nHeight, nPropHeight,
1128                                        aItemIds.nFontHeight );
1129         if( rParser.IsSetWesternProps() )
1130             rItemSet.Put( aFontHeight );
1131         if( rParser.IsSetCJKProps() )
1132         {
1133             aFontHeight.SetWhich( aItemIds.nFontHeightCJK );
1134             rItemSet.Put( aFontHeight );
1135         }
1136         if( rParser.IsSetCTLProps() )
1137         {
1138             aFontHeight.SetWhich( aItemIds.nFontHeightCTL );
1139             rItemSet.Put( aFontHeight );
1140         }
1141     }
1142 }
1143 
1144 /*  */
1145 
1146 
ParseCSS1_font_family(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo &,const SvxCSS1Parser & rParser)1147 static void ParseCSS1_font_family( const CSS1Expression *pExpr,
1148                                    SfxItemSet &rItemSet,
1149                                    SvxCSS1PropertyInfo& /*rPropInfo*/,
1150                                    const SvxCSS1Parser& rParser )
1151 {
1152     DBG_ASSERT( pExpr, "kein Ausdruck" );
1153 
1154     String aName, aStyleName, aDfltName;
1155     FontFamily eFamily = FAMILY_DONTKNOW;
1156     FontPitch ePitch = PITCH_DONTKNOW;
1157     rtl_TextEncoding eEnc = rParser.GetDfltEncoding();
1158     const FontList *pFList = rParser.GetFontList();
1159     sal_Bool bFirst = sal_True;
1160     sal_Bool bFound = sal_False;
1161     while( pExpr && (bFirst || ','==pExpr->GetOp() || !pExpr->GetOp()) )
1162     {
1163         CSS1Token eType = pExpr->GetType();
1164         if( CSS1_IDENT==eType || CSS1_STRING==eType )
1165         {
1166             String aIdent( pExpr->GetString() );
1167 
1168             if( CSS1_IDENT==eType )
1169             {
1170                 // Alle nachfolgenden id's sammeln und mit einem
1171                 // Space getrennt hintendranhaengen
1172                 const CSS1Expression *pNext = pExpr->GetNext();
1173                 while( pNext && !pNext->GetOp() &&
1174                        CSS1_IDENT==pNext->GetType() )
1175                 {
1176                     (aIdent += ' ') += pNext->GetString();
1177                     pExpr = pNext;
1178                     pNext = pExpr->GetNext();
1179                 }
1180             }
1181             if( aIdent.Len() )
1182             {
1183                 if( !bFound && pFList )
1184                 {
1185                     sal_Handle hFont = pFList->GetFirstFontInfo( aIdent );
1186                     if( 0 != hFont )
1187                     {
1188                         const FontInfo& rFInfo = pFList->GetFontInfo( hFont );
1189                         if( RTL_TEXTENCODING_DONTKNOW != rFInfo.GetCharSet() )
1190                         {
1191                             bFound = sal_True;
1192                             if( RTL_TEXTENCODING_SYMBOL == rFInfo.GetCharSet() )
1193                                 eEnc = RTL_TEXTENCODING_SYMBOL;
1194                         }
1195                     }
1196                 }
1197                 if( !bFirst )
1198                     aName += ';';
1199                 aName += aIdent;
1200             }
1201         }
1202 
1203         pExpr = pExpr->GetNext();
1204         bFirst = sal_False;
1205     }
1206 
1207     if( aName.Len() && !rParser.IsIgnoreFontFamily() )
1208     {
1209         SvxFontItem aFont( eFamily, aName, aStyleName, ePitch,
1210                            eEnc, aItemIds.nFont );
1211         if( rParser.IsSetWesternProps() )
1212             rItemSet.Put( aFont );
1213         if( rParser.IsSetCJKProps() )
1214         {
1215             aFont.SetWhich( aItemIds.nFontCJK );
1216             rItemSet.Put( aFont );
1217         }
1218         if( rParser.IsSetCTLProps() )
1219         {
1220             aFont.SetWhich( aItemIds.nFontCTL );
1221             rItemSet.Put( aFont );
1222         }
1223     }
1224 }
1225 
1226 /*  */
1227 
ParseCSS1_font_weight(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo &,const SvxCSS1Parser & rParser)1228 static void ParseCSS1_font_weight( const CSS1Expression *pExpr,
1229                                    SfxItemSet &rItemSet,
1230                                    SvxCSS1PropertyInfo& /*rPropInfo*/,
1231                                    const SvxCSS1Parser& rParser )
1232 {
1233     DBG_ASSERT( pExpr, "kein Ausdruck" );
1234 
1235     switch( pExpr->GetType() )
1236     {
1237     case CSS1_IDENT:
1238     case CSS1_STRING:   // MS-IE, was sonst
1239         {
1240             sal_uInt16 nWeight;
1241             if( SvxCSS1Parser::GetEnum( aFontWeightTable, pExpr->GetString(),
1242                                         nWeight ) )
1243             {
1244                 SvxWeightItem aWeight( (FontWeight)nWeight, aItemIds.nWeight );
1245                 if( rParser.IsSetWesternProps() )
1246                     rItemSet.Put( aWeight );
1247                 if( rParser.IsSetCJKProps() )
1248                 {
1249                     aWeight.SetWhich( aItemIds.nWeightCJK );
1250                     rItemSet.Put( aWeight );
1251                 }
1252                 if( rParser.IsSetCTLProps() )
1253                 {
1254                     aWeight.SetWhich( aItemIds.nWeightCTL );
1255                     rItemSet.Put( aWeight );
1256                 }
1257             }
1258         }
1259         break;
1260     case CSS1_NUMBER:
1261         {
1262             sal_uInt16 nWeight = (sal_uInt16)pExpr->GetNumber();
1263             SvxWeightItem aWeight( nWeight>400 ? WEIGHT_BOLD : WEIGHT_NORMAL,
1264                                    aItemIds.nWeight );
1265             if( rParser.IsSetWesternProps() )
1266                 rItemSet.Put( aWeight );
1267             if( rParser.IsSetCJKProps() )
1268             {
1269                 aWeight.SetWhich( aItemIds.nWeightCJK );
1270                 rItemSet.Put( aWeight );
1271             }
1272             if( rParser.IsSetCTLProps() )
1273             {
1274                 aWeight.SetWhich( aItemIds.nWeightCTL );
1275                 rItemSet.Put( aWeight );
1276             }
1277         }
1278         break;
1279 
1280     default:
1281         ;
1282     }
1283 }
1284 
1285 /*  */
1286 
ParseCSS1_font_style(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo &,const SvxCSS1Parser & rParser)1287 static void ParseCSS1_font_style( const CSS1Expression *pExpr,
1288                                   SfxItemSet &rItemSet,
1289                                   SvxCSS1PropertyInfo& /*rPropInfo*/,
1290                                   const SvxCSS1Parser& rParser )
1291 {
1292     DBG_ASSERT( pExpr, "kein Ausdruck" );
1293 
1294     sal_Bool bPosture = sal_False;
1295     sal_Bool bCaseMap = sal_False;
1296     FontItalic eItalic = ITALIC_NONE;
1297     SvxCaseMap eCaseMap = SVX_CASEMAP_NOT_MAPPED;
1298 
1299     // normal | italic || small-caps | oblique || small-caps | small-caps
1300     // (wobei nor noch normal | italic und oblique zulaessig sind
1301 
1302     // der Wert kann zwei Werte enthalten!
1303     for( sal_uInt16 i=0; pExpr && i<2; i++ )
1304     {
1305         // Auch hier hinterlaesst MS-IEs Parser seine Spuren
1306         if( (CSS1_IDENT==pExpr->GetType() || CSS1_STRING==pExpr->GetType()) &&
1307             !pExpr->GetOp() )
1308         {
1309             const String& rValue = pExpr->GetString();
1310             // erstmal pruefen, ob es ein Italic-Wert oder 'normal' ist
1311             sal_uInt16 nItalic;
1312             if( SvxCSS1Parser::GetEnum( aFontStyleTable, rValue, nItalic ) )
1313             {
1314                 eItalic = (FontItalic)nItalic;
1315                 if( !bCaseMap && ITALIC_NONE==eItalic )
1316                 {
1317                     // fuer 'normal' muessen wir auch die case-map aussch.
1318                     eCaseMap = SVX_CASEMAP_NOT_MAPPED;
1319                     bCaseMap = sal_True;
1320                 }
1321                 bPosture = sal_True;
1322             }
1323             else if( !bCaseMap &&
1324                      rValue.EqualsIgnoreCaseAscii(sCSS1_PV_small_caps) )
1325             {
1326                 eCaseMap = SVX_CASEMAP_KAPITAELCHEN;
1327                 bCaseMap = sal_True;
1328             }
1329         }
1330 
1331         // den naechsten Ausdruck holen
1332         pExpr = pExpr->GetNext();
1333     }
1334 
1335     if( bPosture )
1336     {
1337         SvxPostureItem aPosture( eItalic, aItemIds.nPosture );
1338         if( rParser.IsSetWesternProps() )
1339             rItemSet.Put( aPosture );
1340         if( rParser.IsSetCJKProps() )
1341         {
1342             aPosture.SetWhich( aItemIds.nPostureCJK );
1343             rItemSet.Put( aPosture );
1344         }
1345         if( rParser.IsSetCTLProps() )
1346         {
1347             aPosture.SetWhich( aItemIds.nPostureCTL );
1348             rItemSet.Put( aPosture );
1349         }
1350     }
1351 
1352     if( bCaseMap )
1353         rItemSet.Put( SvxCaseMapItem( eCaseMap, aItemIds.nCaseMap ) );
1354 }
1355 
1356 /*  */
1357 
ParseCSS1_font_variant(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo &,const SvxCSS1Parser &)1358 static void ParseCSS1_font_variant( const CSS1Expression *pExpr,
1359                                     SfxItemSet &rItemSet,
1360                                     SvxCSS1PropertyInfo& /*rPropInfo*/,
1361                                     const SvxCSS1Parser& /*rParser*/ )
1362 {
1363     DBG_ASSERT( pExpr, "kein Ausdruck" );
1364 
1365     // normal | small-caps
1366 
1367     switch( pExpr->GetType() )
1368     {
1369     case CSS1_IDENT:
1370         {
1371             sal_uInt16 nCaseMap;
1372             if( SvxCSS1Parser::GetEnum( aFontVariantTable, pExpr->GetString(),
1373                                         nCaseMap ) )
1374             {
1375                 rItemSet.Put( SvxCaseMapItem( (SvxCaseMap)nCaseMap,
1376                                                 aItemIds.nCaseMap ) );
1377             }
1378         }
1379     default:
1380         ;
1381     }
1382 }
1383 
1384 /*  */
1385 
ParseCSS1_color(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo &,const SvxCSS1Parser &)1386 static void ParseCSS1_color( const CSS1Expression *pExpr,
1387                              SfxItemSet &rItemSet,
1388                              SvxCSS1PropertyInfo& /*rPropInfo*/,
1389                              const SvxCSS1Parser& /*rParser*/ )
1390 {
1391     DBG_ASSERT( pExpr, "kein Ausdruck" );
1392 
1393     switch( pExpr->GetType() )
1394     {
1395     case CSS1_IDENT:
1396     case CSS1_RGB:
1397     case CSS1_HEXCOLOR:
1398     case CSS1_STRING:       // Wegen MS-IE
1399         {
1400             Color aColor;
1401             if( pExpr->GetColor( aColor ) )
1402                 rItemSet.Put( SvxColorItem( aColor, aItemIds.nColor ) );
1403         }
1404         break;
1405     default:
1406         ;
1407     }
1408 }
1409 
ParseCSS1_direction(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo &,const SvxCSS1Parser &)1410 static void ParseCSS1_direction( const CSS1Expression *pExpr,
1411                              SfxItemSet &rItemSet,
1412                              SvxCSS1PropertyInfo& /*rPropInfo*/,
1413                              const SvxCSS1Parser& /*rParser*/ )
1414 {
1415     DBG_ASSERT( pExpr, "kein Ausdruck" );
1416 
1417     sal_uInt16 nDir;
1418     switch( pExpr->GetType() )
1419     {
1420     case CSS1_IDENT:
1421     case CSS1_STRING:
1422         if( SvxCSS1Parser::GetEnum( aDirectionTable, pExpr->GetString(),
1423                                         nDir ) )
1424         {
1425             rItemSet.Put( SvxFrameDirectionItem(
1426                        static_cast < SvxFrameDirection >( nDir ),
1427                        aItemIds.nDirection ) );
1428         }
1429         break;
1430     default:
1431         ;
1432     }
1433 }
1434 
1435 /*  */
1436 
MergeHori(SvxGraphicPosition & ePos,SvxGraphicPosition eHori)1437 static void MergeHori( SvxGraphicPosition& ePos, SvxGraphicPosition eHori )
1438 {
1439     DBG_ASSERT( GPOS_LT==eHori || GPOS_MT==eHori || GPOS_RT==eHori,
1440                 "vertikale Position nicht oben" );
1441 
1442     switch( ePos )
1443     {
1444     case GPOS_LT:
1445     case GPOS_MT:
1446     case GPOS_RT:
1447         ePos = eHori;
1448         break;
1449 
1450     case GPOS_LM:
1451     case GPOS_MM:
1452     case GPOS_RM:
1453         ePos = GPOS_LT==eHori ? GPOS_LM : (GPOS_MT==eHori ? GPOS_MM : GPOS_RM);
1454         break;
1455 
1456     case GPOS_LB:
1457     case GPOS_MB:
1458     case GPOS_RB:
1459         ePos = GPOS_LT==eHori ? GPOS_LB : (GPOS_MT==eHori ? GPOS_MB : GPOS_RB);
1460         break;
1461 
1462     default:
1463         ;
1464     }
1465 }
1466 
MergeVert(SvxGraphicPosition & ePos,SvxGraphicPosition eVert)1467 static void MergeVert( SvxGraphicPosition& ePos, SvxGraphicPosition eVert )
1468 {
1469     DBG_ASSERT( GPOS_LT==eVert || GPOS_LM==eVert || GPOS_LB==eVert,
1470                 "horizontale Position nicht links" );
1471 
1472     switch( ePos )
1473     {
1474     case GPOS_LT:
1475     case GPOS_LM:
1476     case GPOS_LB:
1477         ePos = eVert;
1478         break;
1479 
1480     case GPOS_MT:
1481     case GPOS_MM:
1482     case GPOS_MB:
1483         ePos = GPOS_LT==eVert ? GPOS_MT : (GPOS_LM==eVert ? GPOS_MM : GPOS_MB);
1484         break;
1485 
1486     case GPOS_RT:
1487     case GPOS_RM:
1488     case GPOS_RB:
1489         ePos = GPOS_LT==eVert ? GPOS_RT : (GPOS_LM==eVert ? GPOS_RM : GPOS_RB);
1490         break;
1491 
1492     default:
1493         ;
1494     }
1495 }
1496 
ParseCSS1_background(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo &,const SvxCSS1Parser & rParser)1497 static void ParseCSS1_background( const CSS1Expression *pExpr,
1498                                   SfxItemSet &rItemSet,
1499                                   SvxCSS1PropertyInfo& /*rPropInfo*/,
1500                                   const SvxCSS1Parser& rParser )
1501 {
1502     DBG_ASSERT( pExpr, "kein Ausdruck" );
1503 
1504     Color aColor;
1505     String aURL;
1506 
1507     sal_Bool bColor = sal_False, bTransparent = sal_False;
1508     SvxGraphicPosition eRepeat = GPOS_TILED;
1509     SvxGraphicPosition ePos = GPOS_LT;
1510     sal_Bool bHori = sal_False, bVert = sal_False;
1511 
1512     while( pExpr && !pExpr->GetOp() )
1513     {
1514         switch( pExpr->GetType() )
1515         {
1516         case CSS1_URL:
1517             pExpr->GetURL( aURL );
1518             break;
1519 
1520         case CSS1_RGB:
1521             bColor = pExpr->GetColor( aColor );
1522             break;
1523 
1524         case CSS1_LENGTH:
1525         case CSS1_PIXLENGTH:
1526             {
1527                 // da wir keine absolute Positionierung koennen,
1528                 // unterscheiden wir nur zwischen  0 und !0. Deshalb
1529                 // koennen Pixel auch wie alle anderen Einheiten behandelt
1530                 // werden.
1531 
1532                 sal_uLong nLength = (sal_uLong)pExpr->GetNumber();
1533                 if( !bHori )
1534                 {
1535                     ePos = nLength ? GPOS_MM : GPOS_LT;
1536                     bHori = sal_True;
1537                 }
1538                 else if( !bVert )
1539                 {
1540                     MergeVert( ePos, (nLength ? GPOS_LM : GPOS_LT) );
1541                     bVert = sal_True;
1542                 }
1543             }
1544             break;
1545 
1546         case CSS1_PERCENTAGE:
1547             {
1548                 // die %-Angabe wird auf den enum abgebildet
1549 
1550                 sal_uInt16 nPerc = (sal_uInt16)pExpr->GetNumber();
1551                 if( !bHori )
1552                 {
1553                     ePos = nPerc < 25 ? GPOS_LT
1554                                       : (nPerc < 75 ? GPOS_MM
1555                                                     : GPOS_RB);
1556                 }
1557                 else if( !bVert )
1558                 {
1559                     SvxGraphicPosition eVert =
1560                         nPerc < 25 ? GPOS_LT: (nPerc < 75 ? GPOS_LM
1561                                                           : GPOS_LB);
1562                     MergeVert( ePos, eVert );
1563                 }
1564             }
1565             break;
1566 
1567         case CSS1_IDENT:
1568         case CSS1_HEXCOLOR:
1569         case CSS1_STRING:       // Wegen MS-IE
1570             {
1571                 sal_uInt16 nEnum;
1572                 const String &rValue = pExpr->GetString();
1573                 if( rValue.EqualsIgnoreCaseAscii( sCSS1_PV_transparent ) )
1574                 {
1575                     bTransparent = sal_True;
1576                 }
1577                 if( SvxCSS1Parser::GetEnum( aBGRepeatTable, rValue, nEnum ) )
1578                 {
1579                     eRepeat = (SvxGraphicPosition)nEnum;
1580                 }
1581                 else if( SvxCSS1Parser::GetEnum( aBGHoriPosTable, rValue, nEnum ) )
1582                 {
1583                     // <position>, horizontal
1584                     MergeHori( ePos, (SvxGraphicPosition)nEnum );
1585                 }
1586                 else if( SvxCSS1Parser::GetEnum( aBGVertPosTable, rValue, nEnum ) )
1587                 {
1588                     // <position>, vertikal
1589                     MergeVert( ePos, (SvxGraphicPosition)nEnum );
1590                 }
1591                 else if( !bColor )
1592                 {
1593                     // <color>
1594                     bColor = pExpr->GetColor( aColor );
1595                 }
1596                 // <scroll> kennen wir nicht
1597             }
1598             break;
1599 
1600         default:
1601             ;
1602         }
1603 
1604         pExpr = pExpr->GetNext();
1605     }
1606 
1607     // transparent schlaegt alles
1608     if( bTransparent )
1609     {
1610         bColor = sal_False;
1611         aURL.Erase();
1612     }
1613 
1614     // repeat hat prio gegenueber einer Position
1615     if( GPOS_NONE == eRepeat )
1616         eRepeat = ePos;
1617 
1618     if( bTransparent || bColor || aURL.Len() )
1619     {
1620         SvxBrushItem aBrushItem( aItemIds.nBrush );
1621 
1622         if( bTransparent )
1623             aBrushItem.SetColor( Color(COL_TRANSPARENT));
1624         else if( bColor )
1625             aBrushItem.SetColor( aColor );
1626 
1627         if( aURL.Len() )
1628         {
1629             aBrushItem.SetGraphicLink( URIHelper::SmartRel2Abs( INetURLObject( rParser.GetBaseURL()), aURL, Link(), false ) );
1630             aBrushItem.SetGraphicPos( eRepeat );
1631         }
1632 
1633         rItemSet.Put( aBrushItem );
1634     }
1635 }
1636 
ParseCSS1_background_color(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo &,const SvxCSS1Parser &)1637 static void ParseCSS1_background_color( const CSS1Expression *pExpr,
1638                                   SfxItemSet &rItemSet,
1639                                   SvxCSS1PropertyInfo& /*rPropInfo*/,
1640                                   const SvxCSS1Parser& /*rParser*/ )
1641 {
1642     DBG_ASSERT( pExpr, "kein Ausdruck" );
1643 
1644     Color aColor;
1645 
1646     sal_Bool bColor = sal_False, bTransparent = sal_False;
1647 
1648     switch( pExpr->GetType() )
1649     {
1650     case CSS1_RGB:
1651         bColor = pExpr->GetColor( aColor );
1652         break;
1653     case CSS1_IDENT:
1654     case CSS1_HEXCOLOR:
1655     case CSS1_STRING:       // Wegen MS-IE
1656         if( pExpr->GetString().EqualsIgnoreCaseAscii( sCSS1_PV_transparent ) )
1657         {
1658             bTransparent = sal_True;
1659         }
1660         else
1661         {
1662             // <color>
1663             bColor = pExpr->GetColor( aColor );
1664         }
1665         break;
1666     default:
1667         ;
1668     }
1669 
1670     if( bTransparent || bColor )
1671     {
1672         SvxBrushItem aBrushItem( aItemIds.nBrush );
1673 
1674         if( bTransparent )
1675             aBrushItem.SetColor( Color(COL_TRANSPARENT) );
1676         else if( bColor )
1677             aBrushItem.SetColor( aColor);
1678 
1679         rItemSet.Put( aBrushItem );
1680     }
1681 }
1682 
1683 /*  */
1684 
ParseCSS1_line_height(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo &,const SvxCSS1Parser & rParser)1685 static void ParseCSS1_line_height( const CSS1Expression *pExpr,
1686                                    SfxItemSet &rItemSet,
1687                                    SvxCSS1PropertyInfo& /*rPropInfo*/,
1688                                    const SvxCSS1Parser& rParser )
1689 {
1690     DBG_ASSERT( pExpr, "kein Ausdruck" );
1691 
1692     sal_uInt16 nHeight = 0;
1693     sal_uInt8 nPropHeight = 0;
1694 
1695     switch( pExpr->GetType() )
1696     {
1697     case CSS1_LENGTH:
1698         nHeight = (sal_uInt16)pExpr->GetULength();
1699         break;
1700     case CSS1_PIXLENGTH:
1701         {
1702             long nPWidth = 0;
1703             long nPHeight = (long)pExpr->GetNumber();
1704             SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
1705             nHeight = (sal_uInt16)nPHeight;
1706         }
1707         break;
1708     case CSS1_PERCENTAGE:
1709         {
1710             sal_uInt16 nPHeight = (sal_uInt16)pExpr->GetNumber();
1711             nPropHeight = nPHeight <= 200 ? (sal_uInt8)nPHeight : 200;
1712         }
1713         break;
1714     case CSS1_NUMBER:
1715         {
1716             sal_uInt16 nPHeight = (sal_uInt16)(pExpr->GetNumber() * 100);
1717             nPropHeight = nPHeight <= 200 ? (sal_uInt8)nPHeight : 200;
1718         }
1719         break;
1720     default:
1721         ;
1722     }
1723 
1724     if( nHeight )
1725     {
1726         if( nHeight < rParser.GetMinFixLineSpace() )
1727             nHeight = rParser.GetMinFixLineSpace();
1728         SvxLineSpacingItem aLSItem( nHeight, aItemIds.nLineSpacing );
1729         aLSItem.SetLineHeight( nHeight );
1730         // --> OD 2006-07-26 #138463#
1731         // interpret <line-height> attribute as minimum line height
1732         aLSItem.GetLineSpaceRule() = SVX_LINE_SPACE_MIN;
1733         // <--
1734         aLSItem.GetInterLineSpaceRule() = SVX_INTER_LINE_SPACE_OFF;
1735         rItemSet.Put( aLSItem );
1736     }
1737     else if( nPropHeight )
1738     {
1739         SvxLineSpacingItem aLSItem( nPropHeight, aItemIds.nLineSpacing );
1740         aLSItem.GetLineSpaceRule() = SVX_LINE_SPACE_AUTO;
1741         if( 100 == nPropHeight )
1742             aLSItem.GetInterLineSpaceRule() = SVX_INTER_LINE_SPACE_OFF;
1743         else
1744             aLSItem.SetPropLineSpace( nPropHeight );
1745         rItemSet.Put( aLSItem );
1746     }
1747 
1748 }
1749 
1750 /*  */
1751 
ParseCSS1_font(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser & rParser)1752 static void ParseCSS1_font( const CSS1Expression *pExpr,
1753                             SfxItemSet &rItemSet,
1754                             SvxCSS1PropertyInfo& rPropInfo,
1755                             const SvxCSS1Parser& rParser )
1756 {
1757     DBG_ASSERT( pExpr, "kein Ausdruck" );
1758 
1759     FontItalic eItalic = ITALIC_NONE;
1760     SvxCaseMap eCaseMap = SVX_CASEMAP_NOT_MAPPED;
1761     FontWeight eWeight = WEIGHT_NORMAL;
1762 
1763     // [ <font-style> || <font-variant> || <font-weight> ] ?
1764     while( pExpr && !pExpr->GetOp() &&
1765            (CSS1_IDENT==pExpr->GetType() ||
1766             CSS1_STRING==pExpr->GetType() ||
1767             CSS1_NUMBER==pExpr->GetType()) )
1768     {
1769         if( CSS1_IDENT==pExpr->GetType() ||
1770             CSS1_STRING==pExpr->GetType() )
1771         {
1772             const String& rValue = pExpr->GetString();
1773 
1774             sal_uInt16 nEnum;
1775 
1776             if( SvxCSS1Parser::GetEnum( aFontStyleTable, rValue, nEnum ) )
1777             {
1778                 eItalic = (FontItalic)nEnum;
1779             }
1780             else if( SvxCSS1Parser::GetEnum( aFontVariantTable, rValue, nEnum ) )
1781             {
1782                 eCaseMap = (SvxCaseMap)nEnum;
1783             }
1784             else if( SvxCSS1Parser::GetEnum( aFontWeightTable, rValue, nEnum ) )
1785             {
1786                 eWeight = (FontWeight)nEnum;
1787             }
1788         }
1789         else
1790         {
1791             eWeight = (sal_uInt16)pExpr->GetNumber() > 400 ? WEIGHT_BOLD
1792                                                        : WEIGHT_NORMAL;
1793         }
1794 
1795         pExpr = pExpr->GetNext();
1796     }
1797 
1798     if( !pExpr || pExpr->GetOp() )
1799         return;
1800 
1801     // Da "font" alle Werte zurecksetzt, fuer die nichts angegeben ist,
1802     // tun wir das hier.
1803     SvxPostureItem aPosture( eItalic, aItemIds.nPosture );
1804     if( rParser.IsSetWesternProps() )
1805         rItemSet.Put( aPosture );
1806     if( rParser.IsSetCJKProps() )
1807     {
1808         aPosture.SetWhich( aItemIds.nPostureCJK );
1809         rItemSet.Put( aPosture );
1810     }
1811     if( rParser.IsSetCTLProps() )
1812     {
1813         aPosture.SetWhich( aItemIds.nPostureCTL );
1814         rItemSet.Put( aPosture );
1815     }
1816 
1817     rItemSet.Put( SvxCaseMapItem( eCaseMap, aItemIds.nCaseMap ) );
1818 
1819     SvxWeightItem aWeight( eWeight, aItemIds.nWeight );
1820     if( rParser.IsSetWesternProps() )
1821         rItemSet.Put( aWeight );
1822     if( rParser.IsSetCJKProps() )
1823     {
1824         aWeight.SetWhich( aItemIds.nWeightCJK );
1825         rItemSet.Put( aWeight );
1826     }
1827     if( rParser.IsSetCTLProps() )
1828     {
1829         aWeight.SetWhich( aItemIds.nWeightCTL );
1830         rItemSet.Put( aWeight );
1831     }
1832 
1833 
1834     // font-size
1835     CSS1Expression aExpr( pExpr->GetType(), pExpr->GetString(),
1836                           pExpr->GetNumber() );
1837     ParseCSS1_font_size( &aExpr, rItemSet, rPropInfo, rParser );
1838     pExpr = pExpr->GetNext();
1839 
1840     if( !pExpr )
1841         return;
1842 
1843     // [ '/' line-height ]?
1844     if( '/' == pExpr->GetOp() )
1845     {
1846         // '/' line-height
1847         aExpr.Set( pExpr->GetType(), pExpr->GetString(), pExpr->GetNumber() );
1848         ParseCSS1_line_height( &aExpr, rItemSet, rPropInfo, rParser );
1849 
1850         pExpr = pExpr->GetNext();
1851     }
1852 
1853     if( !pExpr || pExpr->GetOp() )
1854         return;
1855 
1856     // font-family
1857     ParseCSS1_font_family( pExpr, rItemSet, rPropInfo, rParser );
1858 }
1859 
1860 /*  */
1861 
ParseCSS1_letter_spacing(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo &,const SvxCSS1Parser &)1862 static void ParseCSS1_letter_spacing( const CSS1Expression *pExpr,
1863                                       SfxItemSet &rItemSet,
1864                                       SvxCSS1PropertyInfo& /*rPropInfo*/,
1865                                       const SvxCSS1Parser& /*rParser*/ )
1866 {
1867     DBG_ASSERT( pExpr, "kein Ausdruck" );
1868 
1869     switch( pExpr->GetType() )
1870     {
1871     case CSS1_LENGTH:
1872         rItemSet.Put( SvxKerningItem( (short)pExpr->GetSLength(),
1873                                       aItemIds.nKerning ) );
1874         break;
1875 
1876     case CSS1_PIXLENGTH:
1877         {
1878             long nPWidth = (long)pExpr->GetNumber();
1879             long nPHeight = 0;
1880             SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
1881             rItemSet.Put( SvxKerningItem( (short)nPWidth, aItemIds.nKerning ) );
1882         }
1883         break;
1884 
1885     case CSS1_NUMBER:
1886         if( pExpr->GetNumber() == 0 )
1887         {
1888             // eigentlich unnoetig, aber wir sind ja tollerant
1889             rItemSet.Put( SvxKerningItem( (short)0, aItemIds.nKerning ) );
1890         }
1891         break;
1892 
1893     case CSS1_IDENT:
1894     case CSS1_STRING: // Vorschtshalber auch MS-IE
1895         if( pExpr->GetString().EqualsIgnoreCaseAscii(sCSS1_PV_normal) )
1896         {
1897             rItemSet.Put( SvxKerningItem( (short)0, aItemIds.nKerning ) );
1898         }
1899         break;
1900     default:
1901         ;
1902     }
1903 }
1904 
1905 /*  */
1906 
ParseCSS1_text_decoration(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo &,const SvxCSS1Parser &)1907 static void ParseCSS1_text_decoration( const CSS1Expression *pExpr,
1908                                        SfxItemSet &rItemSet,
1909                                        SvxCSS1PropertyInfo& /*rPropInfo*/,
1910                                        const SvxCSS1Parser& /*rParser*/ )
1911 {
1912     DBG_ASSERT( pExpr, "kein Ausdruck" );
1913 
1914     sal_Bool bUnderline = sal_False;
1915     sal_Bool bOverline = sal_False;
1916     sal_Bool bCrossedOut = sal_False;
1917     sal_Bool bBlink = sal_False;
1918     sal_Bool bBlinkOn = sal_False;
1919     FontUnderline eUnderline  = UNDERLINE_NONE;
1920     FontUnderline eOverline   = UNDERLINE_NONE;
1921     FontStrikeout eCrossedOut = STRIKEOUT_NONE;
1922 
1923     // der Wert kann zwei Werte enthalten! Und MS-IE auch Strings
1924     while( pExpr && (pExpr->GetType() == CSS1_IDENT ||
1925                      pExpr->GetType() == CSS1_STRING) && !pExpr->GetOp() )
1926     {
1927         String aValue = pExpr->GetString();
1928         aValue.ToLowerAscii();
1929         sal_Bool bKnown = sal_False;
1930 
1931         switch( aValue.GetChar( 0 ) )
1932         {
1933         case 'n':
1934             if( aValue.EqualsAscii( sCSS1_PV_none ) )
1935             {
1936                 bUnderline = sal_True;
1937                 eUnderline = UNDERLINE_NONE;
1938 
1939                 bOverline = sal_True;
1940                 eOverline = UNDERLINE_NONE;
1941 
1942                 bCrossedOut = sal_True;
1943                 eCrossedOut = STRIKEOUT_NONE;
1944 
1945                 bBlink = sal_True;
1946                 bBlinkOn = sal_False;
1947 
1948                 bKnown = sal_True;
1949             }
1950             break;
1951 
1952         case 'u':
1953             if( aValue.EqualsAscii( sCSS1_PV_underline ) )
1954             {
1955                 bUnderline = sal_True;
1956                 eUnderline = UNDERLINE_SINGLE;
1957 
1958                 bKnown = sal_True;
1959             }
1960             break;
1961 
1962         case 'o':
1963             if( aValue.EqualsAscii( sCSS1_PV_overline ) )
1964             {
1965                 bOverline = sal_True;
1966                 eOverline = UNDERLINE_SINGLE;
1967 
1968                 bKnown = sal_True;
1969             }
1970             break;
1971 
1972         case 'l':
1973             if( aValue.EqualsAscii( sCSS1_PV_line_through ) )
1974             {
1975                 bCrossedOut = sal_True;
1976                 eCrossedOut = STRIKEOUT_SINGLE;
1977 
1978                 bKnown = sal_True;
1979             }
1980             break;
1981 
1982         case 'b':
1983             if( aValue.EqualsAscii( sCSS1_PV_blink ) )
1984             {
1985                 bBlink = sal_True;
1986                 bBlinkOn = sal_True;
1987 
1988                 bKnown = sal_True;
1989             }
1990             break;
1991         }
1992 
1993         if( !bKnown )
1994         {
1995             bUnderline = sal_True;
1996             eUnderline = UNDERLINE_SINGLE;
1997         }
1998 
1999         pExpr = pExpr->GetNext();
2000     }
2001 
2002     if( bUnderline )
2003         rItemSet.Put( SvxUnderlineItem( eUnderline, aItemIds.nUnderline ) );
2004 
2005     if( bOverline )
2006         rItemSet.Put( SvxOverlineItem( eOverline, aItemIds.nOverline ) );
2007 
2008     if( bCrossedOut )
2009         rItemSet.Put( SvxCrossedOutItem( eCrossedOut, aItemIds.nCrossedOut ) );
2010 
2011     if( bBlink )
2012         rItemSet.Put( SvxBlinkItem( bBlinkOn, aItemIds.nBlink ) );
2013 }
2014 
2015 /*  */
2016 
ParseCSS1_text_align(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo &,const SvxCSS1Parser &)2017 static void ParseCSS1_text_align( const CSS1Expression *pExpr,
2018                                   SfxItemSet &rItemSet,
2019                                   SvxCSS1PropertyInfo& /*rPropInfo*/,
2020                                   const SvxCSS1Parser& /*rParser*/ )
2021 {
2022     DBG_ASSERT( pExpr, "kein Ausdruck" );
2023 
2024     if( CSS1_IDENT==pExpr->GetType() ||
2025         CSS1_STRING==pExpr->GetType() ) // MS-IE, mal wieder
2026     {
2027         sal_uInt16 nAdjust;
2028         if( SvxCSS1Parser::GetEnum( aTextAlignTable, pExpr->GetString(),
2029                                     nAdjust ) )
2030         {
2031             rItemSet.Put( SvxAdjustItem( (SvxAdjust)nAdjust,
2032                                          aItemIds.nAdjust ) );
2033         }
2034     }
2035 }
2036 
2037 /*  */
2038 
ParseCSS1_text_indent(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser &)2039 static void ParseCSS1_text_indent( const CSS1Expression *pExpr,
2040                                    SfxItemSet &rItemSet,
2041                                    SvxCSS1PropertyInfo& rPropInfo,
2042                                    const SvxCSS1Parser& /*rParser*/ )
2043 {
2044     DBG_ASSERT( pExpr, "kein Ausdruck" );
2045 
2046     short nIndent = 0;
2047     sal_Bool bSet = sal_False;
2048     switch( pExpr->GetType() )
2049     {
2050     case CSS1_LENGTH:
2051         nIndent = (short)pExpr->GetSLength();
2052         bSet = sal_True;
2053         break;
2054     case CSS1_PIXLENGTH:
2055         {
2056             long nPWidth = (long)pExpr->GetNumber();
2057             long nPHeight = 0;
2058             SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2059             nIndent = (short)nPWidth;
2060             bSet = sal_True;
2061         }
2062         break;
2063     case CSS1_PERCENTAGE:
2064         // koennen wir nicht
2065         break;
2066     default:
2067         ;
2068     }
2069 
2070     if( bSet )
2071     {
2072         const SfxPoolItem* pItem;
2073         if( SFX_ITEM_SET == rItemSet.GetItemState( aItemIds.nLRSpace, sal_False,
2074                                                    &pItem ) )
2075         {
2076             SvxLRSpaceItem aLRItem( *((const SvxLRSpaceItem*)pItem) );
2077             aLRItem.SetTxtFirstLineOfst( nIndent );
2078             rItemSet.Put( aLRItem );
2079         }
2080         else
2081         {
2082             SvxLRSpaceItem aLRItem( aItemIds.nLRSpace );
2083             aLRItem.SetTxtFirstLineOfst( nIndent );
2084             rItemSet.Put( aLRItem );
2085         }
2086         rPropInfo.bTextIndent = sal_True;
2087     }
2088 }
2089 
2090 /*  */
2091 
ParseCSS1_margin_left(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser &)2092 static void ParseCSS1_margin_left( const CSS1Expression *pExpr,
2093                                    SfxItemSet &rItemSet,
2094                                    SvxCSS1PropertyInfo& rPropInfo,
2095                                    const SvxCSS1Parser& /*rParser*/ )
2096 {
2097     DBG_ASSERT( pExpr, "kein Ausdruck" );
2098 
2099     long nLeft = 0;
2100     sal_Bool bSet = sal_False;
2101     switch( pExpr->GetType() )
2102     {
2103     case CSS1_LENGTH:
2104         {
2105             nLeft = pExpr->GetSLength();
2106             bSet = sal_True;
2107         }
2108         break;
2109     case CSS1_PIXLENGTH:
2110         {
2111             nLeft = (long)pExpr->GetNumber();
2112             long nPHeight = 0;
2113             SvxCSS1Parser::PixelToTwip( nLeft, nPHeight );
2114             bSet = sal_True;
2115         }
2116         break;
2117     case CSS1_PERCENTAGE:
2118         // koennen wir nicht
2119         break;
2120     default:
2121         ;
2122     }
2123 
2124     if( bSet )
2125     {
2126         rPropInfo.nLeftMargin = nLeft;
2127         if( nLeft < 0 )
2128             nLeft = 0;
2129         const SfxPoolItem* pItem;
2130         if( SFX_ITEM_SET == rItemSet.GetItemState( aItemIds.nLRSpace, sal_False,
2131                                                    &pItem ) )
2132         {
2133             SvxLRSpaceItem aLRItem( *((const SvxLRSpaceItem*)pItem) );
2134             aLRItem.SetTxtLeft( (sal_uInt16)nLeft );
2135             rItemSet.Put( aLRItem );
2136         }
2137         else
2138         {
2139             SvxLRSpaceItem aLRItem( aItemIds.nLRSpace );
2140             aLRItem.SetTxtLeft( (sal_uInt16)nLeft );
2141             rItemSet.Put( aLRItem );
2142         }
2143         rPropInfo.bLeftMargin = sal_True;
2144     }
2145 }
2146 
2147 /*  */
2148 
ParseCSS1_margin_right(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser &)2149 static void ParseCSS1_margin_right( const CSS1Expression *pExpr,
2150                                     SfxItemSet &rItemSet,
2151                                     SvxCSS1PropertyInfo& rPropInfo,
2152                                     const SvxCSS1Parser& /*rParser*/ )
2153 {
2154     DBG_ASSERT( pExpr, "kein Ausdruck" );
2155 
2156     long nRight = 0;
2157     sal_Bool bSet = sal_False;
2158     switch( pExpr->GetType() )
2159     {
2160     case CSS1_LENGTH:
2161         {
2162             nRight = pExpr->GetSLength();
2163             bSet = sal_True;
2164         }
2165         break;
2166     case CSS1_PIXLENGTH:
2167         {
2168             nRight = (long)pExpr->GetNumber();
2169             long nPHeight = 0;
2170             SvxCSS1Parser::PixelToTwip( nRight, nPHeight );
2171             bSet = sal_True;
2172         }
2173         break;
2174     case CSS1_PERCENTAGE:
2175         // koennen wir nicht
2176         break;
2177     default:
2178         ;
2179     }
2180 
2181     if( bSet )
2182     {
2183         rPropInfo.nRightMargin = nRight;
2184         if( nRight < 0 )
2185             nRight = 0;
2186         const SfxPoolItem* pItem;
2187         if( SFX_ITEM_SET == rItemSet.GetItemState( aItemIds.nLRSpace, sal_False,
2188                                                    &pItem ) )
2189         {
2190             SvxLRSpaceItem aLRItem( *((const SvxLRSpaceItem*)pItem) );
2191             aLRItem.SetRight( (sal_uInt16)nRight );
2192             rItemSet.Put( aLRItem );
2193         }
2194         else
2195         {
2196             SvxLRSpaceItem aLRItem( aItemIds.nLRSpace );
2197             aLRItem.SetRight( (sal_uInt16)nRight );
2198             rItemSet.Put( aLRItem );
2199         }
2200         rPropInfo.bRightMargin = sal_True;
2201     }
2202 }
2203 
2204 /*  */
2205 
ParseCSS1_margin_top(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser &)2206 static void ParseCSS1_margin_top( const CSS1Expression *pExpr,
2207                                   SfxItemSet &rItemSet,
2208                                   SvxCSS1PropertyInfo& rPropInfo,
2209                                   const SvxCSS1Parser& /*rParser*/ )
2210 {
2211     DBG_ASSERT( pExpr, "kein Ausdruck" );
2212 
2213     sal_uInt16 nUpper = 0;
2214     sal_Bool bSet = sal_False;
2215     switch( pExpr->GetType() )
2216     {
2217     case CSS1_LENGTH:
2218         {
2219             long nTmp = pExpr->GetSLength();
2220             if( nTmp < 0 )
2221                 nTmp = 0;
2222             nUpper = (sal_uInt16)nTmp;
2223             bSet = sal_True;
2224         }
2225         break;
2226     case CSS1_PIXLENGTH:
2227         {
2228             long nPWidth = 0;
2229             long nPHeight =  (long)pExpr->GetNumber();
2230             if( nPHeight < 0 )
2231                 nPHeight = 0;
2232             SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2233             nUpper = (sal_uInt16)nPHeight;
2234             bSet = sal_True;
2235         }
2236         break;
2237     case CSS1_PERCENTAGE:
2238         // koennen wir nicht
2239         break;
2240     default:
2241         ;
2242     }
2243 
2244     if( bSet )
2245     {
2246         const SfxPoolItem* pItem;
2247         if( SFX_ITEM_SET == rItemSet.GetItemState( aItemIds.nULSpace, sal_False,
2248                                                    &pItem ) )
2249         {
2250             SvxULSpaceItem aULItem( *((const SvxULSpaceItem*)pItem) );
2251             aULItem.SetUpper( nUpper );
2252             rItemSet.Put( aULItem );
2253         }
2254         else
2255         {
2256             SvxULSpaceItem aULItem( aItemIds.nULSpace );
2257             aULItem.SetUpper( nUpper );
2258             rItemSet.Put( aULItem );
2259         }
2260         rPropInfo.bTopMargin = sal_True;
2261     }
2262 }
2263 
2264 /*  */
2265 
ParseCSS1_margin_bottom(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser &)2266 static void ParseCSS1_margin_bottom( const CSS1Expression *pExpr,
2267                                      SfxItemSet &rItemSet,
2268                                      SvxCSS1PropertyInfo& rPropInfo,
2269                                      const SvxCSS1Parser& /*rParser*/ )
2270 {
2271     DBG_ASSERT( pExpr, "kein Ausdruck" );
2272 
2273     sal_uInt16 nLower = 0;
2274     sal_Bool bSet = sal_False;
2275     switch( pExpr->GetType() )
2276     {
2277     case CSS1_LENGTH:
2278         {
2279             long nTmp = pExpr->GetSLength();
2280             if( nTmp < 0 )
2281                 nTmp = 0;
2282             nLower = (sal_uInt16)nTmp;
2283             bSet = sal_True;
2284         }
2285         break;
2286     case CSS1_PIXLENGTH:
2287         {
2288             long nPWidth = 0;
2289             long nPHeight =  (long)pExpr->GetNumber();
2290             if( nPHeight < 0 )
2291                 nPHeight = 0;
2292             SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2293             nLower = (sal_uInt16)nPHeight;
2294             bSet = sal_True;
2295         }
2296         break;
2297     case CSS1_PERCENTAGE:
2298         // koennen wir nicht
2299         break;
2300     default:
2301         ;
2302     }
2303 
2304     if( bSet )
2305     {
2306         const SfxPoolItem* pItem;
2307         if( SFX_ITEM_SET == rItemSet.GetItemState( aItemIds.nULSpace, sal_False,
2308                                                    &pItem ) )
2309         {
2310             SvxULSpaceItem aULItem( *((const SvxULSpaceItem*)pItem) );
2311             aULItem.SetLower( nLower );
2312             rItemSet.Put( aULItem );
2313         }
2314         else
2315         {
2316             SvxULSpaceItem aULItem( aItemIds.nULSpace );
2317             aULItem.SetLower( nLower );
2318             rItemSet.Put( aULItem );
2319         }
2320         rPropInfo.bBottomMargin = sal_True;
2321     }
2322 }
2323 
2324 /*  */
2325 
ParseCSS1_margin(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser &)2326 static void ParseCSS1_margin( const CSS1Expression *pExpr,
2327                               SfxItemSet &rItemSet,
2328                               SvxCSS1PropertyInfo& rPropInfo,
2329                               const SvxCSS1Parser& /*rParser*/ )
2330 {
2331     DBG_ASSERT( pExpr, "kein Ausdruck" );
2332 
2333     long nMargins[4] = { 0, 0, 0, 0 };
2334     sal_Bool bSetMargins[4] = { sal_False, sal_False, sal_False, sal_False };
2335 
2336     for( sal_uInt16 i=0; pExpr && i<4 && !pExpr->GetOp(); i++ )
2337     {
2338         sal_Bool bSetThis = sal_False;
2339         long nMargin = 0;
2340 
2341         switch( pExpr->GetType() )
2342         {
2343         case CSS1_LENGTH:
2344             {
2345                 nMargin = pExpr->GetSLength();
2346                 bSetThis = sal_True;
2347             }
2348             break;
2349         case CSS1_PIXLENGTH:
2350             {
2351                 long nPWidth = 0;
2352                 nMargin =  (long)pExpr->GetNumber();
2353                 SvxCSS1Parser::PixelToTwip( nPWidth, nMargin );
2354                 bSetThis = sal_True;
2355             }
2356             break;
2357         case CSS1_PERCENTAGE:
2358             // koennen wir nicht
2359             break;
2360         default:
2361             ;
2362         }
2363 
2364         if( bSetThis )
2365         {
2366             // 0 = top
2367             // 1 = right
2368             // 2 = bottom
2369             // 3 = left
2370             switch( i )
2371             {
2372             case 0:
2373                 nMargins[0] = nMargins[1] =nMargins[2] = nMargins[3] = nMargin;
2374                 bSetMargins[0] = bSetMargins[1] =
2375                 bSetMargins[2] = bSetMargins[3] = sal_True;
2376                 break;
2377             case 1:
2378                 nMargins[1] = nMargins[3] = nMargin;    // right + left
2379                 bSetMargins[1] = bSetMargins[3] = sal_True;
2380                 break;
2381             case 2:
2382                 nMargins[2] = nMargin;  // bottom
2383                 bSetMargins[2] = sal_True;
2384                 break;
2385             case 3:
2386                 nMargins[3] = nMargin;  // left
2387                 bSetMargins[3] = sal_True;
2388                 break;
2389             }
2390         }
2391         pExpr = pExpr->GetNext();
2392     }
2393 
2394     if( bSetMargins[3] || bSetMargins[1] )
2395     {
2396         if( bSetMargins[3] )
2397         {
2398             rPropInfo.bLeftMargin = sal_True;
2399             rPropInfo.nLeftMargin = nMargins[3];
2400             if( nMargins[3] < 0 )
2401                 nMargins[3] = 0;
2402         }
2403         if( bSetMargins[1] )
2404         {
2405             rPropInfo.bRightMargin = sal_True;
2406             rPropInfo.nRightMargin = nMargins[1];
2407             if( nMargins[1] < 0 )
2408                 nMargins[1] = 0;
2409         }
2410 
2411         const SfxPoolItem* pItem;
2412         if( SFX_ITEM_SET == rItemSet.GetItemState( aItemIds.nLRSpace, sal_False,
2413                                                    &pItem ) )
2414         {
2415             SvxLRSpaceItem aLRItem( *((const SvxLRSpaceItem*)pItem) );
2416             if( bSetMargins[3] )
2417                 aLRItem.SetLeft( (sal_uInt16)nMargins[3] );
2418             if( bSetMargins[1] )
2419                 aLRItem.SetRight( (sal_uInt16)nMargins[1] );
2420             rItemSet.Put( aLRItem );
2421         }
2422         else
2423         {
2424             SvxLRSpaceItem aLRItem( aItemIds.nLRSpace );
2425             if( bSetMargins[3] )
2426                 aLRItem.SetLeft( (sal_uInt16)nMargins[3] );
2427             if( bSetMargins[1] )
2428                 aLRItem.SetRight( (sal_uInt16)nMargins[1] );
2429             rItemSet.Put( aLRItem );
2430         }
2431     }
2432 
2433     if( bSetMargins[0] || bSetMargins[2] )
2434     {
2435         if( nMargins[0] < 0 )
2436             nMargins[0] = 0;
2437         if( nMargins[2] < 0 )
2438             nMargins[2] = 0;
2439 
2440         const SfxPoolItem* pItem;
2441         if( SFX_ITEM_SET == rItemSet.GetItemState( aItemIds.nULSpace, sal_False,
2442                                                    &pItem ) )
2443         {
2444             SvxULSpaceItem aULItem( *((const SvxULSpaceItem*)pItem) );
2445             if( bSetMargins[0] )
2446                 aULItem.SetUpper( (sal_uInt16)nMargins[0] );
2447             if( bSetMargins[2] )
2448                 aULItem.SetLower( (sal_uInt16)nMargins[2] );
2449             rItemSet.Put( aULItem );
2450         }
2451         else
2452         {
2453             SvxULSpaceItem aULItem( aItemIds.nULSpace );
2454             if( bSetMargins[0] )
2455                 aULItem.SetUpper( (sal_uInt16)nMargins[0] );
2456             if( bSetMargins[2] )
2457                 aULItem.SetLower( (sal_uInt16)nMargins[2] );
2458             rItemSet.Put( aULItem );
2459         }
2460 
2461         rPropInfo.bTopMargin |= bSetMargins[0];
2462         rPropInfo.bBottomMargin |= bSetMargins[2];
2463     }
2464 }
2465 
2466 /*  */
2467 
ParseCSS1_padding_xxx(const CSS1Expression * pExpr,SfxItemSet &,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser &,sal_uInt16 nWhichLine)2468 static sal_Bool ParseCSS1_padding_xxx( const CSS1Expression *pExpr,
2469                                    SfxItemSet & /*rItemSet*/,
2470                                    SvxCSS1PropertyInfo& rPropInfo,
2471                                    const SvxCSS1Parser& /*rParser*/,
2472                                    sal_uInt16 nWhichLine )
2473 {
2474     DBG_ASSERT( pExpr, "kein Ausdruck" );
2475 
2476     sal_Bool bSet = sal_False;
2477     sal_uInt16 nDist = 0;
2478 
2479     switch( pExpr->GetType() )
2480     {
2481     case CSS1_LENGTH:
2482         {
2483             long nTmp = pExpr->GetSLength();
2484             if( nTmp < 0 )
2485                 nTmp = 0;
2486             else if( nTmp > USHRT_MAX-1 )
2487                 nTmp = USHRT_MAX-1;
2488             nDist = (sal_uInt16)nTmp;
2489             bSet = sal_True;
2490         }
2491         break;
2492     case CSS1_PIXLENGTH:
2493         {
2494             long nPWidth = (long)pExpr->GetNumber();
2495             long nPHeight = 0;
2496             if( nPWidth < 0 )
2497                 nPWidth = 0;
2498             SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2499             if( nPWidth > USHRT_MAX-1 )
2500                 nPWidth = USHRT_MAX-1;
2501             nDist = (sal_uInt16)nPWidth;
2502             bSet = sal_True;
2503         }
2504         break;
2505     case CSS1_PERCENTAGE:
2506         // koennen wir nicht
2507         break;
2508     default:
2509         ;
2510     }
2511 
2512     if( bSet )
2513     {
2514         switch( nWhichLine )
2515         {
2516         case BOX_LINE_TOP:      rPropInfo.nTopBorderDistance = nDist;   break;
2517         case BOX_LINE_BOTTOM:   rPropInfo.nBottomBorderDistance = nDist;break;
2518         case BOX_LINE_LEFT:     rPropInfo.nLeftBorderDistance = nDist;  break;
2519         case BOX_LINE_RIGHT:    rPropInfo.nRightBorderDistance = nDist; break;
2520         }
2521     }
2522 
2523     return bSet;
2524 }
2525 
2526 /*  */
2527 
ParseCSS1_padding_top(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser & rParser)2528 static void ParseCSS1_padding_top( const CSS1Expression *pExpr,
2529                                    SfxItemSet &rItemSet,
2530                                    SvxCSS1PropertyInfo& rPropInfo,
2531                                    const SvxCSS1Parser& rParser )
2532 {
2533     ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_TOP );
2534 }
2535 
ParseCSS1_padding_bottom(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser & rParser)2536 static void ParseCSS1_padding_bottom( const CSS1Expression *pExpr,
2537                                       SfxItemSet &rItemSet,
2538                                       SvxCSS1PropertyInfo& rPropInfo,
2539                                       const SvxCSS1Parser& rParser )
2540 {
2541     ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser,
2542                            BOX_LINE_BOTTOM );
2543 }
2544 
ParseCSS1_padding_left(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser & rParser)2545 static void ParseCSS1_padding_left( const CSS1Expression *pExpr,
2546                                     SfxItemSet &rItemSet,
2547                                     SvxCSS1PropertyInfo& rPropInfo,
2548                                     const SvxCSS1Parser& rParser )
2549 {
2550     ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_LEFT );
2551 }
2552 
ParseCSS1_padding_right(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser & rParser)2553 static void ParseCSS1_padding_right( const CSS1Expression *pExpr,
2554                                      SfxItemSet &rItemSet,
2555                                      SvxCSS1PropertyInfo& rPropInfo,
2556                                      const SvxCSS1Parser& rParser )
2557 {
2558     ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser,
2559                            BOX_LINE_RIGHT );
2560 }
2561 
ParseCSS1_padding(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser & rParser)2562 static void ParseCSS1_padding( const CSS1Expression *pExpr,
2563                                SfxItemSet &rItemSet,
2564                                SvxCSS1PropertyInfo& rPropInfo,
2565                                const SvxCSS1Parser& rParser )
2566 {
2567     sal_uInt16 n=0;
2568     while( n<4 && pExpr && !pExpr->GetOp() )
2569     {
2570         sal_uInt16 nLine = n==0 || n==2 ? BOX_LINE_BOTTOM : BOX_LINE_LEFT;
2571         if( ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser,
2572                                    nLine ) )
2573         {
2574             if( n==0 )
2575             {
2576                 rPropInfo.nTopBorderDistance = rPropInfo.nBottomBorderDistance;
2577                 rPropInfo.nLeftBorderDistance = rPropInfo.nTopBorderDistance;
2578             }
2579             if( n <= 1 )
2580                 rPropInfo.nRightBorderDistance = rPropInfo.nLeftBorderDistance;
2581         }
2582 
2583         pExpr = pExpr->GetNext();
2584         n++;
2585     }
2586 }
2587 
2588 /*  */
2589 
ParseCSS1_border_xxx(const CSS1Expression * pExpr,SfxItemSet &,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser &,sal_uInt16 nWhichLine,sal_Bool bAll)2590 static void ParseCSS1_border_xxx( const CSS1Expression *pExpr,
2591                                   SfxItemSet & /*rItemSet*/,
2592                                   SvxCSS1PropertyInfo& rPropInfo,
2593                                   const SvxCSS1Parser& /*rParser*/,
2594                                   sal_uInt16 nWhichLine, sal_Bool bAll )
2595 {
2596     DBG_ASSERT( pExpr, "kein Ausdruck" );
2597 
2598     sal_uInt16 nWidth = USHRT_MAX;      // die Linien-Dicke
2599     sal_uInt16 nNWidth = 1;             // benannte Linien-Dicke (und default)
2600     CSS1BorderStyle eStyle = CSS1_BS_NONE; // Linien-Style
2601     Color aColor;
2602     sal_Bool bColor = sal_False;
2603 
2604     while( pExpr && !pExpr->GetOp() )
2605     {
2606         switch( pExpr->GetType() )
2607         {
2608         case CSS1_RGB:
2609         case CSS1_HEXCOLOR:
2610             if( pExpr->GetColor( aColor ) )
2611                 bColor = sal_True;
2612             break;
2613 
2614         case CSS1_IDENT:
2615             {
2616                 const String& rValue = pExpr->GetString();
2617                 sal_uInt16 nValue;
2618                 if( SvxCSS1Parser::GetEnum( aBorderWidthTable, rValue, nValue ) )
2619                 {
2620                     nNWidth = nValue;
2621                 }
2622                 else if( SvxCSS1Parser::GetEnum( aBorderStyleTable, rValue, nValue ) )
2623                 {
2624                     eStyle = (CSS1BorderStyle)nValue;
2625                 }
2626                 else if( pExpr->GetColor( aColor ) )
2627                 {
2628                     bColor = sal_True;
2629                 }
2630             }
2631             break;
2632 
2633         case CSS1_LENGTH:
2634             nWidth = (sal_uInt16)pExpr->GetULength();
2635             break;
2636 
2637         case CSS1_PIXLENGTH:
2638             {
2639                 sal_Bool bHori = nWhichLine == BOX_LINE_TOP ||
2640                              nWhichLine == BOX_LINE_BOTTOM;
2641                 // Ein Pixel wird zur Haarlinie (ist huebscher)
2642                 long nWidthL = (long)pExpr->GetNumber();
2643                 if( nWidthL > 1 )
2644                 {
2645                     long nPWidth = bHori ? 0 : nWidthL;
2646                     long nPHeight = bHori ? nWidthL : 0;
2647                     SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2648                     nWidth = (sal_uInt16)(bHori ? nPHeight : nPWidth);
2649                 }
2650                 else
2651                     nWidth = 1;
2652             }
2653             break;
2654 
2655         default:
2656             ;
2657         }
2658 
2659         pExpr = pExpr->GetNext();
2660     }
2661 
2662     for( sal_uInt16 i=0; i<4; i++ )
2663     {
2664         sal_uInt16 nLine = 0;
2665         switch( i )
2666         {
2667         case 0: nLine = BOX_LINE_TOP; break;
2668         case 1: nLine = BOX_LINE_BOTTOM; break;
2669         case 2: nLine = BOX_LINE_LEFT; break;
2670         case 3: nLine = BOX_LINE_RIGHT; break;
2671         }
2672 
2673         if( bAll || nLine == nWhichLine )
2674         {
2675             SvxCSS1BorderInfo *pInfo = rPropInfo.GetBorderInfo( nLine );
2676             pInfo->eStyle = eStyle;
2677             pInfo->nAbsWidth = nWidth;
2678             pInfo->nNamedWidth = nNWidth;
2679             if( bColor )
2680                 pInfo->aColor = aColor;
2681         }
2682     }
2683 }
2684 
ParseCSS1_border_xxx_width(const CSS1Expression * pExpr,SfxItemSet &,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser &,sal_uInt16 nWhichLine)2685 static void ParseCSS1_border_xxx_width( const CSS1Expression *pExpr,
2686                                         SfxItemSet & /*rItemSet*/,
2687                                         SvxCSS1PropertyInfo& rPropInfo,
2688                                         const SvxCSS1Parser& /*rParser*/,
2689                                         sal_uInt16 nWhichLine )
2690 {
2691     DBG_ASSERT( pExpr, "kein Ausdruck" );
2692 
2693     sal_uInt16 nWidth = USHRT_MAX;      // die Linien-Dicke
2694     sal_uInt16 nNWidth = 1;             // benannte Linien-Dicke (und default)
2695 
2696     switch( pExpr->GetType() )
2697     {
2698     case CSS1_IDENT:
2699         {
2700             sal_uInt16 nValue;
2701             if( SvxCSS1Parser::GetEnum( aBorderWidthTable, pExpr->GetString(), nValue ) )
2702             {
2703                 nNWidth = nValue;
2704             }
2705         }
2706         break;
2707 
2708     case CSS1_LENGTH:
2709         nWidth = (sal_uInt16)pExpr->GetULength();
2710         break;
2711 
2712     case CSS1_PIXLENGTH:
2713         {
2714             sal_Bool bHori = nWhichLine == BOX_LINE_TOP ||
2715                          nWhichLine == BOX_LINE_BOTTOM;
2716             long nWidthL = (long)pExpr->GetNumber();
2717             long nPWidth = bHori ? 0 : nWidthL;
2718             long nPHeight = bHori ? nWidthL : 0;
2719             SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2720             nWidth = (sal_uInt16)(bHori ? nPHeight : nPWidth);
2721         }
2722         break;
2723 
2724     default:
2725         ;
2726     }
2727 
2728     SvxCSS1BorderInfo *pInfo = rPropInfo.GetBorderInfo( nWhichLine );
2729     pInfo->nAbsWidth = nWidth;
2730     pInfo->nNamedWidth = nNWidth;
2731 }
2732 
2733 /*  */
2734 
ParseCSS1_border_top_width(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser & rParser)2735 static void ParseCSS1_border_top_width( const CSS1Expression *pExpr,
2736                                         SfxItemSet &rItemSet,
2737                                         SvxCSS1PropertyInfo& rPropInfo,
2738                                         const SvxCSS1Parser& rParser )
2739 {
2740     ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_TOP );
2741 }
2742 
ParseCSS1_border_right_width(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser & rParser)2743 static void ParseCSS1_border_right_width( const CSS1Expression *pExpr,
2744                                         SfxItemSet &rItemSet,
2745                                         SvxCSS1PropertyInfo& rPropInfo,
2746                                         const SvxCSS1Parser& rParser )
2747 {
2748     ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_RIGHT );
2749 }
2750 
ParseCSS1_border_bottom_width(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser & rParser)2751 static void ParseCSS1_border_bottom_width( const CSS1Expression *pExpr,
2752                                         SfxItemSet &rItemSet,
2753                                         SvxCSS1PropertyInfo& rPropInfo,
2754                                         const SvxCSS1Parser& rParser )
2755 {
2756     ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_BOTTOM );
2757 }
2758 
ParseCSS1_border_left_width(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser & rParser)2759 static void ParseCSS1_border_left_width( const CSS1Expression *pExpr,
2760                                         SfxItemSet &rItemSet,
2761                                         SvxCSS1PropertyInfo& rPropInfo,
2762                                         const SvxCSS1Parser& rParser )
2763 {
2764     ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_LEFT );
2765 }
2766 
ParseCSS1_border_width(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser & rParser)2767 static void ParseCSS1_border_width( const CSS1Expression *pExpr,
2768                                     SfxItemSet &rItemSet,
2769                                     SvxCSS1PropertyInfo& rPropInfo,
2770                                     const SvxCSS1Parser& rParser )
2771 {
2772     sal_uInt16 n=0;
2773     while( n<4 && pExpr && !pExpr->GetOp() )
2774     {
2775         sal_uInt16 nLine = n==0 || n==2 ? BOX_LINE_BOTTOM : BOX_LINE_LEFT;
2776         ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, nLine );
2777         rPropInfo.CopyBorderInfo( n, SVX_CSS1_BORDERINFO_WIDTH );
2778 
2779         pExpr = pExpr->GetNext();
2780         n++;
2781     }
2782 }
2783 
ParseCSS1_border_color(const CSS1Expression * pExpr,SfxItemSet &,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser &)2784 static void ParseCSS1_border_color( const CSS1Expression *pExpr,
2785                                     SfxItemSet & /*rItemSet*/,
2786                                     SvxCSS1PropertyInfo& rPropInfo,
2787                                     const SvxCSS1Parser& /*rParser*/ )
2788 {
2789     sal_uInt16 n=0;
2790     while( n<4 && pExpr && !pExpr->GetOp() )
2791     {
2792         sal_uInt16 nLine = n==0 || n==2 ? BOX_LINE_BOTTOM : BOX_LINE_LEFT;
2793         Color aColor;
2794         switch( pExpr->GetType() )
2795         {
2796         case CSS1_RGB:
2797         case CSS1_HEXCOLOR:
2798         case CSS1_IDENT:
2799             if( pExpr->GetColor( aColor ) )
2800                 rPropInfo.GetBorderInfo( nLine )->aColor = aColor;
2801             break;
2802         default:
2803             ;
2804         }
2805         rPropInfo.CopyBorderInfo( n, SVX_CSS1_BORDERINFO_COLOR );
2806 
2807         pExpr = pExpr->GetNext();
2808         n++;
2809     }
2810 }
2811 
ParseCSS1_border_style(const CSS1Expression * pExpr,SfxItemSet &,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser &)2812 static void ParseCSS1_border_style( const CSS1Expression *pExpr,
2813                                     SfxItemSet & /*rItemSet*/,
2814                                     SvxCSS1PropertyInfo& rPropInfo,
2815                                     const SvxCSS1Parser& /*rParser*/ )
2816 {
2817     sal_uInt16 n=0;
2818     while( n<4 && pExpr && !pExpr->GetOp() )
2819     {
2820         sal_uInt16 nLine = n==0 || n==2 ? BOX_LINE_BOTTOM : BOX_LINE_LEFT;
2821         sal_uInt16 nValue;
2822         if( CSS1_IDENT==pExpr->GetType() &&
2823             SvxCSS1Parser::GetEnum( aBorderStyleTable, pExpr->GetString(),
2824                                     nValue ) )
2825         {
2826             rPropInfo.GetBorderInfo( nLine )->eStyle = (CSS1BorderStyle)nValue;
2827         }
2828         rPropInfo.CopyBorderInfo( n, SVX_CSS1_BORDERINFO_STYLE );
2829 
2830         pExpr = pExpr->GetNext();
2831         n++;
2832     }
2833 }
2834 
2835 
ParseCSS1_border_top(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser & rParser)2836 static void ParseCSS1_border_top( const CSS1Expression *pExpr,
2837                                   SfxItemSet &rItemSet,
2838                                   SvxCSS1PropertyInfo& rPropInfo,
2839                                   const SvxCSS1Parser& rParser )
2840 {
2841     ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_TOP, sal_False );
2842 }
2843 
ParseCSS1_border_right(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser & rParser)2844 static void ParseCSS1_border_right( const CSS1Expression *pExpr,
2845                                     SfxItemSet &rItemSet,
2846                                     SvxCSS1PropertyInfo& rPropInfo,
2847                                     const SvxCSS1Parser& rParser )
2848 {
2849     ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_RIGHT, sal_False );
2850 }
2851 
ParseCSS1_border_bottom(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser & rParser)2852 static void ParseCSS1_border_bottom( const CSS1Expression *pExpr,
2853                                      SfxItemSet &rItemSet,
2854                                      SvxCSS1PropertyInfo& rPropInfo,
2855                                      const SvxCSS1Parser& rParser )
2856 {
2857     ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_BOTTOM, sal_False );
2858 }
2859 
ParseCSS1_border_left(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser & rParser)2860 static void ParseCSS1_border_left( const CSS1Expression *pExpr,
2861                                    SfxItemSet &rItemSet,
2862                                    SvxCSS1PropertyInfo& rPropInfo,
2863                                    const SvxCSS1Parser& rParser )
2864 {
2865     ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_LEFT, sal_False );
2866 }
2867 
ParseCSS1_border(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser & rParser)2868 static void ParseCSS1_border( const CSS1Expression *pExpr,
2869                               SfxItemSet &rItemSet,
2870                               SvxCSS1PropertyInfo& rPropInfo,
2871                               const SvxCSS1Parser& rParser )
2872 {
2873     ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, 0, sal_True );
2874 }
2875 
2876 /*  */
2877 
ParseCSS1_float(const CSS1Expression * pExpr,SfxItemSet &,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser &)2878 static void ParseCSS1_float( const CSS1Expression *pExpr,
2879                              SfxItemSet & /*rItemSet*/,
2880                              SvxCSS1PropertyInfo& rPropInfo,
2881                              const SvxCSS1Parser& /*rParser*/ )
2882 {
2883     DBG_ASSERT( pExpr, "kein Ausdruck" );
2884 
2885     if( CSS1_IDENT==pExpr->GetType() )
2886     {
2887         sal_uInt16 nFloat;
2888         if( SvxCSS1Parser::GetEnum( aFloatTable, pExpr->GetString(), nFloat ) )
2889             rPropInfo.eFloat = (SvxAdjust)nFloat;
2890     }
2891 }
2892 
2893 
2894 /*  */
2895 
ParseCSS1_position(const CSS1Expression * pExpr,SfxItemSet &,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser &)2896 static void ParseCSS1_position( const CSS1Expression *pExpr,
2897                                 SfxItemSet & /*rItemSet*/,
2898                                 SvxCSS1PropertyInfo& rPropInfo,
2899                                 const SvxCSS1Parser& /*rParser*/ )
2900 {
2901     DBG_ASSERT( pExpr, "kein Ausdruck" );
2902 
2903     if( CSS1_IDENT==pExpr->GetType() )
2904     {
2905         sal_uInt16 nPos;
2906         if( SvxCSS1Parser::GetEnum( aPositionTable, pExpr->GetString(), nPos ) )
2907             rPropInfo.ePosition = (SvxCSS1Position)nPos;
2908     }
2909 }
2910 
2911 /*  */
2912 
ParseCSS1_length(const CSS1Expression * pExpr,long & rLength,SvxCSS1LengthType & rLengthType,sal_Bool bHori)2913 static void ParseCSS1_length( const CSS1Expression *pExpr,
2914                               long& rLength,
2915                               SvxCSS1LengthType& rLengthType,
2916                               sal_Bool bHori )
2917 {
2918     switch( pExpr->GetType() )
2919     {
2920     case CSS1_IDENT:
2921         if( pExpr->GetString().EqualsIgnoreCaseAscii( sCSS1_PV_auto ) )
2922         {
2923             rLength = 0;
2924             rLengthType = SVX_CSS1_LTYPE_AUTO;
2925         }
2926         break;
2927 
2928     case CSS1_LENGTH:
2929         rLength = pExpr->GetSLength();
2930         rLengthType = SVX_CSS1_LTYPE_TWIP;
2931         break;
2932 
2933     case CSS1_PIXLENGTH:
2934     case CSS1_NUMBER:       // wegen Netscape und IE
2935         {
2936             long nWidthL = (long)pExpr->GetNumber();
2937             long nPWidth = bHori ? 0 : nWidthL;
2938             long nPHeight = bHori ? nWidthL : 0;
2939             SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2940             rLength = (bHori ? nPHeight : nPWidth);
2941             rLengthType = SVX_CSS1_LTYPE_TWIP;
2942         }
2943         break;
2944 
2945     case CSS1_PERCENTAGE:
2946         rLength = (long)pExpr->GetNumber();
2947         if( rLength > 100 )
2948             rLength = 100;
2949         rLengthType = SVX_CSS1_LTYPE_PERCENTAGE;
2950         break;
2951 
2952     default:
2953         ;
2954     }
2955 }
2956 
2957 /*  */
2958 
ParseCSS1_width(const CSS1Expression * pExpr,SfxItemSet &,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser &)2959 static void ParseCSS1_width( const CSS1Expression *pExpr,
2960                              SfxItemSet & /*rItemSet*/,
2961                              SvxCSS1PropertyInfo& rPropInfo,
2962                              const SvxCSS1Parser& /*rParser*/ )
2963 {
2964     ParseCSS1_length( pExpr, rPropInfo.nWidth, rPropInfo.eWidthType, sal_True );
2965 }
2966 
ParseCSS1_height(const CSS1Expression * pExpr,SfxItemSet &,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser &)2967 static void ParseCSS1_height( const CSS1Expression *pExpr,
2968                               SfxItemSet & /*rItemSet*/,
2969                               SvxCSS1PropertyInfo& rPropInfo,
2970                               const SvxCSS1Parser& /*rParser*/ )
2971 {
2972     ParseCSS1_length( pExpr, rPropInfo.nHeight, rPropInfo.eHeightType, sal_False );
2973 }
2974 
ParseCSS1_left(const CSS1Expression * pExpr,SfxItemSet &,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser &)2975 static void ParseCSS1_left( const CSS1Expression *pExpr,
2976                              SfxItemSet & /*rItemSet*/,
2977                              SvxCSS1PropertyInfo& rPropInfo,
2978                              const SvxCSS1Parser& /*rParser*/ )
2979 {
2980     ParseCSS1_length( pExpr, rPropInfo.nLeft, rPropInfo.eLeftType, sal_True );
2981 }
2982 
ParseCSS1_top(const CSS1Expression * pExpr,SfxItemSet &,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser &)2983 static void ParseCSS1_top( const CSS1Expression *pExpr,
2984                            SfxItemSet & /*rItemSet*/,
2985                            SvxCSS1PropertyInfo& rPropInfo,
2986                            const SvxCSS1Parser& /*rParser*/ )
2987 {
2988     ParseCSS1_length( pExpr, rPropInfo.nTop, rPropInfo.eTopType, sal_False );
2989 }
2990 
2991 /*  */
2992 
2993 // Feature: PrintExt
ParseCSS1_size(const CSS1Expression * pExpr,SfxItemSet &,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser &)2994 static void ParseCSS1_size( const CSS1Expression *pExpr,
2995                             SfxItemSet & /*rItemSet*/,
2996                             SvxCSS1PropertyInfo& rPropInfo,
2997                             const SvxCSS1Parser& /*rParser*/ )
2998 {
2999     sal_uInt16 n=0;
3000     while( n<2 && pExpr && !pExpr->GetOp() )
3001     {
3002         switch( pExpr->GetType() )
3003         {
3004         case CSS1_IDENT:
3005             {
3006                 sal_uInt16 nValue;
3007                 if( SvxCSS1Parser::GetEnum( aSizeTable, pExpr->GetString(),
3008                                             nValue ) )
3009                 {
3010                     rPropInfo.eSizeType = (SvxCSS1SizeType)nValue;
3011                 }
3012             }
3013             break;
3014 
3015         case CSS1_LENGTH:
3016             rPropInfo.nHeight = pExpr->GetSLength();
3017             if( n==0 )
3018                 rPropInfo.nWidth = rPropInfo.nHeight;
3019             rPropInfo.eSizeType = SVX_CSS1_STYPE_TWIP;
3020             break;
3021 
3022         case CSS1_PIXLENGTH:
3023             {
3024                 long nPHeight = (long)pExpr->GetNumber();
3025                 long nPWidth = n==0 ? nPHeight : 0;
3026                 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
3027                 rPropInfo.nHeight = nPHeight;
3028                 if( n==0 )
3029                     rPropInfo.nWidth = nPWidth;
3030                 rPropInfo.eSizeType = SVX_CSS1_STYPE_TWIP;
3031             }
3032             break;
3033 
3034         default:
3035             ;
3036         }
3037 
3038         pExpr = pExpr->GetNext();
3039         n++;
3040     }
3041 }
3042 
3043 // /Feature: PrintExt
3044 
3045 /*  */
3046 
3047 // Feature: PrintExt
3048 
ParseCSS1_page_break_xxx(const CSS1Expression * pExpr,SvxCSS1PageBreak & rPBreak)3049 static void ParseCSS1_page_break_xxx( const CSS1Expression *pExpr,
3050                                       SvxCSS1PageBreak& rPBreak )
3051 {
3052     if( CSS1_IDENT == pExpr->GetType() )
3053     {
3054         sal_uInt16 nValue;
3055         if( SvxCSS1Parser::GetEnum( aPageBreakTable, pExpr->GetString(),
3056                                     nValue ) )
3057         {
3058             rPBreak = (SvxCSS1PageBreak)nValue;
3059         }
3060     }
3061 }
3062 
ParseCSS1_page_break_before(const CSS1Expression * pExpr,SfxItemSet &,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser &)3063 static void ParseCSS1_page_break_before( const CSS1Expression *pExpr,
3064                                          SfxItemSet & /*rItemSet*/,
3065                                          SvxCSS1PropertyInfo& rPropInfo,
3066                                          const SvxCSS1Parser& /*rParser*/ )
3067 {
3068     ParseCSS1_page_break_xxx( pExpr, rPropInfo.ePageBreakBefore );
3069 }
3070 
ParseCSS1_page_break_after(const CSS1Expression * pExpr,SfxItemSet &,SvxCSS1PropertyInfo & rPropInfo,const SvxCSS1Parser &)3071 static void ParseCSS1_page_break_after( const CSS1Expression *pExpr,
3072                                         SfxItemSet & /*rItemSet*/,
3073                                         SvxCSS1PropertyInfo& rPropInfo,
3074                                         const SvxCSS1Parser& /*rParser*/ )
3075 {
3076     ParseCSS1_page_break_xxx( pExpr, rPropInfo.ePageBreakAfter );
3077 }
3078 
ParseCSS1_page_break_inside(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo &,const SvxCSS1Parser &)3079 static void ParseCSS1_page_break_inside( const CSS1Expression *pExpr,
3080                                          SfxItemSet &rItemSet,
3081                                          SvxCSS1PropertyInfo& /*rPropInfo*/,
3082                                          const SvxCSS1Parser& /*rParser*/ )
3083 {
3084     SvxCSS1PageBreak eBreak(SVX_CSS1_PBREAK_NONE);
3085     ParseCSS1_page_break_xxx( pExpr, eBreak );
3086 
3087     sal_Bool bSetSplit = sal_False, bSplit = sal_True;
3088     switch( eBreak )
3089     {
3090     case SVX_CSS1_PBREAK_AUTO:
3091         bSetSplit = sal_True;
3092         break;
3093     case SVX_CSS1_PBREAK_AVOID:
3094         bSplit = sal_False;
3095         bSetSplit = sal_True;
3096         break;
3097     default:
3098         ;
3099     }
3100 
3101     if( bSetSplit )
3102         rItemSet.Put( SvxFmtSplitItem( bSplit, aItemIds.nFmtSplit ) );
3103 }
3104 
ParseCSS1_widows(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo &,const SvxCSS1Parser &)3105 static void ParseCSS1_widows( const CSS1Expression *pExpr,
3106                               SfxItemSet &rItemSet,
3107                               SvxCSS1PropertyInfo& /*rPropInfo*/,
3108                               const SvxCSS1Parser& /*rParser*/ )
3109 {
3110     if( CSS1_NUMBER == pExpr->GetType() )
3111     {
3112         sal_uInt8 nVal = pExpr->GetNumber() <= 255
3113                         ? (sal_uInt8)pExpr->GetNumber()
3114                         : 255;
3115         SvxWidowsItem aWidowsItem( nVal, aItemIds.nWidows );
3116         rItemSet.Put( aWidowsItem );
3117     }
3118 }
3119 
ParseCSS1_orphans(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo &,const SvxCSS1Parser &)3120 static void ParseCSS1_orphans( const CSS1Expression *pExpr,
3121                                SfxItemSet &rItemSet,
3122                                SvxCSS1PropertyInfo& /*rPropInfo*/,
3123                                const SvxCSS1Parser& /*rParser*/ )
3124 {
3125     if( CSS1_NUMBER == pExpr->GetType() )
3126     {
3127         sal_uInt8 nVal = pExpr->GetNumber() <= 255
3128                         ? (sal_uInt8)pExpr->GetNumber()
3129                         : 255;
3130         SvxOrphansItem aOrphansItem( nVal, aItemIds.nOrphans );
3131         rItemSet.Put( aOrphansItem );
3132     }
3133 }
3134 // /Feature: PrintExt
3135 
ParseCSS1_so_language(const CSS1Expression * pExpr,SfxItemSet & rItemSet,SvxCSS1PropertyInfo &,const SvxCSS1Parser & rParser)3136 static void ParseCSS1_so_language( const CSS1Expression *pExpr,
3137                                SfxItemSet &rItemSet,
3138                                SvxCSS1PropertyInfo& /*rPropInfo*/,
3139                                const SvxCSS1Parser& rParser )
3140 {
3141     if( CSS1_IDENT == pExpr->GetType() ||
3142         CSS1_STRING == pExpr->GetType() )
3143     {
3144         LanguageType eLang = MsLangId::convertIsoStringToLanguage( pExpr->GetString() );
3145         if( LANGUAGE_DONTKNOW != eLang )
3146         {
3147             SvxLanguageItem aLang( eLang, aItemIds.nLanguage );
3148             if( rParser.IsSetWesternProps() )
3149                 rItemSet.Put( aLang );
3150             if( rParser.IsSetCJKProps() )
3151             {
3152                 aLang.SetWhich( aItemIds.nLanguageCJK );
3153                 rItemSet.Put( aLang );
3154             }
3155             if( rParser.IsSetCTLProps() )
3156             {
3157                 aLang.SetWhich( aItemIds.nLanguageCTL );
3158                 rItemSet.Put( aLang );
3159             }
3160         }
3161     }
3162 }
3163 
3164 /*  */
3165 
3166 // die Zuordung Property zu parsender Funktion
3167 struct CSS1PropEntry
3168 {
3169     union
3170     {
3171         const sal_Char  *sName;
3172         String          *pName;
3173     };
3174     FnParseCSS1Prop pFunc;
3175 };
3176 
3177 #define CSS1_PROP_ENTRY(p) \
3178     {   { sCSS1_P_##p }, ParseCSS1_##p }
3179 
3180 
3181 // die Tabelle mit den Zuordnungen
3182 static CSS1PropEntry __FAR_DATA aCSS1PropFnTab[] =
3183 {
3184     CSS1_PROP_ENTRY(background),
3185     CSS1_PROP_ENTRY(background_color),
3186     CSS1_PROP_ENTRY(border_top_width),
3187     CSS1_PROP_ENTRY(border_right_width),
3188     CSS1_PROP_ENTRY(border_bottom_width),
3189     CSS1_PROP_ENTRY(border_left_width),
3190     CSS1_PROP_ENTRY(border_width),
3191     CSS1_PROP_ENTRY(border_color),
3192     CSS1_PROP_ENTRY(border_style),
3193     CSS1_PROP_ENTRY(border_top),
3194     CSS1_PROP_ENTRY(border_right),
3195     CSS1_PROP_ENTRY(border_bottom),
3196     CSS1_PROP_ENTRY(border_left),
3197     CSS1_PROP_ENTRY(border),
3198     CSS1_PROP_ENTRY(color),
3199     CSS1_PROP_ENTRY(direction),
3200     CSS1_PROP_ENTRY(float),
3201     CSS1_PROP_ENTRY(font_size),
3202     CSS1_PROP_ENTRY(font_family),
3203     CSS1_PROP_ENTRY(font_style),
3204     CSS1_PROP_ENTRY(font_variant),
3205     CSS1_PROP_ENTRY(font_weight),
3206     CSS1_PROP_ENTRY(letter_spacing),
3207     CSS1_PROP_ENTRY(line_height),
3208     CSS1_PROP_ENTRY(font),
3209     CSS1_PROP_ENTRY(text_align),
3210     CSS1_PROP_ENTRY(text_decoration),
3211     CSS1_PROP_ENTRY(text_indent),
3212     CSS1_PROP_ENTRY(margin_left),
3213     CSS1_PROP_ENTRY(margin_right),
3214     CSS1_PROP_ENTRY(margin_top),
3215     CSS1_PROP_ENTRY(margin_bottom),
3216     CSS1_PROP_ENTRY(margin),
3217     CSS1_PROP_ENTRY(padding_top),
3218     CSS1_PROP_ENTRY(padding_bottom),
3219     CSS1_PROP_ENTRY(padding_left),
3220     CSS1_PROP_ENTRY(padding_right),
3221     CSS1_PROP_ENTRY(padding),
3222     CSS1_PROP_ENTRY(position),
3223     CSS1_PROP_ENTRY(left),
3224     CSS1_PROP_ENTRY(top),
3225     CSS1_PROP_ENTRY(width),
3226     CSS1_PROP_ENTRY(height),
3227 // Feature: PrintExt
3228     CSS1_PROP_ENTRY(size),
3229     CSS1_PROP_ENTRY(page_break_before),
3230     CSS1_PROP_ENTRY(page_break_after),
3231     CSS1_PROP_ENTRY(page_break_inside),
3232     CSS1_PROP_ENTRY(widows),
3233     CSS1_PROP_ENTRY(orphans),
3234 // /Feature: PrintExt
3235     CSS1_PROP_ENTRY(so_language)
3236 };
3237 
3238 /*  */
3239 
3240 static int __FAR_DATA bSortedPropFns = sal_False;
3241 
3242 extern "C"
3243 {
3244 static int
3245 #if defined( WNT )
3246  __cdecl
3247 #endif
3248 #if defined( ICC )
3249  _Optlink
3250 #endif
CSS1PropEntryCompare(const void * pFirst,const void * pSecond)3251     CSS1PropEntryCompare( const void *pFirst, const void *pSecond)
3252 {
3253     int nRet;
3254     if( ((CSS1PropEntry*)pFirst)->pFunc )
3255     {
3256         if( ((CSS1PropEntry*)pSecond)->pFunc )
3257             nRet = strcmp( ((CSS1PropEntry*)pFirst)->sName ,
3258                     ((CSS1PropEntry*)pSecond)->sName );
3259         else
3260             nRet = -1 * ((CSS1PropEntry*)pSecond)->pName->CompareToAscii(
3261                             ((CSS1PropEntry*)pFirst)->sName );
3262     }
3263     else
3264     {
3265         if( ((CSS1PropEntry*)pSecond)->pFunc )
3266             nRet = ((CSS1PropEntry*)pFirst)->pName->CompareToAscii(
3267                         ((CSS1PropEntry*)pSecond)->sName );
3268         else
3269             nRet = ((CSS1PropEntry*)pFirst)->pName->CompareTo(
3270                         *((CSS1PropEntry*)pSecond)->pName );
3271     }
3272 
3273     return nRet;
3274 }
3275 }
3276 
ParseProperty(const String & rProperty,const CSS1Expression * pExpr)3277 void SvxCSS1Parser::ParseProperty( const String& rProperty,
3278                                    const CSS1Expression *pExpr )
3279 {
3280     DBG_ASSERT( pItemSet, "DeclarationParsed() ohne ItemSet" );
3281 
3282     if( !bSortedPropFns )
3283     {
3284         qsort( (void*) aCSS1PropFnTab,
3285                 sizeof( aCSS1PropFnTab ) / sizeof( CSS1PropEntry ),
3286                 sizeof( CSS1PropEntry ),
3287                 CSS1PropEntryCompare );
3288         bSortedPropFns = sal_True;
3289     }
3290 
3291     String aTmp( rProperty );
3292     aTmp.ToLowerAscii();
3293 
3294     CSS1PropEntry aSrch;
3295     aSrch.pName = &aTmp;
3296     aSrch.pFunc = 0;
3297 
3298     void* pFound;
3299     if( 0 != ( pFound = bsearch( (char *) &aSrch,
3300                         (void*) aCSS1PropFnTab,
3301                         sizeof( aCSS1PropFnTab ) / sizeof( CSS1PropEntry ),
3302                         sizeof( CSS1PropEntry ),
3303                         CSS1PropEntryCompare )))
3304     {
3305         (((CSS1PropEntry*)pFound)->pFunc)( pExpr, *pItemSet, *pPropInfo, *this );
3306     }
3307 }
3308