Update ooo320-m1
[ooovba.git] / sw / source / filter / html / svxcss1.cxx
blobbda9ee26e033bb71154b3226f593e6ca5cdb70c2
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svxcss1.cxx,v $
10 * $Revision: 1.20.210.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <stdlib.h>
37 #ifndef _SVX_SVXIDS_HRC
38 #include <svx/svxids.hrc>
39 #endif
40 #include <i18npool/mslangid.hxx>
41 #include <svtools/ctrltool.hxx>
42 #include <svtools/urihelper.hxx>
43 #include <svx/udlnitem.hxx>
44 #include <svx/adjitem.hxx>
45 #include <svx/blnkitem.hxx>
46 #include <svx/crsditem.hxx>
47 #include <svx/kernitem.hxx>
48 #include <svx/lspcitem.hxx>
49 #include <svx/fontitem.hxx>
50 #include <svx/postitem.hxx>
51 #include <svx/colritem.hxx>
52 #include <svx/cmapitem.hxx>
53 #include <svx/brshitem.hxx>
54 #include <svx/wghtitem.hxx>
55 #include <svx/fhgtitem.hxx>
56 #include <svx/boxitem.hxx>
57 #include <svx/ulspitem.hxx>
58 #include <svx/lrspitem.hxx>
59 #include <svx/langitem.hxx>
60 #include <svtools/itempool.hxx>
61 #include <svx/spltitem.hxx>
62 #include <svx/widwitem.hxx>
63 #include <svx/frmdiritem.hxx>
64 #include <svx/orphitem.hxx>
65 #include <svtools/svparser.hxx>
66 #include <vcl/svapp.hxx>
67 #include <vcl/wrkwin.hxx>
69 #include "css1kywd.hxx"
70 #include "svxcss1.hxx"
72 // die Funktionen zum Parsen einer CSS1-Property sind von folgendem Typ:
73 typedef void (*FnParseCSS1Prop)( const CSS1Expression *pExpr,
74 SfxItemSet& rItemSet,
75 SvxCSS1PropertyInfo& rPropInfo,
76 const SvxCSS1Parser& rParser );
78 SV_IMPL_PTRARR( CSS1Selectors, CSS1Selector* )
81 /* \f */
83 static CSS1PropertyEnum __READONLY_DATA aFontSizeTable[] =
85 { sCSS1_PV_xx_small, 0 },
86 { sCSS1_PV_x_small, 1 },
87 { sCSS1_PV_small, 2 },
88 { sCSS1_PV_medium, 3 },
89 { sCSS1_PV_large, 4 },
90 { sCSS1_PV_x_large, 5 },
91 { sCSS1_PV_xx_large, 6 },
92 { 0, 0 }
95 static CSS1PropertyEnum __READONLY_DATA aFontFamilyTable[] =
97 { sCSS1_PV_serif, FAMILY_ROMAN },
98 { sCSS1_PV_sans_serif, FAMILY_SWISS },
99 { sCSS1_PV_cursive, FAMILY_SCRIPT },
100 { sCSS1_PV_fantasy, FAMILY_DECORATIVE },
101 { sCSS1_PV_monospace, FAMILY_MODERN },
102 { 0, 0 }
105 static CSS1PropertyEnum __READONLY_DATA aFontWeightTable[] =
107 { sCSS1_PV_extra_light, WEIGHT_NORMAL }, // WEIGHT_ULTRALIGHT (OBS)
108 { sCSS1_PV_light, WEIGHT_NORMAL }, // WEIGHT_LIGHT (OBSOLETE)
109 { sCSS1_PV_demi_light, WEIGHT_NORMAL }, // WEIGHT_SEMILIGHT (OBS)
110 { sCSS1_PV_medium, WEIGHT_NORMAL }, // WEIGHT_MEDIUM (OBS)
111 { sCSS1_PV_normal, WEIGHT_NORMAL }, // WEIGHT_MEDIUM
112 { sCSS1_PV_demi_bold, WEIGHT_NORMAL }, // WEIGHT_SEMIBOLD (OBS)
113 { sCSS1_PV_bold, WEIGHT_BOLD }, // WEIGHT_BOLD (OBSOLETE)
114 { sCSS1_PV_extra_bold, WEIGHT_BOLD }, // WEIGHT_ULTRABOLD (OBS)
115 { sCSS1_PV_bolder, WEIGHT_BOLD },
116 { sCSS1_PV_lighter, WEIGHT_NORMAL },
117 { 0, 0 }
120 static CSS1PropertyEnum __READONLY_DATA aFontStyleTable[] =
122 { sCSS1_PV_normal, ITALIC_NONE },
123 { sCSS1_PV_italic, ITALIC_NORMAL },
124 { sCSS1_PV_oblique, ITALIC_NORMAL },
125 { 0, 0 }
128 static CSS1PropertyEnum __READONLY_DATA aFontVariantTable[] =
130 { sCSS1_PV_normal, SVX_CASEMAP_NOT_MAPPED },
131 { sCSS1_PV_small_caps, SVX_CASEMAP_KAPITAELCHEN },
132 { 0, 0 }
135 static CSS1PropertyEnum __READONLY_DATA aDirectionTable[] =
137 { sCSS1_PV_ltr, FRMDIR_HORI_LEFT_TOP },
138 { sCSS1_PV_rtl, FRMDIR_HORI_RIGHT_TOP },
139 { sCSS1_PV_inherit, FRMDIR_ENVIRONMENT },
140 { 0, 0 }
143 /* \f */
145 static CSS1PropertyEnum __READONLY_DATA aBGRepeatTable[] =
147 { sCSS1_PV_repeat, GPOS_TILED },
148 { sCSS1_PV_repeat_x, GPOS_TILED },
149 { sCSS1_PV_repeat_y, GPOS_TILED },
150 { sCSS1_PV_no_repeat, GPOS_NONE },
151 { 0, 0 }
154 static CSS1PropertyEnum __READONLY_DATA aBGHoriPosTable[] =
156 { sCSS1_PV_left, GPOS_LT },
157 { sCSS1_PV_center, GPOS_MT },
158 { sCSS1_PV_right, GPOS_RT },
159 { 0, 0 }
162 static CSS1PropertyEnum __READONLY_DATA aBGVertPosTable[] =
164 { sCSS1_PV_top, GPOS_LT },
165 { sCSS1_PV_middle, GPOS_LM },
166 { sCSS1_PV_bottom, GPOS_LB },
167 { 0, 0 }
170 /* \f */
172 static CSS1PropertyEnum __READONLY_DATA aTextAlignTable[] =
174 { sCSS1_PV_left, SVX_ADJUST_LEFT },
175 { sCSS1_PV_center, SVX_ADJUST_CENTER },
176 { sCSS1_PV_right, SVX_ADJUST_RIGHT },
177 { sCSS1_PV_justify, SVX_ADJUST_BLOCK },
178 { 0, 0 }
181 /* \f */
183 static CSS1PropertyEnum __READONLY_DATA aBorderWidthTable[] =
185 { sCSS1_PV_thin, 0 }, // DEF_LINE_WIDTH_0 / DEF_DOUBLE_LINE0
186 { sCSS1_PV_medium, 1 }, // DEF_LINE_WIDTH_1 / DEF_DOUBLE_LINE1
187 { sCSS1_PV_thick, 2 }, // DEF_LINE_WIDTH_2 / DEF_DOUBLE_LINE2
188 { 0, 0 }
191 enum CSS1BorderStyle { CSS1_BS_NONE, CSS1_BS_SINGLE, CSS1_BS_DOUBLE };
193 static CSS1PropertyEnum __READONLY_DATA aBorderStyleTable[] =
195 { sCSS1_PV_none, CSS1_BS_NONE },
196 { sCSS1_PV_dotted, CSS1_BS_SINGLE },
197 { sCSS1_PV_dashed, CSS1_BS_SINGLE },
198 { sCSS1_PV_solid, CSS1_BS_SINGLE },
199 { sCSS1_PV_double, CSS1_BS_DOUBLE },
200 { sCSS1_PV_groove, CSS1_BS_SINGLE },
201 { sCSS1_PV_ridge, CSS1_BS_SINGLE },
202 { sCSS1_PV_inset, CSS1_BS_SINGLE },
203 { sCSS1_PV_outset, CSS1_BS_SINGLE },
204 { 0, 0 }
207 static CSS1PropertyEnum __READONLY_DATA aFloatTable[] =
209 { sCSS1_PV_left, SVX_ADJUST_LEFT },
210 { sCSS1_PV_right, SVX_ADJUST_RIGHT },
211 { sCSS1_PV_none, SVX_ADJUST_END },
212 { 0, 0 }
215 static CSS1PropertyEnum __READONLY_DATA aPositionTable[] =
217 { sCSS1_PV_absolute, SVX_CSS1_POS_ABSOLUTE },
218 { sCSS1_PV_relative, SVX_CSS1_POS_RELATIVE },
219 { sCSS1_PV_static, SVX_CSS1_POS_STATIC },
220 { 0, 0 }
223 // Feature: PrintExt
224 static CSS1PropertyEnum __READONLY_DATA aSizeTable[] =
226 { sCSS1_PV_auto, SVX_CSS1_STYPE_AUTO },
227 { sCSS1_PV_landscape, SVX_CSS1_STYPE_LANDSCAPE },
228 { sCSS1_PV_portrait, SVX_CSS1_STYPE_PORTRAIT },
229 { 0, 0 }
232 static CSS1PropertyEnum __READONLY_DATA aPageBreakTable[] =
234 { sCSS1_PV_auto, SVX_CSS1_PBREAK_AUTO },
235 { sCSS1_PV_always, SVX_CSS1_PBREAK_ALWAYS },
236 { sCSS1_PV_avoid, SVX_CSS1_PBREAK_AVOID },
237 { sCSS1_PV_left, SVX_CSS1_PBREAK_LEFT },
238 { sCSS1_PV_right, SVX_CSS1_PBREAK_RIGHT },
239 { 0, 0 }
242 // /Feature: PrintExt
244 /* \f */
246 // Ein Eintrag besteht aus vier USHORTs. Der erste ist die Gesamtbreite,
247 // die anderen sind die 3 Einzelbreiten
249 #define SBORDER_ENTRY( n ) \
250 DEF_LINE_WIDTH_##n, DEF_LINE_WIDTH_##n, 0, 0
252 #define DBORDER_ENTRY( n ) \
253 DEF_DOUBLE_LINE##n##_OUT + DEF_DOUBLE_LINE##n##_IN + \
254 DEF_DOUBLE_LINE##n##_DIST, \
255 DEF_DOUBLE_LINE##n##_OUT, \
256 DEF_DOUBLE_LINE##n##_IN, \
257 DEF_DOUBLE_LINE##n##_DIST
259 #define TDBORDER_ENTRY( n ) \
260 DEF_DOUBLE_LINE##n##_OUT, \
261 DEF_DOUBLE_LINE##n##_OUT, \
262 DEF_DOUBLE_LINE##n##_IN, \
263 DEF_DOUBLE_LINE##n##_DIST
266 static USHORT __READONLY_DATA aSBorderWidths[] =
268 SBORDER_ENTRY( 0 ), SBORDER_ENTRY( 1 ), SBORDER_ENTRY( 2 ),
269 SBORDER_ENTRY( 3 ), SBORDER_ENTRY( 4 )
272 static USHORT __READONLY_DATA aDBorderWidths[] =
274 DBORDER_ENTRY( 0 ),
275 DBORDER_ENTRY( 7 ),
276 DBORDER_ENTRY( 1 ),
277 DBORDER_ENTRY( 8 ),
278 DBORDER_ENTRY( 4 ),
279 DBORDER_ENTRY( 9 ),
280 DBORDER_ENTRY( 3 ),
281 DBORDER_ENTRY( 10 ),
282 DBORDER_ENTRY( 2 ),
283 DBORDER_ENTRY( 5 )
286 static USHORT __READONLY_DATA aTDBorderWidths[] =
288 TDBORDER_ENTRY( 7 ), TDBORDER_ENTRY( 8 ), TDBORDER_ENTRY( 9 ),
289 TDBORDER_ENTRY( 10 )
292 #undef SBORDER_ENTRY
293 #undef DBORDER_ENTRY
295 /* \f */
297 struct SvxCSS1ItemIds
299 USHORT nFont;
300 USHORT nFontCJK;
301 USHORT nFontCTL;
302 USHORT nPosture;
303 USHORT nPostureCJK;
304 USHORT nPostureCTL;
305 USHORT nWeight;
306 USHORT nWeightCJK;
307 USHORT nWeightCTL;
308 USHORT nFontHeight;
309 USHORT nFontHeightCJK;
310 USHORT nFontHeightCTL;
311 USHORT nUnderline;
312 USHORT nOverline;
313 USHORT nCrossedOut;
314 USHORT nColor;
315 USHORT nKerning;
316 USHORT nCaseMap;
317 USHORT nBlink;
319 USHORT nLineSpacing;
320 USHORT nAdjust;
321 USHORT nWidows;
322 USHORT nOrphans;
323 USHORT nFmtSplit;
325 USHORT nLRSpace;
326 USHORT nULSpace;
327 USHORT nBox;
328 USHORT nBrush;
330 USHORT nLanguage;
331 USHORT nLanguageCJK;
332 USHORT nLanguageCTL;
333 USHORT nDirection;
337 static SvxCSS1ItemIds aItemIds;
340 /* \f */
342 struct SvxCSS1BorderInfo
344 Color aColor;
345 USHORT nAbsWidth;
346 USHORT nNamedWidth;
347 CSS1BorderStyle eStyle;
349 SvxCSS1BorderInfo() :
350 aColor( COL_BLACK ), nAbsWidth( USHRT_MAX ),
351 nNamedWidth( USHRT_MAX ), eStyle( CSS1_BS_NONE )
354 SvxCSS1BorderInfo( const SvxCSS1BorderInfo& rInfo ) :
355 aColor( rInfo.aColor ), nAbsWidth( rInfo.nAbsWidth ),
356 nNamedWidth( rInfo.nNamedWidth ), eStyle( rInfo.eStyle )
359 void SetBorderLine( USHORT nLine, SvxBoxItem &rBoxItem ) const;
362 void SvxCSS1BorderInfo::SetBorderLine( USHORT nLine, SvxBoxItem &rBoxItem ) const
364 if( CSS1_BS_NONE==eStyle || nAbsWidth==0 ||
365 (nAbsWidth==USHRT_MAX && nNamedWidth==USHRT_MAX) )
367 rBoxItem.SetLine( 0, nLine );
368 return;
371 SvxBorderLine aBorderLine( &aColor );
373 // Linien-Stil doppelt oder einfach?
374 BOOL bDouble = eStyle == CSS1_BS_DOUBLE;
376 // benannte Breite umrechnenen, wenn keine absolute gegeben ist
377 if( nAbsWidth==USHRT_MAX )
379 const USHORT *aWidths = bDouble ? aDBorderWidths : aSBorderWidths;
380 USHORT nNWidth = nNamedWidth * 4;
381 aBorderLine.SetOutWidth( aWidths[nNWidth+1] );
382 aBorderLine.SetInWidth( aWidths[nNWidth+2] );
383 aBorderLine.SetDistance( aWidths[nNWidth+3] );
385 else
387 SvxCSS1Parser::SetBorderWidth( aBorderLine, nAbsWidth, bDouble );
390 rBoxItem.SetLine( &aBorderLine, nLine );
394 /* \f */
396 SvxCSS1PropertyInfo::SvxCSS1PropertyInfo()
398 for( USHORT i=0; i<4; i++ )
399 aBorderInfos[i] = 0;
401 Clear();
404 SvxCSS1PropertyInfo::SvxCSS1PropertyInfo( const SvxCSS1PropertyInfo& rProp ) :
405 aId( rProp.aId ),
406 bTopMargin( rProp.bTopMargin ),
407 bBottomMargin( rProp.bBottomMargin ),
408 bLeftMargin( rProp.bLeftMargin ),
409 bRightMargin( rProp.bRightMargin ),
410 bTextIndent( rProp.bTextIndent ),
411 eFloat( rProp.eFloat ),
412 ePosition( rProp.ePosition ),
413 nTopBorderDistance( rProp.nTopBorderDistance ),
414 nBottomBorderDistance( rProp.nBottomBorderDistance ),
415 nLeftBorderDistance( rProp.nLeftBorderDistance ),
416 nRightBorderDistance( rProp.nRightBorderDistance ),
417 nLeft( rProp.nLeft ),
418 nTop( rProp.nTop ),
419 nWidth( rProp.nWidth ),
420 nHeight( rProp.nHeight ),
421 nLeftMargin( rProp.nLeftMargin ),
422 nRightMargin( rProp.nRightMargin ),
423 eLeftType( rProp.eLeftType ),
424 eTopType( rProp.eTopType ),
425 eWidthType( rProp.eWidthType ),
426 eHeightType( rProp.eHeightType ),
427 // Feature: PrintExt
428 eSizeType( rProp.eSizeType ),
429 ePageBreakBefore( rProp.ePageBreakBefore ),
430 ePageBreakAfter( rProp.ePageBreakAfter )
431 // /Feature: PrintExt
433 for( USHORT i=0; i<4; i++ )
434 aBorderInfos[i] = rProp.aBorderInfos[i]
435 ? new SvxCSS1BorderInfo( *rProp.aBorderInfos[i] )
436 : 0;
439 SvxCSS1PropertyInfo::~SvxCSS1PropertyInfo()
441 DestroyBorderInfos();
444 void SvxCSS1PropertyInfo::DestroyBorderInfos()
446 for( USHORT i=0; i<4; i++ )
448 delete aBorderInfos[i];
449 aBorderInfos[i] = 0;
453 void SvxCSS1PropertyInfo::Clear()
455 aId.Erase();
456 bTopMargin = bBottomMargin = FALSE;
457 bLeftMargin = bRightMargin = bTextIndent = FALSE;
458 nLeftMargin = nRightMargin = 0;
459 eFloat = SVX_ADJUST_END;
461 ePosition = SVX_CSS1_POS_NONE;
462 nTopBorderDistance = nBottomBorderDistance =
463 nLeftBorderDistance = nRightBorderDistance = USHRT_MAX;
464 nLeft = nTop = nWidth = nHeight = 0;
465 eLeftType = eTopType = eWidthType = eHeightType = SVX_CSS1_LTYPE_NONE;
467 // Feature: PrintExt
468 eSizeType = SVX_CSS1_STYPE_NONE;
469 ePageBreakBefore = SVX_CSS1_PBREAK_NONE;
470 ePageBreakAfter = SVX_CSS1_PBREAK_NONE;
472 DestroyBorderInfos();
475 void SvxCSS1PropertyInfo::Merge( const SvxCSS1PropertyInfo& rProp )
477 if( rProp.bTopMargin )
478 bTopMargin = TRUE;
479 if( rProp.bBottomMargin )
480 bBottomMargin = TRUE;
482 if( rProp.bLeftMargin )
484 bLeftMargin = TRUE;
485 nLeftMargin = rProp.nLeftMargin;
487 if( rProp.bRightMargin )
489 bRightMargin = TRUE;
490 nRightMargin = rProp.nRightMargin;
492 if( rProp.bTextIndent )
493 bTextIndent = TRUE;
495 for( USHORT i=0; i<4; i++ )
497 if( rProp.aBorderInfos[i] )
499 if( aBorderInfos[i] )
500 delete aBorderInfos[i];
502 aBorderInfos[i] = new SvxCSS1BorderInfo( *rProp.aBorderInfos[i] );
506 if( USHRT_MAX != rProp.nTopBorderDistance )
507 nTopBorderDistance = rProp.nTopBorderDistance;
508 if( USHRT_MAX != rProp.nBottomBorderDistance )
509 nBottomBorderDistance = rProp.nBottomBorderDistance;
510 if( USHRT_MAX != rProp.nLeftBorderDistance )
511 nLeftBorderDistance = rProp.nLeftBorderDistance;
512 if( USHRT_MAX != rProp.nRightBorderDistance )
513 nRightBorderDistance = rProp.nRightBorderDistance;
515 if( rProp.eFloat != SVX_ADJUST_END )
516 eFloat = rProp.eFloat;
518 if( rProp.ePosition != SVX_CSS1_POS_NONE )
519 ePosition = rProp.ePosition;
521 // Feature: PrintExt
522 if( rProp.eSizeType != SVX_CSS1_STYPE_NONE )
524 eSizeType = rProp.eSizeType;
525 nWidth = rProp.nWidth;
526 nHeight = rProp.nHeight;
529 if( rProp.ePageBreakBefore != SVX_CSS1_PBREAK_NONE )
530 ePageBreakBefore = rProp.ePageBreakBefore;
532 if( rProp.ePageBreakAfter != SVX_CSS1_PBREAK_NONE )
533 ePageBreakAfter = rProp.ePageBreakAfter;
535 // /Feature: PrintExt
537 if( rProp.eLeftType != SVX_CSS1_LTYPE_NONE )
539 eLeftType = rProp.eLeftType;
540 nLeft = rProp.nLeft;
543 if( rProp.eTopType != SVX_CSS1_LTYPE_NONE )
545 eTopType = rProp.eTopType;
546 nTop = rProp.nTop;
549 if( rProp.eWidthType != SVX_CSS1_LTYPE_NONE )
551 eWidthType = rProp.eWidthType;
552 nWidth = rProp.nWidth;
555 if( rProp.eHeightType != SVX_CSS1_LTYPE_NONE )
557 eHeightType = rProp.eHeightType;
558 nHeight = rProp.nHeight;
562 SvxCSS1BorderInfo *SvxCSS1PropertyInfo::GetBorderInfo( USHORT nLine, BOOL bCreate )
564 USHORT nPos = 0;
565 switch( nLine )
567 case BOX_LINE_TOP: nPos = 0; break;
568 case BOX_LINE_BOTTOM: nPos = 1; break;
569 case BOX_LINE_LEFT: nPos = 2; break;
570 case BOX_LINE_RIGHT: nPos = 3; break;
573 if( !aBorderInfos[nPos] && bCreate )
574 aBorderInfos[nPos] = new SvxCSS1BorderInfo;
576 return aBorderInfos[nPos];
579 void SvxCSS1PropertyInfo::CopyBorderInfo( USHORT nSrcLine, USHORT nDstLine,
580 USHORT nWhat )
582 SvxCSS1BorderInfo *pSrcInfo = GetBorderInfo( nSrcLine, FALSE );
583 if( !pSrcInfo )
584 return;
586 SvxCSS1BorderInfo *pDstInfo = GetBorderInfo( nDstLine );
587 if( (nWhat & SVX_CSS1_BORDERINFO_WIDTH) != 0 )
589 pDstInfo->nAbsWidth = pSrcInfo->nAbsWidth;
590 pDstInfo->nNamedWidth = pSrcInfo->nNamedWidth;
593 if( (nWhat & SVX_CSS1_BORDERINFO_COLOR) != 0 )
594 pDstInfo->aColor = pSrcInfo->aColor;
596 if( (nWhat & SVX_CSS1_BORDERINFO_STYLE) != 0 )
597 pDstInfo->eStyle = pSrcInfo->eStyle;
600 void SvxCSS1PropertyInfo::CopyBorderInfo( USHORT nCount, USHORT nWhat )
602 if( nCount==0 )
604 CopyBorderInfo( BOX_LINE_BOTTOM, BOX_LINE_TOP, nWhat );
605 CopyBorderInfo( BOX_LINE_TOP, BOX_LINE_LEFT, nWhat );
607 if( nCount<=1 )
609 CopyBorderInfo( BOX_LINE_LEFT, BOX_LINE_RIGHT, nWhat );
613 void SvxCSS1PropertyInfo::SetBoxItem( SfxItemSet& rItemSet,
614 USHORT nMinBorderDist,
615 const SvxBoxItem *pDfltItem,
616 BOOL bTable )
618 BOOL bChg = nTopBorderDistance != USHRT_MAX ||
619 nBottomBorderDistance != USHRT_MAX ||
620 nLeftBorderDistance != USHRT_MAX ||
621 nRightBorderDistance != USHRT_MAX;
622 USHORT i;
624 for( i = 0; !bChg && i < 4; i++ )
625 bChg = aBorderInfos[i]!=0;
627 if( !bChg )
628 return;
630 SvxBoxItem aBoxItem( aItemIds.nBox );
631 if( pDfltItem )
632 aBoxItem = *pDfltItem;
634 SvxCSS1BorderInfo *pInfo = GetBorderInfo( BOX_LINE_TOP, FALSE );
635 if( pInfo )
636 pInfo->SetBorderLine( BOX_LINE_TOP, aBoxItem );
638 pInfo = GetBorderInfo( BOX_LINE_BOTTOM, FALSE );
639 if( pInfo )
640 pInfo->SetBorderLine( BOX_LINE_BOTTOM, aBoxItem );
642 pInfo = GetBorderInfo( BOX_LINE_LEFT, FALSE );
643 if( pInfo )
644 pInfo->SetBorderLine( BOX_LINE_LEFT, aBoxItem );
646 pInfo = GetBorderInfo( BOX_LINE_RIGHT, FALSE );
647 if( pInfo )
648 pInfo->SetBorderLine( BOX_LINE_RIGHT, aBoxItem );
650 for( i=0; i<4; i++ )
652 USHORT nLine = BOX_LINE_TOP, nDist = 0;
653 switch( i )
655 case 0: nLine = BOX_LINE_TOP;
656 nDist = nTopBorderDistance;
657 nTopBorderDistance = USHRT_MAX;
658 break;
659 case 1: nLine = BOX_LINE_BOTTOM;
660 nDist = nBottomBorderDistance;
661 nBottomBorderDistance = USHRT_MAX;
662 break;
663 case 2: nLine = BOX_LINE_LEFT;
664 nDist = nLeftBorderDistance;
665 nLeftBorderDistance = USHRT_MAX;
666 break;
667 case 3: nLine = BOX_LINE_RIGHT;
668 nDist = nRightBorderDistance;
669 nRightBorderDistance = USHRT_MAX;
670 break;
673 if( aBoxItem.GetLine( nLine ) )
675 if( USHRT_MAX == nDist )
676 nDist = aBoxItem.GetDistance( nLine );
678 if( nDist < nMinBorderDist )
679 nDist = nMinBorderDist;
681 else
683 if( USHRT_MAX == nDist )
684 nDist = aBoxItem.GetDistance( nLine );
686 if( !bTable )
687 nDist = 0U;
688 else if( nDist && nDist < nMinBorderDist )
689 nDist = nMinBorderDist;
692 aBoxItem.SetDistance( nDist, nLine );
695 rItemSet.Put( aBoxItem );
697 DestroyBorderInfos();
701 /* \f */
703 SvxCSS1MapEntry::SvxCSS1MapEntry( const String& rKey, const SfxItemSet& rItemSet,
704 const SvxCSS1PropertyInfo& rProp ) :
705 aKey( rKey ),
706 aItemSet( rItemSet ),
707 aPropInfo( rProp )
709 // TODO: ToUpperAscii
710 aKey.ToUpperAscii();
713 #if defined( ICC ) || defined( BLC )
714 BOOL operator==( const SvxCSS1MapEntry& rE1, const SvxCSS1MapEntry& rE2 )
716 return rE1.aKey==rE2.aKey;
719 BOOL operator<( const SvxCSS1MapEntry& rE1, const SvxCSS1MapEntry& rE2 )
721 return rE1.aKey<rE2.aKey;
723 #endif
725 SV_IMPL_OP_PTRARR_SORT( SvxCSS1Map, SvxCSS1MapEntryPtr )
727 /* \f */
729 BOOL SvxCSS1Parser::StyleParsed( const CSS1Selector * /*pSelector*/,
730 SfxItemSet& /*rItemSet*/,
731 SvxCSS1PropertyInfo& /*rPropInfo*/ )
733 // wie man sieht passiert hier gar nichts
734 return TRUE;
737 BOOL SvxCSS1Parser::SelectorParsed( const CSS1Selector *pSelector,
738 BOOL bFirst )
740 if( bFirst )
742 DBG_ASSERT( pSheetItemSet, "Wo ist der Item-Set fuer Style-Sheets?" );
744 // Dieses ist der erste Selektor einer Rule, also muessen
745 // die bisher geparsten Items auf die Styles verteilt werden
746 // pSheetPropInfo->CreateBoxItem( *pSheetItemSet, GetDfltBorderDist() );
747 for( USHORT i=0; i<aSelectors.Count(); i++ )
749 StyleParsed( aSelectors[i], *pSheetItemSet, *pSheetPropInfo );
751 pSheetItemSet->ClearItem();
752 pSheetPropInfo->Clear();
754 // und die naechste Rule vorbereiten
755 if( aSelectors.Count() )
756 aSelectors.DeleteAndDestroy( 0, aSelectors.Count() );
759 aSelectors.C40_INSERT( CSS1Selector, pSelector, aSelectors.Count() );
761 return FALSE; // den Selektor haben wir gespeichert. Loeschen toedlich!
765 BOOL SvxCSS1Parser::DeclarationParsed( const String& rProperty,
766 const CSS1Expression *pExpr )
768 DBG_ASSERT( pExpr, "DeclarationParsed() ohne Expression" );
770 if( !pExpr )
771 return TRUE;
773 ParseProperty( rProperty, pExpr );
775 return TRUE; // die Deklaration brauchen wir nicht mehr. Loeschen!
778 /* \f */
780 SvxCSS1Parser::SvxCSS1Parser( SfxItemPool& rPool, const String& rBaseURL, USHORT nMinFixLineSp,
781 USHORT *pWhichIds, USHORT nWhichIds ) :
782 CSS1Parser(),
783 sBaseURL( rBaseURL ),
784 pSheetItemSet(0),
785 pItemSet(0),
786 pSearchEntry( 0 ),
787 nMinFixLineSpace( nMinFixLineSp ),
788 eDfltEnc( RTL_TEXTENCODING_DONTKNOW ),
789 nScriptFlags( CSS1_SCRIPT_ALL ),
790 bIgnoreFontFamily( FALSE )
792 // Item-Ids auch initialisieren
793 aItemIds.nFont = rPool.GetTrueWhich( SID_ATTR_CHAR_FONT, FALSE );
794 aItemIds.nFontCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_FONT, FALSE );
795 aItemIds.nFontCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_FONT, FALSE );
796 aItemIds.nPosture = rPool.GetTrueWhich( SID_ATTR_CHAR_POSTURE, FALSE );
797 aItemIds.nPostureCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_POSTURE, FALSE );
798 aItemIds.nPostureCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_POSTURE, FALSE );
799 aItemIds.nWeight = rPool.GetTrueWhich( SID_ATTR_CHAR_WEIGHT, FALSE );
800 aItemIds.nWeightCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_WEIGHT, FALSE );
801 aItemIds.nWeightCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_WEIGHT, FALSE );
802 aItemIds.nFontHeight = rPool.GetTrueWhich( SID_ATTR_CHAR_FONTHEIGHT, FALSE );
803 aItemIds.nFontHeightCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT, FALSE );
804 aItemIds.nFontHeightCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT, FALSE );
805 aItemIds.nUnderline = rPool.GetTrueWhich( SID_ATTR_CHAR_UNDERLINE, FALSE );
806 aItemIds.nOverline = rPool.GetTrueWhich( SID_ATTR_CHAR_OVERLINE, FALSE );
807 aItemIds.nCrossedOut = rPool.GetTrueWhich( SID_ATTR_CHAR_STRIKEOUT, FALSE );
808 aItemIds.nColor = rPool.GetTrueWhich( SID_ATTR_CHAR_COLOR, FALSE );
809 aItemIds.nKerning = rPool.GetTrueWhich( SID_ATTR_CHAR_KERNING, FALSE );
810 aItemIds.nCaseMap = rPool.GetTrueWhich( SID_ATTR_CHAR_CASEMAP, FALSE );
811 aItemIds.nBlink = rPool.GetTrueWhich( SID_ATTR_FLASH, FALSE );
813 aItemIds.nLineSpacing = rPool.GetTrueWhich( SID_ATTR_PARA_LINESPACE, FALSE );
814 aItemIds.nAdjust = rPool.GetTrueWhich( SID_ATTR_PARA_ADJUST, FALSE );
815 aItemIds.nWidows = rPool.GetTrueWhich( SID_ATTR_PARA_WIDOWS, FALSE );
816 aItemIds.nOrphans = rPool.GetTrueWhich( SID_ATTR_PARA_ORPHANS, FALSE );
817 aItemIds.nFmtSplit = rPool.GetTrueWhich( SID_ATTR_PARA_SPLIT, FALSE );
819 aItemIds.nLRSpace = rPool.GetTrueWhich( SID_ATTR_LRSPACE, FALSE );
820 aItemIds.nULSpace = rPool.GetTrueWhich( SID_ATTR_ULSPACE, FALSE );
821 aItemIds.nBox = rPool.GetTrueWhich( SID_ATTR_BORDER_OUTER, FALSE );
822 aItemIds.nBrush = rPool.GetTrueWhich( SID_ATTR_BRUSH, FALSE );
824 aItemIds.nLanguage = rPool.GetTrueWhich( SID_ATTR_CHAR_LANGUAGE, FALSE );
825 aItemIds.nLanguageCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_LANGUAGE, FALSE );
826 aItemIds.nLanguageCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_LANGUAGE, FALSE );
827 aItemIds.nDirection = rPool.GetTrueWhich( SID_ATTR_FRAMEDIRECTION, FALSE );
829 aWhichMap.Insert( (USHORT)0, (USHORT)0 );
830 SvParser::BuildWhichTbl( aWhichMap, (USHORT *)&aItemIds,
831 sizeof(aItemIds) / sizeof(USHORT) );
832 if( pWhichIds && nWhichIds )
833 SvParser::BuildWhichTbl( aWhichMap, pWhichIds, nWhichIds );
835 pSheetItemSet = new SfxItemSet( rPool, aWhichMap.GetData() );
836 pSheetPropInfo = new SvxCSS1PropertyInfo;
837 pSearchEntry = new SvxCSS1MapEntry( rPool, aWhichMap.GetData() );
840 SvxCSS1Parser::~SvxCSS1Parser()
842 delete pSheetItemSet;
843 delete pSheetPropInfo;
844 delete pSearchEntry;
848 /* \f */
850 BOOL SvxCSS1Parser::ParseStyleSheet( const String& rIn )
852 pItemSet = pSheetItemSet;
853 pPropInfo = pSheetPropInfo;
855 BOOL bSuccess = CSS1Parser::ParseStyleSheet( rIn );
857 // die bisher geparsten Items auf die Styles verteilt werden
858 // pSheetPropInfo->CreateBoxItem( *pSheetItemSet, GetDfltBorderDist() );
859 for( USHORT i=0; i<aSelectors.Count(); i++ )
861 StyleParsed( aSelectors[i], *pSheetItemSet, *pSheetPropInfo );
864 // und etwas aufrauemen
865 if( aSelectors.Count() )
866 aSelectors.DeleteAndDestroy( 0, aSelectors.Count() );
867 pSheetItemSet->ClearItem();
868 pSheetPropInfo->Clear();
870 pItemSet = 0;
871 pPropInfo = 0;
873 return bSuccess;
876 BOOL SvxCSS1Parser::ParseStyleOption( const String& rIn,
877 SfxItemSet& rItemSet,
878 SvxCSS1PropertyInfo& rPropInfo )
880 pItemSet = &rItemSet;
881 pPropInfo = &rPropInfo;
883 BOOL bSuccess = CSS1Parser::ParseStyleOption( rIn );
884 rItemSet.ClearItem( aItemIds.nDirection );
885 // pPropInfo->CreateBoxItem( *pItemSet, GetDfltBorderDist() );
887 pItemSet = 0;
888 pPropInfo = 0;
890 return bSuccess;
893 /* \f */
895 BOOL SvxCSS1Parser::GetEnum( const CSS1PropertyEnum *pPropTable,
896 const String &rValue, USHORT& rEnum )
898 String aValue( rValue );
899 aValue.ToLowerAscii();
900 while( pPropTable->pName )
902 if( !rValue.EqualsIgnoreCaseAscii( pPropTable->pName ) )
903 pPropTable++;
904 else
905 break;
908 if( pPropTable->pName )
909 rEnum = pPropTable->nEnum;
911 return (pPropTable->pName != 0);
914 void SvxCSS1Parser::PixelToTwip( long &rWidth, long &rHeight )
916 if( Application::GetDefaultDevice() )
918 Size aTwipSz( rWidth, rHeight );
919 aTwipSz = Application::GetDefaultDevice()->PixelToLogic( aTwipSz,
920 MapMode(MAP_TWIP) );
922 rWidth = aTwipSz.Width();
923 rHeight = aTwipSz.Height();
927 void SvxCSS1Parser::SetBorderWidth( SvxBorderLine& aBorderLine, USHORT nWidth,
928 BOOL bDouble, BOOL bTable )
930 const USHORT *aWidths;
931 USHORT nSize;
932 if( !bDouble )
934 aWidths = aSBorderWidths;
935 nSize = sizeof( aSBorderWidths );
937 else if( bTable )
939 aWidths = aTDBorderWidths;
940 nSize = sizeof( aTDBorderWidths );
942 else
944 aWidths = aDBorderWidths;
945 nSize = sizeof( aDBorderWidths );
948 USHORT i = (nSize / sizeof(USHORT)) - 4;
949 while( i>0 &&
950 nWidth <= ((aWidths[i] + aWidths[i-4]) / 2) )
952 DBG_ASSERT( aWidths[i] > aWidths[i-4],
953 "Linienbreiten sind nicht sortiert!" );
954 i -= 4;
957 aBorderLine.SetOutWidth( aWidths[i+1] );
958 aBorderLine.SetInWidth( aWidths[i+2] );
959 aBorderLine.SetDistance( aWidths[i+3] );
962 sal_uInt32 SvxCSS1Parser::GetFontHeight( USHORT nSize ) const
964 USHORT nHeight;
966 switch( nSize )
968 case 0: nHeight = 8*20; break;
969 case 1: nHeight = 10*20; break;
970 case 2: nHeight = 11*20; break;
971 case 3: nHeight = 12*20; break;
972 case 4: nHeight = 17*20; break;
973 case 5: nHeight = 20*20; break;
974 case 6:
975 default: nHeight = 32*20; break;
978 return nHeight;
981 const FontList *SvxCSS1Parser::GetFontList() const
983 return 0;
986 SvxCSS1MapEntry *SvxCSS1Parser::GetMapEntry( const String& rKey,
987 const SvxCSS1Map& rMap ) const
989 pSearchEntry->SetKey( rKey );
991 SvxCSS1MapEntry *pRet = 0;
992 USHORT nPos;
993 if( rMap.Seek_Entry( pSearchEntry, &nPos ) )
994 pRet = rMap[nPos];
996 return pRet;
999 void SvxCSS1Parser::InsertMapEntry( const String& rKey,
1000 const SfxItemSet& rItemSet,
1001 const SvxCSS1PropertyInfo& rProp,
1002 SvxCSS1Map& rMap )
1004 SvxCSS1MapEntry *pEntry = GetMapEntry( rKey, rMap );
1005 if( pEntry )
1007 MergeStyles( rItemSet, rProp,
1008 pEntry->GetItemSet(), pEntry->GetPropertyInfo(), TRUE );
1010 else
1012 rMap.Insert( new SvxCSS1MapEntry( rKey, rItemSet, rProp ) );
1017 void SvxCSS1Parser::MergeStyles( const SfxItemSet& rSrcSet,
1018 const SvxCSS1PropertyInfo& rSrcInfo,
1019 SfxItemSet& rTargetSet,
1020 SvxCSS1PropertyInfo& rTargetInfo,
1021 BOOL bSmart )
1023 if( !bSmart )
1025 rTargetSet.Put( rSrcSet );
1027 else
1029 SvxLRSpaceItem aLRSpace( (const SvxLRSpaceItem&)rTargetSet.Get(aItemIds.nLRSpace) );
1030 SvxULSpaceItem aULSpace( (const SvxULSpaceItem&)rTargetSet.Get(aItemIds.nULSpace) );
1031 SvxBoxItem aBox( (const SvxBoxItem&)rTargetSet.Get(aItemIds.nBox) );
1033 rTargetSet.Put( rSrcSet );
1035 if( rSrcInfo.bLeftMargin || rSrcInfo.bRightMargin ||
1036 rSrcInfo.bTextIndent )
1038 const SvxLRSpaceItem& rNewLRSpace =
1039 (const SvxLRSpaceItem&)rSrcSet.Get( aItemIds.nLRSpace );
1041 if( rSrcInfo.bLeftMargin )
1042 aLRSpace.SetLeft( rNewLRSpace.GetLeft() );
1043 if( rSrcInfo.bRightMargin )
1044 aLRSpace.SetRight( rNewLRSpace.GetRight() );
1045 if( rSrcInfo.bTextIndent )
1046 aLRSpace.SetTxtFirstLineOfst( rNewLRSpace.GetTxtFirstLineOfst() );
1048 rTargetSet.Put( aLRSpace );
1051 if( rSrcInfo.bTopMargin || rSrcInfo.bBottomMargin )
1053 const SvxULSpaceItem& rNewULSpace =
1054 (const SvxULSpaceItem&)rSrcSet.Get( aItemIds.nULSpace );
1056 if( rSrcInfo.bTopMargin )
1057 aULSpace.SetUpper( rNewULSpace.GetUpper() );
1058 if( rSrcInfo.bBottomMargin )
1059 aULSpace.SetLower( rNewULSpace.GetLower() );
1061 rTargetSet.Put( aULSpace );
1065 rTargetInfo.Merge( rSrcInfo );
1068 void SvxCSS1Parser::SetDfltEncoding( rtl_TextEncoding eEnc )
1070 eDfltEnc = eEnc;
1073 /* \f */
1075 static void ParseCSS1_font_size( const CSS1Expression *pExpr,
1076 SfxItemSet &rItemSet,
1077 SvxCSS1PropertyInfo& /*rPropInfo*/,
1078 const SvxCSS1Parser& rParser )
1080 DBG_ASSERT( pExpr, "kein Ausdruck" );
1082 ULONG nHeight = 0;
1083 USHORT nPropHeight = 100;
1085 switch( pExpr->GetType() )
1087 case CSS1_LENGTH:
1088 nHeight = pExpr->GetULength();
1089 break;
1090 case CSS1_PIXLENGTH:
1092 long nPWidth = 0;
1093 long nPHeight = (long)pExpr->GetNumber();
1094 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
1095 nHeight = (ULONG)nPHeight;
1097 break;
1098 //#ifdef PERCENTAGE_POSSIBLE
1099 case CSS1_PERCENTAGE:
1100 // nur fuer Drop-Caps!
1101 nPropHeight = (USHORT)pExpr->GetNumber();
1102 break;
1103 //#endif
1104 case CSS1_IDENT:
1106 USHORT nSize;
1107 #ifdef PERCENTAGE_POSSIBLE
1108 const String& rValue = pExpr->GetString();
1109 #endif
1110 if( SvxCSS1Parser::GetEnum( aFontSizeTable, pExpr->GetString(),
1111 nSize ) )
1113 nHeight = rParser.GetFontHeight( nSize );
1115 #ifdef PERCENTAGE_POSSIBLE
1116 else if( rValue.EqualsIgnoreCaseAscii( sCSS1_PV_larger ) )
1118 nPropHeight = 150;
1120 else if( rValue.EqualsIgnoreCaseAscii( sCSS1_PV_smaller ) )
1122 nPropHeight = 67;
1124 #endif
1126 break;
1128 default:
1132 if( nHeight || nPropHeight!=100 )
1134 SvxFontHeightItem aFontHeight( nHeight, nPropHeight,
1135 aItemIds.nFontHeight );
1136 if( rParser.IsSetWesternProps() )
1137 rItemSet.Put( aFontHeight );
1138 if( rParser.IsSetCJKProps() )
1140 aFontHeight.SetWhich( aItemIds.nFontHeightCJK );
1141 rItemSet.Put( aFontHeight );
1143 if( rParser.IsSetCTLProps() )
1145 aFontHeight.SetWhich( aItemIds.nFontHeightCTL );
1146 rItemSet.Put( aFontHeight );
1151 /* \f */
1154 static void ParseCSS1_font_family( const CSS1Expression *pExpr,
1155 SfxItemSet &rItemSet,
1156 SvxCSS1PropertyInfo& /*rPropInfo*/,
1157 const SvxCSS1Parser& rParser )
1159 DBG_ASSERT( pExpr, "kein Ausdruck" );
1161 String aName, aStyleName, aDfltName;
1162 FontFamily eFamily = FAMILY_DONTKNOW;
1163 FontPitch ePitch = PITCH_DONTKNOW;
1164 rtl_TextEncoding eEnc = rParser.GetDfltEncoding();
1165 const FontList *pFList = rParser.GetFontList();
1166 BOOL bFirst = TRUE;
1167 BOOL bFound = FALSE;
1168 while( pExpr && (bFirst || ','==pExpr->GetOp() || !pExpr->GetOp()) )
1170 CSS1Token eType = pExpr->GetType();
1171 if( CSS1_IDENT==eType || CSS1_STRING==eType )
1173 String aIdent( pExpr->GetString() );
1175 if( CSS1_IDENT==eType )
1177 // Alle nachfolgenden id's sammeln und mit einem
1178 // Space getrennt hintendranhaengen
1179 const CSS1Expression *pNext = pExpr->GetNext();
1180 while( pNext && !pNext->GetOp() &&
1181 CSS1_IDENT==pNext->GetType() )
1183 (aIdent += ' ') += pNext->GetString();
1184 pExpr = pNext;
1185 pNext = pExpr->GetNext();
1188 if( aIdent.Len() )
1190 if( !bFound && pFList )
1192 sal_Handle hFont = pFList->GetFirstFontInfo( aIdent );
1193 if( 0 != hFont )
1195 const FontInfo& rFInfo = pFList->GetFontInfo( hFont );
1196 if( RTL_TEXTENCODING_DONTKNOW != rFInfo.GetCharSet() )
1198 bFound = TRUE;
1199 if( RTL_TEXTENCODING_SYMBOL == rFInfo.GetCharSet() )
1200 eEnc = RTL_TEXTENCODING_SYMBOL;
1204 if( !bFirst )
1205 aName += ';';
1206 aName += aIdent;
1210 pExpr = pExpr->GetNext();
1211 bFirst = FALSE;
1214 if( aName.Len() && !rParser.IsIgnoreFontFamily() )
1216 SvxFontItem aFont( eFamily, aName, aStyleName, ePitch,
1217 eEnc, aItemIds.nFont );
1218 if( rParser.IsSetWesternProps() )
1219 rItemSet.Put( aFont );
1220 if( rParser.IsSetCJKProps() )
1222 aFont.SetWhich( aItemIds.nFontCJK );
1223 rItemSet.Put( aFont );
1225 if( rParser.IsSetCTLProps() )
1227 aFont.SetWhich( aItemIds.nFontCTL );
1228 rItemSet.Put( aFont );
1233 /* \f */
1235 static void ParseCSS1_font_weight( const CSS1Expression *pExpr,
1236 SfxItemSet &rItemSet,
1237 SvxCSS1PropertyInfo& /*rPropInfo*/,
1238 const SvxCSS1Parser& rParser )
1240 DBG_ASSERT( pExpr, "kein Ausdruck" );
1242 switch( pExpr->GetType() )
1244 case CSS1_IDENT:
1245 case CSS1_STRING: // MS-IE, was sonst
1247 USHORT nWeight;
1248 if( SvxCSS1Parser::GetEnum( aFontWeightTable, pExpr->GetString(),
1249 nWeight ) )
1251 SvxWeightItem aWeight( (FontWeight)nWeight, aItemIds.nWeight );
1252 if( rParser.IsSetWesternProps() )
1253 rItemSet.Put( aWeight );
1254 if( rParser.IsSetCJKProps() )
1256 aWeight.SetWhich( aItemIds.nWeightCJK );
1257 rItemSet.Put( aWeight );
1259 if( rParser.IsSetCTLProps() )
1261 aWeight.SetWhich( aItemIds.nWeightCTL );
1262 rItemSet.Put( aWeight );
1266 break;
1267 case CSS1_NUMBER:
1269 USHORT nWeight = (USHORT)pExpr->GetNumber();
1270 SvxWeightItem aWeight( nWeight>400 ? WEIGHT_BOLD : WEIGHT_NORMAL,
1271 aItemIds.nWeight );
1272 if( rParser.IsSetWesternProps() )
1273 rItemSet.Put( aWeight );
1274 if( rParser.IsSetCJKProps() )
1276 aWeight.SetWhich( aItemIds.nWeightCJK );
1277 rItemSet.Put( aWeight );
1279 if( rParser.IsSetCTLProps() )
1281 aWeight.SetWhich( aItemIds.nWeightCTL );
1282 rItemSet.Put( aWeight );
1285 break;
1287 default:
1292 /* \f */
1294 static void ParseCSS1_font_style( const CSS1Expression *pExpr,
1295 SfxItemSet &rItemSet,
1296 SvxCSS1PropertyInfo& /*rPropInfo*/,
1297 const SvxCSS1Parser& rParser )
1299 DBG_ASSERT( pExpr, "kein Ausdruck" );
1301 BOOL bPosture = FALSE;
1302 BOOL bCaseMap = FALSE;
1303 FontItalic eItalic = ITALIC_NONE;
1304 SvxCaseMap eCaseMap = SVX_CASEMAP_NOT_MAPPED;
1306 // normal | italic || small-caps | oblique || small-caps | small-caps
1307 // (wobei nor noch normal | italic und oblique zulaessig sind
1309 // der Wert kann zwei Werte enthalten!
1310 for( USHORT i=0; pExpr && i<2; i++ )
1312 // Auch hier hinterlaesst MS-IEs Parser seine Spuren
1313 if( (CSS1_IDENT==pExpr->GetType() || CSS1_STRING==pExpr->GetType()) &&
1314 !pExpr->GetOp() )
1316 const String& rValue = pExpr->GetString();
1317 // erstmal pruefen, ob es ein Italic-Wert oder 'normal' ist
1318 USHORT nItalic;
1319 if( SvxCSS1Parser::GetEnum( aFontStyleTable, rValue, nItalic ) )
1321 eItalic = (FontItalic)nItalic;
1322 if( !bCaseMap && ITALIC_NONE==eItalic )
1324 // fuer 'normal' muessen wir auch die case-map aussch.
1325 eCaseMap = SVX_CASEMAP_NOT_MAPPED;
1326 bCaseMap = TRUE;
1328 bPosture = TRUE;
1330 else if( !bCaseMap &&
1331 rValue.EqualsIgnoreCaseAscii(sCSS1_PV_small_caps) )
1333 eCaseMap = SVX_CASEMAP_KAPITAELCHEN;
1334 bCaseMap = TRUE;
1338 // den naechsten Ausdruck holen
1339 pExpr = pExpr->GetNext();
1342 if( bPosture )
1344 SvxPostureItem aPosture( eItalic, aItemIds.nPosture );
1345 if( rParser.IsSetWesternProps() )
1346 rItemSet.Put( aPosture );
1347 if( rParser.IsSetCJKProps() )
1349 aPosture.SetWhich( aItemIds.nPostureCJK );
1350 rItemSet.Put( aPosture );
1352 if( rParser.IsSetCTLProps() )
1354 aPosture.SetWhich( aItemIds.nPostureCTL );
1355 rItemSet.Put( aPosture );
1359 if( bCaseMap )
1360 rItemSet.Put( SvxCaseMapItem( eCaseMap, aItemIds.nCaseMap ) );
1363 /* \f */
1365 static void ParseCSS1_font_variant( const CSS1Expression *pExpr,
1366 SfxItemSet &rItemSet,
1367 SvxCSS1PropertyInfo& /*rPropInfo*/,
1368 const SvxCSS1Parser& /*rParser*/ )
1370 DBG_ASSERT( pExpr, "kein Ausdruck" );
1372 // normal | small-caps
1374 switch( pExpr->GetType() )
1376 case CSS1_IDENT:
1378 USHORT nCaseMap;
1379 if( SvxCSS1Parser::GetEnum( aFontVariantTable, pExpr->GetString(),
1380 nCaseMap ) )
1382 rItemSet.Put( SvxCaseMapItem( (SvxCaseMap)nCaseMap,
1383 aItemIds.nCaseMap ) );
1386 default:
1391 /* \f */
1393 static void ParseCSS1_color( const CSS1Expression *pExpr,
1394 SfxItemSet &rItemSet,
1395 SvxCSS1PropertyInfo& /*rPropInfo*/,
1396 const SvxCSS1Parser& /*rParser*/ )
1398 DBG_ASSERT( pExpr, "kein Ausdruck" );
1400 switch( pExpr->GetType() )
1402 case CSS1_IDENT:
1403 case CSS1_RGB:
1404 case CSS1_HEXCOLOR:
1405 case CSS1_STRING: // Wegen MS-IE
1407 Color aColor;
1408 if( pExpr->GetColor( aColor ) )
1409 rItemSet.Put( SvxColorItem( aColor, aItemIds.nColor ) );
1411 break;
1412 default:
1417 static void ParseCSS1_direction( const CSS1Expression *pExpr,
1418 SfxItemSet &rItemSet,
1419 SvxCSS1PropertyInfo& /*rPropInfo*/,
1420 const SvxCSS1Parser& /*rParser*/ )
1422 DBG_ASSERT( pExpr, "kein Ausdruck" );
1424 sal_uInt16 nDir;
1425 switch( pExpr->GetType() )
1427 case CSS1_IDENT:
1428 case CSS1_STRING:
1429 if( SvxCSS1Parser::GetEnum( aDirectionTable, pExpr->GetString(),
1430 nDir ) )
1432 rItemSet.Put( SvxFrameDirectionItem(
1433 static_cast < SvxFrameDirection >( nDir ),
1434 aItemIds.nDirection ) );
1436 break;
1437 default:
1442 /* \f */
1444 static void MergeHori( SvxGraphicPosition& ePos, SvxGraphicPosition eHori )
1446 DBG_ASSERT( GPOS_LT==eHori || GPOS_MT==eHori || GPOS_RT==eHori,
1447 "vertikale Position nicht oben" );
1449 switch( ePos )
1451 case GPOS_LT:
1452 case GPOS_MT:
1453 case GPOS_RT:
1454 ePos = eHori;
1455 break;
1457 case GPOS_LM:
1458 case GPOS_MM:
1459 case GPOS_RM:
1460 ePos = GPOS_LT==eHori ? GPOS_LM : (GPOS_MT==eHori ? GPOS_MM : GPOS_RM);
1461 break;
1463 case GPOS_LB:
1464 case GPOS_MB:
1465 case GPOS_RB:
1466 ePos = GPOS_LT==eHori ? GPOS_LB : (GPOS_MT==eHori ? GPOS_MB : GPOS_RB);
1467 break;
1469 default:
1474 static void MergeVert( SvxGraphicPosition& ePos, SvxGraphicPosition eVert )
1476 DBG_ASSERT( GPOS_LT==eVert || GPOS_LM==eVert || GPOS_LB==eVert,
1477 "horizontale Position nicht links" );
1479 switch( ePos )
1481 case GPOS_LT:
1482 case GPOS_LM:
1483 case GPOS_LB:
1484 ePos = eVert;
1485 break;
1487 case GPOS_MT:
1488 case GPOS_MM:
1489 case GPOS_MB:
1490 ePos = GPOS_LT==eVert ? GPOS_MT : (GPOS_LM==eVert ? GPOS_MM : GPOS_MB);
1491 break;
1493 case GPOS_RT:
1494 case GPOS_RM:
1495 case GPOS_RB:
1496 ePos = GPOS_LT==eVert ? GPOS_RT : (GPOS_LM==eVert ? GPOS_RM : GPOS_RB);
1497 break;
1499 default:
1504 static void ParseCSS1_background( const CSS1Expression *pExpr,
1505 SfxItemSet &rItemSet,
1506 SvxCSS1PropertyInfo& /*rPropInfo*/,
1507 const SvxCSS1Parser& rParser )
1509 DBG_ASSERT( pExpr, "kein Ausdruck" );
1511 Color aColor;
1512 String aURL;
1514 BOOL bColor = FALSE, bTransparent = FALSE;
1515 SvxGraphicPosition eRepeat = GPOS_TILED;
1516 SvxGraphicPosition ePos = GPOS_LT;
1517 BOOL bHori = FALSE, bVert = FALSE;
1519 while( pExpr && !pExpr->GetOp() )
1521 switch( pExpr->GetType() )
1523 case CSS1_URL:
1524 pExpr->GetURL( aURL );
1525 break;
1527 case CSS1_RGB:
1528 bColor = pExpr->GetColor( aColor );
1529 break;
1531 case CSS1_LENGTH:
1532 case CSS1_PIXLENGTH:
1534 // da wir keine absolute Positionierung koennen,
1535 // unterscheiden wir nur zwischen 0 und !0. Deshalb
1536 // koennen Pixel auch wie alle anderen Einheiten behandelt
1537 // werden.
1539 ULONG nLength = (ULONG)pExpr->GetNumber();
1540 if( !bHori )
1542 ePos = nLength ? GPOS_MM : GPOS_LT;
1543 bHori = TRUE;
1545 else if( !bVert )
1547 MergeVert( ePos, (nLength ? GPOS_LM : GPOS_LT) );
1548 bVert = TRUE;
1551 break;
1553 case CSS1_PERCENTAGE:
1555 // die %-Angabe wird auf den enum abgebildet
1557 USHORT nPerc = (USHORT)pExpr->GetNumber();
1558 if( !bHori )
1560 ePos = nPerc < 25 ? GPOS_LT
1561 : (nPerc < 75 ? GPOS_MM
1562 : GPOS_RB);
1564 else if( !bVert )
1566 SvxGraphicPosition eVert =
1567 nPerc < 25 ? GPOS_LT: (nPerc < 75 ? GPOS_LM
1568 : GPOS_LB);
1569 MergeVert( ePos, eVert );
1572 break;
1574 case CSS1_IDENT:
1575 case CSS1_HEXCOLOR:
1576 case CSS1_STRING: // Wegen MS-IE
1578 USHORT nEnum;
1579 const String &rValue = pExpr->GetString();
1580 if( rValue.EqualsIgnoreCaseAscii( sCSS1_PV_transparent ) )
1582 bTransparent = TRUE;
1584 if( SvxCSS1Parser::GetEnum( aBGRepeatTable, rValue, nEnum ) )
1586 eRepeat = (SvxGraphicPosition)nEnum;
1588 else if( SvxCSS1Parser::GetEnum( aBGHoriPosTable, rValue, nEnum ) )
1590 // <position>, horizontal
1591 MergeHori( ePos, (SvxGraphicPosition)nEnum );
1593 else if( SvxCSS1Parser::GetEnum( aBGVertPosTable, rValue, nEnum ) )
1595 // <position>, vertikal
1596 MergeVert( ePos, (SvxGraphicPosition)nEnum );
1598 else if( !bColor )
1600 // <color>
1601 bColor = pExpr->GetColor( aColor );
1603 // <scroll> kennen wir nicht
1605 break;
1607 default:
1611 pExpr = pExpr->GetNext();
1614 // transparent schlaegt alles
1615 if( bTransparent )
1617 bColor = FALSE;
1618 aURL.Erase();
1621 // repeat hat prio gegenueber einer Position
1622 if( GPOS_NONE == eRepeat )
1623 eRepeat = ePos;
1625 if( bTransparent || bColor || aURL.Len() )
1627 SvxBrushItem aBrushItem( aItemIds.nBrush );
1629 if( bTransparent )
1630 aBrushItem.SetColor( Color(COL_TRANSPARENT));
1631 else if( bColor )
1632 aBrushItem.SetColor( aColor );
1634 if( aURL.Len() )
1636 aBrushItem.SetGraphicLink( URIHelper::SmartRel2Abs( INetURLObject( rParser.GetBaseURL()), aURL, Link(), false ) );
1637 aBrushItem.SetGraphicPos( eRepeat );
1640 rItemSet.Put( aBrushItem );
1644 static void ParseCSS1_background_color( const CSS1Expression *pExpr,
1645 SfxItemSet &rItemSet,
1646 SvxCSS1PropertyInfo& /*rPropInfo*/,
1647 const SvxCSS1Parser& /*rParser*/ )
1649 DBG_ASSERT( pExpr, "kein Ausdruck" );
1651 Color aColor;
1653 BOOL bColor = FALSE, bTransparent = FALSE;
1655 switch( pExpr->GetType() )
1657 case CSS1_RGB:
1658 bColor = pExpr->GetColor( aColor );
1659 break;
1660 case CSS1_IDENT:
1661 case CSS1_HEXCOLOR:
1662 case CSS1_STRING: // Wegen MS-IE
1663 if( pExpr->GetString().EqualsIgnoreCaseAscii( sCSS1_PV_transparent ) )
1665 bTransparent = TRUE;
1667 else
1669 // <color>
1670 bColor = pExpr->GetColor( aColor );
1672 break;
1673 default:
1677 if( bTransparent || bColor )
1679 SvxBrushItem aBrushItem( aItemIds.nBrush );
1681 if( bTransparent )
1682 aBrushItem.SetColor( Color(COL_TRANSPARENT) );
1683 else if( bColor )
1684 aBrushItem.SetColor( aColor);
1686 rItemSet.Put( aBrushItem );
1690 /* \f */
1692 static void ParseCSS1_line_height( const CSS1Expression *pExpr,
1693 SfxItemSet &rItemSet,
1694 SvxCSS1PropertyInfo& /*rPropInfo*/,
1695 const SvxCSS1Parser& rParser )
1697 DBG_ASSERT( pExpr, "kein Ausdruck" );
1699 USHORT nHeight = 0;
1700 BYTE nPropHeight = 0;
1702 switch( pExpr->GetType() )
1704 case CSS1_LENGTH:
1705 nHeight = (USHORT)pExpr->GetULength();
1706 break;
1707 case CSS1_PIXLENGTH:
1709 long nPWidth = 0;
1710 long nPHeight = (long)pExpr->GetNumber();
1711 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
1712 nHeight = (USHORT)nPHeight;
1714 break;
1715 case CSS1_PERCENTAGE:
1717 USHORT nPHeight = (USHORT)pExpr->GetNumber();
1718 nPropHeight = nPHeight <= 200 ? (BYTE)nPHeight : 200;
1720 break;
1721 case CSS1_NUMBER:
1723 USHORT nPHeight = (USHORT)(pExpr->GetNumber() * 100);
1724 nPropHeight = nPHeight <= 200 ? (BYTE)nPHeight : 200;
1726 break;
1727 default:
1731 if( nHeight )
1733 if( nHeight < rParser.GetMinFixLineSpace() )
1734 nHeight = rParser.GetMinFixLineSpace();
1735 SvxLineSpacingItem aLSItem( nHeight, aItemIds.nLineSpacing );
1736 aLSItem.SetLineHeight( nHeight );
1737 // --> OD 2006-07-26 #138463#
1738 // interpret <line-height> attribute as minimum line height
1739 aLSItem.GetLineSpaceRule() = SVX_LINE_SPACE_MIN;
1740 // <--
1741 aLSItem.GetInterLineSpaceRule() = SVX_INTER_LINE_SPACE_OFF;
1742 rItemSet.Put( aLSItem );
1744 else if( nPropHeight )
1746 SvxLineSpacingItem aLSItem( nPropHeight, aItemIds.nLineSpacing );
1747 aLSItem.GetLineSpaceRule() = SVX_LINE_SPACE_AUTO;
1748 if( 100 == nPropHeight )
1749 aLSItem.GetInterLineSpaceRule() = SVX_INTER_LINE_SPACE_OFF;
1750 else
1751 aLSItem.SetPropLineSpace( nPropHeight );
1752 rItemSet.Put( aLSItem );
1757 /* \f */
1759 static void ParseCSS1_font( const CSS1Expression *pExpr,
1760 SfxItemSet &rItemSet,
1761 SvxCSS1PropertyInfo& rPropInfo,
1762 const SvxCSS1Parser& rParser )
1764 DBG_ASSERT( pExpr, "kein Ausdruck" );
1766 FontItalic eItalic = ITALIC_NONE;
1767 SvxCaseMap eCaseMap = SVX_CASEMAP_NOT_MAPPED;
1768 FontWeight eWeight = WEIGHT_NORMAL;
1770 // [ <font-style> || <font-variant> || <font-weight> ] ?
1771 while( pExpr && !pExpr->GetOp() &&
1772 (CSS1_IDENT==pExpr->GetType() ||
1773 CSS1_STRING==pExpr->GetType() ||
1774 CSS1_NUMBER==pExpr->GetType()) )
1776 if( CSS1_IDENT==pExpr->GetType() ||
1777 CSS1_STRING==pExpr->GetType() )
1779 const String& rValue = pExpr->GetString();
1781 USHORT nEnum;
1783 if( SvxCSS1Parser::GetEnum( aFontStyleTable, rValue, nEnum ) )
1785 eItalic = (FontItalic)nEnum;
1787 else if( SvxCSS1Parser::GetEnum( aFontVariantTable, rValue, nEnum ) )
1789 eCaseMap = (SvxCaseMap)nEnum;
1791 else if( SvxCSS1Parser::GetEnum( aFontWeightTable, rValue, nEnum ) )
1793 eWeight = (FontWeight)nEnum;
1796 else
1798 eWeight = (USHORT)pExpr->GetNumber() > 400 ? WEIGHT_BOLD
1799 : WEIGHT_NORMAL;
1802 pExpr = pExpr->GetNext();
1805 if( !pExpr || pExpr->GetOp() )
1806 return;
1808 // Da "font" alle Werte zurecksetzt, fuer die nichts angegeben ist,
1809 // tun wir das hier.
1810 SvxPostureItem aPosture( eItalic, aItemIds.nPosture );
1811 if( rParser.IsSetWesternProps() )
1812 rItemSet.Put( aPosture );
1813 if( rParser.IsSetCJKProps() )
1815 aPosture.SetWhich( aItemIds.nPostureCJK );
1816 rItemSet.Put( aPosture );
1818 if( rParser.IsSetCTLProps() )
1820 aPosture.SetWhich( aItemIds.nPostureCTL );
1821 rItemSet.Put( aPosture );
1824 rItemSet.Put( SvxCaseMapItem( eCaseMap, aItemIds.nCaseMap ) );
1826 SvxWeightItem aWeight( eWeight, aItemIds.nWeight );
1827 if( rParser.IsSetWesternProps() )
1828 rItemSet.Put( aWeight );
1829 if( rParser.IsSetCJKProps() )
1831 aWeight.SetWhich( aItemIds.nWeightCJK );
1832 rItemSet.Put( aWeight );
1834 if( rParser.IsSetCTLProps() )
1836 aWeight.SetWhich( aItemIds.nWeightCTL );
1837 rItemSet.Put( aWeight );
1841 // font-size
1842 CSS1Expression aExpr( pExpr->GetType(), pExpr->GetString(),
1843 pExpr->GetNumber() );
1844 ParseCSS1_font_size( &aExpr, rItemSet, rPropInfo, rParser );
1845 pExpr = pExpr->GetNext();
1847 if( !pExpr )
1848 return;
1850 // [ '/' line-height ]?
1851 if( '/' == pExpr->GetOp() )
1853 // '/' line-height
1854 aExpr.Set( pExpr->GetType(), pExpr->GetString(), pExpr->GetNumber() );
1855 ParseCSS1_line_height( &aExpr, rItemSet, rPropInfo, rParser );
1857 pExpr = pExpr->GetNext();
1860 if( !pExpr || pExpr->GetOp() )
1861 return;
1863 // font-family
1864 ParseCSS1_font_family( pExpr, rItemSet, rPropInfo, rParser );
1867 /* \f */
1869 static void ParseCSS1_letter_spacing( const CSS1Expression *pExpr,
1870 SfxItemSet &rItemSet,
1871 SvxCSS1PropertyInfo& /*rPropInfo*/,
1872 const SvxCSS1Parser& /*rParser*/ )
1874 DBG_ASSERT( pExpr, "kein Ausdruck" );
1876 switch( pExpr->GetType() )
1878 case CSS1_LENGTH:
1879 rItemSet.Put( SvxKerningItem( (short)pExpr->GetSLength(),
1880 aItemIds.nKerning ) );
1881 break;
1883 case CSS1_PIXLENGTH:
1885 long nPWidth = (long)pExpr->GetNumber();
1886 long nPHeight = 0;
1887 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
1888 rItemSet.Put( SvxKerningItem( (short)nPWidth, aItemIds.nKerning ) );
1890 break;
1892 case CSS1_NUMBER:
1893 if( pExpr->GetNumber() == 0 )
1895 // eigentlich unnoetig, aber wir sind ja tollerant
1896 rItemSet.Put( SvxKerningItem( (short)0, aItemIds.nKerning ) );
1898 break;
1900 case CSS1_IDENT:
1901 case CSS1_STRING: // Vorschtshalber auch MS-IE
1902 if( pExpr->GetString().EqualsIgnoreCaseAscii(sCSS1_PV_normal) )
1904 rItemSet.Put( SvxKerningItem( (short)0, aItemIds.nKerning ) );
1906 break;
1907 default:
1912 /* \f */
1914 static void ParseCSS1_text_decoration( const CSS1Expression *pExpr,
1915 SfxItemSet &rItemSet,
1916 SvxCSS1PropertyInfo& /*rPropInfo*/,
1917 const SvxCSS1Parser& /*rParser*/ )
1919 DBG_ASSERT( pExpr, "kein Ausdruck" );
1921 BOOL bUnderline = FALSE;
1922 BOOL bOverline = FALSE;
1923 BOOL bCrossedOut = FALSE;
1924 BOOL bBlink = FALSE;
1925 BOOL bBlinkOn = FALSE;
1926 FontUnderline eUnderline = UNDERLINE_NONE;
1927 FontUnderline eOverline = UNDERLINE_NONE;
1928 FontStrikeout eCrossedOut = STRIKEOUT_NONE;
1930 // der Wert kann zwei Werte enthalten! Und MS-IE auch Strings
1931 while( pExpr && (pExpr->GetType() == CSS1_IDENT ||
1932 pExpr->GetType() == CSS1_STRING) && !pExpr->GetOp() )
1934 String aValue = pExpr->GetString();
1935 aValue.ToLowerAscii();
1936 BOOL bKnown = FALSE;
1938 switch( aValue.GetChar( 0 ) )
1940 case 'n':
1941 if( aValue.EqualsAscii( sCSS1_PV_none ) )
1943 bUnderline = TRUE;
1944 eUnderline = UNDERLINE_NONE;
1946 bOverline = TRUE;
1947 eOverline = UNDERLINE_NONE;
1949 bCrossedOut = TRUE;
1950 eCrossedOut = STRIKEOUT_NONE;
1952 bBlink = TRUE;
1953 bBlinkOn = FALSE;
1955 bKnown = TRUE;
1957 break;
1959 case 'u':
1960 if( aValue.EqualsAscii( sCSS1_PV_underline ) )
1962 bUnderline = TRUE;
1963 eUnderline = UNDERLINE_SINGLE;
1965 bKnown = TRUE;
1967 break;
1969 case 'o':
1970 if( aValue.EqualsAscii( sCSS1_PV_overline ) )
1972 bOverline = TRUE;
1973 eOverline = UNDERLINE_SINGLE;
1975 bKnown = TRUE;
1977 break;
1979 case 'l':
1980 if( aValue.EqualsAscii( sCSS1_PV_line_through ) )
1982 bCrossedOut = TRUE;
1983 eCrossedOut = STRIKEOUT_SINGLE;
1985 bKnown = TRUE;
1987 break;
1989 case 'b':
1990 if( aValue.EqualsAscii( sCSS1_PV_blink ) )
1992 bBlink = TRUE;
1993 bBlinkOn = TRUE;
1995 bKnown = TRUE;
1997 break;
2000 if( !bKnown )
2002 bUnderline = TRUE;
2003 eUnderline = UNDERLINE_SINGLE;
2006 pExpr = pExpr->GetNext();
2009 if( bUnderline )
2010 rItemSet.Put( SvxUnderlineItem( eUnderline, aItemIds.nUnderline ) );
2012 if( bOverline )
2013 rItemSet.Put( SvxOverlineItem( eOverline, aItemIds.nOverline ) );
2015 if( bCrossedOut )
2016 rItemSet.Put( SvxCrossedOutItem( eCrossedOut, aItemIds.nCrossedOut ) );
2018 if( bBlink )
2019 rItemSet.Put( SvxBlinkItem( bBlinkOn, aItemIds.nBlink ) );
2022 /* \f */
2024 static void ParseCSS1_text_align( const CSS1Expression *pExpr,
2025 SfxItemSet &rItemSet,
2026 SvxCSS1PropertyInfo& /*rPropInfo*/,
2027 const SvxCSS1Parser& /*rParser*/ )
2029 DBG_ASSERT( pExpr, "kein Ausdruck" );
2031 if( CSS1_IDENT==pExpr->GetType() ||
2032 CSS1_STRING==pExpr->GetType() ) // MS-IE, mal wieder
2034 USHORT nAdjust;
2035 if( SvxCSS1Parser::GetEnum( aTextAlignTable, pExpr->GetString(),
2036 nAdjust ) )
2038 rItemSet.Put( SvxAdjustItem( (SvxAdjust)nAdjust,
2039 aItemIds.nAdjust ) );
2044 /* \f */
2046 static void ParseCSS1_text_indent( const CSS1Expression *pExpr,
2047 SfxItemSet &rItemSet,
2048 SvxCSS1PropertyInfo& rPropInfo,
2049 const SvxCSS1Parser& /*rParser*/ )
2051 DBG_ASSERT( pExpr, "kein Ausdruck" );
2053 short nIndent = 0;
2054 BOOL bSet = FALSE;
2055 switch( pExpr->GetType() )
2057 case CSS1_LENGTH:
2058 nIndent = (short)pExpr->GetSLength();
2059 bSet = TRUE;
2060 break;
2061 case CSS1_PIXLENGTH:
2063 long nPWidth = (long)pExpr->GetNumber();
2064 long nPHeight = 0;
2065 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2066 nIndent = (short)nPWidth;
2067 bSet = TRUE;
2069 break;
2070 case CSS1_PERCENTAGE:
2071 // koennen wir nicht
2072 break;
2073 default:
2077 if( bSet )
2079 const SfxPoolItem* pItem;
2080 if( SFX_ITEM_SET == rItemSet.GetItemState( aItemIds.nLRSpace, FALSE,
2081 &pItem ) )
2083 SvxLRSpaceItem aLRItem( *((const SvxLRSpaceItem*)pItem) );
2084 aLRItem.SetTxtFirstLineOfst( nIndent );
2085 rItemSet.Put( aLRItem );
2087 else
2089 SvxLRSpaceItem aLRItem( aItemIds.nLRSpace );
2090 aLRItem.SetTxtFirstLineOfst( nIndent );
2091 rItemSet.Put( aLRItem );
2093 rPropInfo.bTextIndent = TRUE;
2097 /* \f */
2099 static void ParseCSS1_margin_left( const CSS1Expression *pExpr,
2100 SfxItemSet &rItemSet,
2101 SvxCSS1PropertyInfo& rPropInfo,
2102 const SvxCSS1Parser& /*rParser*/ )
2104 DBG_ASSERT( pExpr, "kein Ausdruck" );
2106 long nLeft = 0;
2107 BOOL bSet = FALSE;
2108 switch( pExpr->GetType() )
2110 case CSS1_LENGTH:
2112 nLeft = pExpr->GetSLength();
2113 bSet = TRUE;
2115 break;
2116 case CSS1_PIXLENGTH:
2118 nLeft = (long)pExpr->GetNumber();
2119 long nPHeight = 0;
2120 SvxCSS1Parser::PixelToTwip( nLeft, nPHeight );
2121 bSet = TRUE;
2123 break;
2124 case CSS1_PERCENTAGE:
2125 // koennen wir nicht
2126 break;
2127 default:
2131 if( bSet )
2133 rPropInfo.nLeftMargin = nLeft;
2134 if( nLeft < 0 )
2135 nLeft = 0;
2136 const SfxPoolItem* pItem;
2137 if( SFX_ITEM_SET == rItemSet.GetItemState( aItemIds.nLRSpace, FALSE,
2138 &pItem ) )
2140 SvxLRSpaceItem aLRItem( *((const SvxLRSpaceItem*)pItem) );
2141 aLRItem.SetTxtLeft( (USHORT)nLeft );
2142 rItemSet.Put( aLRItem );
2144 else
2146 SvxLRSpaceItem aLRItem( aItemIds.nLRSpace );
2147 aLRItem.SetTxtLeft( (USHORT)nLeft );
2148 rItemSet.Put( aLRItem );
2150 rPropInfo.bLeftMargin = TRUE;
2154 /* \f */
2156 static void ParseCSS1_margin_right( const CSS1Expression *pExpr,
2157 SfxItemSet &rItemSet,
2158 SvxCSS1PropertyInfo& rPropInfo,
2159 const SvxCSS1Parser& /*rParser*/ )
2161 DBG_ASSERT( pExpr, "kein Ausdruck" );
2163 long nRight = 0;
2164 BOOL bSet = FALSE;
2165 switch( pExpr->GetType() )
2167 case CSS1_LENGTH:
2169 nRight = pExpr->GetSLength();
2170 bSet = TRUE;
2172 break;
2173 case CSS1_PIXLENGTH:
2175 nRight = (long)pExpr->GetNumber();
2176 long nPHeight = 0;
2177 SvxCSS1Parser::PixelToTwip( nRight, nPHeight );
2178 bSet = TRUE;
2180 break;
2181 case CSS1_PERCENTAGE:
2182 // koennen wir nicht
2183 break;
2184 default:
2188 if( bSet )
2190 rPropInfo.nRightMargin = nRight;
2191 if( nRight < 0 )
2192 nRight = 0;
2193 const SfxPoolItem* pItem;
2194 if( SFX_ITEM_SET == rItemSet.GetItemState( aItemIds.nLRSpace, FALSE,
2195 &pItem ) )
2197 SvxLRSpaceItem aLRItem( *((const SvxLRSpaceItem*)pItem) );
2198 aLRItem.SetRight( (USHORT)nRight );
2199 rItemSet.Put( aLRItem );
2201 else
2203 SvxLRSpaceItem aLRItem( aItemIds.nLRSpace );
2204 aLRItem.SetRight( (USHORT)nRight );
2205 rItemSet.Put( aLRItem );
2207 rPropInfo.bRightMargin = TRUE;
2211 /* \f */
2213 static void ParseCSS1_margin_top( const CSS1Expression *pExpr,
2214 SfxItemSet &rItemSet,
2215 SvxCSS1PropertyInfo& rPropInfo,
2216 const SvxCSS1Parser& /*rParser*/ )
2218 DBG_ASSERT( pExpr, "kein Ausdruck" );
2220 USHORT nUpper = 0;
2221 BOOL bSet = FALSE;
2222 switch( pExpr->GetType() )
2224 case CSS1_LENGTH:
2226 long nTmp = pExpr->GetSLength();
2227 if( nTmp < 0 )
2228 nTmp = 0;
2229 nUpper = (USHORT)nTmp;
2230 bSet = TRUE;
2232 break;
2233 case CSS1_PIXLENGTH:
2235 long nPWidth = 0;
2236 long nPHeight = (long)pExpr->GetNumber();
2237 if( nPHeight < 0 )
2238 nPHeight = 0;
2239 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2240 nUpper = (USHORT)nPHeight;
2241 bSet = TRUE;
2243 break;
2244 case CSS1_PERCENTAGE:
2245 // koennen wir nicht
2246 break;
2247 default:
2251 if( bSet )
2253 const SfxPoolItem* pItem;
2254 if( SFX_ITEM_SET == rItemSet.GetItemState( aItemIds.nULSpace, FALSE,
2255 &pItem ) )
2257 SvxULSpaceItem aULItem( *((const SvxULSpaceItem*)pItem) );
2258 aULItem.SetUpper( nUpper );
2259 rItemSet.Put( aULItem );
2261 else
2263 SvxULSpaceItem aULItem( aItemIds.nULSpace );
2264 aULItem.SetUpper( nUpper );
2265 rItemSet.Put( aULItem );
2267 rPropInfo.bTopMargin = TRUE;
2271 /* \f */
2273 static void ParseCSS1_margin_bottom( const CSS1Expression *pExpr,
2274 SfxItemSet &rItemSet,
2275 SvxCSS1PropertyInfo& rPropInfo,
2276 const SvxCSS1Parser& /*rParser*/ )
2278 DBG_ASSERT( pExpr, "kein Ausdruck" );
2280 USHORT nLower = 0;
2281 BOOL bSet = FALSE;
2282 switch( pExpr->GetType() )
2284 case CSS1_LENGTH:
2286 long nTmp = pExpr->GetSLength();
2287 if( nTmp < 0 )
2288 nTmp = 0;
2289 nLower = (USHORT)nTmp;
2290 bSet = TRUE;
2292 break;
2293 case CSS1_PIXLENGTH:
2295 long nPWidth = 0;
2296 long nPHeight = (long)pExpr->GetNumber();
2297 if( nPHeight < 0 )
2298 nPHeight = 0;
2299 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2300 nLower = (USHORT)nPHeight;
2301 bSet = TRUE;
2303 break;
2304 case CSS1_PERCENTAGE:
2305 // koennen wir nicht
2306 break;
2307 default:
2311 if( bSet )
2313 const SfxPoolItem* pItem;
2314 if( SFX_ITEM_SET == rItemSet.GetItemState( aItemIds.nULSpace, FALSE,
2315 &pItem ) )
2317 SvxULSpaceItem aULItem( *((const SvxULSpaceItem*)pItem) );
2318 aULItem.SetLower( nLower );
2319 rItemSet.Put( aULItem );
2321 else
2323 SvxULSpaceItem aULItem( aItemIds.nULSpace );
2324 aULItem.SetLower( nLower );
2325 rItemSet.Put( aULItem );
2327 rPropInfo.bBottomMargin = TRUE;
2331 /* \f */
2333 static void ParseCSS1_margin( const CSS1Expression *pExpr,
2334 SfxItemSet &rItemSet,
2335 SvxCSS1PropertyInfo& rPropInfo,
2336 const SvxCSS1Parser& /*rParser*/ )
2338 DBG_ASSERT( pExpr, "kein Ausdruck" );
2340 long nMargins[4] = { 0, 0, 0, 0 };
2341 BOOL bSetMargins[4] = { FALSE, FALSE, FALSE, FALSE };
2343 for( USHORT i=0; pExpr && i<4 && !pExpr->GetOp(); i++ )
2345 BOOL bSetThis = FALSE;
2346 long nMargin = 0;
2348 switch( pExpr->GetType() )
2350 case CSS1_LENGTH:
2352 nMargin = pExpr->GetSLength();
2353 bSetThis = TRUE;
2355 break;
2356 case CSS1_PIXLENGTH:
2358 long nPWidth = 0;
2359 nMargin = (long)pExpr->GetNumber();
2360 SvxCSS1Parser::PixelToTwip( nPWidth, nMargin );
2361 bSetThis = TRUE;
2363 break;
2364 case CSS1_PERCENTAGE:
2365 // koennen wir nicht
2366 break;
2367 default:
2371 if( bSetThis )
2373 // 0 = top
2374 // 1 = right
2375 // 2 = bottom
2376 // 3 = left
2377 switch( i )
2379 case 0:
2380 nMargins[0] = nMargins[1] =nMargins[2] = nMargins[3] = nMargin;
2381 bSetMargins[0] = bSetMargins[1] =
2382 bSetMargins[2] = bSetMargins[3] = TRUE;
2383 break;
2384 case 1:
2385 nMargins[1] = nMargins[3] = nMargin; // right + left
2386 bSetMargins[1] = bSetMargins[3] = TRUE;
2387 break;
2388 case 2:
2389 nMargins[2] = nMargin; // bottom
2390 bSetMargins[2] = TRUE;
2391 break;
2392 case 3:
2393 nMargins[3] = nMargin; // left
2394 bSetMargins[3] = TRUE;
2395 break;
2398 pExpr = pExpr->GetNext();
2401 if( bSetMargins[3] || bSetMargins[1] )
2403 if( bSetMargins[3] )
2405 rPropInfo.bLeftMargin = TRUE;
2406 rPropInfo.nLeftMargin = nMargins[3];
2407 if( nMargins[3] < 0 )
2408 nMargins[3] = 0;
2410 if( bSetMargins[1] )
2412 rPropInfo.bRightMargin = TRUE;
2413 rPropInfo.nRightMargin = nMargins[1];
2414 if( nMargins[1] < 0 )
2415 nMargins[1] = 0;
2418 const SfxPoolItem* pItem;
2419 if( SFX_ITEM_SET == rItemSet.GetItemState( aItemIds.nLRSpace, FALSE,
2420 &pItem ) )
2422 SvxLRSpaceItem aLRItem( *((const SvxLRSpaceItem*)pItem) );
2423 if( bSetMargins[3] )
2424 aLRItem.SetLeft( (USHORT)nMargins[3] );
2425 if( bSetMargins[1] )
2426 aLRItem.SetRight( (USHORT)nMargins[1] );
2427 rItemSet.Put( aLRItem );
2429 else
2431 SvxLRSpaceItem aLRItem( aItemIds.nLRSpace );
2432 if( bSetMargins[3] )
2433 aLRItem.SetLeft( (USHORT)nMargins[3] );
2434 if( bSetMargins[1] )
2435 aLRItem.SetRight( (USHORT)nMargins[1] );
2436 rItemSet.Put( aLRItem );
2440 if( bSetMargins[0] || bSetMargins[2] )
2442 if( nMargins[0] < 0 )
2443 nMargins[0] = 0;
2444 if( nMargins[2] < 0 )
2445 nMargins[2] = 0;
2447 const SfxPoolItem* pItem;
2448 if( SFX_ITEM_SET == rItemSet.GetItemState( aItemIds.nULSpace, FALSE,
2449 &pItem ) )
2451 SvxULSpaceItem aULItem( *((const SvxULSpaceItem*)pItem) );
2452 if( bSetMargins[0] )
2453 aULItem.SetUpper( (USHORT)nMargins[0] );
2454 if( bSetMargins[2] )
2455 aULItem.SetLower( (USHORT)nMargins[2] );
2456 rItemSet.Put( aULItem );
2458 else
2460 SvxULSpaceItem aULItem( aItemIds.nULSpace );
2461 if( bSetMargins[0] )
2462 aULItem.SetUpper( (USHORT)nMargins[0] );
2463 if( bSetMargins[2] )
2464 aULItem.SetLower( (USHORT)nMargins[2] );
2465 rItemSet.Put( aULItem );
2468 rPropInfo.bTopMargin |= bSetMargins[0];
2469 rPropInfo.bBottomMargin |= bSetMargins[2];
2473 /* \f */
2475 static BOOL ParseCSS1_padding_xxx( const CSS1Expression *pExpr,
2476 SfxItemSet & /*rItemSet*/,
2477 SvxCSS1PropertyInfo& rPropInfo,
2478 const SvxCSS1Parser& /*rParser*/,
2479 USHORT nWhichLine )
2481 DBG_ASSERT( pExpr, "kein Ausdruck" );
2483 BOOL bSet = FALSE;
2484 USHORT nDist = 0;
2486 switch( pExpr->GetType() )
2488 case CSS1_LENGTH:
2490 long nTmp = pExpr->GetSLength();
2491 if( nTmp < 0 )
2492 nTmp = 0;
2493 else if( nTmp > USHRT_MAX-1 )
2494 nTmp = USHRT_MAX-1;
2495 nDist = (USHORT)nTmp;
2496 bSet = TRUE;
2498 break;
2499 case CSS1_PIXLENGTH:
2501 long nPWidth = (long)pExpr->GetNumber();
2502 long nPHeight = 0;
2503 if( nPWidth < 0 )
2504 nPWidth = 0;
2505 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2506 if( nPWidth > USHRT_MAX-1 )
2507 nPWidth = USHRT_MAX-1;
2508 nDist = (USHORT)nPWidth;
2509 bSet = TRUE;
2511 break;
2512 case CSS1_PERCENTAGE:
2513 // koennen wir nicht
2514 break;
2515 default:
2519 if( bSet )
2521 switch( nWhichLine )
2523 case BOX_LINE_TOP: rPropInfo.nTopBorderDistance = nDist; break;
2524 case BOX_LINE_BOTTOM: rPropInfo.nBottomBorderDistance = nDist;break;
2525 case BOX_LINE_LEFT: rPropInfo.nLeftBorderDistance = nDist; break;
2526 case BOX_LINE_RIGHT: rPropInfo.nRightBorderDistance = nDist; break;
2530 return bSet;
2533 /* \f */
2535 static void ParseCSS1_padding_top( const CSS1Expression *pExpr,
2536 SfxItemSet &rItemSet,
2537 SvxCSS1PropertyInfo& rPropInfo,
2538 const SvxCSS1Parser& rParser )
2540 ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_TOP );
2543 static void ParseCSS1_padding_bottom( const CSS1Expression *pExpr,
2544 SfxItemSet &rItemSet,
2545 SvxCSS1PropertyInfo& rPropInfo,
2546 const SvxCSS1Parser& rParser )
2548 ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser,
2549 BOX_LINE_BOTTOM );
2552 static void ParseCSS1_padding_left( const CSS1Expression *pExpr,
2553 SfxItemSet &rItemSet,
2554 SvxCSS1PropertyInfo& rPropInfo,
2555 const SvxCSS1Parser& rParser )
2557 ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_LEFT );
2560 static void ParseCSS1_padding_right( const CSS1Expression *pExpr,
2561 SfxItemSet &rItemSet,
2562 SvxCSS1PropertyInfo& rPropInfo,
2563 const SvxCSS1Parser& rParser )
2565 ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser,
2566 BOX_LINE_RIGHT );
2569 static void ParseCSS1_padding( const CSS1Expression *pExpr,
2570 SfxItemSet &rItemSet,
2571 SvxCSS1PropertyInfo& rPropInfo,
2572 const SvxCSS1Parser& rParser )
2574 USHORT n=0;
2575 while( n<4 && pExpr && !pExpr->GetOp() )
2577 USHORT nLine = n==0 || n==2 ? BOX_LINE_BOTTOM : BOX_LINE_LEFT;
2578 if( ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser,
2579 nLine ) )
2581 if( n==0 )
2583 rPropInfo.nTopBorderDistance = rPropInfo.nBottomBorderDistance;
2584 rPropInfo.nLeftBorderDistance = rPropInfo.nTopBorderDistance;
2586 if( n <= 1 )
2587 rPropInfo.nRightBorderDistance = rPropInfo.nLeftBorderDistance;
2590 pExpr = pExpr->GetNext();
2591 n++;
2595 /* \f */
2597 static void ParseCSS1_border_xxx( const CSS1Expression *pExpr,
2598 SfxItemSet & /*rItemSet*/,
2599 SvxCSS1PropertyInfo& rPropInfo,
2600 const SvxCSS1Parser& /*rParser*/,
2601 USHORT nWhichLine, BOOL bAll )
2603 DBG_ASSERT( pExpr, "kein Ausdruck" );
2605 USHORT nWidth = USHRT_MAX; // die Linien-Dicke
2606 USHORT nNWidth = 1; // benannte Linien-Dicke (und default)
2607 CSS1BorderStyle eStyle = CSS1_BS_NONE; // Linien-Style
2608 Color aColor;
2609 BOOL bColor = FALSE;
2611 while( pExpr && !pExpr->GetOp() )
2613 switch( pExpr->GetType() )
2615 case CSS1_RGB:
2616 case CSS1_HEXCOLOR:
2617 if( pExpr->GetColor( aColor ) )
2618 bColor = TRUE;
2619 break;
2621 case CSS1_IDENT:
2623 const String& rValue = pExpr->GetString();
2624 USHORT nValue;
2625 if( SvxCSS1Parser::GetEnum( aBorderWidthTable, rValue, nValue ) )
2627 nNWidth = nValue;
2629 else if( SvxCSS1Parser::GetEnum( aBorderStyleTable, rValue, nValue ) )
2631 eStyle = (CSS1BorderStyle)nValue;
2633 else if( pExpr->GetColor( aColor ) )
2635 bColor = TRUE;
2638 break;
2640 case CSS1_LENGTH:
2641 nWidth = (USHORT)pExpr->GetULength();
2642 break;
2644 case CSS1_PIXLENGTH:
2646 BOOL bHori = nWhichLine == BOX_LINE_TOP ||
2647 nWhichLine == BOX_LINE_BOTTOM;
2648 // Ein Pixel wird zur Haarlinie (ist huebscher)
2649 long nWidthL = (long)pExpr->GetNumber();
2650 if( nWidthL > 1 )
2652 long nPWidth = bHori ? 0 : nWidthL;
2653 long nPHeight = bHori ? nWidthL : 0;
2654 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2655 nWidth = (USHORT)(bHori ? nPHeight : nPWidth);
2657 else
2658 nWidth = 1;
2660 break;
2662 default:
2666 pExpr = pExpr->GetNext();
2669 for( USHORT i=0; i<4; i++ )
2671 USHORT nLine = 0;
2672 switch( i )
2674 case 0: nLine = BOX_LINE_TOP; break;
2675 case 1: nLine = BOX_LINE_BOTTOM; break;
2676 case 2: nLine = BOX_LINE_LEFT; break;
2677 case 3: nLine = BOX_LINE_RIGHT; break;
2680 if( bAll || nLine == nWhichLine )
2682 SvxCSS1BorderInfo *pInfo = rPropInfo.GetBorderInfo( nLine );
2683 pInfo->eStyle = eStyle;
2684 pInfo->nAbsWidth = nWidth;
2685 pInfo->nNamedWidth = nNWidth;
2686 if( bColor )
2687 pInfo->aColor = aColor;
2692 static void ParseCSS1_border_xxx_width( const CSS1Expression *pExpr,
2693 SfxItemSet & /*rItemSet*/,
2694 SvxCSS1PropertyInfo& rPropInfo,
2695 const SvxCSS1Parser& /*rParser*/,
2696 USHORT nWhichLine )
2698 DBG_ASSERT( pExpr, "kein Ausdruck" );
2700 USHORT nWidth = USHRT_MAX; // die Linien-Dicke
2701 USHORT nNWidth = 1; // benannte Linien-Dicke (und default)
2703 switch( pExpr->GetType() )
2705 case CSS1_IDENT:
2707 USHORT nValue;
2708 if( SvxCSS1Parser::GetEnum( aBorderWidthTable, pExpr->GetString(), nValue ) )
2710 nNWidth = nValue;
2713 break;
2715 case CSS1_LENGTH:
2716 nWidth = (USHORT)pExpr->GetULength();
2717 break;
2719 case CSS1_PIXLENGTH:
2721 BOOL bHori = nWhichLine == BOX_LINE_TOP ||
2722 nWhichLine == BOX_LINE_BOTTOM;
2723 long nWidthL = (long)pExpr->GetNumber();
2724 long nPWidth = bHori ? 0 : nWidthL;
2725 long nPHeight = bHori ? nWidthL : 0;
2726 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2727 nWidth = (USHORT)(bHori ? nPHeight : nPWidth);
2729 break;
2731 default:
2735 SvxCSS1BorderInfo *pInfo = rPropInfo.GetBorderInfo( nWhichLine );
2736 pInfo->nAbsWidth = nWidth;
2737 pInfo->nNamedWidth = nNWidth;
2740 /* \f */
2742 static void ParseCSS1_border_top_width( const CSS1Expression *pExpr,
2743 SfxItemSet &rItemSet,
2744 SvxCSS1PropertyInfo& rPropInfo,
2745 const SvxCSS1Parser& rParser )
2747 ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_TOP );
2750 static void ParseCSS1_border_right_width( const CSS1Expression *pExpr,
2751 SfxItemSet &rItemSet,
2752 SvxCSS1PropertyInfo& rPropInfo,
2753 const SvxCSS1Parser& rParser )
2755 ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_RIGHT );
2758 static void ParseCSS1_border_bottom_width( const CSS1Expression *pExpr,
2759 SfxItemSet &rItemSet,
2760 SvxCSS1PropertyInfo& rPropInfo,
2761 const SvxCSS1Parser& rParser )
2763 ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_BOTTOM );
2766 static void ParseCSS1_border_left_width( const CSS1Expression *pExpr,
2767 SfxItemSet &rItemSet,
2768 SvxCSS1PropertyInfo& rPropInfo,
2769 const SvxCSS1Parser& rParser )
2771 ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_LEFT );
2774 static void ParseCSS1_border_width( const CSS1Expression *pExpr,
2775 SfxItemSet &rItemSet,
2776 SvxCSS1PropertyInfo& rPropInfo,
2777 const SvxCSS1Parser& rParser )
2779 USHORT n=0;
2780 while( n<4 && pExpr && !pExpr->GetOp() )
2782 USHORT nLine = n==0 || n==2 ? BOX_LINE_BOTTOM : BOX_LINE_LEFT;
2783 ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, nLine );
2784 rPropInfo.CopyBorderInfo( n, SVX_CSS1_BORDERINFO_WIDTH );
2786 pExpr = pExpr->GetNext();
2787 n++;
2791 static void ParseCSS1_border_color( const CSS1Expression *pExpr,
2792 SfxItemSet & /*rItemSet*/,
2793 SvxCSS1PropertyInfo& rPropInfo,
2794 const SvxCSS1Parser& /*rParser*/ )
2796 USHORT n=0;
2797 while( n<4 && pExpr && !pExpr->GetOp() )
2799 USHORT nLine = n==0 || n==2 ? BOX_LINE_BOTTOM : BOX_LINE_LEFT;
2800 Color aColor;
2801 switch( pExpr->GetType() )
2803 case CSS1_RGB:
2804 case CSS1_HEXCOLOR:
2805 case CSS1_IDENT:
2806 if( pExpr->GetColor( aColor ) )
2807 rPropInfo.GetBorderInfo( nLine )->aColor = aColor;
2808 break;
2809 default:
2812 rPropInfo.CopyBorderInfo( n, SVX_CSS1_BORDERINFO_COLOR );
2814 pExpr = pExpr->GetNext();
2815 n++;
2819 static void ParseCSS1_border_style( const CSS1Expression *pExpr,
2820 SfxItemSet & /*rItemSet*/,
2821 SvxCSS1PropertyInfo& rPropInfo,
2822 const SvxCSS1Parser& /*rParser*/ )
2824 USHORT n=0;
2825 while( n<4 && pExpr && !pExpr->GetOp() )
2827 USHORT nLine = n==0 || n==2 ? BOX_LINE_BOTTOM : BOX_LINE_LEFT;
2828 USHORT nValue;
2829 if( CSS1_IDENT==pExpr->GetType() &&
2830 SvxCSS1Parser::GetEnum( aBorderStyleTable, pExpr->GetString(),
2831 nValue ) )
2833 rPropInfo.GetBorderInfo( nLine )->eStyle = (CSS1BorderStyle)nValue;
2835 rPropInfo.CopyBorderInfo( n, SVX_CSS1_BORDERINFO_STYLE );
2837 pExpr = pExpr->GetNext();
2838 n++;
2843 static void ParseCSS1_border_top( const CSS1Expression *pExpr,
2844 SfxItemSet &rItemSet,
2845 SvxCSS1PropertyInfo& rPropInfo,
2846 const SvxCSS1Parser& rParser )
2848 ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_TOP, FALSE );
2851 static void ParseCSS1_border_right( const CSS1Expression *pExpr,
2852 SfxItemSet &rItemSet,
2853 SvxCSS1PropertyInfo& rPropInfo,
2854 const SvxCSS1Parser& rParser )
2856 ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_RIGHT, FALSE );
2859 static void ParseCSS1_border_bottom( const CSS1Expression *pExpr,
2860 SfxItemSet &rItemSet,
2861 SvxCSS1PropertyInfo& rPropInfo,
2862 const SvxCSS1Parser& rParser )
2864 ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_BOTTOM, FALSE );
2867 static void ParseCSS1_border_left( const CSS1Expression *pExpr,
2868 SfxItemSet &rItemSet,
2869 SvxCSS1PropertyInfo& rPropInfo,
2870 const SvxCSS1Parser& rParser )
2872 ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, BOX_LINE_LEFT, FALSE );
2875 static void ParseCSS1_border( const CSS1Expression *pExpr,
2876 SfxItemSet &rItemSet,
2877 SvxCSS1PropertyInfo& rPropInfo,
2878 const SvxCSS1Parser& rParser )
2880 ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, 0, TRUE );
2883 /* \f */
2885 static void ParseCSS1_float( const CSS1Expression *pExpr,
2886 SfxItemSet & /*rItemSet*/,
2887 SvxCSS1PropertyInfo& rPropInfo,
2888 const SvxCSS1Parser& /*rParser*/ )
2890 DBG_ASSERT( pExpr, "kein Ausdruck" );
2892 if( CSS1_IDENT==pExpr->GetType() )
2894 USHORT nFloat;
2895 if( SvxCSS1Parser::GetEnum( aFloatTable, pExpr->GetString(), nFloat ) )
2896 rPropInfo.eFloat = (SvxAdjust)nFloat;
2901 /* \f */
2903 static void ParseCSS1_position( const CSS1Expression *pExpr,
2904 SfxItemSet & /*rItemSet*/,
2905 SvxCSS1PropertyInfo& rPropInfo,
2906 const SvxCSS1Parser& /*rParser*/ )
2908 DBG_ASSERT( pExpr, "kein Ausdruck" );
2910 if( CSS1_IDENT==pExpr->GetType() )
2912 USHORT nPos;
2913 if( SvxCSS1Parser::GetEnum( aPositionTable, pExpr->GetString(), nPos ) )
2914 rPropInfo.ePosition = (SvxCSS1Position)nPos;
2918 /* \f */
2920 static void ParseCSS1_length( const CSS1Expression *pExpr,
2921 long& rLength,
2922 SvxCSS1LengthType& rLengthType,
2923 BOOL bHori )
2925 switch( pExpr->GetType() )
2927 case CSS1_IDENT:
2928 if( pExpr->GetString().EqualsIgnoreCaseAscii( sCSS1_PV_auto ) )
2930 rLength = 0;
2931 rLengthType = SVX_CSS1_LTYPE_AUTO;
2933 break;
2935 case CSS1_LENGTH:
2936 rLength = pExpr->GetSLength();
2937 rLengthType = SVX_CSS1_LTYPE_TWIP;
2938 break;
2940 case CSS1_PIXLENGTH:
2941 case CSS1_NUMBER: // wegen Netscape und IE
2943 long nWidthL = (long)pExpr->GetNumber();
2944 long nPWidth = bHori ? 0 : nWidthL;
2945 long nPHeight = bHori ? nWidthL : 0;
2946 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2947 rLength = (bHori ? nPHeight : nPWidth);
2948 rLengthType = SVX_CSS1_LTYPE_TWIP;
2950 break;
2952 case CSS1_PERCENTAGE:
2953 rLength = (long)pExpr->GetNumber();
2954 if( rLength > 100 )
2955 rLength = 100;
2956 rLengthType = SVX_CSS1_LTYPE_PERCENTAGE;
2957 break;
2959 default:
2964 /* \f */
2966 static void ParseCSS1_width( const CSS1Expression *pExpr,
2967 SfxItemSet & /*rItemSet*/,
2968 SvxCSS1PropertyInfo& rPropInfo,
2969 const SvxCSS1Parser& /*rParser*/ )
2971 ParseCSS1_length( pExpr, rPropInfo.nWidth, rPropInfo.eWidthType, TRUE );
2974 static void ParseCSS1_height( const CSS1Expression *pExpr,
2975 SfxItemSet & /*rItemSet*/,
2976 SvxCSS1PropertyInfo& rPropInfo,
2977 const SvxCSS1Parser& /*rParser*/ )
2979 ParseCSS1_length( pExpr, rPropInfo.nHeight, rPropInfo.eHeightType, FALSE );
2982 static void ParseCSS1_left( const CSS1Expression *pExpr,
2983 SfxItemSet & /*rItemSet*/,
2984 SvxCSS1PropertyInfo& rPropInfo,
2985 const SvxCSS1Parser& /*rParser*/ )
2987 ParseCSS1_length( pExpr, rPropInfo.nLeft, rPropInfo.eLeftType, TRUE );
2990 static void ParseCSS1_top( const CSS1Expression *pExpr,
2991 SfxItemSet & /*rItemSet*/,
2992 SvxCSS1PropertyInfo& rPropInfo,
2993 const SvxCSS1Parser& /*rParser*/ )
2995 ParseCSS1_length( pExpr, rPropInfo.nTop, rPropInfo.eTopType, FALSE );
2998 /* \f */
3000 // Feature: PrintExt
3001 static void ParseCSS1_size( const CSS1Expression *pExpr,
3002 SfxItemSet & /*rItemSet*/,
3003 SvxCSS1PropertyInfo& rPropInfo,
3004 const SvxCSS1Parser& /*rParser*/ )
3006 USHORT n=0;
3007 while( n<2 && pExpr && !pExpr->GetOp() )
3009 switch( pExpr->GetType() )
3011 case CSS1_IDENT:
3013 USHORT nValue;
3014 if( SvxCSS1Parser::GetEnum( aSizeTable, pExpr->GetString(),
3015 nValue ) )
3017 rPropInfo.eSizeType = (SvxCSS1SizeType)nValue;
3020 break;
3022 case CSS1_LENGTH:
3023 rPropInfo.nHeight = pExpr->GetSLength();
3024 if( n==0 )
3025 rPropInfo.nWidth = rPropInfo.nHeight;
3026 rPropInfo.eSizeType = SVX_CSS1_STYPE_TWIP;
3027 break;
3029 case CSS1_PIXLENGTH:
3031 long nPHeight = (long)pExpr->GetNumber();
3032 long nPWidth = n==0 ? nPHeight : 0;
3033 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
3034 rPropInfo.nHeight = nPHeight;
3035 if( n==0 )
3036 rPropInfo.nWidth = nPWidth;
3037 rPropInfo.eSizeType = SVX_CSS1_STYPE_TWIP;
3039 break;
3041 default:
3045 pExpr = pExpr->GetNext();
3046 n++;
3050 // /Feature: PrintExt
3052 /* \f */
3054 // Feature: PrintExt
3056 static void ParseCSS1_page_break_xxx( const CSS1Expression *pExpr,
3057 SvxCSS1PageBreak& rPBreak )
3059 if( CSS1_IDENT == pExpr->GetType() )
3061 USHORT nValue;
3062 if( SvxCSS1Parser::GetEnum( aPageBreakTable, pExpr->GetString(),
3063 nValue ) )
3065 rPBreak = (SvxCSS1PageBreak)nValue;
3070 static void ParseCSS1_page_break_before( const CSS1Expression *pExpr,
3071 SfxItemSet & /*rItemSet*/,
3072 SvxCSS1PropertyInfo& rPropInfo,
3073 const SvxCSS1Parser& /*rParser*/ )
3075 ParseCSS1_page_break_xxx( pExpr, rPropInfo.ePageBreakBefore );
3078 static void ParseCSS1_page_break_after( const CSS1Expression *pExpr,
3079 SfxItemSet & /*rItemSet*/,
3080 SvxCSS1PropertyInfo& rPropInfo,
3081 const SvxCSS1Parser& /*rParser*/ )
3083 ParseCSS1_page_break_xxx( pExpr, rPropInfo.ePageBreakAfter );
3086 static void ParseCSS1_page_break_inside( const CSS1Expression *pExpr,
3087 SfxItemSet &rItemSet,
3088 SvxCSS1PropertyInfo& /*rPropInfo*/,
3089 const SvxCSS1Parser& /*rParser*/ )
3091 SvxCSS1PageBreak eBreak(SVX_CSS1_PBREAK_NONE);
3092 ParseCSS1_page_break_xxx( pExpr, eBreak );
3094 BOOL bSetSplit = FALSE, bSplit = TRUE;
3095 switch( eBreak )
3097 case SVX_CSS1_PBREAK_AUTO:
3098 bSetSplit = TRUE;
3099 break;
3100 case SVX_CSS1_PBREAK_AVOID:
3101 bSplit = FALSE;
3102 bSetSplit = TRUE;
3103 break;
3104 default:
3108 if( bSetSplit )
3109 rItemSet.Put( SvxFmtSplitItem( bSplit, aItemIds.nFmtSplit ) );
3112 static void ParseCSS1_widows( const CSS1Expression *pExpr,
3113 SfxItemSet &rItemSet,
3114 SvxCSS1PropertyInfo& /*rPropInfo*/,
3115 const SvxCSS1Parser& /*rParser*/ )
3117 if( CSS1_NUMBER == pExpr->GetType() )
3119 BYTE nVal = pExpr->GetNumber() <= 255
3120 ? (BYTE)pExpr->GetNumber()
3121 : 255;
3122 SvxWidowsItem aWidowsItem( nVal, aItemIds.nWidows );
3123 rItemSet.Put( aWidowsItem );
3127 static void ParseCSS1_orphans( const CSS1Expression *pExpr,
3128 SfxItemSet &rItemSet,
3129 SvxCSS1PropertyInfo& /*rPropInfo*/,
3130 const SvxCSS1Parser& /*rParser*/ )
3132 if( CSS1_NUMBER == pExpr->GetType() )
3134 BYTE nVal = pExpr->GetNumber() <= 255
3135 ? (BYTE)pExpr->GetNumber()
3136 : 255;
3137 SvxOrphansItem aOrphansItem( nVal, aItemIds.nOrphans );
3138 rItemSet.Put( aOrphansItem );
3141 // /Feature: PrintExt
3143 static void ParseCSS1_so_language( const CSS1Expression *pExpr,
3144 SfxItemSet &rItemSet,
3145 SvxCSS1PropertyInfo& /*rPropInfo*/,
3146 const SvxCSS1Parser& rParser )
3148 if( CSS1_IDENT == pExpr->GetType() ||
3149 CSS1_STRING == pExpr->GetType() )
3151 LanguageType eLang = MsLangId::convertIsoStringToLanguage( pExpr->GetString() );
3152 if( LANGUAGE_DONTKNOW != eLang )
3154 SvxLanguageItem aLang( eLang, aItemIds.nLanguage );
3155 if( rParser.IsSetWesternProps() )
3156 rItemSet.Put( aLang );
3157 if( rParser.IsSetCJKProps() )
3159 aLang.SetWhich( aItemIds.nLanguageCJK );
3160 rItemSet.Put( aLang );
3162 if( rParser.IsSetCTLProps() )
3164 aLang.SetWhich( aItemIds.nLanguageCTL );
3165 rItemSet.Put( aLang );
3171 /* \f */
3173 // die Zuordung Property zu parsender Funktion
3174 struct CSS1PropEntry
3176 union
3178 const sal_Char *sName;
3179 String *pName;
3181 FnParseCSS1Prop pFunc;
3184 #define CSS1_PROP_ENTRY(p) \
3185 { { sCSS1_P_##p }, ParseCSS1_##p }
3188 // die Tabelle mit den Zuordnungen
3189 static CSS1PropEntry __FAR_DATA aCSS1PropFnTab[] =
3191 CSS1_PROP_ENTRY(background),
3192 CSS1_PROP_ENTRY(background_color),
3193 CSS1_PROP_ENTRY(border_top_width),
3194 CSS1_PROP_ENTRY(border_right_width),
3195 CSS1_PROP_ENTRY(border_bottom_width),
3196 CSS1_PROP_ENTRY(border_left_width),
3197 CSS1_PROP_ENTRY(border_width),
3198 CSS1_PROP_ENTRY(border_color),
3199 CSS1_PROP_ENTRY(border_style),
3200 CSS1_PROP_ENTRY(border_top),
3201 CSS1_PROP_ENTRY(border_right),
3202 CSS1_PROP_ENTRY(border_bottom),
3203 CSS1_PROP_ENTRY(border_left),
3204 CSS1_PROP_ENTRY(border),
3205 CSS1_PROP_ENTRY(color),
3206 CSS1_PROP_ENTRY(direction),
3207 CSS1_PROP_ENTRY(float),
3208 CSS1_PROP_ENTRY(font_size),
3209 CSS1_PROP_ENTRY(font_family),
3210 CSS1_PROP_ENTRY(font_style),
3211 CSS1_PROP_ENTRY(font_variant),
3212 CSS1_PROP_ENTRY(font_weight),
3213 CSS1_PROP_ENTRY(letter_spacing),
3214 CSS1_PROP_ENTRY(line_height),
3215 CSS1_PROP_ENTRY(font),
3216 CSS1_PROP_ENTRY(text_align),
3217 CSS1_PROP_ENTRY(text_decoration),
3218 CSS1_PROP_ENTRY(text_indent),
3219 CSS1_PROP_ENTRY(margin_left),
3220 CSS1_PROP_ENTRY(margin_right),
3221 CSS1_PROP_ENTRY(margin_top),
3222 CSS1_PROP_ENTRY(margin_bottom),
3223 CSS1_PROP_ENTRY(margin),
3224 CSS1_PROP_ENTRY(padding_top),
3225 CSS1_PROP_ENTRY(padding_bottom),
3226 CSS1_PROP_ENTRY(padding_left),
3227 CSS1_PROP_ENTRY(padding_right),
3228 CSS1_PROP_ENTRY(padding),
3229 CSS1_PROP_ENTRY(position),
3230 CSS1_PROP_ENTRY(left),
3231 CSS1_PROP_ENTRY(top),
3232 CSS1_PROP_ENTRY(width),
3233 CSS1_PROP_ENTRY(height),
3234 // Feature: PrintExt
3235 CSS1_PROP_ENTRY(size),
3236 CSS1_PROP_ENTRY(page_break_before),
3237 CSS1_PROP_ENTRY(page_break_after),
3238 CSS1_PROP_ENTRY(page_break_inside),
3239 CSS1_PROP_ENTRY(widows),
3240 CSS1_PROP_ENTRY(orphans),
3241 // /Feature: PrintExt
3242 CSS1_PROP_ENTRY(so_language)
3245 /* \f */
3247 static int __FAR_DATA bSortedPropFns = FALSE;
3249 extern "C"
3251 static int
3252 #if defined( WNT )
3253 __cdecl
3254 #endif
3255 #if defined( ICC )
3256 _Optlink
3257 #endif
3258 CSS1PropEntryCompare( const void *pFirst, const void *pSecond)
3260 int nRet;
3261 if( ((CSS1PropEntry*)pFirst)->pFunc )
3263 if( ((CSS1PropEntry*)pSecond)->pFunc )
3264 nRet = strcmp( ((CSS1PropEntry*)pFirst)->sName ,
3265 ((CSS1PropEntry*)pSecond)->sName );
3266 else
3267 nRet = -1 * ((CSS1PropEntry*)pSecond)->pName->CompareToAscii(
3268 ((CSS1PropEntry*)pFirst)->sName );
3270 else
3272 if( ((CSS1PropEntry*)pSecond)->pFunc )
3273 nRet = ((CSS1PropEntry*)pFirst)->pName->CompareToAscii(
3274 ((CSS1PropEntry*)pSecond)->sName );
3275 else
3276 nRet = ((CSS1PropEntry*)pFirst)->pName->CompareTo(
3277 *((CSS1PropEntry*)pSecond)->pName );
3280 return nRet;
3284 void SvxCSS1Parser::ParseProperty( const String& rProperty,
3285 const CSS1Expression *pExpr )
3287 DBG_ASSERT( pItemSet, "DeclarationParsed() ohne ItemSet" );
3289 if( !bSortedPropFns )
3291 qsort( (void*) aCSS1PropFnTab,
3292 sizeof( aCSS1PropFnTab ) / sizeof( CSS1PropEntry ),
3293 sizeof( CSS1PropEntry ),
3294 CSS1PropEntryCompare );
3295 bSortedPropFns = TRUE;
3298 String aTmp( rProperty );
3299 aTmp.ToLowerAscii();
3301 CSS1PropEntry aSrch;
3302 aSrch.pName = &aTmp;
3303 aSrch.pFunc = 0;
3305 void* pFound;
3306 if( 0 != ( pFound = bsearch( (char *) &aSrch,
3307 (void*) aCSS1PropFnTab,
3308 sizeof( aCSS1PropFnTab ) / sizeof( CSS1PropEntry ),
3309 sizeof( CSS1PropEntry ),
3310 CSS1PropEntryCompare )))
3312 (((CSS1PropEntry*)pFound)->pFunc)( pExpr, *pItemSet, *pPropInfo, *this );