build fix
[LibreOffice.git] / sw / source / filter / html / svxcss1.cxx
blobca43c6a71a1a4e9dad64baba95ef5fedefde9ea5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <stdlib.h>
22 #include <svx/svxids.hrc>
23 #include <i18nlangtag/languagetag.hxx>
24 #include <svtools/ctrltool.hxx>
25 #include <svl/urihelper.hxx>
26 #include <editeng/udlnitem.hxx>
27 #include <editeng/adjustitem.hxx>
28 #include <editeng/blinkitem.hxx>
29 #include <editeng/crossedoutitem.hxx>
30 #include <editeng/kernitem.hxx>
31 #include <editeng/lspcitem.hxx>
32 #include <editeng/fontitem.hxx>
33 #include <editeng/postitem.hxx>
34 #include <editeng/colritem.hxx>
35 #include <editeng/cmapitem.hxx>
36 #include <editeng/brushitem.hxx>
37 #include <editeng/wghtitem.hxx>
38 #include <editeng/fhgtitem.hxx>
39 #include <editeng/boxitem.hxx>
40 #include <editeng/ulspitem.hxx>
41 #include <editeng/lrspitem.hxx>
42 #include <editeng/langitem.hxx>
43 #include <svl/itempool.hxx>
44 #include <editeng/spltitem.hxx>
45 #include <editeng/widwitem.hxx>
46 #include <editeng/frmdiritem.hxx>
47 #include <editeng/orphitem.hxx>
48 #include <svtools/svparser.hxx>
49 #include <swtypes.hxx>
50 #include <vcl/svapp.hxx>
51 #include <vcl/wrkwin.hxx>
52 #include <o3tl/make_unique.hxx>
54 #include "css1kywd.hxx"
55 #include "svxcss1.hxx"
57 #include <utility>
59 using namespace ::com::sun::star;
61 // die Funktionen zum Parsen einer CSS1-Property sind von folgendem Typ:
62 typedef void (*FnParseCSS1Prop)( const CSS1Expression *pExpr,
63 SfxItemSet& rItemSet,
64 SvxCSS1PropertyInfo& rPropInfo,
65 const SvxCSS1Parser& rParser );
67 static CSS1PropertyEnum const aFontSizeTable[] =
69 { "xx-small", 0 },
70 { "x-small", 1 },
71 { "small", 2 },
72 { "medium", 3 },
73 { "large", 4 },
74 { "x-large", 5 },
75 { "xx-large", 6 },
76 { nullptr, 0 }
79 static CSS1PropertyEnum const aFontWeightTable[] =
81 { "extra-light", WEIGHT_NORMAL }, // WEIGHT_ULTRALIGHT (OBS)
82 { "light", WEIGHT_NORMAL }, // WEIGHT_LIGHT (OBSOLETE)
83 { "demi-light", WEIGHT_NORMAL }, // WEIGHT_SEMILIGHT (OBS)
84 { "medium", WEIGHT_NORMAL }, // WEIGHT_MEDIUM (OBS)
85 { "normal", WEIGHT_NORMAL }, // WEIGHT_MEDIUM
86 { "demi-bold", WEIGHT_NORMAL }, // WEIGHT_SEMIBOLD (OBS)
87 { "bold", WEIGHT_BOLD }, // WEIGHT_BOLD (OBSOLETE)
88 { "extra-bold", WEIGHT_BOLD }, // WEIGHT_ULTRABOLD (OBS)
89 { "bolder", WEIGHT_BOLD },
90 { "lighter", WEIGHT_NORMAL },
91 { nullptr, 0 }
94 static CSS1PropertyEnum const aFontStyleTable[] =
96 { "normal", ITALIC_NONE },
97 { "italic", ITALIC_NORMAL },
98 { "oblique", ITALIC_NORMAL },
99 { nullptr, 0 }
102 static CSS1PropertyEnum const aFontVariantTable[] =
104 { "normal", SVX_CASEMAP_NOT_MAPPED },
105 { "small-caps", SVX_CASEMAP_KAPITAELCHEN },
106 { nullptr, 0 }
109 static CSS1PropertyEnum const aTextTransformTable[] =
111 { "uppercase", SVX_CASEMAP_VERSALIEN },
112 { "lowercase", SVX_CASEMAP_GEMEINE },
113 { "capitalize", SVX_CASEMAP_TITEL },
114 { nullptr, 0 }
117 static CSS1PropertyEnum const aDirectionTable[] =
119 { "ltr", FRMDIR_HORI_LEFT_TOP },
120 { "rtl", FRMDIR_HORI_RIGHT_TOP },
121 { "inherit", FRMDIR_ENVIRONMENT },
122 { nullptr, 0 }
125 static CSS1PropertyEnum const aBGRepeatTable[] =
127 { "repeat", GPOS_TILED },
128 { "repeat-x", GPOS_TILED },
129 { "repeat-y", GPOS_TILED },
130 { "no-repeat", GPOS_NONE },
131 { nullptr, 0 }
134 static CSS1PropertyEnum const aBGHoriPosTable[] =
136 { "left", GPOS_LT },
137 { "center", GPOS_MT },
138 { "right", GPOS_RT },
139 { nullptr, 0 }
142 static CSS1PropertyEnum const aBGVertPosTable[] =
144 { "top", GPOS_LT },
145 { "middle", GPOS_LM },
146 { "bottom", GPOS_LB },
147 { nullptr, 0 }
150 static CSS1PropertyEnum const aTextAlignTable[] =
152 { "left", SVX_ADJUST_LEFT },
153 { "center", SVX_ADJUST_CENTER },
154 { "right", SVX_ADJUST_RIGHT },
155 { "justify", SVX_ADJUST_BLOCK },
156 { nullptr, 0 }
159 static CSS1PropertyEnum const aBorderWidthTable[] =
161 { "thin", 0 }, // DEF_LINE_WIDTH_0 / DEF_DOUBLE_LINE0
162 { "medium", 1 }, // DEF_LINE_WIDTH_1 / DEF_DOUBLE_LINE1
163 { "thick", 2 }, // DEF_LINE_WIDTH_2 / DEF_DOUBLE_LINE2
164 { nullptr, 0 }
167 enum CSS1BorderStyle { CSS1_BS_NONE, CSS1_BS_SINGLE, CSS1_BS_DOUBLE, CSS1_BS_DOTTED, CSS1_BS_DASHED, CSS1_BS_GROOVE, CSS1_BS_RIDGE, CSS1_BS_INSET, CSS1_BS_OUTSET };
169 static CSS1PropertyEnum const aBorderStyleTable[] =
171 { "none", CSS1_BS_NONE },
172 { "dotted", CSS1_BS_DOTTED },
173 { "dashed", CSS1_BS_DASHED },
174 { "solid", CSS1_BS_SINGLE },
175 { "double", CSS1_BS_DOUBLE },
176 { "groove", CSS1_BS_GROOVE },
177 { "ridge", CSS1_BS_RIDGE },
178 { "inset", CSS1_BS_INSET },
179 { "outset", CSS1_BS_OUTSET },
180 { nullptr, 0 }
183 static CSS1PropertyEnum const aFloatTable[] =
185 { "left", SVX_ADJUST_LEFT },
186 { "right", SVX_ADJUST_RIGHT },
187 { "none", SVX_ADJUST_END },
188 { nullptr, 0 }
191 static CSS1PropertyEnum const aPositionTable[] =
193 { "absolute", SVX_CSS1_POS_ABSOLUTE },
194 { "relative", SVX_CSS1_POS_RELATIVE },
195 { "static", SVX_CSS1_POS_STATIC },
196 { nullptr, 0 }
199 // Feature: PrintExt
200 static CSS1PropertyEnum const aSizeTable[] =
202 { "auto", SVX_CSS1_STYPE_AUTO },
203 { "landscape", SVX_CSS1_STYPE_LANDSCAPE },
204 { "portrait", SVX_CSS1_STYPE_PORTRAIT },
205 { nullptr, 0 }
208 static CSS1PropertyEnum const aPageBreakTable[] =
210 { "auto", SVX_CSS1_PBREAK_AUTO },
211 { "always", SVX_CSS1_PBREAK_ALWAYS },
212 { "avoid", SVX_CSS1_PBREAK_AVOID },
213 { "left", SVX_CSS1_PBREAK_LEFT },
214 { "right", SVX_CSS1_PBREAK_RIGHT },
215 { nullptr, 0 }
219 static sal_uInt16 const aBorderWidths[] =
221 DEF_LINE_WIDTH_0,
222 DEF_LINE_WIDTH_5,
223 DEF_LINE_WIDTH_1
226 #undef SBORDER_ENTRY
227 #undef DBORDER_ENTRY
229 struct SvxCSS1ItemIds
231 sal_uInt16 nFont;
232 sal_uInt16 nFontCJK;
233 sal_uInt16 nFontCTL;
234 sal_uInt16 nPosture;
235 sal_uInt16 nPostureCJK;
236 sal_uInt16 nPostureCTL;
237 sal_uInt16 nWeight;
238 sal_uInt16 nWeightCJK;
239 sal_uInt16 nWeightCTL;
240 sal_uInt16 nFontHeight;
241 sal_uInt16 nFontHeightCJK;
242 sal_uInt16 nFontHeightCTL;
243 sal_uInt16 nUnderline;
244 sal_uInt16 nOverline;
245 sal_uInt16 nCrossedOut;
246 sal_uInt16 nColor;
247 sal_uInt16 nKerning;
248 sal_uInt16 nCaseMap;
249 sal_uInt16 nBlink;
251 sal_uInt16 nLineSpacing;
252 sal_uInt16 nAdjust;
253 sal_uInt16 nWidows;
254 sal_uInt16 nOrphans;
255 sal_uInt16 nFormatSplit;
257 sal_uInt16 nLRSpace;
258 sal_uInt16 nULSpace;
259 sal_uInt16 nBox;
260 sal_uInt16 nBrush;
262 sal_uInt16 nLanguage;
263 sal_uInt16 nLanguageCJK;
264 sal_uInt16 nLanguageCTL;
265 sal_uInt16 nDirection;
268 static SvxCSS1ItemIds aItemIds;
270 struct SvxCSS1BorderInfo
272 Color aColor;
273 sal_uInt16 nAbsWidth;
274 sal_uInt16 nNamedWidth;
275 CSS1BorderStyle eStyle;
277 SvxCSS1BorderInfo() :
278 aColor( COL_BLACK ), nAbsWidth( USHRT_MAX ),
279 nNamedWidth( USHRT_MAX ), eStyle( CSS1_BS_NONE )
282 SvxCSS1BorderInfo( const SvxCSS1BorderInfo& rInfo ) :
283 aColor( rInfo.aColor ), nAbsWidth( rInfo.nAbsWidth ),
284 nNamedWidth( rInfo.nNamedWidth ), eStyle( rInfo.eStyle )
287 void SetBorderLine( SvxBoxItemLine nLine, SvxBoxItem &rBoxItem ) const;
290 void SvxCSS1BorderInfo::SetBorderLine( SvxBoxItemLine nLine, SvxBoxItem &rBoxItem ) const
292 if( CSS1_BS_NONE==eStyle || nAbsWidth==0 ||
293 (nAbsWidth==USHRT_MAX && nNamedWidth==USHRT_MAX) )
295 rBoxItem.SetLine( nullptr, nLine );
296 return;
299 ::editeng::SvxBorderLine aBorderLine( &aColor );
301 // Linien-Stil doppelt oder einfach?
302 switch ( eStyle )
304 case CSS1_BS_SINGLE:
305 aBorderLine.SetBorderLineStyle(table::BorderLineStyle::SOLID);
306 break;
307 case CSS1_BS_DOUBLE:
308 aBorderLine.SetBorderLineStyle(table::BorderLineStyle::DOUBLE);
309 break;
310 case CSS1_BS_DOTTED:
311 aBorderLine.SetBorderLineStyle(table::BorderLineStyle::DOTTED);
312 break;
313 case CSS1_BS_DASHED:
314 aBorderLine.SetBorderLineStyle(table::BorderLineStyle::DASHED);
315 break;
316 case CSS1_BS_GROOVE:
317 aBorderLine.SetBorderLineStyle(table::BorderLineStyle::ENGRAVED);
318 break;
319 case CSS1_BS_RIDGE:
320 aBorderLine.SetBorderLineStyle(table::BorderLineStyle::EMBOSSED);
321 break;
322 case CSS1_BS_INSET:
323 aBorderLine.SetBorderLineStyle(table::BorderLineStyle::INSET);
324 break;
325 case CSS1_BS_OUTSET:
326 aBorderLine.SetBorderLineStyle(table::BorderLineStyle::OUTSET);
327 break;
328 default:
329 aBorderLine.SetBorderLineStyle(table::BorderLineStyle::NONE);
330 break;
333 // benannte Breite umrechnenen, wenn keine absolute gegeben ist
334 if( nAbsWidth==USHRT_MAX )
335 aBorderLine.SetWidth( aBorderWidths[ nNamedWidth ] );
336 else
337 aBorderLine.SetWidth( nAbsWidth );
339 rBoxItem.SetLine( &aBorderLine, nLine );
342 SvxCSS1PropertyInfo::SvxCSS1PropertyInfo()
344 for(SvxCSS1BorderInfo* & rp : m_aBorderInfos)
345 rp = nullptr;
347 Clear();
350 SvxCSS1PropertyInfo::SvxCSS1PropertyInfo( const SvxCSS1PropertyInfo& rProp ) :
351 m_aId( rProp.m_aId ),
352 m_bTopMargin( rProp.m_bTopMargin ),
353 m_bBottomMargin( rProp.m_bBottomMargin ),
354 m_bLeftMargin( rProp.m_bLeftMargin ),
355 m_bRightMargin( rProp.m_bRightMargin ),
356 m_bTextIndent( rProp.m_bTextIndent ),
357 m_eFloat( rProp.m_eFloat ),
358 m_ePosition( rProp.m_ePosition ),
359 m_nTopBorderDistance( rProp.m_nTopBorderDistance ),
360 m_nBottomBorderDistance( rProp.m_nBottomBorderDistance ),
361 m_nLeftBorderDistance( rProp.m_nLeftBorderDistance ),
362 m_nRightBorderDistance( rProp.m_nRightBorderDistance ),
363 m_nColumnCount( rProp.m_nColumnCount ),
364 m_nLeft( rProp.m_nLeft ),
365 m_nTop( rProp.m_nTop ),
366 m_nWidth( rProp.m_nWidth ),
367 m_nHeight( rProp.m_nHeight ),
368 m_nLeftMargin( rProp.m_nLeftMargin ),
369 m_nRightMargin( rProp.m_nRightMargin ),
370 m_eLeftType( rProp.m_eLeftType ),
371 m_eTopType( rProp.m_eTopType ),
372 m_eWidthType( rProp.m_eWidthType ),
373 m_eHeightType( rProp.m_eHeightType ),
374 m_eSizeType( rProp.m_eSizeType ),
375 m_ePageBreakBefore( rProp.m_ePageBreakBefore ),
376 m_ePageBreakAfter( rProp.m_ePageBreakAfter )
378 for( size_t i=0; i<SAL_N_ELEMENTS(m_aBorderInfos); ++i )
379 m_aBorderInfos[i] = rProp.m_aBorderInfos[i]
380 ? new SvxCSS1BorderInfo( *rProp.m_aBorderInfos[i] )
381 : nullptr;
384 SvxCSS1PropertyInfo::~SvxCSS1PropertyInfo()
386 DestroyBorderInfos();
389 void SvxCSS1PropertyInfo::DestroyBorderInfos()
391 for(SvxCSS1BorderInfo* & rp : m_aBorderInfos)
393 delete rp;
394 rp = nullptr;
398 void SvxCSS1PropertyInfo::Clear()
400 m_aId.clear();
401 m_bTopMargin = m_bBottomMargin = false;
402 m_bLeftMargin = m_bRightMargin = m_bTextIndent = false;
403 m_nLeftMargin = m_nRightMargin = 0;
404 m_eFloat = SVX_ADJUST_END;
406 m_ePosition = SVX_CSS1_POS_NONE;
407 m_nTopBorderDistance = m_nBottomBorderDistance =
408 m_nLeftBorderDistance = m_nRightBorderDistance = USHRT_MAX;
410 m_nColumnCount = 0;
412 m_nLeft = m_nTop = m_nWidth = m_nHeight = 0;
413 m_eLeftType = m_eTopType = m_eWidthType = m_eHeightType = SVX_CSS1_LTYPE_NONE;
415 // Feature: PrintExt
416 m_eSizeType = SVX_CSS1_STYPE_NONE;
417 m_ePageBreakBefore = SVX_CSS1_PBREAK_NONE;
418 m_ePageBreakAfter = SVX_CSS1_PBREAK_NONE;
420 DestroyBorderInfos();
423 void SvxCSS1PropertyInfo::Merge( const SvxCSS1PropertyInfo& rProp )
425 if( rProp.m_bTopMargin )
426 m_bTopMargin = true;
427 if( rProp.m_bBottomMargin )
428 m_bBottomMargin = true;
430 if( rProp.m_bLeftMargin )
432 m_bLeftMargin = true;
433 m_nLeftMargin = rProp.m_nLeftMargin;
435 if( rProp.m_bRightMargin )
437 m_bRightMargin = true;
438 m_nRightMargin = rProp.m_nRightMargin;
440 if( rProp.m_bTextIndent )
441 m_bTextIndent = true;
443 for( size_t i=0; i<SAL_N_ELEMENTS(m_aBorderInfos); ++i )
445 if( rProp.m_aBorderInfos[i] )
447 if( m_aBorderInfos[i] )
448 delete m_aBorderInfos[i];
450 m_aBorderInfos[i] = new SvxCSS1BorderInfo( *rProp.m_aBorderInfos[i] );
454 if( USHRT_MAX != rProp.m_nTopBorderDistance )
455 m_nTopBorderDistance = rProp.m_nTopBorderDistance;
456 if( USHRT_MAX != rProp.m_nBottomBorderDistance )
457 m_nBottomBorderDistance = rProp.m_nBottomBorderDistance;
458 if( USHRT_MAX != rProp.m_nLeftBorderDistance )
459 m_nLeftBorderDistance = rProp.m_nLeftBorderDistance;
460 if( USHRT_MAX != rProp.m_nRightBorderDistance )
461 m_nRightBorderDistance = rProp.m_nRightBorderDistance;
463 m_nColumnCount = rProp.m_nColumnCount;
465 if( rProp.m_eFloat != SVX_ADJUST_END )
466 m_eFloat = rProp.m_eFloat;
468 if( rProp.m_ePosition != SVX_CSS1_POS_NONE )
469 m_ePosition = rProp.m_ePosition;
471 // Feature: PrintExt
472 if( rProp.m_eSizeType != SVX_CSS1_STYPE_NONE )
474 m_eSizeType = rProp.m_eSizeType;
475 m_nWidth = rProp.m_nWidth;
476 m_nHeight = rProp.m_nHeight;
479 if( rProp.m_ePageBreakBefore != SVX_CSS1_PBREAK_NONE )
480 m_ePageBreakBefore = rProp.m_ePageBreakBefore;
482 if( rProp.m_ePageBreakAfter != SVX_CSS1_PBREAK_NONE )
483 m_ePageBreakAfter = rProp.m_ePageBreakAfter;
485 if( rProp.m_eLeftType != SVX_CSS1_LTYPE_NONE )
487 m_eLeftType = rProp.m_eLeftType;
488 m_nLeft = rProp.m_nLeft;
491 if( rProp.m_eTopType != SVX_CSS1_LTYPE_NONE )
493 m_eTopType = rProp.m_eTopType;
494 m_nTop = rProp.m_nTop;
497 if( rProp.m_eWidthType != SVX_CSS1_LTYPE_NONE )
499 m_eWidthType = rProp.m_eWidthType;
500 m_nWidth = rProp.m_nWidth;
503 if( rProp.m_eHeightType != SVX_CSS1_LTYPE_NONE )
505 m_eHeightType = rProp.m_eHeightType;
506 m_nHeight = rProp.m_nHeight;
510 SvxCSS1BorderInfo *SvxCSS1PropertyInfo::GetBorderInfo( SvxBoxItemLine nLine, bool bCreate )
512 sal_uInt16 nPos = 0;
513 switch( nLine )
515 case SvxBoxItemLine::TOP: nPos = 0; break;
516 case SvxBoxItemLine::BOTTOM: nPos = 1; break;
517 case SvxBoxItemLine::LEFT: nPos = 2; break;
518 case SvxBoxItemLine::RIGHT: nPos = 3; break;
521 if( !m_aBorderInfos[nPos] && bCreate )
522 m_aBorderInfos[nPos] = new SvxCSS1BorderInfo;
524 return m_aBorderInfos[nPos];
527 void SvxCSS1PropertyInfo::CopyBorderInfo( SvxBoxItemLine nSrcLine, SvxBoxItemLine nDstLine,
528 sal_uInt16 nWhat )
530 SvxCSS1BorderInfo *pSrcInfo = GetBorderInfo( nSrcLine, false );
531 if( !pSrcInfo )
532 return;
534 SvxCSS1BorderInfo *pDstInfo = GetBorderInfo( nDstLine );
535 if( (nWhat & SVX_CSS1_BORDERINFO_WIDTH) != 0 )
537 pDstInfo->nAbsWidth = pSrcInfo->nAbsWidth;
538 pDstInfo->nNamedWidth = pSrcInfo->nNamedWidth;
541 if( (nWhat & SVX_CSS1_BORDERINFO_COLOR) != 0 )
542 pDstInfo->aColor = pSrcInfo->aColor;
544 if( (nWhat & SVX_CSS1_BORDERINFO_STYLE) != 0 )
545 pDstInfo->eStyle = pSrcInfo->eStyle;
548 void SvxCSS1PropertyInfo::CopyBorderInfo( sal_uInt16 nCount, sal_uInt16 nWhat )
550 if( nCount==0 )
552 CopyBorderInfo( SvxBoxItemLine::BOTTOM, SvxBoxItemLine::TOP, nWhat );
553 CopyBorderInfo( SvxBoxItemLine::TOP, SvxBoxItemLine::LEFT, nWhat );
555 if( nCount<=1 )
557 CopyBorderInfo( SvxBoxItemLine::LEFT, SvxBoxItemLine::RIGHT, nWhat );
561 void SvxCSS1PropertyInfo::SetBoxItem( SfxItemSet& rItemSet,
562 sal_uInt16 nMinBorderDist,
563 const SvxBoxItem *pDfltItem )
565 bool bChg = m_nTopBorderDistance != USHRT_MAX ||
566 m_nBottomBorderDistance != USHRT_MAX ||
567 m_nLeftBorderDistance != USHRT_MAX ||
568 m_nRightBorderDistance != USHRT_MAX;
570 for( size_t i=0; !bChg && i<SAL_N_ELEMENTS(m_aBorderInfos); ++i )
571 bChg = m_aBorderInfos[i]!=nullptr;
573 if( !bChg )
574 return;
576 SvxBoxItem aBoxItem( aItemIds.nBox );
577 if( pDfltItem )
578 aBoxItem = *pDfltItem;
580 SvxCSS1BorderInfo *pInfo = GetBorderInfo( SvxBoxItemLine::TOP, false );
581 if( pInfo )
582 pInfo->SetBorderLine( SvxBoxItemLine::TOP, aBoxItem );
584 pInfo = GetBorderInfo( SvxBoxItemLine::BOTTOM, false );
585 if( pInfo )
586 pInfo->SetBorderLine( SvxBoxItemLine::BOTTOM, aBoxItem );
588 pInfo = GetBorderInfo( SvxBoxItemLine::LEFT, false );
589 if( pInfo )
590 pInfo->SetBorderLine( SvxBoxItemLine::LEFT, aBoxItem );
592 pInfo = GetBorderInfo( SvxBoxItemLine::RIGHT, false );
593 if( pInfo )
594 pInfo->SetBorderLine( SvxBoxItemLine::RIGHT, aBoxItem );
596 for( size_t i=0; i<SAL_N_ELEMENTS(m_aBorderInfos); ++i )
598 SvxBoxItemLine nLine = SvxBoxItemLine::TOP;
599 sal_uInt16 nDist = 0;
600 switch( i )
602 case 0: nLine = SvxBoxItemLine::TOP;
603 nDist = m_nTopBorderDistance;
604 m_nTopBorderDistance = USHRT_MAX;
605 break;
606 case 1: nLine = SvxBoxItemLine::BOTTOM;
607 nDist = m_nBottomBorderDistance;
608 m_nBottomBorderDistance = USHRT_MAX;
609 break;
610 case 2: nLine = SvxBoxItemLine::LEFT;
611 nDist = m_nLeftBorderDistance;
612 m_nLeftBorderDistance = USHRT_MAX;
613 break;
614 case 3: nLine = SvxBoxItemLine::RIGHT;
615 nDist = m_nRightBorderDistance;
616 m_nRightBorderDistance = USHRT_MAX;
617 break;
620 if( aBoxItem.GetLine( nLine ) )
622 if( USHRT_MAX == nDist )
623 nDist = aBoxItem.GetDistance( nLine );
625 if( nDist < nMinBorderDist )
626 nDist = nMinBorderDist;
628 else
630 nDist = 0U;
633 aBoxItem.SetDistance( nDist, nLine );
636 rItemSet.Put( aBoxItem );
638 DestroyBorderInfos();
641 SvxCSS1MapEntry::SvxCSS1MapEntry( const SfxItemSet& rItemSet,
642 const SvxCSS1PropertyInfo& rProp ) :
643 aItemSet( rItemSet ),
644 aPropInfo( rProp )
647 void SvxCSS1Parser::StyleParsed( const CSS1Selector * /*pSelector*/,
648 SfxItemSet& /*rItemSet*/,
649 SvxCSS1PropertyInfo& /*rPropInfo*/ )
651 // wie man sieht passiert hier gar nichts
654 bool SvxCSS1Parser::SelectorParsed( CSS1Selector *pSelector, bool bFirst )
656 if( bFirst )
658 OSL_ENSURE( pSheetItemSet, "Where is the Item-Set for Style-Sheets?" );
660 for (std::unique_ptr<CSS1Selector> & rpSelection : m_Selectors)
662 StyleParsed(rpSelection.get(), *pSheetItemSet, *pSheetPropInfo);
664 pSheetItemSet->ClearItem();
665 pSheetPropInfo->Clear();
667 // und die naechste Rule vorbereiten
668 m_Selectors.clear();
671 m_Selectors.push_back(std::unique_ptr<CSS1Selector>(pSelector));
673 return false; // den Selektor haben wir gespeichert. Loeschen toedlich!
676 bool SvxCSS1Parser::DeclarationParsed( const OUString& rProperty,
677 const CSS1Expression *pExpr )
679 OSL_ENSURE( pExpr, "DeclarationParsed() without Expression" );
681 if( !pExpr )
682 return true;
684 ParseProperty( rProperty, pExpr );
686 return true; // die Deklaration brauchen wir nicht mehr. Loeschen!
689 SvxCSS1Parser::SvxCSS1Parser( SfxItemPool& rPool, const OUString& rBaseURL,
690 sal_uInt16 *pWhichIds, sal_uInt16 nWhichIds ) :
691 CSS1Parser(),
692 sBaseURL( rBaseURL ),
693 pSheetItemSet(nullptr),
694 pItemSet(nullptr),
695 pSearchEntry( nullptr ),
696 pPropInfo( nullptr ),
697 nMinFixLineSpace( MM50/2 ),
698 eDfltEnc( RTL_TEXTENCODING_DONTKNOW ),
699 nScriptFlags( CSS1_SCRIPT_ALL ),
700 bIgnoreFontFamily( false )
702 // Item-Ids auch initialisieren
703 aItemIds.nFont = rPool.GetTrueWhich( SID_ATTR_CHAR_FONT, false );
704 aItemIds.nFontCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_FONT, false );
705 aItemIds.nFontCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_FONT, false );
706 aItemIds.nPosture = rPool.GetTrueWhich( SID_ATTR_CHAR_POSTURE, false );
707 aItemIds.nPostureCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_POSTURE, false );
708 aItemIds.nPostureCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_POSTURE, false );
709 aItemIds.nWeight = rPool.GetTrueWhich( SID_ATTR_CHAR_WEIGHT, false );
710 aItemIds.nWeightCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_WEIGHT, false );
711 aItemIds.nWeightCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_WEIGHT, false );
712 aItemIds.nFontHeight = rPool.GetTrueWhich( SID_ATTR_CHAR_FONTHEIGHT, false );
713 aItemIds.nFontHeightCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT, false );
714 aItemIds.nFontHeightCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT, false );
715 aItemIds.nUnderline = rPool.GetTrueWhich( SID_ATTR_CHAR_UNDERLINE, false );
716 aItemIds.nOverline = rPool.GetTrueWhich( SID_ATTR_CHAR_OVERLINE, false );
717 aItemIds.nCrossedOut = rPool.GetTrueWhich( SID_ATTR_CHAR_STRIKEOUT, false );
718 aItemIds.nColor = rPool.GetTrueWhich( SID_ATTR_CHAR_COLOR, false );
719 aItemIds.nKerning = rPool.GetTrueWhich( SID_ATTR_CHAR_KERNING, false );
720 aItemIds.nCaseMap = rPool.GetTrueWhich( SID_ATTR_CHAR_CASEMAP, false );
721 aItemIds.nBlink = rPool.GetTrueWhich( SID_ATTR_FLASH, false );
723 aItemIds.nLineSpacing = rPool.GetTrueWhich( SID_ATTR_PARA_LINESPACE, false );
724 aItemIds.nAdjust = rPool.GetTrueWhich( SID_ATTR_PARA_ADJUST, false );
725 aItemIds.nWidows = rPool.GetTrueWhich( SID_ATTR_PARA_WIDOWS, false );
726 aItemIds.nOrphans = rPool.GetTrueWhich( SID_ATTR_PARA_ORPHANS, false );
727 aItemIds.nFormatSplit = rPool.GetTrueWhich( SID_ATTR_PARA_SPLIT, false );
729 aItemIds.nLRSpace = rPool.GetTrueWhich( SID_ATTR_LRSPACE, false );
730 aItemIds.nULSpace = rPool.GetTrueWhich( SID_ATTR_ULSPACE, false );
731 aItemIds.nBox = rPool.GetTrueWhich( SID_ATTR_BORDER_OUTER, false );
732 aItemIds.nBrush = rPool.GetTrueWhich( SID_ATTR_BRUSH, false );
734 aItemIds.nLanguage = rPool.GetTrueWhich( SID_ATTR_CHAR_LANGUAGE, false );
735 aItemIds.nLanguageCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_LANGUAGE, false );
736 aItemIds.nLanguageCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_LANGUAGE, false );
737 aItemIds.nDirection = rPool.GetTrueWhich( SID_ATTR_FRAMEDIRECTION, false );
739 aWhichMap.insert( aWhichMap.begin(), 0 );
740 SvParser::BuildWhichTable( aWhichMap, reinterpret_cast<sal_uInt16 *>(&aItemIds),
741 sizeof(aItemIds) / sizeof(sal_uInt16) );
742 if( pWhichIds && nWhichIds )
743 SvParser::BuildWhichTable( aWhichMap, pWhichIds, nWhichIds );
745 pSheetItemSet = new SfxItemSet( rPool, &aWhichMap[0] );
746 pSheetPropInfo = new SvxCSS1PropertyInfo;
747 pSearchEntry = new SvxCSS1MapEntry( rPool, &aWhichMap[0] );
750 SvxCSS1Parser::~SvxCSS1Parser()
752 delete pSheetItemSet;
753 delete pSheetPropInfo;
754 delete pSearchEntry;
757 void SvxCSS1Parser::InsertId( const OUString& rId,
758 const SfxItemSet& rItemSet,
759 const SvxCSS1PropertyInfo& rProp )
761 InsertMapEntry( rId, rItemSet, rProp, m_Ids );
764 const SvxCSS1MapEntry* SvxCSS1Parser::GetId( const OUString& rId ) const
766 CSS1Map::const_iterator itr = m_Ids.find(rId);
767 return itr == m_Ids.end() ? nullptr : itr->second.get();
770 void SvxCSS1Parser::InsertClass( const OUString& rClass,
771 const SfxItemSet& rItemSet,
772 const SvxCSS1PropertyInfo& rProp )
774 InsertMapEntry( rClass, rItemSet, rProp, m_Classes );
777 const SvxCSS1MapEntry* SvxCSS1Parser::GetClass( const OUString& rClass ) const
779 CSS1Map::const_iterator itr = m_Classes.find(rClass);
780 return itr == m_Classes.end() ? nullptr : itr->second.get();
783 void SvxCSS1Parser::InsertPage( const OUString& rPage,
784 bool bPseudo,
785 const SfxItemSet& rItemSet,
786 const SvxCSS1PropertyInfo& rProp )
788 OUString aKey( rPage );
789 if( bPseudo )
790 aKey = ":" + aKey;
791 InsertMapEntry( aKey, rItemSet, rProp, m_Pages );
794 SvxCSS1MapEntry* SvxCSS1Parser::GetPage( const OUString& rPage, bool bPseudo )
796 OUString aKey( rPage );
797 if( bPseudo )
798 aKey = ":" + aKey;
800 CSS1Map::iterator itr = m_Pages.find(aKey);
801 return itr == m_Pages.end() ? nullptr : itr->second.get();
804 void SvxCSS1Parser::InsertTag( const OUString& rTag,
805 const SfxItemSet& rItemSet,
806 const SvxCSS1PropertyInfo& rProp )
808 InsertMapEntry( rTag, rItemSet, rProp, m_Tags );
811 SvxCSS1MapEntry* SvxCSS1Parser::GetTag( const OUString& rTag )
813 CSS1Map::iterator itr = m_Tags.find(rTag);
814 return itr == m_Tags.end() ? nullptr : itr->second.get();
817 bool SvxCSS1Parser::ParseStyleSheet( const OUString& rIn )
819 pItemSet = pSheetItemSet;
820 pPropInfo = pSheetPropInfo;
822 bool bSuccess = CSS1Parser::ParseStyleSheet( rIn );
824 for (std::unique_ptr<CSS1Selector> & rpSelector : m_Selectors)
826 StyleParsed(rpSelector.get(), *pSheetItemSet, *pSheetPropInfo);
829 // und etwas aufrauemen
830 m_Selectors.clear();
831 pSheetItemSet->ClearItem();
832 pSheetPropInfo->Clear();
834 pItemSet = nullptr;
835 pPropInfo = nullptr;
837 return bSuccess;
840 void SvxCSS1Parser::ParseStyleOption( const OUString& rIn,
841 SfxItemSet& rItemSet,
842 SvxCSS1PropertyInfo& rPropInfo )
844 pItemSet = &rItemSet;
845 pPropInfo = &rPropInfo;
847 CSS1Parser::ParseStyleOption( rIn );
848 rItemSet.ClearItem( aItemIds.nDirection );
850 pItemSet = nullptr;
851 pPropInfo = nullptr;
854 bool SvxCSS1Parser::GetEnum( const CSS1PropertyEnum *pPropTable,
855 const OUString &rValue, sal_uInt16& rEnum )
857 while( pPropTable->pName )
859 if( !rValue.equalsIgnoreAsciiCaseAscii( pPropTable->pName ) )
860 pPropTable++;
861 else
862 break;
865 if( pPropTable->pName )
866 rEnum = pPropTable->nEnum;
868 return (pPropTable->pName != nullptr);
871 void SvxCSS1Parser::PixelToTwip( long &rWidth, long &rHeight )
873 if( Application::GetDefaultDevice() )
875 Size aTwipSz( rWidth, rHeight );
876 aTwipSz = Application::GetDefaultDevice()->PixelToLogic( aTwipSz,
877 MapMode(MapUnit::MapTwip) );
879 rWidth = aTwipSz.Width();
880 rHeight = aTwipSz.Height();
884 sal_uInt32 SvxCSS1Parser::GetFontHeight( sal_uInt16 nSize ) const
886 sal_uInt16 nHeight;
888 switch( nSize )
890 case 0: nHeight = 8*20; break;
891 case 1: nHeight = 10*20; break;
892 case 2: nHeight = 11*20; break;
893 case 3: nHeight = 12*20; break;
894 case 4: nHeight = 17*20; break;
895 case 5: nHeight = 20*20; break;
896 case 6:
897 default: nHeight = 32*20; break;
900 return nHeight;
903 const FontList *SvxCSS1Parser::GetFontList() const
905 return nullptr;
908 void SvxCSS1Parser::InsertMapEntry( const OUString& rKey,
909 const SfxItemSet& rItemSet,
910 const SvxCSS1PropertyInfo& rProp,
911 CSS1Map& rMap )
913 CSS1Map::iterator itr = rMap.find(rKey);
914 if (itr == rMap.end())
916 rMap.insert(std::make_pair(rKey, o3tl::make_unique<SvxCSS1MapEntry>(rItemSet, rProp)));
918 else
920 SvxCSS1MapEntry *const p = itr->second.get();
921 MergeStyles( rItemSet, rProp,
922 p->GetItemSet(), p->GetPropertyInfo(), true );
926 void SvxCSS1Parser::MergeStyles( const SfxItemSet& rSrcSet,
927 const SvxCSS1PropertyInfo& rSrcInfo,
928 SfxItemSet& rTargetSet,
929 SvxCSS1PropertyInfo& rTargetInfo,
930 bool bSmart )
932 if( !bSmart )
934 rTargetSet.Put( rSrcSet );
936 else
938 SvxLRSpaceItem aLRSpace( static_cast<const SvxLRSpaceItem&>(rTargetSet.Get(aItemIds.nLRSpace)) );
939 SvxULSpaceItem aULSpace( static_cast<const SvxULSpaceItem&>(rTargetSet.Get(aItemIds.nULSpace)) );
940 SvxBoxItem aBox( static_cast<const SvxBoxItem&>(rTargetSet.Get(aItemIds.nBox)) );
942 rTargetSet.Put( rSrcSet );
944 if( rSrcInfo.m_bLeftMargin || rSrcInfo.m_bRightMargin ||
945 rSrcInfo.m_bTextIndent )
947 const SvxLRSpaceItem& rNewLRSpace =
948 static_cast<const SvxLRSpaceItem&>(rSrcSet.Get( aItemIds.nLRSpace ));
950 if( rSrcInfo.m_bLeftMargin )
951 aLRSpace.SetLeft( rNewLRSpace.GetLeft() );
952 if( rSrcInfo.m_bRightMargin )
953 aLRSpace.SetRight( rNewLRSpace.GetRight() );
954 if( rSrcInfo.m_bTextIndent )
955 aLRSpace.SetTextFirstLineOfst( rNewLRSpace.GetTextFirstLineOfst() );
957 rTargetSet.Put( aLRSpace );
960 if( rSrcInfo.m_bTopMargin || rSrcInfo.m_bBottomMargin )
962 const SvxULSpaceItem& rNewULSpace =
963 static_cast<const SvxULSpaceItem&>(rSrcSet.Get( aItemIds.nULSpace ));
965 if( rSrcInfo.m_bTopMargin )
966 aULSpace.SetUpper( rNewULSpace.GetUpper() );
967 if( rSrcInfo.m_bBottomMargin )
968 aULSpace.SetLower( rNewULSpace.GetLower() );
970 rTargetSet.Put( aULSpace );
974 rTargetInfo.Merge( rSrcInfo );
977 void SvxCSS1Parser::SetDfltEncoding( rtl_TextEncoding eEnc )
979 eDfltEnc = eEnc;
982 static void ParseCSS1_font_size( const CSS1Expression *pExpr,
983 SfxItemSet &rItemSet,
984 SvxCSS1PropertyInfo& /*rPropInfo*/,
985 const SvxCSS1Parser& rParser )
987 OSL_ENSURE( pExpr, "no expression" );
989 sal_uLong nHeight = 0;
990 sal_uInt16 nPropHeight = 100;
992 switch( pExpr->GetType() )
994 case CSS1_LENGTH:
995 nHeight = pExpr->GetULength();
996 break;
997 case CSS1_PIXLENGTH:
999 long nPWidth = 0;
1000 long nPHeight = (long)pExpr->GetNumber();
1001 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
1002 nHeight = (sal_uLong)nPHeight;
1004 break;
1005 case CSS1_PERCENTAGE:
1006 // nur fuer Drop-Caps!
1007 nPropHeight = (sal_uInt16)pExpr->GetNumber();
1008 break;
1009 case CSS1_IDENT:
1011 sal_uInt16 nSize;
1013 if( SvxCSS1Parser::GetEnum( aFontSizeTable, pExpr->GetString(),
1014 nSize ) )
1016 nHeight = rParser.GetFontHeight( nSize );
1019 break;
1021 default:
1025 if( nHeight || nPropHeight!=100 )
1027 SvxFontHeightItem aFontHeight( nHeight, nPropHeight,
1028 aItemIds.nFontHeight );
1029 if( rParser.IsSetWesternProps() )
1030 rItemSet.Put( aFontHeight );
1031 if( rParser.IsSetCJKProps() )
1033 aFontHeight.SetWhich( aItemIds.nFontHeightCJK );
1034 rItemSet.Put( aFontHeight );
1036 if( rParser.IsSetCTLProps() )
1038 aFontHeight.SetWhich( aItemIds.nFontHeightCTL );
1039 rItemSet.Put( aFontHeight );
1044 static void ParseCSS1_font_family( const CSS1Expression *pExpr,
1045 SfxItemSet &rItemSet,
1046 SvxCSS1PropertyInfo& /*rPropInfo*/,
1047 const SvxCSS1Parser& rParser )
1049 OSL_ENSURE( pExpr, "no expression" );
1051 OUString aName, aStyleName;
1052 FontFamily eFamily = FAMILY_DONTKNOW;
1053 FontPitch ePitch = PITCH_DONTKNOW;
1054 rtl_TextEncoding eEnc = rParser.GetDfltEncoding();
1055 const FontList *pFList = rParser.GetFontList();
1056 bool bFirst = true;
1057 bool bFound = false;
1058 while( pExpr && (bFirst || ','==pExpr->GetOp() || !pExpr->GetOp()) )
1060 CSS1Token eType = pExpr->GetType();
1061 if( CSS1_IDENT==eType || CSS1_STRING==eType )
1063 OUString aIdent( pExpr->GetString() );
1065 if( CSS1_IDENT==eType )
1067 // Alle nachfolgenden id's sammeln und mit einem
1068 // Space getrennt hintendranhaengen
1069 const CSS1Expression *pNext = pExpr->GetNext();
1070 while( pNext && !pNext->GetOp() &&
1071 CSS1_IDENT==pNext->GetType() )
1073 aIdent += " " + pNext->GetString();
1074 pExpr = pNext;
1075 pNext = pExpr->GetNext();
1078 if( !aIdent.isEmpty() )
1080 if( !bFound && pFList )
1082 sal_Handle hFont = pFList->GetFirstFontMetric( aIdent );
1083 if( nullptr != hFont )
1085 const FontMetric& rFMetric = FontList::GetFontMetric( hFont );
1086 if( RTL_TEXTENCODING_DONTKNOW != rFMetric.GetCharSet() )
1088 bFound = true;
1089 if( RTL_TEXTENCODING_SYMBOL == rFMetric.GetCharSet() )
1090 eEnc = RTL_TEXTENCODING_SYMBOL;
1094 if( !bFirst )
1095 aName += ";";
1096 aName += aIdent;
1100 pExpr = pExpr->GetNext();
1101 bFirst = false;
1104 if( !aName.isEmpty() && !rParser.IsIgnoreFontFamily() )
1106 SvxFontItem aFont( eFamily, aName, aStyleName, ePitch,
1107 eEnc, aItemIds.nFont );
1108 if( rParser.IsSetWesternProps() )
1109 rItemSet.Put( aFont );
1110 if( rParser.IsSetCJKProps() )
1112 aFont.SetWhich( aItemIds.nFontCJK );
1113 rItemSet.Put( aFont );
1115 if( rParser.IsSetCTLProps() )
1117 aFont.SetWhich( aItemIds.nFontCTL );
1118 rItemSet.Put( aFont );
1123 static void ParseCSS1_font_weight( const CSS1Expression *pExpr,
1124 SfxItemSet &rItemSet,
1125 SvxCSS1PropertyInfo& /*rPropInfo*/,
1126 const SvxCSS1Parser& rParser )
1128 OSL_ENSURE( pExpr, "no expression" );
1130 switch( pExpr->GetType() )
1132 case CSS1_IDENT:
1133 case CSS1_STRING: // MS-IE, was sonst
1135 sal_uInt16 nWeight;
1136 if( SvxCSS1Parser::GetEnum( aFontWeightTable, pExpr->GetString(),
1137 nWeight ) )
1139 SvxWeightItem aWeight( (FontWeight)nWeight, aItemIds.nWeight );
1140 if( rParser.IsSetWesternProps() )
1141 rItemSet.Put( aWeight );
1142 if( rParser.IsSetCJKProps() )
1144 aWeight.SetWhich( aItemIds.nWeightCJK );
1145 rItemSet.Put( aWeight );
1147 if( rParser.IsSetCTLProps() )
1149 aWeight.SetWhich( aItemIds.nWeightCTL );
1150 rItemSet.Put( aWeight );
1154 break;
1155 case CSS1_NUMBER:
1157 sal_uInt16 nWeight = (sal_uInt16)pExpr->GetNumber();
1158 SvxWeightItem aWeight( nWeight>400 ? WEIGHT_BOLD : WEIGHT_NORMAL,
1159 aItemIds.nWeight );
1160 if( rParser.IsSetWesternProps() )
1161 rItemSet.Put( aWeight );
1162 if( rParser.IsSetCJKProps() )
1164 aWeight.SetWhich( aItemIds.nWeightCJK );
1165 rItemSet.Put( aWeight );
1167 if( rParser.IsSetCTLProps() )
1169 aWeight.SetWhich( aItemIds.nWeightCTL );
1170 rItemSet.Put( aWeight );
1173 break;
1175 default:
1180 static void ParseCSS1_font_style( const CSS1Expression *pExpr,
1181 SfxItemSet &rItemSet,
1182 SvxCSS1PropertyInfo& /*rPropInfo*/,
1183 const SvxCSS1Parser& rParser )
1185 OSL_ENSURE( pExpr, "no expression" );
1187 bool bPosture = false;
1188 bool bCaseMap = false;
1189 FontItalic eItalic = ITALIC_NONE;
1190 SvxCaseMap eCaseMap = SVX_CASEMAP_NOT_MAPPED;
1192 // normal | italic || small-caps | oblique || small-caps | small-caps
1193 // (wobei nor noch normal | italic und oblique zulaessig sind
1195 // der Wert kann zwei Werte enthalten!
1196 for( int i=0; pExpr && i<2; ++i )
1198 // Auch hier hinterlaesst MS-IEs Parser seine Spuren
1199 if( (CSS1_IDENT==pExpr->GetType() || CSS1_STRING==pExpr->GetType()) &&
1200 !pExpr->GetOp() )
1202 const OUString& rValue = pExpr->GetString();
1203 // erstmal pruefen, ob es ein Italic-Wert oder 'normal' ist
1204 sal_uInt16 nItalic;
1205 if( SvxCSS1Parser::GetEnum( aFontStyleTable, rValue, nItalic ) )
1207 eItalic = (FontItalic)nItalic;
1208 if( !bCaseMap && ITALIC_NONE==eItalic )
1210 // fuer 'normal' muessen wir auch die case-map aussch.
1211 eCaseMap = SVX_CASEMAP_NOT_MAPPED;
1212 bCaseMap = true;
1214 bPosture = true;
1216 else if( !bCaseMap &&
1217 rValue.equalsIgnoreAsciiCase( "small-caps" ) )
1219 eCaseMap = SVX_CASEMAP_KAPITAELCHEN;
1220 bCaseMap = true;
1224 // den naechsten Ausdruck holen
1225 pExpr = pExpr->GetNext();
1228 if( bPosture )
1230 SvxPostureItem aPosture( eItalic, aItemIds.nPosture );
1231 if( rParser.IsSetWesternProps() )
1232 rItemSet.Put( aPosture );
1233 if( rParser.IsSetCJKProps() )
1235 aPosture.SetWhich( aItemIds.nPostureCJK );
1236 rItemSet.Put( aPosture );
1238 if( rParser.IsSetCTLProps() )
1240 aPosture.SetWhich( aItemIds.nPostureCTL );
1241 rItemSet.Put( aPosture );
1245 if( bCaseMap )
1246 rItemSet.Put( SvxCaseMapItem( eCaseMap, aItemIds.nCaseMap ) );
1249 static void ParseCSS1_font_variant( const CSS1Expression *pExpr,
1250 SfxItemSet &rItemSet,
1251 SvxCSS1PropertyInfo& /*rPropInfo*/,
1252 const SvxCSS1Parser& /*rParser*/ )
1254 assert(pExpr && "no expression");
1256 // normal | small-caps
1257 switch( pExpr->GetType() )
1259 case CSS1_IDENT:
1261 sal_uInt16 nCaseMap;
1262 if( SvxCSS1Parser::GetEnum( aFontVariantTable, pExpr->GetString(),
1263 nCaseMap ) )
1265 rItemSet.Put( SvxCaseMapItem( (SvxCaseMap)nCaseMap,
1266 aItemIds.nCaseMap ) );
1268 break;
1270 default:
1271 break;
1275 static void ParseCSS1_text_transform( const CSS1Expression *pExpr,
1276 SfxItemSet &rItemSet,
1277 SvxCSS1PropertyInfo& /*rPropInfo*/,
1278 const SvxCSS1Parser& /*rParser*/ )
1280 OSL_ENSURE( pExpr, "no expression" );
1282 // none | capitalize | uppercase | lowercase
1284 switch( pExpr->GetType() )
1286 case CSS1_IDENT:
1288 sal_uInt16 nCaseMap;
1289 if( SvxCSS1Parser::GetEnum( aTextTransformTable, pExpr->GetString(),
1290 nCaseMap ) )
1292 rItemSet.Put( SvxCaseMapItem( (SvxCaseMap)nCaseMap,
1293 aItemIds.nCaseMap ) );
1295 break;
1297 default:
1298 break;
1302 static void ParseCSS1_color( const CSS1Expression *pExpr,
1303 SfxItemSet &rItemSet,
1304 SvxCSS1PropertyInfo& /*rPropInfo*/,
1305 const SvxCSS1Parser& /*rParser*/ )
1307 OSL_ENSURE( pExpr, "no expression" );
1309 switch( pExpr->GetType() )
1311 case CSS1_IDENT:
1312 case CSS1_RGB:
1313 case CSS1_HEXCOLOR:
1314 case CSS1_STRING: // Wegen MS-IE
1316 Color aColor;
1317 if( pExpr->GetColor( aColor ) )
1318 rItemSet.Put( SvxColorItem( aColor, aItemIds.nColor ) );
1320 break;
1321 default:
1326 static void ParseCSS1_column_count( const CSS1Expression *pExpr,
1327 SfxItemSet& /*rItemSet*/,
1328 SvxCSS1PropertyInfo &rPropInfo,
1329 const SvxCSS1Parser& /*rParser*/ )
1331 assert(pExpr && "no expression");
1333 if ( pExpr->GetType() == CSS1_NUMBER )
1335 double columnCount = pExpr->GetNumber();
1336 if ( columnCount >= 2 )
1338 rPropInfo.m_nColumnCount = columnCount;
1343 static void ParseCSS1_direction( const CSS1Expression *pExpr,
1344 SfxItemSet &rItemSet,
1345 SvxCSS1PropertyInfo& /*rPropInfo*/,
1346 const SvxCSS1Parser& /*rParser*/ )
1348 assert(pExpr && "no expression");
1350 sal_uInt16 nDir;
1351 switch( pExpr->GetType() )
1353 case CSS1_IDENT:
1354 case CSS1_STRING:
1355 if( SvxCSS1Parser::GetEnum( aDirectionTable, pExpr->GetString(),
1356 nDir ) )
1358 rItemSet.Put( SvxFrameDirectionItem(
1359 static_cast < SvxFrameDirection >( nDir ),
1360 aItemIds.nDirection ) );
1362 break;
1363 default:
1368 static void MergeHori( SvxGraphicPosition& ePos, SvxGraphicPosition eHori )
1370 OSL_ENSURE( GPOS_LT==eHori || GPOS_MT==eHori || GPOS_RT==eHori,
1371 "vertical position not at the top" );
1373 switch( ePos )
1375 case GPOS_LT:
1376 case GPOS_MT:
1377 case GPOS_RT:
1378 ePos = eHori;
1379 break;
1381 case GPOS_LM:
1382 case GPOS_MM:
1383 case GPOS_RM:
1384 ePos = GPOS_LT==eHori ? GPOS_LM : (GPOS_MT==eHori ? GPOS_MM : GPOS_RM);
1385 break;
1387 case GPOS_LB:
1388 case GPOS_MB:
1389 case GPOS_RB:
1390 ePos = GPOS_LT==eHori ? GPOS_LB : (GPOS_MT==eHori ? GPOS_MB : GPOS_RB);
1391 break;
1393 default:
1398 static void MergeVert( SvxGraphicPosition& ePos, SvxGraphicPosition eVert )
1400 OSL_ENSURE( GPOS_LT==eVert || GPOS_LM==eVert || GPOS_LB==eVert,
1401 "horizontal position not on the left side" );
1403 switch( ePos )
1405 case GPOS_LT:
1406 case GPOS_LM:
1407 case GPOS_LB:
1408 ePos = eVert;
1409 break;
1411 case GPOS_MT:
1412 case GPOS_MM:
1413 case GPOS_MB:
1414 ePos = GPOS_LT==eVert ? GPOS_MT : (GPOS_LM==eVert ? GPOS_MM : GPOS_MB);
1415 break;
1417 case GPOS_RT:
1418 case GPOS_RM:
1419 case GPOS_RB:
1420 ePos = GPOS_LT==eVert ? GPOS_RT : (GPOS_LM==eVert ? GPOS_RM : GPOS_RB);
1421 break;
1423 default:
1428 static void ParseCSS1_background( const CSS1Expression *pExpr,
1429 SfxItemSet &rItemSet,
1430 SvxCSS1PropertyInfo& /*rPropInfo*/,
1431 const SvxCSS1Parser& rParser )
1433 OSL_ENSURE( pExpr, "no expression" );
1435 Color aColor;
1436 OUString aURL;
1438 bool bColor = false, bTransparent = false;
1439 SvxGraphicPosition eRepeat = GPOS_TILED;
1440 SvxGraphicPosition ePos = GPOS_LT;
1441 bool bHori = false, bVert = false;
1443 while( pExpr && !pExpr->GetOp() )
1445 switch( pExpr->GetType() )
1447 case CSS1_URL:
1448 pExpr->GetURL( aURL );
1449 break;
1451 case CSS1_RGB:
1452 bColor = pExpr->GetColor( aColor );
1453 break;
1455 case CSS1_LENGTH:
1456 case CSS1_PIXLENGTH:
1458 // da wir keine absolute Positionierung koennen,
1459 // unterscheiden wir nur zwischen 0 und !0. Deshalb
1460 // koennen Pixel auch wie alle anderen Einheiten behandelt
1461 // werden.
1463 sal_uLong nLength = (sal_uLong)pExpr->GetNumber();
1464 if( !bHori )
1466 ePos = nLength ? GPOS_MM : GPOS_LT;
1467 bHori = true;
1469 else if( !bVert )
1471 MergeVert( ePos, (nLength ? GPOS_LM : GPOS_LT) );
1472 bVert = true;
1475 break;
1477 case CSS1_PERCENTAGE:
1479 // die %-Angabe wird auf den enum abgebildet
1481 sal_uInt16 nPerc = (sal_uInt16)pExpr->GetNumber();
1482 if( !bHori )
1484 ePos = nPerc < 25 ? GPOS_LT
1485 : (nPerc < 75 ? GPOS_MM
1486 : GPOS_RB);
1488 else if( !bVert )
1490 SvxGraphicPosition eVert =
1491 nPerc < 25 ? GPOS_LT: (nPerc < 75 ? GPOS_LM
1492 : GPOS_LB);
1493 MergeVert( ePos, eVert );
1496 break;
1498 case CSS1_IDENT:
1499 case CSS1_HEXCOLOR:
1500 case CSS1_STRING: // Wegen MS-IE
1502 sal_uInt16 nEnum;
1503 const OUString &rValue = pExpr->GetString();
1504 if( rValue.equalsIgnoreAsciiCase( "transparent" ) )
1506 bTransparent = true;
1508 if( SvxCSS1Parser::GetEnum( aBGRepeatTable, rValue, nEnum ) )
1510 eRepeat = (SvxGraphicPosition)nEnum;
1512 else if( SvxCSS1Parser::GetEnum( aBGHoriPosTable, rValue, nEnum ) )
1514 // <position>, horizontal
1515 MergeHori( ePos, (SvxGraphicPosition)nEnum );
1517 else if( SvxCSS1Parser::GetEnum( aBGVertPosTable, rValue, nEnum ) )
1519 // <position>, vertikal
1520 MergeVert( ePos, (SvxGraphicPosition)nEnum );
1522 else if( !bColor )
1524 // <color>
1525 bColor = pExpr->GetColor( aColor );
1527 // <scroll> kennen wir nicht
1529 break;
1531 default:
1535 pExpr = pExpr->GetNext();
1538 // transparent schlaegt alles
1539 if( bTransparent )
1541 bColor = false;
1542 aURL.clear();
1545 // repeat hat prio gegenueber einer Position
1546 if( GPOS_NONE == eRepeat )
1547 eRepeat = ePos;
1549 if( bTransparent || bColor || !aURL.isEmpty() )
1551 SvxBrushItem aBrushItem( aItemIds.nBrush );
1553 if( bTransparent )
1554 aBrushItem.SetColor( Color(COL_TRANSPARENT));
1555 else if( bColor )
1556 aBrushItem.SetColor( aColor );
1558 if( !aURL.isEmpty() )
1560 aBrushItem.SetGraphicLink( URIHelper::SmartRel2Abs( INetURLObject( rParser.GetBaseURL()), aURL, Link<OUString *, bool>(), false ) );
1561 aBrushItem.SetGraphicPos( eRepeat );
1564 rItemSet.Put( aBrushItem );
1568 static void ParseCSS1_background_color( const CSS1Expression *pExpr,
1569 SfxItemSet &rItemSet,
1570 SvxCSS1PropertyInfo& /*rPropInfo*/,
1571 const SvxCSS1Parser& /*rParser*/ )
1573 OSL_ENSURE( pExpr, "no expression" );
1575 Color aColor;
1577 bool bColor = false, bTransparent = false;
1579 switch( pExpr->GetType() )
1581 case CSS1_RGB:
1582 bColor = pExpr->GetColor( aColor );
1583 break;
1584 case CSS1_IDENT:
1585 case CSS1_HEXCOLOR:
1586 case CSS1_STRING: // Wegen MS-IE
1587 if( pExpr->GetString().equalsIgnoreAsciiCase( "transparent" ) )
1589 bTransparent = true;
1591 else
1593 // <color>
1594 bColor = pExpr->GetColor( aColor );
1596 break;
1597 default:
1601 if( bTransparent || bColor )
1603 SvxBrushItem aBrushItem( aItemIds.nBrush );
1605 if( bTransparent )
1606 aBrushItem.SetColor( Color(COL_TRANSPARENT) );
1607 else if( bColor )
1608 aBrushItem.SetColor( aColor);
1610 rItemSet.Put( aBrushItem );
1614 static void ParseCSS1_line_height( const CSS1Expression *pExpr,
1615 SfxItemSet &rItemSet,
1616 SvxCSS1PropertyInfo& /*rPropInfo*/,
1617 const SvxCSS1Parser& rParser )
1619 OSL_ENSURE( pExpr, "no expression" );
1621 sal_uInt16 nHeight = 0;
1622 sal_uInt8 nPropHeight = 0;
1624 switch( pExpr->GetType() )
1626 case CSS1_LENGTH:
1627 nHeight = (sal_uInt16)pExpr->GetULength();
1628 break;
1629 case CSS1_PIXLENGTH:
1631 long nPWidth = 0;
1632 long nPHeight = (long)pExpr->GetNumber();
1633 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
1634 nHeight = (sal_uInt16)nPHeight;
1636 break;
1637 case CSS1_PERCENTAGE:
1639 sal_uInt16 nPHeight = (sal_uInt16)pExpr->GetNumber();
1640 nPropHeight = nPHeight <= 200 ? (sal_uInt8)nPHeight : 200;
1642 break;
1643 case CSS1_NUMBER:
1645 sal_uInt16 nPHeight = (sal_uInt16)(pExpr->GetNumber() * 100);
1646 nPropHeight = nPHeight <= 200 ? (sal_uInt8)nPHeight : 200;
1648 break;
1649 default:
1653 if( nHeight )
1655 if( nHeight < rParser.GetMinFixLineSpace() )
1656 nHeight = rParser.GetMinFixLineSpace();
1657 SvxLineSpacingItem aLSItem( nHeight, aItemIds.nLineSpacing );
1658 aLSItem.SetLineHeight( nHeight );
1659 // interpret <line-height> attribute as minimum line height
1660 aLSItem.SetLineSpaceRule( SvxLineSpaceRule::Min );
1661 aLSItem.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off );
1662 rItemSet.Put( aLSItem );
1664 else if( nPropHeight )
1666 SvxLineSpacingItem aLSItem( nPropHeight, aItemIds.nLineSpacing );
1667 aLSItem.SetLineSpaceRule( SvxLineSpaceRule::Auto );
1668 if( 100 == nPropHeight )
1669 aLSItem.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off );
1670 else
1671 aLSItem.SetPropLineSpace( nPropHeight );
1672 rItemSet.Put( aLSItem );
1677 static void ParseCSS1_font( const CSS1Expression *pExpr,
1678 SfxItemSet &rItemSet,
1679 SvxCSS1PropertyInfo& rPropInfo,
1680 const SvxCSS1Parser& rParser )
1682 OSL_ENSURE( pExpr, "no expression" );
1684 FontItalic eItalic = ITALIC_NONE;
1685 SvxCaseMap eCaseMap = SVX_CASEMAP_NOT_MAPPED;
1686 FontWeight eWeight = WEIGHT_NORMAL;
1688 // [ <font-style> || <font-variant> || <font-weight> ] ?
1689 while( pExpr && !pExpr->GetOp() &&
1690 (CSS1_IDENT==pExpr->GetType() ||
1691 CSS1_STRING==pExpr->GetType() ||
1692 CSS1_NUMBER==pExpr->GetType()) )
1694 if( CSS1_IDENT==pExpr->GetType() ||
1695 CSS1_STRING==pExpr->GetType() )
1697 const OUString& rValue = pExpr->GetString();
1699 sal_uInt16 nEnum;
1701 if( SvxCSS1Parser::GetEnum( aFontStyleTable, rValue, nEnum ) )
1703 eItalic = (FontItalic)nEnum;
1705 else if( SvxCSS1Parser::GetEnum( aFontVariantTable, rValue, nEnum ) )
1707 eCaseMap = (SvxCaseMap)nEnum;
1709 else if( SvxCSS1Parser::GetEnum( aFontWeightTable, rValue, nEnum ) )
1711 eWeight = (FontWeight)nEnum;
1714 else
1716 eWeight = (sal_uInt16)pExpr->GetNumber() > 400 ? WEIGHT_BOLD
1717 : WEIGHT_NORMAL;
1720 pExpr = pExpr->GetNext();
1723 if( !pExpr || pExpr->GetOp() )
1724 return;
1726 // Da "font" alle Werte zurecksetzt, fuer die nichts angegeben ist,
1727 // tun wir das hier.
1728 SvxPostureItem aPosture( eItalic, aItemIds.nPosture );
1729 if( rParser.IsSetWesternProps() )
1730 rItemSet.Put( aPosture );
1731 if( rParser.IsSetCJKProps() )
1733 aPosture.SetWhich( aItemIds.nPostureCJK );
1734 rItemSet.Put( aPosture );
1736 if( rParser.IsSetCTLProps() )
1738 aPosture.SetWhich( aItemIds.nPostureCTL );
1739 rItemSet.Put( aPosture );
1742 rItemSet.Put( SvxCaseMapItem( eCaseMap, aItemIds.nCaseMap ) );
1744 SvxWeightItem aWeight( eWeight, aItemIds.nWeight );
1745 if( rParser.IsSetWesternProps() )
1746 rItemSet.Put( aWeight );
1747 if( rParser.IsSetCJKProps() )
1749 aWeight.SetWhich( aItemIds.nWeightCJK );
1750 rItemSet.Put( aWeight );
1752 if( rParser.IsSetCTLProps() )
1754 aWeight.SetWhich( aItemIds.nWeightCTL );
1755 rItemSet.Put( aWeight );
1758 // font-size
1759 CSS1Expression aExpr( pExpr->GetType(), pExpr->GetString(),
1760 pExpr->GetNumber() );
1761 ParseCSS1_font_size( &aExpr, rItemSet, rPropInfo, rParser );
1762 pExpr = pExpr->GetNext();
1764 if( !pExpr )
1765 return;
1767 // [ '/' line-height ]?
1768 if( '/' == pExpr->GetOp() )
1770 // '/' line-height
1771 aExpr.Set( pExpr->GetType(), pExpr->GetString(), pExpr->GetNumber() );
1772 ParseCSS1_line_height( &aExpr, rItemSet, rPropInfo, rParser );
1774 pExpr = pExpr->GetNext();
1777 if( !pExpr || pExpr->GetOp() )
1778 return;
1780 // font-family
1781 ParseCSS1_font_family( pExpr, rItemSet, rPropInfo, rParser );
1784 static void ParseCSS1_letter_spacing( const CSS1Expression *pExpr,
1785 SfxItemSet &rItemSet,
1786 SvxCSS1PropertyInfo& /*rPropInfo*/,
1787 const SvxCSS1Parser& /*rParser*/ )
1789 OSL_ENSURE( pExpr, "no expression" );
1791 switch( pExpr->GetType() )
1793 case CSS1_LENGTH:
1794 rItemSet.Put( SvxKerningItem( (short)pExpr->GetSLength(),
1795 aItemIds.nKerning ) );
1796 break;
1798 case CSS1_PIXLENGTH:
1800 long nPWidth = (long)pExpr->GetNumber();
1801 long nPHeight = 0;
1802 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
1803 rItemSet.Put( SvxKerningItem( (short)nPWidth, aItemIds.nKerning ) );
1805 break;
1807 case CSS1_NUMBER:
1808 if( pExpr->GetNumber() == 0 )
1810 // eigentlich unnoetig, aber wir sind ja tollerant
1811 rItemSet.Put( SvxKerningItem( (short)0, aItemIds.nKerning ) );
1813 break;
1815 case CSS1_IDENT:
1816 case CSS1_STRING: // Vorschtshalber auch MS-IE
1817 if( pExpr->GetString().equalsIgnoreAsciiCase( "normal" ) )
1819 rItemSet.Put( SvxKerningItem( (short)0, aItemIds.nKerning ) );
1821 break;
1822 default:
1827 static void ParseCSS1_text_decoration( const CSS1Expression *pExpr,
1828 SfxItemSet &rItemSet,
1829 SvxCSS1PropertyInfo& /*rPropInfo*/,
1830 const SvxCSS1Parser& /*rParser*/ )
1832 OSL_ENSURE( pExpr, "no expression" );
1834 bool bUnderline = false;
1835 bool bOverline = false;
1836 bool bCrossedOut = false;
1837 bool bBlink = false;
1838 bool bBlinkOn = false;
1839 FontLineStyle eUnderline = LINESTYLE_NONE;
1840 FontLineStyle eOverline = LINESTYLE_NONE;
1841 FontStrikeout eCrossedOut = STRIKEOUT_NONE;
1843 // der Wert kann zwei Werte enthalten! Und MS-IE auch Strings
1844 while( pExpr && (pExpr->GetType() == CSS1_IDENT ||
1845 pExpr->GetType() == CSS1_STRING) && !pExpr->GetOp() )
1847 OUString aValue = pExpr->GetString().toAsciiLowerCase();
1848 bool bKnown = false;
1850 switch( aValue[0] )
1852 case 'n':
1853 if( aValue == "none" )
1855 bUnderline = true;
1856 eUnderline = LINESTYLE_NONE;
1858 bOverline = true;
1859 eOverline = LINESTYLE_NONE;
1861 bCrossedOut = true;
1862 eCrossedOut = STRIKEOUT_NONE;
1864 bBlink = true;
1865 bBlinkOn = false;
1867 bKnown = true;
1869 break;
1871 case 'u':
1872 if( aValue == "underline" )
1874 bUnderline = true;
1875 eUnderline = LINESTYLE_SINGLE;
1877 bKnown = true;
1879 break;
1881 case 'o':
1882 if( aValue == "overline" )
1884 bOverline = true;
1885 eOverline = LINESTYLE_SINGLE;
1887 bKnown = true;
1889 break;
1891 case 'l':
1892 if( aValue == "line-through" )
1894 bCrossedOut = true;
1895 eCrossedOut = STRIKEOUT_SINGLE;
1897 bKnown = true;
1899 break;
1901 case 'b':
1902 if( aValue == "blink" )
1904 bBlink = true;
1905 bBlinkOn = true;
1907 bKnown = true;
1909 break;
1912 if( !bKnown )
1914 bUnderline = true;
1915 eUnderline = LINESTYLE_SINGLE;
1918 pExpr = pExpr->GetNext();
1921 if( bUnderline )
1922 rItemSet.Put( SvxUnderlineItem( eUnderline, aItemIds.nUnderline ) );
1924 if( bOverline )
1925 rItemSet.Put( SvxOverlineItem( eOverline, aItemIds.nOverline ) );
1927 if( bCrossedOut )
1928 rItemSet.Put( SvxCrossedOutItem( eCrossedOut, aItemIds.nCrossedOut ) );
1930 if( bBlink )
1931 rItemSet.Put( SvxBlinkItem( bBlinkOn, aItemIds.nBlink ) );
1934 static void ParseCSS1_text_align( const CSS1Expression *pExpr,
1935 SfxItemSet &rItemSet,
1936 SvxCSS1PropertyInfo& /*rPropInfo*/,
1937 const SvxCSS1Parser& /*rParser*/ )
1939 OSL_ENSURE( pExpr, "no expression" );
1941 if( CSS1_IDENT==pExpr->GetType() ||
1942 CSS1_STRING==pExpr->GetType() ) // MS-IE, mal wieder
1944 sal_uInt16 nAdjust;
1945 if( SvxCSS1Parser::GetEnum( aTextAlignTable, pExpr->GetString(),
1946 nAdjust ) )
1948 rItemSet.Put( SvxAdjustItem( (SvxAdjust)nAdjust,
1949 aItemIds.nAdjust ) );
1954 static void ParseCSS1_text_indent( const CSS1Expression *pExpr,
1955 SfxItemSet &rItemSet,
1956 SvxCSS1PropertyInfo& rPropInfo,
1957 const SvxCSS1Parser& /*rParser*/ )
1959 OSL_ENSURE( pExpr, "no expression" );
1961 short nIndent = 0;
1962 bool bSet = false;
1963 switch( pExpr->GetType() )
1965 case CSS1_LENGTH:
1966 nIndent = (short)pExpr->GetSLength();
1967 bSet = true;
1968 break;
1969 case CSS1_PIXLENGTH:
1971 long nPWidth = (long)pExpr->GetNumber();
1972 long nPHeight = 0;
1973 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
1974 nIndent = (short)nPWidth;
1975 bSet = true;
1977 break;
1978 case CSS1_PERCENTAGE:
1979 // koennen wir nicht
1980 break;
1981 default:
1985 if( bSet )
1987 const SfxPoolItem* pItem;
1988 if( SfxItemState::SET == rItemSet.GetItemState( aItemIds.nLRSpace, false,
1989 &pItem ) )
1991 SvxLRSpaceItem aLRItem( *static_cast<const SvxLRSpaceItem*>(pItem) );
1992 aLRItem.SetTextFirstLineOfst( nIndent );
1993 rItemSet.Put( aLRItem );
1995 else
1997 SvxLRSpaceItem aLRItem( aItemIds.nLRSpace );
1998 aLRItem.SetTextFirstLineOfst( nIndent );
1999 rItemSet.Put( aLRItem );
2001 rPropInfo.m_bTextIndent = true;
2005 static void ParseCSS1_margin_left( const CSS1Expression *pExpr,
2006 SfxItemSet &rItemSet,
2007 SvxCSS1PropertyInfo& rPropInfo,
2008 const SvxCSS1Parser& /*rParser*/ )
2010 OSL_ENSURE( pExpr, "no expression" );
2012 long nLeft = 0;
2013 bool bSet = false;
2014 switch( pExpr->GetType() )
2016 case CSS1_LENGTH:
2018 nLeft = pExpr->GetSLength();
2019 bSet = true;
2021 break;
2022 case CSS1_PIXLENGTH:
2024 nLeft = (long)pExpr->GetNumber();
2025 long nPHeight = 0;
2026 SvxCSS1Parser::PixelToTwip( nLeft, nPHeight );
2027 bSet = true;
2029 break;
2030 case CSS1_PERCENTAGE:
2031 // koennen wir nicht
2032 break;
2033 default:
2037 if( bSet )
2039 rPropInfo.m_nLeftMargin = nLeft;
2040 if( nLeft < 0 )
2041 nLeft = 0;
2042 const SfxPoolItem* pItem;
2043 if( SfxItemState::SET == rItemSet.GetItemState( aItemIds.nLRSpace, false,
2044 &pItem ) )
2046 SvxLRSpaceItem aLRItem( *static_cast<const SvxLRSpaceItem*>(pItem) );
2047 aLRItem.SetTextLeft( (sal_uInt16)nLeft );
2048 rItemSet.Put( aLRItem );
2050 else
2052 SvxLRSpaceItem aLRItem( aItemIds.nLRSpace );
2053 aLRItem.SetTextLeft( (sal_uInt16)nLeft );
2054 rItemSet.Put( aLRItem );
2056 rPropInfo.m_bLeftMargin = true;
2060 static void ParseCSS1_margin_right( const CSS1Expression *pExpr,
2061 SfxItemSet &rItemSet,
2062 SvxCSS1PropertyInfo& rPropInfo,
2063 const SvxCSS1Parser& /*rParser*/ )
2065 OSL_ENSURE( pExpr, "no expression" );
2067 long nRight = 0;
2068 bool bSet = false;
2069 switch( pExpr->GetType() )
2071 case CSS1_LENGTH:
2073 nRight = pExpr->GetSLength();
2074 bSet = true;
2076 break;
2077 case CSS1_PIXLENGTH:
2079 nRight = (long)pExpr->GetNumber();
2080 long nPHeight = 0;
2081 SvxCSS1Parser::PixelToTwip( nRight, nPHeight );
2082 bSet = true;
2084 break;
2085 case CSS1_PERCENTAGE:
2086 // koennen wir nicht
2087 break;
2088 default:
2092 if( bSet )
2094 rPropInfo.m_nRightMargin = nRight;
2095 if( nRight < 0 )
2096 nRight = 0;
2097 const SfxPoolItem* pItem;
2098 if( SfxItemState::SET == rItemSet.GetItemState( aItemIds.nLRSpace, false,
2099 &pItem ) )
2101 SvxLRSpaceItem aLRItem( *static_cast<const SvxLRSpaceItem*>(pItem) );
2102 aLRItem.SetRight( (sal_uInt16)nRight );
2103 rItemSet.Put( aLRItem );
2105 else
2107 SvxLRSpaceItem aLRItem( aItemIds.nLRSpace );
2108 aLRItem.SetRight( (sal_uInt16)nRight );
2109 rItemSet.Put( aLRItem );
2111 rPropInfo.m_bRightMargin = true;
2115 static void ParseCSS1_margin_top( const CSS1Expression *pExpr,
2116 SfxItemSet &rItemSet,
2117 SvxCSS1PropertyInfo& rPropInfo,
2118 const SvxCSS1Parser& /*rParser*/ )
2120 assert(pExpr && "no expression");
2122 sal_uInt16 nUpper = 0;
2123 bool bSet = false;
2124 switch( pExpr->GetType() )
2126 case CSS1_LENGTH:
2128 long nTmp = pExpr->GetSLength();
2129 if( nTmp < 0 )
2130 nTmp = 0;
2131 nUpper = (sal_uInt16)nTmp;
2132 bSet = true;
2134 break;
2135 case CSS1_PIXLENGTH:
2137 long nPWidth = 0;
2138 long nPHeight = (long)pExpr->GetNumber();
2139 if( nPHeight < 0 )
2140 nPHeight = 0;
2141 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2142 nUpper = (sal_uInt16)nPHeight;
2143 bSet = true;
2145 break;
2146 case CSS1_PERCENTAGE:
2147 // koennen wir nicht
2148 break;
2149 default:
2153 if( bSet )
2155 const SfxPoolItem* pItem;
2156 if( SfxItemState::SET == rItemSet.GetItemState( aItemIds.nULSpace, false,
2157 &pItem ) )
2159 SvxULSpaceItem aULItem( *static_cast<const SvxULSpaceItem*>(pItem) );
2160 aULItem.SetUpper( nUpper );
2161 rItemSet.Put( aULItem );
2163 else
2165 SvxULSpaceItem aULItem( aItemIds.nULSpace );
2166 aULItem.SetUpper( nUpper );
2167 rItemSet.Put( aULItem );
2169 rPropInfo.m_bTopMargin = true;
2173 static void ParseCSS1_margin_bottom( const CSS1Expression *pExpr,
2174 SfxItemSet &rItemSet,
2175 SvxCSS1PropertyInfo& rPropInfo,
2176 const SvxCSS1Parser& /*rParser*/ )
2178 OSL_ENSURE( pExpr, "no expression" );
2180 sal_uInt16 nLower = 0;
2181 bool bSet = false;
2182 switch( pExpr->GetType() )
2184 case CSS1_LENGTH:
2186 long nTmp = pExpr->GetSLength();
2187 if( nTmp < 0 )
2188 nTmp = 0;
2189 nLower = (sal_uInt16)nTmp;
2190 bSet = true;
2192 break;
2193 case CSS1_PIXLENGTH:
2195 long nPWidth = 0;
2196 long nPHeight = (long)pExpr->GetNumber();
2197 if( nPHeight < 0 )
2198 nPHeight = 0;
2199 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2200 nLower = (sal_uInt16)nPHeight;
2201 bSet = true;
2203 break;
2204 case CSS1_PERCENTAGE:
2205 // koennen wir nicht
2206 break;
2207 default:
2211 if( bSet )
2213 const SfxPoolItem* pItem;
2214 if( SfxItemState::SET == rItemSet.GetItemState( aItemIds.nULSpace, false,
2215 &pItem ) )
2217 SvxULSpaceItem aULItem( *static_cast<const SvxULSpaceItem*>(pItem) );
2218 aULItem.SetLower( nLower );
2219 rItemSet.Put( aULItem );
2221 else
2223 SvxULSpaceItem aULItem( aItemIds.nULSpace );
2224 aULItem.SetLower( nLower );
2225 rItemSet.Put( aULItem );
2227 rPropInfo.m_bBottomMargin = true;
2231 static void ParseCSS1_margin( const CSS1Expression *pExpr,
2232 SfxItemSet &rItemSet,
2233 SvxCSS1PropertyInfo& rPropInfo,
2234 const SvxCSS1Parser& /*rParser*/ )
2236 OSL_ENSURE( pExpr, "no expression" );
2238 long nMargins[4] = { 0, 0, 0, 0 };
2239 bool bSetMargins[4] = { false, false, false, false };
2241 for( int i=0; pExpr && i<4 && !pExpr->GetOp(); ++i )
2243 bool bSetThis = false;
2244 long nMargin = 0;
2246 switch( pExpr->GetType() )
2248 case CSS1_LENGTH:
2250 nMargin = pExpr->GetSLength();
2251 bSetThis = true;
2253 break;
2254 case CSS1_PIXLENGTH:
2256 long nPWidth = 0;
2257 nMargin = (long)pExpr->GetNumber();
2258 SvxCSS1Parser::PixelToTwip( nPWidth, nMargin );
2259 bSetThis = true;
2261 break;
2262 case CSS1_PERCENTAGE:
2263 // koennen wir nicht
2264 break;
2265 default:
2269 if( bSetThis )
2271 // 0 = top
2272 // 1 = right
2273 // 2 = bottom
2274 // 3 = left
2275 switch( i )
2277 case 0:
2278 nMargins[0] = nMargins[1] =nMargins[2] = nMargins[3] = nMargin;
2279 bSetMargins[0] = bSetMargins[1] =
2280 bSetMargins[2] = bSetMargins[3] = true;
2281 break;
2282 case 1:
2283 nMargins[1] = nMargins[3] = nMargin; // right + left
2284 bSetMargins[1] = bSetMargins[3] = true;
2285 break;
2286 case 2:
2287 nMargins[2] = nMargin; // bottom
2288 bSetMargins[2] = true;
2289 break;
2290 case 3:
2291 nMargins[3] = nMargin; // left
2292 bSetMargins[3] = true;
2293 break;
2296 pExpr = pExpr->GetNext();
2299 if( bSetMargins[3] || bSetMargins[1] )
2301 if( bSetMargins[3] )
2303 rPropInfo.m_bLeftMargin = true;
2304 rPropInfo.m_nLeftMargin = nMargins[3];
2305 if( nMargins[3] < 0 )
2306 nMargins[3] = 0;
2308 if( bSetMargins[1] )
2310 rPropInfo.m_bRightMargin = true;
2311 rPropInfo.m_nRightMargin = nMargins[1];
2312 if( nMargins[1] < 0 )
2313 nMargins[1] = 0;
2316 const SfxPoolItem* pItem;
2317 if( SfxItemState::SET == rItemSet.GetItemState( aItemIds.nLRSpace, false,
2318 &pItem ) )
2320 SvxLRSpaceItem aLRItem( *static_cast<const SvxLRSpaceItem*>(pItem) );
2321 if( bSetMargins[3] )
2322 aLRItem.SetLeft( (sal_uInt16)nMargins[3] );
2323 if( bSetMargins[1] )
2324 aLRItem.SetRight( (sal_uInt16)nMargins[1] );
2325 rItemSet.Put( aLRItem );
2327 else
2329 SvxLRSpaceItem aLRItem( aItemIds.nLRSpace );
2330 if( bSetMargins[3] )
2331 aLRItem.SetLeft( (sal_uInt16)nMargins[3] );
2332 if( bSetMargins[1] )
2333 aLRItem.SetRight( (sal_uInt16)nMargins[1] );
2334 rItemSet.Put( aLRItem );
2338 if( bSetMargins[0] || bSetMargins[2] )
2340 if( nMargins[0] < 0 )
2341 nMargins[0] = 0;
2342 if( nMargins[2] < 0 )
2343 nMargins[2] = 0;
2345 const SfxPoolItem* pItem;
2346 if( SfxItemState::SET == rItemSet.GetItemState( aItemIds.nULSpace, false,
2347 &pItem ) )
2349 SvxULSpaceItem aULItem( *static_cast<const SvxULSpaceItem*>(pItem) );
2350 if( bSetMargins[0] )
2351 aULItem.SetUpper( (sal_uInt16)nMargins[0] );
2352 if( bSetMargins[2] )
2353 aULItem.SetLower( (sal_uInt16)nMargins[2] );
2354 rItemSet.Put( aULItem );
2356 else
2358 SvxULSpaceItem aULItem( aItemIds.nULSpace );
2359 if( bSetMargins[0] )
2360 aULItem.SetUpper( (sal_uInt16)nMargins[0] );
2361 if( bSetMargins[2] )
2362 aULItem.SetLower( (sal_uInt16)nMargins[2] );
2363 rItemSet.Put( aULItem );
2366 rPropInfo.m_bTopMargin |= bSetMargins[0];
2367 rPropInfo.m_bBottomMargin |= bSetMargins[2];
2371 static bool ParseCSS1_padding_xxx( const CSS1Expression *pExpr,
2372 SfxItemSet & /*rItemSet*/,
2373 SvxCSS1PropertyInfo& rPropInfo,
2374 const SvxCSS1Parser& /*rParser*/,
2375 SvxBoxItemLine nWhichLine )
2377 OSL_ENSURE( pExpr, "no expression" );
2379 bool bSet = false;
2380 sal_uInt16 nDist = 0;
2382 switch( pExpr->GetType() )
2384 case CSS1_LENGTH:
2386 long nTmp = pExpr->GetSLength();
2387 if( nTmp < 0 )
2388 nTmp = 0;
2389 else if( nTmp > USHRT_MAX-1 )
2390 nTmp = USHRT_MAX-1;
2391 nDist = (sal_uInt16)nTmp;
2392 bSet = true;
2394 break;
2395 case CSS1_PIXLENGTH:
2397 long nPWidth = (long)pExpr->GetNumber();
2398 long nPHeight = 0;
2399 if( nPWidth < 0 )
2400 nPWidth = 0;
2401 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2402 if( nPWidth > USHRT_MAX-1 )
2403 nPWidth = USHRT_MAX-1;
2404 nDist = (sal_uInt16)nPWidth;
2405 bSet = true;
2407 break;
2408 case CSS1_PERCENTAGE:
2409 // koennen wir nicht
2410 break;
2411 default:
2415 if( bSet )
2417 switch( nWhichLine )
2419 case SvxBoxItemLine::TOP: rPropInfo.m_nTopBorderDistance = nDist; break;
2420 case SvxBoxItemLine::BOTTOM: rPropInfo.m_nBottomBorderDistance = nDist;break;
2421 case SvxBoxItemLine::LEFT: rPropInfo.m_nLeftBorderDistance = nDist; break;
2422 case SvxBoxItemLine::RIGHT: rPropInfo.m_nRightBorderDistance = nDist; break;
2426 return bSet;
2429 static void ParseCSS1_padding_top( const CSS1Expression *pExpr,
2430 SfxItemSet &rItemSet,
2431 SvxCSS1PropertyInfo& rPropInfo,
2432 const SvxCSS1Parser& rParser )
2434 ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::TOP );
2437 static void ParseCSS1_padding_bottom( const CSS1Expression *pExpr,
2438 SfxItemSet &rItemSet,
2439 SvxCSS1PropertyInfo& rPropInfo,
2440 const SvxCSS1Parser& rParser )
2442 ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser,
2443 SvxBoxItemLine::BOTTOM );
2446 static void ParseCSS1_padding_left( const CSS1Expression *pExpr,
2447 SfxItemSet &rItemSet,
2448 SvxCSS1PropertyInfo& rPropInfo,
2449 const SvxCSS1Parser& rParser )
2451 ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::LEFT );
2454 static void ParseCSS1_padding_right( const CSS1Expression *pExpr,
2455 SfxItemSet &rItemSet,
2456 SvxCSS1PropertyInfo& rPropInfo,
2457 const SvxCSS1Parser& rParser )
2459 ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser,
2460 SvxBoxItemLine::RIGHT );
2463 static void ParseCSS1_padding( const CSS1Expression *pExpr,
2464 SfxItemSet &rItemSet,
2465 SvxCSS1PropertyInfo& rPropInfo,
2466 const SvxCSS1Parser& rParser )
2468 int n=0;
2469 while( n<4 && pExpr && !pExpr->GetOp() )
2471 SvxBoxItemLine nLine = n==0 || n==2 ? SvxBoxItemLine::BOTTOM : SvxBoxItemLine::LEFT;
2472 if( ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser,
2473 nLine ) )
2475 if( n==0 )
2477 rPropInfo.m_nTopBorderDistance = rPropInfo.m_nBottomBorderDistance;
2478 rPropInfo.m_nLeftBorderDistance = rPropInfo.m_nTopBorderDistance;
2480 if( n <= 1 )
2481 rPropInfo.m_nRightBorderDistance = rPropInfo.m_nLeftBorderDistance;
2484 pExpr = pExpr->GetNext();
2485 n++;
2489 static void ParseCSS1_border_xxx( const CSS1Expression *pExpr,
2490 SfxItemSet & /*rItemSet*/,
2491 SvxCSS1PropertyInfo& rPropInfo,
2492 const SvxCSS1Parser& /*rParser*/,
2493 SvxBoxItemLine nWhichLine, bool bAll )
2495 OSL_ENSURE( pExpr, "no expression" );
2497 sal_uInt16 nWidth = USHRT_MAX; // die Linien-Dicke
2498 sal_uInt16 nNWidth = 1; // benannte Linien-Dicke (und default)
2499 CSS1BorderStyle eStyle = CSS1_BS_NONE; // Linien-Style
2500 Color aColor;
2501 bool bColor = false;
2503 while( pExpr && !pExpr->GetOp() )
2505 switch( pExpr->GetType() )
2507 case CSS1_RGB:
2508 case CSS1_HEXCOLOR:
2509 if( pExpr->GetColor( aColor ) )
2510 bColor = true;
2511 break;
2513 case CSS1_IDENT:
2515 const OUString& rValue = pExpr->GetString();
2516 sal_uInt16 nValue;
2517 if( SvxCSS1Parser::GetEnum( aBorderWidthTable, rValue, nValue ) )
2519 nNWidth = nValue;
2521 else if( SvxCSS1Parser::GetEnum( aBorderStyleTable, rValue, nValue ) )
2523 eStyle = (CSS1BorderStyle)nValue;
2525 else if( pExpr->GetColor( aColor ) )
2527 bColor = true;
2530 break;
2532 case CSS1_LENGTH:
2533 nWidth = (sal_uInt16)pExpr->GetULength();
2534 break;
2536 case CSS1_PIXLENGTH:
2538 bool bHori = nWhichLine == SvxBoxItemLine::TOP ||
2539 nWhichLine == SvxBoxItemLine::BOTTOM;
2540 // Ein Pixel wird zur Haarlinie (ist huebscher)
2541 long nWidthL = (long)pExpr->GetNumber();
2542 if( nWidthL > 1 )
2544 long nPWidth = bHori ? 0 : nWidthL;
2545 long nPHeight = bHori ? nWidthL : 0;
2546 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2547 nWidth = (sal_uInt16)(bHori ? nPHeight : nPWidth);
2549 else
2550 nWidth = 1;
2552 break;
2554 default:
2558 pExpr = pExpr->GetNext();
2561 for( int i=0; i<4; ++i )
2563 SvxBoxItemLine nLine = SvxBoxItemLine::TOP;
2564 switch( i )
2566 case 0: nLine = SvxBoxItemLine::TOP; break;
2567 case 1: nLine = SvxBoxItemLine::BOTTOM; break;
2568 case 2: nLine = SvxBoxItemLine::LEFT; break;
2569 case 3: nLine = SvxBoxItemLine::RIGHT; break;
2572 if( bAll || nLine == nWhichLine )
2574 SvxCSS1BorderInfo *pInfo = rPropInfo.GetBorderInfo( nLine );
2575 pInfo->eStyle = eStyle;
2576 pInfo->nAbsWidth = nWidth;
2577 pInfo->nNamedWidth = nNWidth;
2578 if( bColor )
2579 pInfo->aColor = aColor;
2584 static void ParseCSS1_border_xxx_width( const CSS1Expression *pExpr,
2585 SfxItemSet & /*rItemSet*/,
2586 SvxCSS1PropertyInfo& rPropInfo,
2587 const SvxCSS1Parser& /*rParser*/,
2588 SvxBoxItemLine nWhichLine )
2590 OSL_ENSURE( pExpr, "no expression" );
2592 sal_uInt16 nWidth = USHRT_MAX; // die Linien-Dicke
2593 sal_uInt16 nNWidth = 1; // benannte Linien-Dicke (und default)
2595 switch( pExpr->GetType() )
2597 case CSS1_IDENT:
2599 sal_uInt16 nValue;
2600 if( SvxCSS1Parser::GetEnum( aBorderWidthTable, pExpr->GetString(), nValue ) )
2602 nNWidth = nValue;
2605 break;
2607 case CSS1_LENGTH:
2608 nWidth = (sal_uInt16)pExpr->GetULength();
2609 break;
2611 case CSS1_PIXLENGTH:
2613 bool bHori = nWhichLine == SvxBoxItemLine::TOP ||
2614 nWhichLine == SvxBoxItemLine::BOTTOM;
2615 long nWidthL = (long)pExpr->GetNumber();
2616 long nPWidth = bHori ? 0 : nWidthL;
2617 long nPHeight = bHori ? nWidthL : 0;
2618 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2619 nWidth = (sal_uInt16)(bHori ? nPHeight : nPWidth);
2621 break;
2623 default:
2627 SvxCSS1BorderInfo *pInfo = rPropInfo.GetBorderInfo( nWhichLine );
2628 pInfo->nAbsWidth = nWidth;
2629 pInfo->nNamedWidth = nNWidth;
2632 static void ParseCSS1_border_top_width( const CSS1Expression *pExpr,
2633 SfxItemSet &rItemSet,
2634 SvxCSS1PropertyInfo& rPropInfo,
2635 const SvxCSS1Parser& rParser )
2637 ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::TOP );
2640 static void ParseCSS1_border_right_width( const CSS1Expression *pExpr,
2641 SfxItemSet &rItemSet,
2642 SvxCSS1PropertyInfo& rPropInfo,
2643 const SvxCSS1Parser& rParser )
2645 ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::RIGHT );
2648 static void ParseCSS1_border_bottom_width( const CSS1Expression *pExpr,
2649 SfxItemSet &rItemSet,
2650 SvxCSS1PropertyInfo& rPropInfo,
2651 const SvxCSS1Parser& rParser )
2653 ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::BOTTOM );
2656 static void ParseCSS1_border_left_width( const CSS1Expression *pExpr,
2657 SfxItemSet &rItemSet,
2658 SvxCSS1PropertyInfo& rPropInfo,
2659 const SvxCSS1Parser& rParser )
2661 ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::LEFT );
2664 static void ParseCSS1_border_width( const CSS1Expression *pExpr,
2665 SfxItemSet &rItemSet,
2666 SvxCSS1PropertyInfo& rPropInfo,
2667 const SvxCSS1Parser& rParser )
2669 sal_uInt16 n=0;
2670 while( n<4 && pExpr && !pExpr->GetOp() )
2672 SvxBoxItemLine nLine = n==0 || n==2 ? SvxBoxItemLine::BOTTOM : SvxBoxItemLine::LEFT;
2673 ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, nLine );
2674 rPropInfo.CopyBorderInfo( n, SVX_CSS1_BORDERINFO_WIDTH );
2676 pExpr = pExpr->GetNext();
2677 n++;
2681 static void ParseCSS1_border_color( const CSS1Expression *pExpr,
2682 SfxItemSet & /*rItemSet*/,
2683 SvxCSS1PropertyInfo& rPropInfo,
2684 const SvxCSS1Parser& /*rParser*/ )
2686 sal_uInt16 n=0;
2687 while( n<4 && pExpr && !pExpr->GetOp() )
2689 SvxBoxItemLine nLine = n==0 || n==2 ? SvxBoxItemLine::BOTTOM : SvxBoxItemLine::LEFT;
2690 Color aColor;
2691 switch( pExpr->GetType() )
2693 case CSS1_RGB:
2694 case CSS1_HEXCOLOR:
2695 case CSS1_IDENT:
2696 if( pExpr->GetColor( aColor ) )
2697 rPropInfo.GetBorderInfo( nLine )->aColor = aColor;
2698 break;
2699 default:
2702 rPropInfo.CopyBorderInfo( n, SVX_CSS1_BORDERINFO_COLOR );
2704 pExpr = pExpr->GetNext();
2705 n++;
2709 static void ParseCSS1_border_style( const CSS1Expression *pExpr,
2710 SfxItemSet & /*rItemSet*/,
2711 SvxCSS1PropertyInfo& rPropInfo,
2712 const SvxCSS1Parser& /*rParser*/ )
2714 sal_uInt16 n=0;
2715 while( n<4 && pExpr && !pExpr->GetOp() )
2717 SvxBoxItemLine nLine = n==0 || n==2 ? SvxBoxItemLine::BOTTOM : SvxBoxItemLine::LEFT;
2718 sal_uInt16 nValue = 0;
2719 if( CSS1_IDENT==pExpr->GetType() &&
2720 SvxCSS1Parser::GetEnum( aBorderStyleTable, pExpr->GetString(),
2721 nValue ) )
2723 rPropInfo.GetBorderInfo( nLine )->eStyle = (CSS1BorderStyle)nValue;
2725 rPropInfo.CopyBorderInfo( n, SVX_CSS1_BORDERINFO_STYLE );
2727 pExpr = pExpr->GetNext();
2728 n++;
2732 static void ParseCSS1_border_top( const CSS1Expression *pExpr,
2733 SfxItemSet &rItemSet,
2734 SvxCSS1PropertyInfo& rPropInfo,
2735 const SvxCSS1Parser& rParser )
2737 ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::TOP, false );
2740 static void ParseCSS1_border_right( const CSS1Expression *pExpr,
2741 SfxItemSet &rItemSet,
2742 SvxCSS1PropertyInfo& rPropInfo,
2743 const SvxCSS1Parser& rParser )
2745 ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::RIGHT, false );
2748 static void ParseCSS1_border_bottom( const CSS1Expression *pExpr,
2749 SfxItemSet &rItemSet,
2750 SvxCSS1PropertyInfo& rPropInfo,
2751 const SvxCSS1Parser& rParser )
2753 ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::BOTTOM, false );
2756 static void ParseCSS1_border_left( const CSS1Expression *pExpr,
2757 SfxItemSet &rItemSet,
2758 SvxCSS1PropertyInfo& rPropInfo,
2759 const SvxCSS1Parser& rParser )
2761 ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::LEFT, false );
2764 static void ParseCSS1_border( const CSS1Expression *pExpr,
2765 SfxItemSet &rItemSet,
2766 SvxCSS1PropertyInfo& rPropInfo,
2767 const SvxCSS1Parser& rParser )
2769 ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::TOP, true );
2772 static void ParseCSS1_float( const CSS1Expression *pExpr,
2773 SfxItemSet & /*rItemSet*/,
2774 SvxCSS1PropertyInfo& rPropInfo,
2775 const SvxCSS1Parser& /*rParser*/ )
2777 OSL_ENSURE( pExpr, "no expression" );
2779 if( CSS1_IDENT==pExpr->GetType() )
2781 sal_uInt16 nFloat;
2782 if( SvxCSS1Parser::GetEnum( aFloatTable, pExpr->GetString(), nFloat ) )
2783 rPropInfo.m_eFloat = (SvxAdjust)nFloat;
2787 static void ParseCSS1_position( const CSS1Expression *pExpr,
2788 SfxItemSet & /*rItemSet*/,
2789 SvxCSS1PropertyInfo& rPropInfo,
2790 const SvxCSS1Parser& /*rParser*/ )
2792 OSL_ENSURE( pExpr, "no expression" );
2794 if( CSS1_IDENT==pExpr->GetType() )
2796 sal_uInt16 nPos;
2797 if( SvxCSS1Parser::GetEnum( aPositionTable, pExpr->GetString(), nPos ) )
2798 rPropInfo.m_ePosition = (SvxCSS1Position)nPos;
2802 static void ParseCSS1_length( const CSS1Expression *pExpr,
2803 long& rLength,
2804 SvxCSS1LengthType& rLengthType,
2805 bool bHori )
2807 switch( pExpr->GetType() )
2809 case CSS1_IDENT:
2810 if( pExpr->GetString().equalsIgnoreAsciiCase( "auto" ) )
2812 rLength = 0;
2813 rLengthType = SVX_CSS1_LTYPE_AUTO;
2815 break;
2817 case CSS1_LENGTH:
2818 rLength = pExpr->GetSLength();
2819 rLengthType = SVX_CSS1_LTYPE_TWIP;
2820 break;
2822 case CSS1_PIXLENGTH:
2823 case CSS1_NUMBER: // wegen Netscape und IE
2825 long nWidthL = (long)pExpr->GetNumber();
2826 long nPWidth = bHori ? 0 : nWidthL;
2827 long nPHeight = bHori ? nWidthL : 0;
2828 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2829 rLength = (bHori ? nPHeight : nPWidth);
2830 rLengthType = SVX_CSS1_LTYPE_TWIP;
2832 break;
2834 case CSS1_PERCENTAGE:
2835 rLength = (long)pExpr->GetNumber();
2836 if( rLength > 100 )
2837 rLength = 100;
2838 rLengthType = SVX_CSS1_LTYPE_PERCENTAGE;
2839 break;
2841 default:
2846 static void ParseCSS1_width( const CSS1Expression *pExpr,
2847 SfxItemSet & /*rItemSet*/,
2848 SvxCSS1PropertyInfo& rPropInfo,
2849 const SvxCSS1Parser& /*rParser*/ )
2851 ParseCSS1_length( pExpr, rPropInfo.m_nWidth, rPropInfo.m_eWidthType, true );
2854 static void ParseCSS1_height( const CSS1Expression *pExpr,
2855 SfxItemSet & /*rItemSet*/,
2856 SvxCSS1PropertyInfo& rPropInfo,
2857 const SvxCSS1Parser& /*rParser*/ )
2859 ParseCSS1_length( pExpr, rPropInfo.m_nHeight, rPropInfo.m_eHeightType, false );
2862 static void ParseCSS1_left( const CSS1Expression *pExpr,
2863 SfxItemSet & /*rItemSet*/,
2864 SvxCSS1PropertyInfo& rPropInfo,
2865 const SvxCSS1Parser& /*rParser*/ )
2867 ParseCSS1_length( pExpr, rPropInfo.m_nLeft, rPropInfo.m_eLeftType, true );
2870 static void ParseCSS1_top( const CSS1Expression *pExpr,
2871 SfxItemSet & /*rItemSet*/,
2872 SvxCSS1PropertyInfo& rPropInfo,
2873 const SvxCSS1Parser& /*rParser*/ )
2875 ParseCSS1_length( pExpr, rPropInfo.m_nTop, rPropInfo.m_eTopType, false );
2878 // Feature: PrintExt
2879 static void ParseCSS1_size( const CSS1Expression *pExpr,
2880 SfxItemSet & /*rItemSet*/,
2881 SvxCSS1PropertyInfo& rPropInfo,
2882 const SvxCSS1Parser& /*rParser*/ )
2884 int n=0;
2885 while( n<2 && pExpr && !pExpr->GetOp() )
2887 switch( pExpr->GetType() )
2889 case CSS1_IDENT:
2891 sal_uInt16 nValue;
2892 if( SvxCSS1Parser::GetEnum( aSizeTable, pExpr->GetString(),
2893 nValue ) )
2895 rPropInfo.m_eSizeType = (SvxCSS1SizeType)nValue;
2898 break;
2900 case CSS1_LENGTH:
2901 rPropInfo.m_nHeight = pExpr->GetSLength();
2902 if( n==0 )
2903 rPropInfo.m_nWidth = rPropInfo.m_nHeight;
2904 rPropInfo.m_eSizeType = SVX_CSS1_STYPE_TWIP;
2905 break;
2907 case CSS1_PIXLENGTH:
2909 long nPHeight = (long)pExpr->GetNumber();
2910 long nPWidth = n==0 ? nPHeight : 0;
2911 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2912 rPropInfo.m_nHeight = nPHeight;
2913 if( n==0 )
2914 rPropInfo.m_nWidth = nPWidth;
2915 rPropInfo.m_eSizeType = SVX_CSS1_STYPE_TWIP;
2917 break;
2919 default:
2923 pExpr = pExpr->GetNext();
2924 n++;
2928 static void ParseCSS1_page_break_xxx( const CSS1Expression *pExpr,
2929 SvxCSS1PageBreak& rPBreak )
2931 if( CSS1_IDENT == pExpr->GetType() )
2933 sal_uInt16 nValue;
2934 if( SvxCSS1Parser::GetEnum( aPageBreakTable, pExpr->GetString(),
2935 nValue ) )
2937 rPBreak = (SvxCSS1PageBreak)nValue;
2942 static void ParseCSS1_page_break_before( const CSS1Expression *pExpr,
2943 SfxItemSet & /*rItemSet*/,
2944 SvxCSS1PropertyInfo& rPropInfo,
2945 const SvxCSS1Parser& /*rParser*/ )
2947 ParseCSS1_page_break_xxx( pExpr, rPropInfo.m_ePageBreakBefore );
2950 static void ParseCSS1_page_break_after( const CSS1Expression *pExpr,
2951 SfxItemSet & /*rItemSet*/,
2952 SvxCSS1PropertyInfo& rPropInfo,
2953 const SvxCSS1Parser& /*rParser*/ )
2955 ParseCSS1_page_break_xxx( pExpr, rPropInfo.m_ePageBreakAfter );
2958 static void ParseCSS1_page_break_inside( const CSS1Expression *pExpr,
2959 SfxItemSet &rItemSet,
2960 SvxCSS1PropertyInfo& /*rPropInfo*/,
2961 const SvxCSS1Parser& /*rParser*/ )
2963 SvxCSS1PageBreak eBreak(SVX_CSS1_PBREAK_NONE);
2964 ParseCSS1_page_break_xxx( pExpr, eBreak );
2966 bool bSetSplit = false, bSplit = true;
2967 switch( eBreak )
2969 case SVX_CSS1_PBREAK_AUTO:
2970 bSetSplit = true;
2971 break;
2972 case SVX_CSS1_PBREAK_AVOID:
2973 bSplit = false;
2974 bSetSplit = true;
2975 break;
2976 default:
2980 if( bSetSplit )
2981 rItemSet.Put( SvxFormatSplitItem( bSplit, aItemIds.nFormatSplit ) );
2984 static void ParseCSS1_widows( const CSS1Expression *pExpr,
2985 SfxItemSet &rItemSet,
2986 SvxCSS1PropertyInfo& /*rPropInfo*/,
2987 const SvxCSS1Parser& /*rParser*/ )
2989 if( CSS1_NUMBER == pExpr->GetType() )
2991 sal_uInt8 nVal = pExpr->GetNumber() <= 255
2992 ? (sal_uInt8)pExpr->GetNumber()
2993 : 255;
2994 SvxWidowsItem aWidowsItem( nVal, aItemIds.nWidows );
2995 rItemSet.Put( aWidowsItem );
2999 static void ParseCSS1_orphans( const CSS1Expression *pExpr,
3000 SfxItemSet &rItemSet,
3001 SvxCSS1PropertyInfo& /*rPropInfo*/,
3002 const SvxCSS1Parser& /*rParser*/ )
3004 if( CSS1_NUMBER == pExpr->GetType() )
3006 sal_uInt8 nVal = pExpr->GetNumber() <= 255
3007 ? (sal_uInt8)pExpr->GetNumber()
3008 : 255;
3009 SvxOrphansItem aOrphansItem( nVal, aItemIds.nOrphans );
3010 rItemSet.Put( aOrphansItem );
3014 static void ParseCSS1_so_language( const CSS1Expression *pExpr,
3015 SfxItemSet &rItemSet,
3016 SvxCSS1PropertyInfo& /*rPropInfo*/,
3017 const SvxCSS1Parser& rParser )
3019 if( CSS1_IDENT == pExpr->GetType() ||
3020 CSS1_STRING == pExpr->GetType() )
3022 LanguageType eLang = LanguageTag::convertToLanguageTypeWithFallback( pExpr->GetString() );
3023 if( LANGUAGE_DONTKNOW != eLang )
3025 SvxLanguageItem aLang( eLang, aItemIds.nLanguage );
3026 if( rParser.IsSetWesternProps() )
3027 rItemSet.Put( aLang );
3028 if( rParser.IsSetCJKProps() )
3030 aLang.SetWhich( aItemIds.nLanguageCJK );
3031 rItemSet.Put( aLang );
3033 if( rParser.IsSetCTLProps() )
3035 aLang.SetWhich( aItemIds.nLanguageCTL );
3036 rItemSet.Put( aLang );
3042 // die Zuordung Property zu parsender Funktion
3043 struct CSS1PropEntry
3045 union
3047 const sal_Char *sName;
3048 OUString *pName;
3050 FnParseCSS1Prop pFunc;
3053 #define CSS1_PROP_ENTRY(p) \
3054 { { sCSS1_P_##p }, ParseCSS1_##p }
3056 // die Tabelle mit den Zuordnungen
3057 static CSS1PropEntry aCSS1PropFnTab[] =
3059 CSS1_PROP_ENTRY(background),
3060 CSS1_PROP_ENTRY(background_color),
3061 CSS1_PROP_ENTRY(border_top_width),
3062 CSS1_PROP_ENTRY(border_right_width),
3063 CSS1_PROP_ENTRY(border_bottom_width),
3064 CSS1_PROP_ENTRY(border_left_width),
3065 CSS1_PROP_ENTRY(border_width),
3066 CSS1_PROP_ENTRY(border_color),
3067 CSS1_PROP_ENTRY(border_style),
3068 CSS1_PROP_ENTRY(border_top),
3069 CSS1_PROP_ENTRY(border_right),
3070 CSS1_PROP_ENTRY(border_bottom),
3071 CSS1_PROP_ENTRY(border_left),
3072 CSS1_PROP_ENTRY(border),
3073 CSS1_PROP_ENTRY(color),
3074 CSS1_PROP_ENTRY(column_count),
3075 CSS1_PROP_ENTRY(direction),
3076 CSS1_PROP_ENTRY(float),
3077 CSS1_PROP_ENTRY(font_size),
3078 CSS1_PROP_ENTRY(font_family),
3079 CSS1_PROP_ENTRY(font_style),
3080 CSS1_PROP_ENTRY(font_variant),
3081 CSS1_PROP_ENTRY(font_weight),
3082 CSS1_PROP_ENTRY(letter_spacing),
3083 CSS1_PROP_ENTRY(line_height),
3084 CSS1_PROP_ENTRY(font),
3085 CSS1_PROP_ENTRY(text_align),
3086 CSS1_PROP_ENTRY(text_decoration),
3087 CSS1_PROP_ENTRY(text_indent),
3088 CSS1_PROP_ENTRY(text_transform),
3089 CSS1_PROP_ENTRY(margin_left),
3090 CSS1_PROP_ENTRY(margin_right),
3091 CSS1_PROP_ENTRY(margin_top),
3092 CSS1_PROP_ENTRY(margin_bottom),
3093 CSS1_PROP_ENTRY(margin),
3094 CSS1_PROP_ENTRY(padding_top),
3095 CSS1_PROP_ENTRY(padding_bottom),
3096 CSS1_PROP_ENTRY(padding_left),
3097 CSS1_PROP_ENTRY(padding_right),
3098 CSS1_PROP_ENTRY(padding),
3099 CSS1_PROP_ENTRY(position),
3100 CSS1_PROP_ENTRY(left),
3101 CSS1_PROP_ENTRY(top),
3102 CSS1_PROP_ENTRY(width),
3103 CSS1_PROP_ENTRY(height),
3104 CSS1_PROP_ENTRY(size),
3105 CSS1_PROP_ENTRY(page_break_before),
3106 CSS1_PROP_ENTRY(page_break_after),
3107 CSS1_PROP_ENTRY(page_break_inside),
3108 CSS1_PROP_ENTRY(widows),
3109 CSS1_PROP_ENTRY(orphans),
3110 CSS1_PROP_ENTRY(so_language)
3113 extern "C"
3115 static int SAL_CALL CSS1PropEntryCompare( const void *pFirst, const void *pSecond)
3117 int nRet;
3118 if( static_cast<const CSS1PropEntry*>(pFirst)->pFunc )
3120 if( static_cast<const CSS1PropEntry*>(pSecond)->pFunc )
3121 nRet = strcmp( static_cast<const CSS1PropEntry*>(pFirst)->sName ,
3122 static_cast<const CSS1PropEntry*>(pSecond)->sName );
3123 else
3124 nRet = -1 * static_cast<const CSS1PropEntry*>(pSecond)->pName->compareToAscii(
3125 static_cast<const CSS1PropEntry*>(pFirst)->sName );
3127 else
3129 if( static_cast<const CSS1PropEntry*>(pSecond)->pFunc )
3130 nRet = static_cast<const CSS1PropEntry*>(pFirst)->pName->compareToAscii(
3131 static_cast<const CSS1PropEntry*>(pSecond)->sName );
3132 else
3133 nRet = static_cast<const CSS1PropEntry*>(pFirst)->pName->compareTo(
3134 *static_cast<const CSS1PropEntry*>(pSecond)->pName );
3137 return nRet;
3141 void SvxCSS1Parser::ParseProperty( const OUString& rProperty,
3142 const CSS1Expression *pExpr )
3144 OSL_ENSURE( pItemSet, "DeclarationParsed() without ItemSet" );
3146 static bool bSortedPropFns = false;
3148 if( !bSortedPropFns )
3150 qsort( static_cast<void*>(aCSS1PropFnTab),
3151 sizeof( aCSS1PropFnTab ) / sizeof( CSS1PropEntry ),
3152 sizeof( CSS1PropEntry ),
3153 CSS1PropEntryCompare );
3154 bSortedPropFns = true;
3157 OUString aTmp( rProperty.toAsciiLowerCase() );
3159 CSS1PropEntry aSrch;
3160 aSrch.pName = &aTmp;
3161 aSrch.pFunc = nullptr;
3163 void* pFound;
3164 if( nullptr != ( pFound = bsearch( &aSrch,
3165 static_cast<void*>(aCSS1PropFnTab),
3166 sizeof( aCSS1PropFnTab ) / sizeof( CSS1PropEntry ),
3167 sizeof( CSS1PropEntry ),
3168 CSS1PropEntryCompare )))
3170 (static_cast<CSS1PropEntry*>(pFound)->pFunc)( pExpr, *pItemSet, *pPropInfo, *this );
3174 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */