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