loplugin:constvars in sw
[LibreOffice.git] / sw / source / filter / html / svxcss1.cxx
blob17f6d57501283a682e955b976392811fc2c90474
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 <sal/config.h>
22 #include <cmath>
23 #include <memory>
24 #include <stdlib.h>
26 #include <svx/svxids.hrc>
27 #include <i18nlangtag/languagetag.hxx>
28 #include <svtools/ctrltool.hxx>
29 #include <svl/urihelper.hxx>
30 #include <editeng/udlnitem.hxx>
31 #include <editeng/adjustitem.hxx>
32 #include <editeng/blinkitem.hxx>
33 #include <editeng/crossedoutitem.hxx>
34 #include <editeng/kernitem.hxx>
35 #include <editeng/lspcitem.hxx>
36 #include <editeng/fontitem.hxx>
37 #include <editeng/postitem.hxx>
38 #include <editeng/colritem.hxx>
39 #include <editeng/cmapitem.hxx>
40 #include <editeng/brushitem.hxx>
41 #include <editeng/wghtitem.hxx>
42 #include <editeng/fhgtitem.hxx>
43 #include <editeng/borderline.hxx>
44 #include <editeng/boxitem.hxx>
45 #include <editeng/ulspitem.hxx>
46 #include <editeng/lrspitem.hxx>
47 #include <editeng/langitem.hxx>
48 #include <svl/itempool.hxx>
49 #include <editeng/spltitem.hxx>
50 #include <editeng/widwitem.hxx>
51 #include <editeng/frmdiritem.hxx>
52 #include <editeng/orphitem.hxx>
53 #include <svtools/svparser.hxx>
54 #include <swtypes.hxx>
55 #include <vcl/svapp.hxx>
56 #include <vcl/wrkwin.hxx>
57 #include <sal/log.hxx>
58 #include <osl/diagnose.h>
60 #include "css1kywd.hxx"
61 #include "svxcss1.hxx"
62 #include "htmlnum.hxx"
64 #include <utility>
66 using namespace ::com::sun::star;
68 /// type of functions to parse CSS1 properties
69 typedef void (*FnParseCSS1Prop)( const CSS1Expression *pExpr,
70 SfxItemSet& rItemSet,
71 SvxCSS1PropertyInfo& rPropInfo,
72 const SvxCSS1Parser& rParser );
74 static CSS1PropertyEnum const aFontSizeTable[] =
76 { "xx-small", 0 },
77 { "x-small", 1 },
78 { "small", 2 },
79 { "medium", 3 },
80 { "large", 4 },
81 { "x-large", 5 },
82 { "xx-large", 6 },
83 { nullptr, 0 }
86 static CSS1PropertyEnum const aFontWeightTable[] =
88 { "extra-light", WEIGHT_NORMAL }, // WEIGHT_ULTRALIGHT (OBS)
89 { "light", WEIGHT_NORMAL }, // WEIGHT_LIGHT (OBSOLETE)
90 { "demi-light", WEIGHT_NORMAL }, // WEIGHT_SEMILIGHT (OBS)
91 { "medium", WEIGHT_NORMAL }, // WEIGHT_MEDIUM (OBS)
92 { "normal", WEIGHT_NORMAL }, // WEIGHT_MEDIUM
93 { "demi-bold", WEIGHT_NORMAL }, // WEIGHT_SEMIBOLD (OBS)
94 { "bold", WEIGHT_BOLD }, // WEIGHT_BOLD (OBSOLETE)
95 { "extra-bold", WEIGHT_BOLD }, // WEIGHT_ULTRABOLD (OBS)
96 { "bolder", WEIGHT_BOLD },
97 { "lighter", WEIGHT_NORMAL },
98 { nullptr, 0 }
101 static CSS1PropertyEnum const aFontStyleTable[] =
103 { "normal", ITALIC_NONE },
104 { "italic", ITALIC_NORMAL },
105 { "oblique", ITALIC_NORMAL },
106 { nullptr, 0 }
109 static CSS1PropertyEnum const aFontVariantTable[] =
111 { "normal", sal_uInt16(SvxCaseMap::NotMapped) },
112 { "small-caps", sal_uInt16(SvxCaseMap::SmallCaps) },
113 { nullptr, 0 }
116 static CSS1PropertyEnum const aTextTransformTable[] =
118 { "uppercase", sal_uInt16(SvxCaseMap::Uppercase) },
119 { "lowercase", sal_uInt16(SvxCaseMap::Lowercase) },
120 { "capitalize", sal_uInt16(SvxCaseMap::Capitalize) },
121 { nullptr, 0 }
124 static CSS1PropertyEnum const aDirectionTable[] =
126 { "ltr", sal_uInt16(SvxFrameDirection::Horizontal_LR_TB) },
127 { "rtl", sal_uInt16(SvxFrameDirection::Horizontal_RL_TB) },
128 { "inherit", sal_uInt16(SvxFrameDirection::Environment) },
129 { nullptr, 0 }
132 static CSS1PropertyEnum const aBGRepeatTable[] =
134 { "repeat", GPOS_TILED },
135 { "repeat-x", GPOS_TILED },
136 { "repeat-y", GPOS_TILED },
137 { "no-repeat", GPOS_NONE },
138 { nullptr, 0 }
141 static CSS1PropertyEnum const aBGHoriPosTable[] =
143 { "left", GPOS_LT },
144 { "center", GPOS_MT },
145 { "right", GPOS_RT },
146 { nullptr, 0 }
149 static CSS1PropertyEnum const aBGVertPosTable[] =
151 { "top", GPOS_LT },
152 { "middle", GPOS_LM },
153 { "bottom", GPOS_LB },
154 { nullptr, 0 }
157 static CSS1PropertyEnum const aTextAlignTable[] =
159 { "left", sal_uInt16(SvxAdjust::Left) },
160 { "center", sal_uInt16(SvxAdjust::Center) },
161 { "right", sal_uInt16(SvxAdjust::Right) },
162 { "justify", sal_uInt16(SvxAdjust::Block) },
163 { nullptr, 0 }
166 static CSS1PropertyEnum const aBorderWidthTable[] =
168 { "thin", 0 }, // DEF_LINE_WIDTH_0 / DEF_DOUBLE_LINE0
169 { "medium", 1 }, // DEF_LINE_WIDTH_1 / DEF_DOUBLE_LINE1
170 { "thick", 2 }, // DEF_LINE_WIDTH_2 / DEF_DOUBLE_LINE2
171 { nullptr, 0 }
174 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 };
176 static CSS1PropertyEnum const aBorderStyleTable[] =
178 { "none", CSS1_BS_NONE },
179 { "dotted", CSS1_BS_DOTTED },
180 { "dashed", CSS1_BS_DASHED },
181 { "solid", CSS1_BS_SINGLE },
182 { "double", CSS1_BS_DOUBLE },
183 { "groove", CSS1_BS_GROOVE },
184 { "ridge", CSS1_BS_RIDGE },
185 { "inset", CSS1_BS_INSET },
186 { "outset", CSS1_BS_OUTSET },
187 { nullptr, 0 }
190 static CSS1PropertyEnum const aFloatTable[] =
192 { "left", sal_uInt16(SvxAdjust::Left) },
193 { "right", sal_uInt16(SvxAdjust::Right) },
194 { "none", sal_uInt16(SvxAdjust::End) },
195 { nullptr, 0 }
198 static CSS1PropertyEnum const aPositionTable[] =
200 { "absolute", SVX_CSS1_POS_ABSOLUTE },
201 { "relative", SVX_CSS1_POS_RELATIVE },
202 { "static", SVX_CSS1_POS_STATIC },
203 { nullptr, 0 }
206 // Feature: PrintExt
207 static CSS1PropertyEnum const aSizeTable[] =
209 { "auto", SVX_CSS1_STYPE_AUTO },
210 { "landscape", SVX_CSS1_STYPE_LANDSCAPE },
211 { "portrait", SVX_CSS1_STYPE_PORTRAIT },
212 { nullptr, 0 }
215 static CSS1PropertyEnum const aPageBreakTable[] =
217 { "auto", SVX_CSS1_PBREAK_AUTO },
218 { "always", SVX_CSS1_PBREAK_ALWAYS },
219 { "avoid", SVX_CSS1_PBREAK_AVOID },
220 { "left", SVX_CSS1_PBREAK_LEFT },
221 { "right", SVX_CSS1_PBREAK_RIGHT },
222 { nullptr, 0 }
225 static CSS1PropertyEnum const aNumberStyleTable[] =
227 { "decimal", SVX_NUM_ARABIC },
228 { "lower-alpha", SVX_NUM_CHARS_LOWER_LETTER },
229 { "lower-latin", SVX_NUM_CHARS_LOWER_LETTER },
230 { "lower-roman", SVX_NUM_ROMAN_LOWER },
231 { "upper-alpha", SVX_NUM_CHARS_UPPER_LETTER },
232 { "upper-latin", SVX_NUM_CHARS_UPPER_LETTER },
233 { "upper-roman", SVX_NUM_ROMAN_UPPER },
234 { nullptr, 0 }
237 static CSS1PropertyEnum const aBulletStyleTable[] =
239 { "circle", HTML_BULLETCHAR_CIRCLE },
240 { "disc", HTML_BULLETCHAR_DISC },
241 { "square", HTML_BULLETCHAR_SQUARE },
242 { nullptr, 0 }
246 static sal_uInt16 const aBorderWidths[] =
248 DEF_LINE_WIDTH_0,
249 DEF_LINE_WIDTH_5,
250 DEF_LINE_WIDTH_1
253 #undef SBORDER_ENTRY
254 #undef DBORDER_ENTRY
256 struct SvxCSS1ItemIds
258 sal_uInt16 nFont;
259 sal_uInt16 nFontCJK;
260 sal_uInt16 nFontCTL;
261 sal_uInt16 nPosture;
262 sal_uInt16 nPostureCJK;
263 sal_uInt16 nPostureCTL;
264 sal_uInt16 nWeight;
265 sal_uInt16 nWeightCJK;
266 sal_uInt16 nWeightCTL;
267 sal_uInt16 nFontHeight;
268 sal_uInt16 nFontHeightCJK;
269 sal_uInt16 nFontHeightCTL;
270 sal_uInt16 nUnderline;
271 sal_uInt16 nOverline;
272 sal_uInt16 nCrossedOut;
273 sal_uInt16 nColor;
274 sal_uInt16 nKerning;
275 sal_uInt16 nCaseMap;
276 sal_uInt16 nBlink;
278 sal_uInt16 nLineSpacing;
279 sal_uInt16 nAdjust;
280 sal_uInt16 nWidows;
281 sal_uInt16 nOrphans;
282 sal_uInt16 nFormatSplit;
284 sal_uInt16 nLRSpace;
285 sal_uInt16 nULSpace;
286 sal_uInt16 nBox;
287 sal_uInt16 nBrush;
289 sal_uInt16 nLanguage;
290 sal_uInt16 nLanguageCJK;
291 sal_uInt16 nLanguageCTL;
292 sal_uInt16 nDirection;
295 static SvxCSS1ItemIds aItemIds;
297 struct SvxCSS1BorderInfo
299 Color aColor;
300 sal_uInt16 nAbsWidth;
301 sal_uInt16 nNamedWidth;
302 CSS1BorderStyle eStyle;
304 SvxCSS1BorderInfo() :
305 aColor( COL_BLACK ), nAbsWidth( USHRT_MAX ),
306 nNamedWidth( USHRT_MAX ), eStyle( CSS1_BS_NONE )
309 void SetBorderLine( SvxBoxItemLine nLine, SvxBoxItem &rBoxItem ) const;
312 void SvxCSS1BorderInfo::SetBorderLine( SvxBoxItemLine nLine, SvxBoxItem &rBoxItem ) const
314 if( CSS1_BS_NONE==eStyle || nAbsWidth==0 ||
315 (nAbsWidth==USHRT_MAX && nNamedWidth==USHRT_MAX) )
317 rBoxItem.SetLine( nullptr, nLine );
318 return;
321 ::editeng::SvxBorderLine aBorderLine( &aColor );
323 // Line style double or single?
324 switch ( eStyle )
326 case CSS1_BS_SINGLE:
327 aBorderLine.SetBorderLineStyle(SvxBorderLineStyle::SOLID);
328 break;
329 case CSS1_BS_DOUBLE:
330 aBorderLine.SetBorderLineStyle(SvxBorderLineStyle::DOUBLE);
331 break;
332 case CSS1_BS_DOTTED:
333 aBorderLine.SetBorderLineStyle(SvxBorderLineStyle::DOTTED);
334 break;
335 case CSS1_BS_DASHED:
336 aBorderLine.SetBorderLineStyle(SvxBorderLineStyle::DASHED);
337 break;
338 case CSS1_BS_GROOVE:
339 aBorderLine.SetBorderLineStyle(SvxBorderLineStyle::ENGRAVED);
340 break;
341 case CSS1_BS_RIDGE:
342 aBorderLine.SetBorderLineStyle(SvxBorderLineStyle::EMBOSSED);
343 break;
344 case CSS1_BS_INSET:
345 aBorderLine.SetBorderLineStyle(SvxBorderLineStyle::INSET);
346 break;
347 case CSS1_BS_OUTSET:
348 aBorderLine.SetBorderLineStyle(SvxBorderLineStyle::OUTSET);
349 break;
350 default:
351 aBorderLine.SetBorderLineStyle(SvxBorderLineStyle::NONE);
352 break;
355 // convert named width, if no absolute is given
356 if( nAbsWidth==USHRT_MAX )
357 aBorderLine.SetWidth( aBorderWidths[ nNamedWidth ] );
358 else
359 aBorderLine.SetWidth( nAbsWidth );
361 rBoxItem.SetLine( &aBorderLine, nLine );
364 SvxCSS1PropertyInfo::SvxCSS1PropertyInfo()
366 Clear();
369 SvxCSS1PropertyInfo::SvxCSS1PropertyInfo( const SvxCSS1PropertyInfo& rProp ) :
370 m_aId( rProp.m_aId ),
371 m_bTopMargin( rProp.m_bTopMargin ),
372 m_bBottomMargin( rProp.m_bBottomMargin ),
373 m_bLeftMargin( rProp.m_bLeftMargin ),
374 m_bRightMargin( rProp.m_bRightMargin ),
375 m_bTextIndent( rProp.m_bTextIndent ),
376 m_bNumbering ( rProp.m_bNumbering ),
377 m_bBullet ( rProp.m_bBullet ),
378 m_eFloat( rProp.m_eFloat ),
379 m_ePosition( rProp.m_ePosition ),
380 m_nTopBorderDistance( rProp.m_nTopBorderDistance ),
381 m_nBottomBorderDistance( rProp.m_nBottomBorderDistance ),
382 m_nLeftBorderDistance( rProp.m_nLeftBorderDistance ),
383 m_nRightBorderDistance( rProp.m_nRightBorderDistance ),
384 m_nNumberingType ( rProp.m_nNumberingType ),
385 m_cBulletChar( rProp.m_cBulletChar ),
386 m_nColumnCount( rProp.m_nColumnCount ),
387 m_nLeft( rProp.m_nLeft ),
388 m_nTop( rProp.m_nTop ),
389 m_nWidth( rProp.m_nWidth ),
390 m_nHeight( rProp.m_nHeight ),
391 m_nLeftMargin( rProp.m_nLeftMargin ),
392 m_nRightMargin( rProp.m_nRightMargin ),
393 m_eLeftType( rProp.m_eLeftType ),
394 m_eTopType( rProp.m_eTopType ),
395 m_eWidthType( rProp.m_eWidthType ),
396 m_eHeightType( rProp.m_eHeightType ),
397 m_eSizeType( rProp.m_eSizeType ),
398 m_ePageBreakBefore( rProp.m_ePageBreakBefore ),
399 m_ePageBreakAfter( rProp.m_ePageBreakAfter )
401 for( size_t i=0; i<m_aBorderInfos.size(); ++i )
402 if (rProp.m_aBorderInfos[i])
403 m_aBorderInfos[i].reset( new SvxCSS1BorderInfo( *rProp.m_aBorderInfos[i] ) );
406 SvxCSS1PropertyInfo::~SvxCSS1PropertyInfo()
410 void SvxCSS1PropertyInfo::DestroyBorderInfos()
412 for(auto & rp : m_aBorderInfos)
413 rp.reset();
416 void SvxCSS1PropertyInfo::Clear()
418 m_aId.clear();
419 m_bTopMargin = m_bBottomMargin = false;
420 m_bLeftMargin = m_bRightMargin = m_bTextIndent = false;
421 m_bNumbering = m_bBullet = false;
422 m_nLeftMargin = m_nRightMargin = 0;
423 m_eFloat = SvxAdjust::End;
425 m_ePosition = SVX_CSS1_POS_NONE;
426 m_nTopBorderDistance = m_nBottomBorderDistance =
427 m_nLeftBorderDistance = m_nRightBorderDistance = UNSET_BORDER_DISTANCE;
429 m_nNumberingType = SVX_NUM_CHARS_UPPER_LETTER;
430 m_cBulletChar = ' ';
432 m_nColumnCount = 0;
434 m_nLeft = m_nTop = m_nWidth = m_nHeight = 0;
435 m_eLeftType = m_eTopType = m_eWidthType = m_eHeightType = SVX_CSS1_LTYPE_NONE;
437 // Feature: PrintExt
438 m_eSizeType = SVX_CSS1_STYPE_NONE;
439 m_ePageBreakBefore = SVX_CSS1_PBREAK_NONE;
440 m_ePageBreakAfter = SVX_CSS1_PBREAK_NONE;
442 DestroyBorderInfos();
445 void SvxCSS1PropertyInfo::Merge( const SvxCSS1PropertyInfo& rProp )
447 if( rProp.m_bTopMargin )
448 m_bTopMargin = true;
449 if( rProp.m_bBottomMargin )
450 m_bBottomMargin = true;
452 if( rProp.m_bLeftMargin )
454 m_bLeftMargin = true;
455 m_nLeftMargin = rProp.m_nLeftMargin;
457 if( rProp.m_bRightMargin )
459 m_bRightMargin = true;
460 m_nRightMargin = rProp.m_nRightMargin;
462 if( rProp.m_bTextIndent )
463 m_bTextIndent = true;
465 for( size_t i=0; i<m_aBorderInfos.size(); ++i )
467 if( rProp.m_aBorderInfos[i] )
468 m_aBorderInfos[i].reset( new SvxCSS1BorderInfo( *rProp.m_aBorderInfos[i] ) );
471 if( UNSET_BORDER_DISTANCE != rProp.m_nTopBorderDistance )
472 m_nTopBorderDistance = rProp.m_nTopBorderDistance;
473 if( UNSET_BORDER_DISTANCE != rProp.m_nBottomBorderDistance )
474 m_nBottomBorderDistance = rProp.m_nBottomBorderDistance;
475 if( UNSET_BORDER_DISTANCE != rProp.m_nLeftBorderDistance )
476 m_nLeftBorderDistance = rProp.m_nLeftBorderDistance;
477 if( UNSET_BORDER_DISTANCE != rProp.m_nRightBorderDistance )
478 m_nRightBorderDistance = rProp.m_nRightBorderDistance;
480 m_nColumnCount = rProp.m_nColumnCount;
482 if( rProp.m_eFloat != SvxAdjust::End )
483 m_eFloat = rProp.m_eFloat;
485 if( rProp.m_ePosition != SVX_CSS1_POS_NONE )
486 m_ePosition = rProp.m_ePosition;
488 // Feature: PrintExt
489 if( rProp.m_eSizeType != SVX_CSS1_STYPE_NONE )
491 m_eSizeType = rProp.m_eSizeType;
492 m_nWidth = rProp.m_nWidth;
493 m_nHeight = rProp.m_nHeight;
496 if( rProp.m_ePageBreakBefore != SVX_CSS1_PBREAK_NONE )
497 m_ePageBreakBefore = rProp.m_ePageBreakBefore;
499 if( rProp.m_ePageBreakAfter != SVX_CSS1_PBREAK_NONE )
500 m_ePageBreakAfter = rProp.m_ePageBreakAfter;
502 if( rProp.m_eLeftType != SVX_CSS1_LTYPE_NONE )
504 m_eLeftType = rProp.m_eLeftType;
505 m_nLeft = rProp.m_nLeft;
508 if( rProp.m_eTopType != SVX_CSS1_LTYPE_NONE )
510 m_eTopType = rProp.m_eTopType;
511 m_nTop = rProp.m_nTop;
514 if( rProp.m_eWidthType != SVX_CSS1_LTYPE_NONE )
516 m_eWidthType = rProp.m_eWidthType;
517 m_nWidth = rProp.m_nWidth;
520 if( rProp.m_eHeightType != SVX_CSS1_LTYPE_NONE )
522 m_eHeightType = rProp.m_eHeightType;
523 m_nHeight = rProp.m_nHeight;
527 SvxCSS1BorderInfo *SvxCSS1PropertyInfo::GetBorderInfo( SvxBoxItemLine nLine, bool bCreate )
529 sal_uInt16 nPos = 0;
530 switch( nLine )
532 case SvxBoxItemLine::TOP: nPos = 0; break;
533 case SvxBoxItemLine::BOTTOM: nPos = 1; break;
534 case SvxBoxItemLine::LEFT: nPos = 2; break;
535 case SvxBoxItemLine::RIGHT: nPos = 3; break;
538 if( !m_aBorderInfos[nPos] && bCreate )
539 m_aBorderInfos[nPos].reset( new SvxCSS1BorderInfo );
541 return m_aBorderInfos[nPos].get();
544 void SvxCSS1PropertyInfo::CopyBorderInfo( SvxBoxItemLine nSrcLine, SvxBoxItemLine nDstLine,
545 sal_uInt16 nWhat )
547 SvxCSS1BorderInfo *pSrcInfo = GetBorderInfo( nSrcLine, false );
548 if( !pSrcInfo )
549 return;
551 SvxCSS1BorderInfo *pDstInfo = GetBorderInfo( nDstLine );
552 if( (nWhat & SVX_CSS1_BORDERINFO_WIDTH) != 0 )
554 pDstInfo->nAbsWidth = pSrcInfo->nAbsWidth;
555 pDstInfo->nNamedWidth = pSrcInfo->nNamedWidth;
558 if( (nWhat & SVX_CSS1_BORDERINFO_COLOR) != 0 )
559 pDstInfo->aColor = pSrcInfo->aColor;
561 if( (nWhat & SVX_CSS1_BORDERINFO_STYLE) != 0 )
562 pDstInfo->eStyle = pSrcInfo->eStyle;
565 void SvxCSS1PropertyInfo::CopyBorderInfo( sal_uInt16 nCount, sal_uInt16 nWhat )
567 if( nCount==0 )
569 CopyBorderInfo( SvxBoxItemLine::BOTTOM, SvxBoxItemLine::TOP, nWhat );
570 CopyBorderInfo( SvxBoxItemLine::TOP, SvxBoxItemLine::LEFT, nWhat );
572 if( nCount<=1 )
574 CopyBorderInfo( SvxBoxItemLine::LEFT, SvxBoxItemLine::RIGHT, nWhat );
578 void SvxCSS1PropertyInfo::SetBoxItem( SfxItemSet& rItemSet,
579 sal_uInt16 nMinBorderDist,
580 const SvxBoxItem *pDfltItem )
582 bool bChg = m_nTopBorderDistance != UNSET_BORDER_DISTANCE ||
583 m_nBottomBorderDistance != UNSET_BORDER_DISTANCE ||
584 m_nLeftBorderDistance != UNSET_BORDER_DISTANCE ||
585 m_nRightBorderDistance != UNSET_BORDER_DISTANCE;
587 for( size_t i=0; !bChg && i<m_aBorderInfos.size(); ++i )
588 bChg = m_aBorderInfos[i]!=nullptr;
590 if( !bChg )
591 return;
593 std::shared_ptr<SvxBoxItem> aBoxItem(std::make_shared<SvxBoxItem>(aItemIds.nBox));
594 if( pDfltItem )
595 aBoxItem.reset(static_cast<SvxBoxItem*>(pDfltItem->Clone()));
597 SvxCSS1BorderInfo *pInfo = GetBorderInfo( SvxBoxItemLine::TOP, false );
598 if( pInfo )
599 pInfo->SetBorderLine( SvxBoxItemLine::TOP, *aBoxItem );
601 pInfo = GetBorderInfo( SvxBoxItemLine::BOTTOM, false );
602 if( pInfo )
603 pInfo->SetBorderLine( SvxBoxItemLine::BOTTOM, *aBoxItem );
605 pInfo = GetBorderInfo( SvxBoxItemLine::LEFT, false );
606 if( pInfo )
607 pInfo->SetBorderLine( SvxBoxItemLine::LEFT, *aBoxItem );
609 pInfo = GetBorderInfo( SvxBoxItemLine::RIGHT, false );
610 if( pInfo )
611 pInfo->SetBorderLine( SvxBoxItemLine::RIGHT, *aBoxItem );
613 for( size_t i=0; i<m_aBorderInfos.size(); ++i )
615 SvxBoxItemLine nLine = SvxBoxItemLine::TOP;
616 sal_uInt16 nDist = 0;
617 switch( i )
619 case 0: nLine = SvxBoxItemLine::TOP;
620 nDist = m_nTopBorderDistance;
621 m_nTopBorderDistance = UNSET_BORDER_DISTANCE;
622 break;
623 case 1: nLine = SvxBoxItemLine::BOTTOM;
624 nDist = m_nBottomBorderDistance;
625 m_nBottomBorderDistance = UNSET_BORDER_DISTANCE;
626 break;
627 case 2: nLine = SvxBoxItemLine::LEFT;
628 nDist = m_nLeftBorderDistance;
629 m_nLeftBorderDistance = UNSET_BORDER_DISTANCE;
630 break;
631 case 3: nLine = SvxBoxItemLine::RIGHT;
632 nDist = m_nRightBorderDistance;
633 m_nRightBorderDistance = UNSET_BORDER_DISTANCE;
634 break;
637 if( aBoxItem->GetLine( nLine ) )
639 if( UNSET_BORDER_DISTANCE == nDist )
640 nDist = aBoxItem->GetDistance( nLine );
642 if( nDist < nMinBorderDist )
643 nDist = nMinBorderDist;
645 else
647 nDist = 0U;
650 aBoxItem->SetDistance( nDist, nLine );
653 rItemSet.Put( *aBoxItem );
655 DestroyBorderInfos();
658 SvxCSS1MapEntry::SvxCSS1MapEntry( const SfxItemSet& rItemSet,
659 const SvxCSS1PropertyInfo& rProp ) :
660 aItemSet( rItemSet ),
661 aPropInfo( rProp )
664 void SvxCSS1Parser::StyleParsed( const CSS1Selector * /*pSelector*/,
665 SfxItemSet& /*rItemSet*/,
666 SvxCSS1PropertyInfo& /*rPropInfo*/ )
668 // you see nothing is happening here
671 void SvxCSS1Parser::SelectorParsed( std::unique_ptr<CSS1Selector> pSelector, bool bFirst )
673 if( bFirst )
675 OSL_ENSURE( pSheetItemSet, "Where is the Item-Set for Style-Sheets?" );
677 for (const std::unique_ptr<CSS1Selector> & rpSelection : m_Selectors)
679 StyleParsed(rpSelection.get(), *pSheetItemSet, *pSheetPropInfo);
681 pSheetItemSet->ClearItem();
682 pSheetPropInfo->Clear();
684 // prepare the next rule
685 m_Selectors.clear();
688 m_Selectors.push_back(std::move(pSelector));
691 SvxCSS1Parser::SvxCSS1Parser( SfxItemPool& rPool, const OUString& rBaseURL,
692 sal_uInt16 const *pWhichIds, sal_uInt16 nWhichIds ) :
693 CSS1Parser(),
694 sBaseURL( rBaseURL ),
695 pItemSet(nullptr),
696 pPropInfo( nullptr ),
697 eDfltEnc( RTL_TEXTENCODING_DONTKNOW ),
698 bIgnoreFontFamily( false )
700 // also initialize item IDs
701 aItemIds.nFont = rPool.GetTrueWhich( SID_ATTR_CHAR_FONT, false );
702 aItemIds.nFontCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_FONT, false );
703 aItemIds.nFontCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_FONT, false );
704 aItemIds.nPosture = rPool.GetTrueWhich( SID_ATTR_CHAR_POSTURE, false );
705 aItemIds.nPostureCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_POSTURE, false );
706 aItemIds.nPostureCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_POSTURE, false );
707 aItemIds.nWeight = rPool.GetTrueWhich( SID_ATTR_CHAR_WEIGHT, false );
708 aItemIds.nWeightCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_WEIGHT, false );
709 aItemIds.nWeightCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_WEIGHT, false );
710 aItemIds.nFontHeight = rPool.GetTrueWhich( SID_ATTR_CHAR_FONTHEIGHT, false );
711 aItemIds.nFontHeightCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT, false );
712 aItemIds.nFontHeightCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT, false );
713 aItemIds.nUnderline = rPool.GetTrueWhich( SID_ATTR_CHAR_UNDERLINE, false );
714 aItemIds.nOverline = rPool.GetTrueWhich( SID_ATTR_CHAR_OVERLINE, false );
715 aItemIds.nCrossedOut = rPool.GetTrueWhich( SID_ATTR_CHAR_STRIKEOUT, false );
716 aItemIds.nColor = rPool.GetTrueWhich( SID_ATTR_CHAR_COLOR, false );
717 aItemIds.nKerning = rPool.GetTrueWhich( SID_ATTR_CHAR_KERNING, false );
718 aItemIds.nCaseMap = rPool.GetTrueWhich( SID_ATTR_CHAR_CASEMAP, false );
719 aItemIds.nBlink = rPool.GetTrueWhich( SID_ATTR_FLASH, false );
721 aItemIds.nLineSpacing = rPool.GetTrueWhich( SID_ATTR_PARA_LINESPACE, false );
722 aItemIds.nAdjust = rPool.GetTrueWhich( SID_ATTR_PARA_ADJUST, false );
723 aItemIds.nWidows = rPool.GetTrueWhich( SID_ATTR_PARA_WIDOWS, false );
724 aItemIds.nOrphans = rPool.GetTrueWhich( SID_ATTR_PARA_ORPHANS, false );
725 aItemIds.nFormatSplit = rPool.GetTrueWhich( SID_ATTR_PARA_SPLIT, false );
727 aItemIds.nLRSpace = rPool.GetTrueWhich( SID_ATTR_LRSPACE, false );
728 aItemIds.nULSpace = rPool.GetTrueWhich( SID_ATTR_ULSPACE, false );
729 aItemIds.nBox = rPool.GetTrueWhich( SID_ATTR_BORDER_OUTER, false );
730 aItemIds.nBrush = rPool.GetTrueWhich( SID_ATTR_BRUSH, false );
732 aItemIds.nLanguage = rPool.GetTrueWhich( SID_ATTR_CHAR_LANGUAGE, false );
733 aItemIds.nLanguageCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_LANGUAGE, false );
734 aItemIds.nLanguageCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_LANGUAGE, false );
735 aItemIds.nDirection = rPool.GetTrueWhich( SID_ATTR_FRAMEDIRECTION, false );
737 aWhichMap.insert( aWhichMap.begin(), 0 );
738 BuildWhichTable( aWhichMap, reinterpret_cast<sal_uInt16 *>(&aItemIds),
739 sizeof(aItemIds) / sizeof(sal_uInt16) );
740 if( pWhichIds && nWhichIds )
741 BuildWhichTable( aWhichMap, pWhichIds, nWhichIds );
743 pSheetItemSet.reset( new SfxItemSet( rPool, aWhichMap.data() ) );
744 pSheetPropInfo.reset( new SvxCSS1PropertyInfo );
747 SvxCSS1Parser::~SvxCSS1Parser()
749 pSheetItemSet.reset();
750 pSheetPropInfo.reset();
753 void SvxCSS1Parser::InsertId( const OUString& rId,
754 const SfxItemSet& rItemSet,
755 const SvxCSS1PropertyInfo& rProp )
757 InsertMapEntry( rId, rItemSet, rProp, m_Ids );
760 const SvxCSS1MapEntry* SvxCSS1Parser::GetId( const OUString& rId ) const
762 CSS1Map::const_iterator itr = m_Ids.find(rId);
763 return itr == m_Ids.end() ? nullptr : itr->second.get();
766 void SvxCSS1Parser::InsertClass( const OUString& rClass,
767 const SfxItemSet& rItemSet,
768 const SvxCSS1PropertyInfo& rProp )
770 InsertMapEntry( rClass, rItemSet, rProp, m_Classes );
773 const SvxCSS1MapEntry* SvxCSS1Parser::GetClass( const OUString& rClass ) const
775 CSS1Map::const_iterator itr = m_Classes.find(rClass);
776 return itr == m_Classes.end() ? nullptr : itr->second.get();
779 void SvxCSS1Parser::InsertPage( const OUString& rPage,
780 bool bPseudo,
781 const SfxItemSet& rItemSet,
782 const SvxCSS1PropertyInfo& rProp )
784 OUString aKey( rPage );
785 if( bPseudo )
786 aKey = ":" + aKey;
787 InsertMapEntry( aKey, rItemSet, rProp, m_Pages );
790 SvxCSS1MapEntry* SvxCSS1Parser::GetPage( const OUString& rPage, bool bPseudo )
792 OUString aKey( rPage );
793 if( bPseudo )
794 aKey = ":" + aKey;
796 CSS1Map::iterator itr = m_Pages.find(aKey);
797 return itr == m_Pages.end() ? nullptr : itr->second.get();
800 void SvxCSS1Parser::InsertTag( const OUString& rTag,
801 const SfxItemSet& rItemSet,
802 const SvxCSS1PropertyInfo& rProp )
804 InsertMapEntry( rTag, rItemSet, rProp, m_Tags );
807 SvxCSS1MapEntry* SvxCSS1Parser::GetTag( const OUString& rTag )
809 CSS1Map::iterator itr = m_Tags.find(rTag);
810 return itr == m_Tags.end() ? nullptr : itr->second.get();
813 bool SvxCSS1Parser::ParseStyleSheet( const OUString& rIn )
815 pItemSet = pSheetItemSet.get();
816 pPropInfo = pSheetPropInfo.get();
818 CSS1Parser::ParseStyleSheet( rIn );
820 for (const std::unique_ptr<CSS1Selector> & rpSelector : m_Selectors)
822 StyleParsed(rpSelector.get(), *pSheetItemSet, *pSheetPropInfo);
825 // and clean up a little bit
826 m_Selectors.clear();
827 pSheetItemSet->ClearItem();
828 pSheetPropInfo->Clear();
830 pItemSet = nullptr;
831 pPropInfo = nullptr;
833 return true;
836 void SvxCSS1Parser::ParseStyleOption( const OUString& rIn,
837 SfxItemSet& rItemSet,
838 SvxCSS1PropertyInfo& rPropInfo )
840 pItemSet = &rItemSet;
841 pPropInfo = &rPropInfo;
843 CSS1Parser::ParseStyleOption( rIn );
844 rItemSet.ClearItem( aItemIds.nDirection );
846 pItemSet = nullptr;
847 pPropInfo = nullptr;
850 bool SvxCSS1Parser::GetEnum( const CSS1PropertyEnum *pPropTable,
851 const OUString &rValue, sal_uInt16& rEnum )
853 while( pPropTable->pName )
855 if( !rValue.equalsIgnoreAsciiCaseAscii( pPropTable->pName ) )
856 pPropTable++;
857 else
858 break;
861 if( pPropTable->pName )
862 rEnum = pPropTable->nEnum;
864 return (pPropTable->pName != nullptr);
867 void SvxCSS1Parser::PixelToTwip( long &rWidth, long &rHeight )
869 if( Application::GetDefaultDevice() )
871 Size aTwipSz( rWidth, rHeight );
872 aTwipSz = Application::GetDefaultDevice()->PixelToLogic( aTwipSz,
873 MapMode(MapUnit::MapTwip) );
875 rWidth = aTwipSz.Width();
876 rHeight = aTwipSz.Height();
880 sal_uInt32 SvxCSS1Parser::GetFontHeight( sal_uInt16 nSize ) const
882 sal_uInt16 nHeight;
884 switch( nSize )
886 case 0: nHeight = 8*20; break;
887 case 1: nHeight = 10*20; break;
888 case 2: nHeight = 11*20; break;
889 case 3: nHeight = 12*20; break;
890 case 4: nHeight = 17*20; break;
891 case 5: nHeight = 20*20; break;
892 case 6:
893 default: nHeight = 32*20; break;
896 return nHeight;
899 const FontList *SvxCSS1Parser::GetFontList() const
901 return nullptr;
904 void SvxCSS1Parser::InsertMapEntry( const OUString& rKey,
905 const SfxItemSet& rItemSet,
906 const SvxCSS1PropertyInfo& rProp,
907 CSS1Map& rMap )
909 CSS1Map::iterator itr = rMap.find(rKey);
910 if (itr == rMap.end())
912 rMap.insert(std::make_pair(rKey, std::make_unique<SvxCSS1MapEntry>(rItemSet, rProp)));
914 else
916 SvxCSS1MapEntry *const p = itr->second.get();
917 MergeStyles( rItemSet, rProp,
918 p->GetItemSet(), p->GetPropertyInfo(), true );
922 void SvxCSS1Parser::MergeStyles( const SfxItemSet& rSrcSet,
923 const SvxCSS1PropertyInfo& rSrcInfo,
924 SfxItemSet& rTargetSet,
925 SvxCSS1PropertyInfo& rTargetInfo,
926 bool bSmart )
928 if( !bSmart )
930 rTargetSet.Put( rSrcSet );
932 else
934 SvxLRSpaceItem aLRSpace( static_cast<const SvxLRSpaceItem&>(rTargetSet.Get(aItemIds.nLRSpace)) );
935 SvxULSpaceItem aULSpace( static_cast<const SvxULSpaceItem&>(rTargetSet.Get(aItemIds.nULSpace)) );
937 rTargetSet.Put( rSrcSet );
939 if( rSrcInfo.m_bLeftMargin || rSrcInfo.m_bRightMargin ||
940 rSrcInfo.m_bTextIndent )
942 const SvxLRSpaceItem& rNewLRSpace =
943 static_cast<const SvxLRSpaceItem&>(rSrcSet.Get( aItemIds.nLRSpace ));
945 if( rSrcInfo.m_bLeftMargin )
946 aLRSpace.SetLeft( rNewLRSpace.GetLeft() );
947 if( rSrcInfo.m_bRightMargin )
948 aLRSpace.SetRight( rNewLRSpace.GetRight() );
949 if( rSrcInfo.m_bTextIndent )
950 aLRSpace.SetTextFirstLineOfst( rNewLRSpace.GetTextFirstLineOfst() );
952 rTargetSet.Put( aLRSpace );
955 if( rSrcInfo.m_bTopMargin || rSrcInfo.m_bBottomMargin )
957 const SvxULSpaceItem& rNewULSpace =
958 static_cast<const SvxULSpaceItem&>(rSrcSet.Get( aItemIds.nULSpace ));
960 if( rSrcInfo.m_bTopMargin )
961 aULSpace.SetUpper( rNewULSpace.GetUpper() );
962 if( rSrcInfo.m_bBottomMargin )
963 aULSpace.SetLower( rNewULSpace.GetLower() );
965 rTargetSet.Put( aULSpace );
969 rTargetInfo.Merge( rSrcInfo );
972 void SvxCSS1Parser::SetDfltEncoding( rtl_TextEncoding eEnc )
974 eDfltEnc = eEnc;
977 static void ParseCSS1_font_size( const CSS1Expression *pExpr,
978 SfxItemSet &rItemSet,
979 SvxCSS1PropertyInfo& /*rPropInfo*/,
980 const SvxCSS1Parser& rParser )
982 OSL_ENSURE( pExpr, "no expression" );
984 sal_uLong nHeight = 0;
985 sal_uInt16 nPropHeight = 100;
987 switch( pExpr->GetType() )
989 case CSS1_LENGTH:
990 nHeight = pExpr->GetULength();
991 break;
992 case CSS1_PIXLENGTH:
994 double fHeight = pExpr->GetNumber();
995 if (fHeight < SAL_MAX_INT32/2.0 && fHeight > SAL_MIN_INT32/2.0)
997 long nPHeight = static_cast<long>(fHeight);
998 long nPWidth = 0;
999 SvxCSS1Parser::PixelToTwip(nPWidth, nPHeight);
1000 nHeight = static_cast<sal_uLong>(nPHeight);
1002 else
1004 SAL_WARN("sw.html", "out-of-size pxlength: " << fHeight);
1007 break;
1008 case CSS1_PERCENTAGE:
1009 // only for drop caps!
1010 nPropHeight = static_cast<sal_uInt16>(pExpr->GetNumber());
1011 break;
1012 case CSS1_IDENT:
1014 sal_uInt16 nSize;
1016 if( SvxCSS1Parser::GetEnum( aFontSizeTable, pExpr->GetString(),
1017 nSize ) )
1019 nHeight = rParser.GetFontHeight( nSize );
1022 break;
1024 default:
1028 if( nHeight || nPropHeight!=100 )
1030 SvxFontHeightItem aFontHeight( nHeight, nPropHeight,
1031 aItemIds.nFontHeight );
1032 rItemSet.Put( aFontHeight );
1033 aFontHeight.SetWhich( aItemIds.nFontHeightCJK );
1034 rItemSet.Put( aFontHeight );
1035 aFontHeight.SetWhich( aItemIds.nFontHeightCTL );
1036 rItemSet.Put( aFontHeight );
1040 static void ParseCSS1_font_family( const CSS1Expression *pExpr,
1041 SfxItemSet &rItemSet,
1042 SvxCSS1PropertyInfo& /*rPropInfo*/,
1043 const SvxCSS1Parser& rParser )
1045 OSL_ENSURE( pExpr, "no expression" );
1047 OUStringBuffer aName;
1048 rtl_TextEncoding eEnc = rParser.GetDfltEncoding();
1049 const FontList *pFList = rParser.GetFontList();
1050 bool bFirst = true;
1051 bool bFound = false;
1052 while( pExpr && (bFirst || ','==pExpr->GetOp() || !pExpr->GetOp()) )
1054 CSS1Token eType = pExpr->GetType();
1055 if( CSS1_IDENT==eType || CSS1_STRING==eType )
1057 OUString aIdent( pExpr->GetString() );
1059 if( CSS1_IDENT==eType )
1061 // Collect all following IDs and append them with a space
1062 const CSS1Expression *pNext = pExpr->GetNext();
1063 while( pNext && !pNext->GetOp() &&
1064 CSS1_IDENT==pNext->GetType() )
1066 aIdent += " " + pNext->GetString();
1067 pExpr = pNext;
1068 pNext = pExpr->GetNext();
1071 if( !aIdent.isEmpty() )
1073 if( !bFound && pFList )
1075 sal_Handle hFont = pFList->GetFirstFontMetric( aIdent );
1076 if( nullptr != hFont )
1078 const FontMetric& rFMetric = FontList::GetFontMetric( hFont );
1079 if( RTL_TEXTENCODING_DONTKNOW != rFMetric.GetCharSet() )
1081 bFound = true;
1082 if( RTL_TEXTENCODING_SYMBOL == rFMetric.GetCharSet() )
1083 eEnc = RTL_TEXTENCODING_SYMBOL;
1087 if( !bFirst )
1088 aName.append(";");
1089 aName.append(aIdent);
1093 pExpr = pExpr->GetNext();
1094 bFirst = false;
1097 if( !aName.isEmpty() && !rParser.IsIgnoreFontFamily() )
1099 SvxFontItem aFont( FAMILY_DONTKNOW, aName.makeStringAndClear(), OUString(), PITCH_DONTKNOW,
1100 eEnc, aItemIds.nFont );
1101 rItemSet.Put( aFont );
1102 aFont.SetWhich( aItemIds.nFontCJK );
1103 rItemSet.Put( aFont );
1104 aFont.SetWhich( aItemIds.nFontCTL );
1105 rItemSet.Put( aFont );
1109 static void ParseCSS1_font_weight( const CSS1Expression *pExpr,
1110 SfxItemSet &rItemSet,
1111 SvxCSS1PropertyInfo& /*rPropInfo*/,
1112 const SvxCSS1Parser& /*rParser*/ )
1114 OSL_ENSURE( pExpr, "no expression" );
1116 switch( pExpr->GetType() )
1118 case CSS1_IDENT:
1119 case CSS1_STRING: // MS-IE, what else
1121 sal_uInt16 nWeight;
1122 if( SvxCSS1Parser::GetEnum( aFontWeightTable, pExpr->GetString(),
1123 nWeight ) )
1125 SvxWeightItem aWeight( static_cast<FontWeight>(nWeight), aItemIds.nWeight );
1126 rItemSet.Put( aWeight );
1127 aWeight.SetWhich( aItemIds.nWeightCJK );
1128 rItemSet.Put( aWeight );
1129 aWeight.SetWhich( aItemIds.nWeightCTL );
1130 rItemSet.Put( aWeight );
1133 break;
1134 case CSS1_NUMBER:
1136 sal_uInt16 nWeight = static_cast<sal_uInt16>(pExpr->GetNumber());
1137 SvxWeightItem aWeight( nWeight>400 ? WEIGHT_BOLD : WEIGHT_NORMAL,
1138 aItemIds.nWeight );
1139 rItemSet.Put( aWeight );
1140 aWeight.SetWhich( aItemIds.nWeightCJK );
1141 rItemSet.Put( aWeight );
1142 aWeight.SetWhich( aItemIds.nWeightCTL );
1143 rItemSet.Put( aWeight );
1145 break;
1147 default:
1152 static void ParseCSS1_font_style( const CSS1Expression *pExpr,
1153 SfxItemSet &rItemSet,
1154 SvxCSS1PropertyInfo& /*rPropInfo*/,
1155 const SvxCSS1Parser& /*rParser*/ )
1157 OSL_ENSURE( pExpr, "no expression" );
1159 bool bPosture = false;
1160 bool bCaseMap = false;
1161 FontItalic eItalic = ITALIC_NONE;
1162 SvxCaseMap eCaseMap = SvxCaseMap::NotMapped;
1164 // normal | italic || small-caps | oblique || small-caps | small-caps
1165 // (only normal, italic and oblique are valid)
1167 // the value can have two values!
1168 for( int i=0; pExpr && i<2; ++i )
1170 // also here MS-IE parser leaves traces
1171 if( (CSS1_IDENT==pExpr->GetType() || CSS1_STRING==pExpr->GetType()) &&
1172 !pExpr->GetOp() )
1174 const OUString& rValue = pExpr->GetString();
1175 // first check if the value is italic or 'normal'
1176 sal_uInt16 nItalic;
1177 if( SvxCSS1Parser::GetEnum( aFontStyleTable, rValue, nItalic ) )
1179 eItalic = static_cast<FontItalic>(nItalic);
1180 if( !bCaseMap && ITALIC_NONE==eItalic )
1182 // for 'normal' we must also exclude case-map
1183 eCaseMap = SvxCaseMap::NotMapped;
1184 bCaseMap = true;
1186 bPosture = true;
1188 else if( !bCaseMap &&
1189 rValue.equalsIgnoreAsciiCase( "small-caps" ) )
1191 eCaseMap = SvxCaseMap::SmallCaps;
1192 bCaseMap = true;
1196 // fetch next expression
1197 pExpr = pExpr->GetNext();
1200 if( bPosture )
1202 SvxPostureItem aPosture( eItalic, aItemIds.nPosture );
1203 rItemSet.Put( aPosture );
1204 aPosture.SetWhich( aItemIds.nPostureCJK );
1205 rItemSet.Put( aPosture );
1206 aPosture.SetWhich( aItemIds.nPostureCTL );
1207 rItemSet.Put( aPosture );
1210 if( bCaseMap )
1211 rItemSet.Put( SvxCaseMapItem( eCaseMap, aItemIds.nCaseMap ) );
1214 static void ParseCSS1_font_variant( const CSS1Expression *pExpr,
1215 SfxItemSet &rItemSet,
1216 SvxCSS1PropertyInfo& /*rPropInfo*/,
1217 const SvxCSS1Parser& /*rParser*/ )
1219 assert(pExpr && "no expression");
1221 // normal | small-caps
1222 switch( pExpr->GetType() )
1224 case CSS1_IDENT:
1226 sal_uInt16 nCaseMap;
1227 if( SvxCSS1Parser::GetEnum( aFontVariantTable, pExpr->GetString(),
1228 nCaseMap ) )
1230 rItemSet.Put( SvxCaseMapItem( static_cast<SvxCaseMap>(nCaseMap),
1231 aItemIds.nCaseMap ) );
1233 break;
1235 default:
1236 break;
1240 static void ParseCSS1_text_transform( const CSS1Expression *pExpr,
1241 SfxItemSet &rItemSet,
1242 SvxCSS1PropertyInfo& /*rPropInfo*/,
1243 const SvxCSS1Parser& /*rParser*/ )
1245 OSL_ENSURE( pExpr, "no expression" );
1247 // none | capitalize | uppercase | lowercase
1249 switch( pExpr->GetType() )
1251 case CSS1_IDENT:
1253 sal_uInt16 nCaseMap;
1254 if( SvxCSS1Parser::GetEnum( aTextTransformTable, pExpr->GetString(),
1255 nCaseMap ) )
1257 rItemSet.Put( SvxCaseMapItem( static_cast<SvxCaseMap>(nCaseMap),
1258 aItemIds.nCaseMap ) );
1260 break;
1262 default:
1263 break;
1267 static void ParseCSS1_color( const CSS1Expression *pExpr,
1268 SfxItemSet &rItemSet,
1269 SvxCSS1PropertyInfo& /*rPropInfo*/,
1270 const SvxCSS1Parser& /*rParser*/ )
1272 OSL_ENSURE( pExpr, "no expression" );
1274 switch( pExpr->GetType() )
1276 case CSS1_IDENT:
1277 case CSS1_RGB:
1278 case CSS1_HEXCOLOR:
1279 case CSS1_STRING: // because MS-IE
1281 Color aColor;
1282 if( pExpr->GetColor( aColor ) )
1283 rItemSet.Put( SvxColorItem( aColor, aItemIds.nColor ) );
1285 break;
1286 default:
1291 static void ParseCSS1_column_count( const CSS1Expression *pExpr,
1292 SfxItemSet& /*rItemSet*/,
1293 SvxCSS1PropertyInfo &rPropInfo,
1294 const SvxCSS1Parser& /*rParser*/ )
1296 assert(pExpr && "no expression");
1298 if ( pExpr->GetType() == CSS1_NUMBER )
1300 double columnCount = pExpr->GetNumber();
1301 if ( columnCount >= 2 )
1303 rPropInfo.m_nColumnCount = columnCount;
1308 static void ParseCSS1_direction( const CSS1Expression *pExpr,
1309 SfxItemSet &rItemSet,
1310 SvxCSS1PropertyInfo& /*rPropInfo*/,
1311 const SvxCSS1Parser& /*rParser*/ )
1313 assert(pExpr && "no expression");
1315 sal_uInt16 nDir;
1316 switch( pExpr->GetType() )
1318 case CSS1_IDENT:
1319 case CSS1_STRING:
1320 if( SvxCSS1Parser::GetEnum( aDirectionTable, pExpr->GetString(),
1321 nDir ) )
1323 rItemSet.Put( SvxFrameDirectionItem(
1324 static_cast < SvxFrameDirection >( nDir ),
1325 aItemIds.nDirection ) );
1327 break;
1328 default:
1333 static void MergeHori( SvxGraphicPosition& ePos, SvxGraphicPosition eHori )
1335 OSL_ENSURE( GPOS_LT==eHori || GPOS_MT==eHori || GPOS_RT==eHori,
1336 "vertical position not at the top" );
1338 switch( ePos )
1340 case GPOS_LT:
1341 case GPOS_MT:
1342 case GPOS_RT:
1343 ePos = eHori;
1344 break;
1346 case GPOS_LM:
1347 case GPOS_MM:
1348 case GPOS_RM:
1349 ePos = GPOS_LT==eHori ? GPOS_LM : (GPOS_MT==eHori ? GPOS_MM : GPOS_RM);
1350 break;
1352 case GPOS_LB:
1353 case GPOS_MB:
1354 case GPOS_RB:
1355 ePos = GPOS_LT==eHori ? GPOS_LB : (GPOS_MT==eHori ? GPOS_MB : GPOS_RB);
1356 break;
1358 default:
1363 static void MergeVert( SvxGraphicPosition& ePos, SvxGraphicPosition eVert )
1365 OSL_ENSURE( GPOS_LT==eVert || GPOS_LM==eVert || GPOS_LB==eVert,
1366 "horizontal position not on the left side" );
1368 switch( ePos )
1370 case GPOS_LT:
1371 case GPOS_LM:
1372 case GPOS_LB:
1373 ePos = eVert;
1374 break;
1376 case GPOS_MT:
1377 case GPOS_MM:
1378 case GPOS_MB:
1379 ePos = GPOS_LT==eVert ? GPOS_MT : (GPOS_LM==eVert ? GPOS_MM : GPOS_MB);
1380 break;
1382 case GPOS_RT:
1383 case GPOS_RM:
1384 case GPOS_RB:
1385 ePos = GPOS_LT==eVert ? GPOS_RT : (GPOS_LM==eVert ? GPOS_RM : GPOS_RB);
1386 break;
1388 default:
1393 static void ParseCSS1_background( const CSS1Expression *pExpr,
1394 SfxItemSet &rItemSet,
1395 SvxCSS1PropertyInfo& /*rPropInfo*/,
1396 const SvxCSS1Parser& rParser )
1398 OSL_ENSURE( pExpr, "no expression" );
1400 Color aColor;
1401 OUString aURL;
1403 bool bColor = false, bTransparent = false;
1404 SvxGraphicPosition eRepeat = GPOS_TILED;
1405 SvxGraphicPosition ePos = GPOS_LT;
1406 bool bHori = false, bVert = false;
1408 while( pExpr && !pExpr->GetOp() )
1410 switch( pExpr->GetType() )
1412 case CSS1_URL:
1413 pExpr->GetURL( aURL );
1414 break;
1416 case CSS1_RGB:
1417 bColor = pExpr->GetColor( aColor );
1418 break;
1420 case CSS1_LENGTH:
1421 case CSS1_PIXLENGTH:
1423 // since we don't know any absolute position, we
1424 // only distinguish between 0 and !0. Therefore pixel
1425 // can be handled like all other units.
1427 bool nonZero = std::trunc(pExpr->GetNumber()) != 0.0;
1428 if( !bHori )
1430 ePos = nonZero ? GPOS_MM : GPOS_LT;
1431 bHori = true;
1433 else if( !bVert )
1435 MergeVert( ePos, (nonZero ? GPOS_LM : GPOS_LT) );
1436 bVert = true;
1439 break;
1441 case CSS1_PERCENTAGE:
1443 // the percentage is converted to an enum
1445 sal_uInt16 nPerc = static_cast<sal_uInt16>(pExpr->GetNumber());
1446 if( !bHori )
1448 ePos = nPerc < 25 ? GPOS_LT
1449 : (nPerc < 75 ? GPOS_MM
1450 : GPOS_RB);
1452 else if( !bVert )
1454 SvxGraphicPosition eVert =
1455 nPerc < 25 ? GPOS_LT: (nPerc < 75 ? GPOS_LM
1456 : GPOS_LB);
1457 MergeVert( ePos, eVert );
1460 break;
1462 case CSS1_IDENT:
1463 case CSS1_HEXCOLOR:
1464 case CSS1_STRING: // because of MS-IE
1466 sal_uInt16 nEnum;
1467 const OUString &rValue = pExpr->GetString();
1468 if( rValue.equalsIgnoreAsciiCase( "transparent" ) )
1470 bTransparent = true;
1472 if( SvxCSS1Parser::GetEnum( aBGRepeatTable, rValue, nEnum ) )
1474 eRepeat = static_cast<SvxGraphicPosition>(nEnum);
1476 else if( SvxCSS1Parser::GetEnum( aBGHoriPosTable, rValue, nEnum ) )
1478 // <position>, horizontal
1479 MergeHori( ePos, static_cast<SvxGraphicPosition>(nEnum) );
1481 else if( SvxCSS1Parser::GetEnum( aBGVertPosTable, rValue, nEnum ) )
1483 // <position>, vertical
1484 MergeVert( ePos, static_cast<SvxGraphicPosition>(nEnum) );
1486 else if( !bColor )
1488 // <color>
1489 bColor = pExpr->GetColor( aColor );
1491 // <scroll> we don't know
1493 break;
1495 default:
1499 pExpr = pExpr->GetNext();
1502 // transparent beats everything
1503 if( bTransparent )
1505 bColor = false;
1506 aURL.clear();
1509 // repeat has priority over a position
1510 if( GPOS_NONE == eRepeat )
1511 eRepeat = ePos;
1513 if( bTransparent || bColor || !aURL.isEmpty() )
1515 SvxBrushItem aBrushItem( aItemIds.nBrush );
1517 if( bTransparent )
1518 aBrushItem.SetColor( COL_TRANSPARENT);
1519 else if( bColor )
1520 aBrushItem.SetColor( aColor );
1522 if( !aURL.isEmpty() )
1524 aBrushItem.SetGraphicLink( URIHelper::SmartRel2Abs( INetURLObject( rParser.GetBaseURL()), aURL, Link<OUString *, bool>(), false ) );
1525 aBrushItem.SetGraphicPos( eRepeat );
1528 rItemSet.Put( aBrushItem );
1532 static void ParseCSS1_background_color( const CSS1Expression *pExpr,
1533 SfxItemSet &rItemSet,
1534 SvxCSS1PropertyInfo& /*rPropInfo*/,
1535 const SvxCSS1Parser& /*rParser*/ )
1537 OSL_ENSURE( pExpr, "no expression" );
1539 Color aColor;
1541 bool bColor = false, bTransparent = false;
1543 switch( pExpr->GetType() )
1545 case CSS1_RGB:
1546 bColor = pExpr->GetColor( aColor );
1547 break;
1548 case CSS1_IDENT:
1549 case CSS1_HEXCOLOR:
1550 case CSS1_STRING: // because of MS-IE
1551 if( pExpr->GetString().equalsIgnoreAsciiCase( "transparent" ) )
1553 bTransparent = true;
1555 else
1557 // <color>
1558 bColor = pExpr->GetColor( aColor );
1560 break;
1561 default:
1565 if( bTransparent || bColor )
1567 SvxBrushItem aBrushItem( aItemIds.nBrush );
1569 if( bTransparent )
1570 aBrushItem.SetColor( COL_TRANSPARENT );
1571 else if( bColor )
1572 aBrushItem.SetColor( aColor);
1574 rItemSet.Put( aBrushItem );
1578 static void ParseCSS1_line_height( const CSS1Expression *pExpr,
1579 SfxItemSet &rItemSet,
1580 SvxCSS1PropertyInfo& /*rPropInfo*/,
1581 const SvxCSS1Parser& )
1583 OSL_ENSURE( pExpr, "no expression" );
1585 sal_uInt16 nHeight = 0;
1586 sal_uInt16 nPropHeight = 0;
1588 switch( pExpr->GetType() )
1590 case CSS1_LENGTH:
1591 nHeight = static_cast<sal_uInt16>(pExpr->GetULength());
1592 break;
1593 case CSS1_PIXLENGTH:
1595 double fHeight = pExpr->GetNumber();
1596 if (fHeight < SAL_MAX_INT32/2.0 && fHeight > SAL_MIN_INT32/2.0)
1598 long nPHeight = static_cast<long>(fHeight);
1599 long nPWidth = 0;
1600 SvxCSS1Parser::PixelToTwip(nPWidth, nPHeight);
1601 nHeight = static_cast<sal_uInt16>(nPHeight);
1604 break;
1605 case CSS1_PERCENTAGE:
1607 nPropHeight = static_cast<sal_uInt16>(pExpr->GetNumber());
1609 break;
1610 case CSS1_NUMBER:
1612 nPropHeight = static_cast<sal_uInt16>(pExpr->GetNumber() * 100);
1614 break;
1615 default:
1619 if( nHeight )
1621 if( nHeight < SvxCSS1Parser::GetMinFixLineSpace() )
1622 nHeight = SvxCSS1Parser::GetMinFixLineSpace();
1623 SvxLineSpacingItem aLSItem( nHeight, aItemIds.nLineSpacing );
1624 aLSItem.SetLineHeight( nHeight );
1625 // interpret <line-height> attribute as minimum line height
1626 aLSItem.SetLineSpaceRule( SvxLineSpaceRule::Min );
1627 aLSItem.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off );
1628 rItemSet.Put( aLSItem );
1630 else if( nPropHeight )
1632 SvxLineSpacingItem aLSItem( nPropHeight, aItemIds.nLineSpacing );
1633 aLSItem.SetLineSpaceRule( SvxLineSpaceRule::Auto );
1634 if( 100 == nPropHeight )
1635 aLSItem.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off );
1636 else
1637 aLSItem.SetPropLineSpace( nPropHeight );
1638 rItemSet.Put( aLSItem );
1643 static void ParseCSS1_list_style_type( const CSS1Expression *pExpr,
1644 SfxItemSet & /*rItemSet*/,
1645 SvxCSS1PropertyInfo& rPropInfo,
1646 const SvxCSS1Parser& /*rParser*/ )
1648 OSL_ENSURE( pExpr, "no expression" );
1650 if( pExpr->GetType() == CSS1_IDENT )
1652 const OUString& rValue = pExpr->GetString();
1654 // values are context-dependent, so fill both
1655 sal_uInt16 nEnum;
1656 if( SvxCSS1Parser::GetEnum( aNumberStyleTable, rValue, nEnum ) )
1658 rPropInfo.m_bNumbering = true;
1659 rPropInfo.m_nNumberingType = static_cast<SvxNumType>(nEnum);
1661 if( SvxCSS1Parser::GetEnum( aBulletStyleTable, rValue, nEnum ) )
1663 rPropInfo.m_bBullet = true;
1664 rPropInfo.m_cBulletChar = nEnum;
1669 static void ParseCSS1_font( const CSS1Expression *pExpr,
1670 SfxItemSet &rItemSet,
1671 SvxCSS1PropertyInfo& rPropInfo,
1672 const SvxCSS1Parser& rParser )
1674 OSL_ENSURE( pExpr, "no expression" );
1676 FontItalic eItalic = ITALIC_NONE;
1677 SvxCaseMap eCaseMap = SvxCaseMap::NotMapped;
1678 FontWeight eWeight = WEIGHT_NORMAL;
1680 // [ <font-style> || <font-variant> || <font-weight> ] ?
1681 while( pExpr && !pExpr->GetOp() &&
1682 (CSS1_IDENT==pExpr->GetType() ||
1683 CSS1_STRING==pExpr->GetType() ||
1684 CSS1_NUMBER==pExpr->GetType()) )
1686 if( CSS1_IDENT==pExpr->GetType() ||
1687 CSS1_STRING==pExpr->GetType() )
1689 const OUString& rValue = pExpr->GetString();
1691 sal_uInt16 nEnum;
1693 if( SvxCSS1Parser::GetEnum( aFontStyleTable, rValue, nEnum ) )
1695 eItalic = static_cast<FontItalic>(nEnum);
1697 else if( SvxCSS1Parser::GetEnum( aFontVariantTable, rValue, nEnum ) )
1699 eCaseMap = static_cast<SvxCaseMap>(nEnum);
1701 else if( SvxCSS1Parser::GetEnum( aFontWeightTable, rValue, nEnum ) )
1703 eWeight = static_cast<FontWeight>(nEnum);
1706 else
1708 eWeight = static_cast<sal_uInt16>(pExpr->GetNumber()) > 400 ? WEIGHT_BOLD
1709 : WEIGHT_NORMAL;
1712 pExpr = pExpr->GetNext();
1715 if( !pExpr || pExpr->GetOp() )
1716 return;
1718 // Since "font" resets all values for which nothing is specified,
1719 // we do it here.
1720 SvxPostureItem aPosture( eItalic, aItemIds.nPosture );
1721 rItemSet.Put( aPosture );
1722 aPosture.SetWhich( aItemIds.nPostureCJK );
1723 rItemSet.Put( aPosture );
1724 aPosture.SetWhich( aItemIds.nPostureCTL );
1725 rItemSet.Put( aPosture );
1727 rItemSet.Put( SvxCaseMapItem( eCaseMap, aItemIds.nCaseMap ) );
1729 SvxWeightItem aWeight( eWeight, aItemIds.nWeight );
1730 rItemSet.Put( aWeight );
1731 aWeight.SetWhich( aItemIds.nWeightCJK );
1732 rItemSet.Put( aWeight );
1733 aWeight.SetWhich( aItemIds.nWeightCTL );
1734 rItemSet.Put( aWeight );
1736 // font-size
1737 CSS1Expression aExpr( pExpr->GetType(), pExpr->GetString(),
1738 pExpr->GetNumber() );
1739 ParseCSS1_font_size( &aExpr, rItemSet, rPropInfo, rParser );
1740 pExpr = pExpr->GetNext();
1742 if( !pExpr )
1743 return;
1745 // [ '/' line-height ]?
1746 if( '/' == pExpr->GetOp() )
1748 // '/' line-height
1749 aExpr.Set( pExpr->GetType(), pExpr->GetString(), pExpr->GetNumber() );
1750 ParseCSS1_line_height( &aExpr, rItemSet, rPropInfo, rParser );
1752 pExpr = pExpr->GetNext();
1755 if( !pExpr || pExpr->GetOp() )
1756 return;
1758 // font-family
1759 ParseCSS1_font_family( pExpr, rItemSet, rPropInfo, rParser );
1762 static void ParseCSS1_letter_spacing( const CSS1Expression *pExpr,
1763 SfxItemSet &rItemSet,
1764 SvxCSS1PropertyInfo& /*rPropInfo*/,
1765 const SvxCSS1Parser& /*rParser*/ )
1767 OSL_ENSURE( pExpr, "no expression" );
1769 switch( pExpr->GetType() )
1771 case CSS1_LENGTH:
1772 rItemSet.Put( SvxKerningItem( static_cast<short>(pExpr->GetSLength()),
1773 aItemIds.nKerning ) );
1774 break;
1776 case CSS1_PIXLENGTH:
1778 double fHeight = pExpr->GetNumber();
1779 if (fHeight < SAL_MAX_INT32/2.0 && fHeight > SAL_MIN_INT32/2.0)
1781 long nPWidth = static_cast<long>(fHeight);
1782 long nPHeight = 0;
1783 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
1784 rItemSet.Put( SvxKerningItem( static_cast<short>(nPWidth), aItemIds.nKerning ) );
1787 break;
1789 case CSS1_NUMBER:
1790 if( pExpr->GetNumber() == 0 )
1792 // normally unnecessary, but we are tolerant
1793 rItemSet.Put( SvxKerningItem( short(0), aItemIds.nKerning ) );
1795 break;
1797 case CSS1_IDENT:
1798 case CSS1_STRING: // As a precaution also MS-IE
1799 if( pExpr->GetString().equalsIgnoreAsciiCase( "normal" ) )
1801 rItemSet.Put( SvxKerningItem( short(0), aItemIds.nKerning ) );
1803 break;
1804 default:
1809 static void ParseCSS1_text_decoration( const CSS1Expression *pExpr,
1810 SfxItemSet &rItemSet,
1811 SvxCSS1PropertyInfo& /*rPropInfo*/,
1812 const SvxCSS1Parser& /*rParser*/ )
1814 OSL_ENSURE( pExpr, "no expression" );
1816 bool bUnderline = false;
1817 bool bOverline = false;
1818 bool bCrossedOut = false;
1819 bool bBlink = false;
1820 bool bBlinkOn = false;
1821 FontLineStyle eUnderline = LINESTYLE_NONE;
1822 FontLineStyle eOverline = LINESTYLE_NONE;
1823 FontStrikeout eCrossedOut = STRIKEOUT_NONE;
1825 // the value can contain two values! And MS-IE also strings
1826 while( pExpr && (pExpr->GetType() == CSS1_IDENT ||
1827 pExpr->GetType() == CSS1_STRING) && !pExpr->GetOp() )
1829 OUString aValue = pExpr->GetString().toAsciiLowerCase();
1830 bool bKnown = false;
1832 switch( aValue[0] )
1834 case 'n':
1835 if( aValue == "none" )
1837 bUnderline = true;
1838 eUnderline = LINESTYLE_NONE;
1840 bOverline = true;
1841 eOverline = LINESTYLE_NONE;
1843 bCrossedOut = true;
1844 eCrossedOut = STRIKEOUT_NONE;
1846 bBlink = true;
1847 bBlinkOn = false;
1849 bKnown = true;
1851 break;
1853 case 'u':
1854 if( aValue == "underline" )
1856 bUnderline = true;
1857 eUnderline = LINESTYLE_SINGLE;
1859 bKnown = true;
1861 break;
1863 case 'o':
1864 if( aValue == "overline" )
1866 bOverline = true;
1867 eOverline = LINESTYLE_SINGLE;
1869 bKnown = true;
1871 break;
1873 case 'l':
1874 if( aValue == "line-through" )
1876 bCrossedOut = true;
1877 eCrossedOut = STRIKEOUT_SINGLE;
1879 bKnown = true;
1881 break;
1883 case 'b':
1884 if( aValue == "blink" )
1886 bBlink = true;
1887 bBlinkOn = true;
1889 bKnown = true;
1891 break;
1894 if( !bKnown )
1896 bUnderline = true;
1897 eUnderline = LINESTYLE_SINGLE;
1900 pExpr = pExpr->GetNext();
1903 if( bUnderline )
1904 rItemSet.Put( SvxUnderlineItem( eUnderline, aItemIds.nUnderline ) );
1906 if( bOverline )
1907 rItemSet.Put( SvxOverlineItem( eOverline, aItemIds.nOverline ) );
1909 if( bCrossedOut )
1910 rItemSet.Put( SvxCrossedOutItem( eCrossedOut, aItemIds.nCrossedOut ) );
1912 if( bBlink )
1913 rItemSet.Put( SvxBlinkItem( bBlinkOn, aItemIds.nBlink ) );
1916 static void ParseCSS1_text_align( const CSS1Expression *pExpr,
1917 SfxItemSet &rItemSet,
1918 SvxCSS1PropertyInfo& /*rPropInfo*/,
1919 const SvxCSS1Parser& /*rParser*/ )
1921 OSL_ENSURE( pExpr, "no expression" );
1923 if( CSS1_IDENT==pExpr->GetType() ||
1924 CSS1_STRING==pExpr->GetType() ) // MS-IE, again
1926 sal_uInt16 nAdjust;
1927 if( SvxCSS1Parser::GetEnum( aTextAlignTable, pExpr->GetString(),
1928 nAdjust ) )
1930 rItemSet.Put( SvxAdjustItem( static_cast<SvxAdjust>(nAdjust),
1931 aItemIds.nAdjust ) );
1936 static void ParseCSS1_text_indent( const CSS1Expression *pExpr,
1937 SfxItemSet &rItemSet,
1938 SvxCSS1PropertyInfo& rPropInfo,
1939 const SvxCSS1Parser& /*rParser*/ )
1941 OSL_ENSURE( pExpr, "no expression" );
1943 short nIndent = 0;
1944 bool bSet = false;
1945 switch( pExpr->GetType() )
1947 case CSS1_LENGTH:
1948 nIndent = static_cast<short>(pExpr->GetSLength());
1949 bSet = true;
1950 break;
1951 case CSS1_PIXLENGTH:
1953 double fWidth = pExpr->GetNumber();
1954 if (fWidth < SAL_MAX_INT32/2.0 && fWidth > SAL_MIN_INT32/2.0)
1956 long nPWidth = static_cast<long>(fWidth);
1957 long nPHeight = 0;
1958 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
1959 nIndent = static_cast<short>(nPWidth);
1960 bSet = true;
1963 break;
1964 case CSS1_PERCENTAGE:
1965 // we aren't able
1966 break;
1967 default:
1971 if( bSet )
1973 const SfxPoolItem* pItem;
1974 if( SfxItemState::SET == rItemSet.GetItemState( aItemIds.nLRSpace, false,
1975 &pItem ) )
1977 SvxLRSpaceItem aLRItem( *static_cast<const SvxLRSpaceItem*>(pItem) );
1978 aLRItem.SetTextFirstLineOfst( nIndent );
1979 rItemSet.Put( aLRItem );
1981 else
1983 SvxLRSpaceItem aLRItem( aItemIds.nLRSpace );
1984 aLRItem.SetTextFirstLineOfst( nIndent );
1985 rItemSet.Put( aLRItem );
1987 rPropInfo.m_bTextIndent = true;
1991 static void ParseCSS1_margin_left( const CSS1Expression *pExpr,
1992 SfxItemSet &rItemSet,
1993 SvxCSS1PropertyInfo& rPropInfo,
1994 const SvxCSS1Parser& /*rParser*/ )
1996 OSL_ENSURE( pExpr, "no expression" );
1998 long nLeft = 0;
1999 bool bSet = false;
2000 switch( pExpr->GetType() )
2002 case CSS1_LENGTH:
2004 nLeft = pExpr->GetSLength();
2005 bSet = true;
2007 break;
2008 case CSS1_PIXLENGTH:
2010 double fLeft = pExpr->GetNumber();
2011 if (fLeft < SAL_MAX_INT32/2.0 && fLeft > SAL_MIN_INT32/2.0)
2013 nLeft = static_cast<long>(fLeft);
2014 long nPHeight = 0;
2015 SvxCSS1Parser::PixelToTwip( nLeft, nPHeight );
2016 bSet = true;
2018 else
2020 SAL_WARN("sw.html", "out-of-size pxlength: " << fLeft);
2023 break;
2024 case CSS1_PERCENTAGE:
2025 // we aren't able
2026 break;
2027 default:
2031 if( bSet )
2033 rPropInfo.m_nLeftMargin = nLeft;
2034 if( nLeft < 0 )
2035 nLeft = 0;
2036 const SfxPoolItem* pItem;
2037 if( SfxItemState::SET == rItemSet.GetItemState( aItemIds.nLRSpace, false,
2038 &pItem ) )
2040 SvxLRSpaceItem aLRItem( *static_cast<const SvxLRSpaceItem*>(pItem) );
2041 aLRItem.SetTextLeft( static_cast<sal_uInt16>(nLeft) );
2042 rItemSet.Put( aLRItem );
2044 else
2046 SvxLRSpaceItem aLRItem( aItemIds.nLRSpace );
2047 aLRItem.SetTextLeft( static_cast<sal_uInt16>(nLeft) );
2048 rItemSet.Put( aLRItem );
2050 rPropInfo.m_bLeftMargin = true;
2054 static void ParseCSS1_margin_right( const CSS1Expression *pExpr,
2055 SfxItemSet &rItemSet,
2056 SvxCSS1PropertyInfo& rPropInfo,
2057 const SvxCSS1Parser& /*rParser*/ )
2059 OSL_ENSURE( pExpr, "no expression" );
2061 long nRight = 0;
2062 bool bSet = false;
2063 switch( pExpr->GetType() )
2065 case CSS1_LENGTH:
2067 nRight = pExpr->GetSLength();
2068 bSet = true;
2070 break;
2071 case CSS1_PIXLENGTH:
2073 double fRight = pExpr->GetNumber();
2074 if (fRight < SAL_MAX_INT32/2.0 && fRight > SAL_MIN_INT32/2.0)
2076 nRight = static_cast<long>(fRight);
2077 long nPHeight = 0;
2078 SvxCSS1Parser::PixelToTwip( nRight, nPHeight );
2079 bSet = true;
2082 break;
2083 case CSS1_PERCENTAGE:
2084 // we aren't able
2085 break;
2086 default:
2090 if( bSet )
2092 rPropInfo.m_nRightMargin = nRight;
2093 if( nRight < 0 )
2094 nRight = 0;
2095 const SfxPoolItem* pItem;
2096 if( SfxItemState::SET == rItemSet.GetItemState( aItemIds.nLRSpace, false,
2097 &pItem ) )
2099 SvxLRSpaceItem aLRItem( *static_cast<const SvxLRSpaceItem*>(pItem) );
2100 aLRItem.SetRight( static_cast<sal_uInt16>(nRight) );
2101 rItemSet.Put( aLRItem );
2103 else
2105 SvxLRSpaceItem aLRItem( aItemIds.nLRSpace );
2106 aLRItem.SetRight( static_cast<sal_uInt16>(nRight) );
2107 rItemSet.Put( aLRItem );
2109 rPropInfo.m_bRightMargin = true;
2113 static void ParseCSS1_margin_top( const CSS1Expression *pExpr,
2114 SfxItemSet &rItemSet,
2115 SvxCSS1PropertyInfo& rPropInfo,
2116 const SvxCSS1Parser& /*rParser*/ )
2118 assert(pExpr && "no expression");
2120 sal_uInt16 nUpper = 0;
2121 bool bSet = false;
2122 switch( pExpr->GetType() )
2124 case CSS1_LENGTH:
2126 long nTmp = pExpr->GetSLength();
2127 if( nTmp < 0 )
2128 nTmp = 0;
2129 nUpper = static_cast<sal_uInt16>(nTmp);
2130 bSet = true;
2132 break;
2133 case CSS1_PIXLENGTH:
2135 double fHeight = pExpr->GetNumber();
2136 if (fHeight < SAL_MAX_INT32/2.0 && fHeight > SAL_MIN_INT32/2.0)
2138 long nPWidth = 0;
2139 long nPHeight = static_cast<long>(fHeight);
2140 if( nPHeight < 0 )
2141 nPHeight = 0;
2142 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2143 nUpper = static_cast<sal_uInt16>(nPHeight);
2144 bSet = true;
2147 break;
2148 case CSS1_PERCENTAGE:
2149 // we aren't able
2150 break;
2151 default:
2155 if( bSet )
2157 const SfxPoolItem* pItem;
2158 if( SfxItemState::SET == rItemSet.GetItemState( aItemIds.nULSpace, false,
2159 &pItem ) )
2161 SvxULSpaceItem aULItem( *static_cast<const SvxULSpaceItem*>(pItem) );
2162 aULItem.SetUpper( nUpper );
2163 rItemSet.Put( aULItem );
2165 else
2167 SvxULSpaceItem aULItem( aItemIds.nULSpace );
2168 aULItem.SetUpper( nUpper );
2169 rItemSet.Put( aULItem );
2171 rPropInfo.m_bTopMargin = true;
2175 static void ParseCSS1_margin_bottom( const CSS1Expression *pExpr,
2176 SfxItemSet &rItemSet,
2177 SvxCSS1PropertyInfo& rPropInfo,
2178 const SvxCSS1Parser& /*rParser*/ )
2180 OSL_ENSURE( pExpr, "no expression" );
2182 sal_uInt16 nLower = 0;
2183 bool bSet = false;
2184 switch( pExpr->GetType() )
2186 case CSS1_LENGTH:
2188 long nTmp = pExpr->GetSLength();
2189 if( nTmp < 0 )
2190 nTmp = 0;
2191 nLower = static_cast<sal_uInt16>(nTmp);
2192 bSet = true;
2194 break;
2195 case CSS1_PIXLENGTH:
2197 double fHeight = pExpr->GetNumber();
2198 if (fHeight < SAL_MAX_INT32/2.0 && fHeight > SAL_MIN_INT32/2.0)
2200 long nPWidth = 0;
2201 long nPHeight = static_cast<long>(fHeight);
2202 if( nPHeight < 0 )
2203 nPHeight = 0;
2204 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2205 nLower = static_cast<sal_uInt16>(nPHeight);
2206 bSet = true;
2209 break;
2210 case CSS1_PERCENTAGE:
2211 // we aren't able
2212 break;
2213 default:
2217 if( bSet )
2219 const SfxPoolItem* pItem;
2220 if( SfxItemState::SET == rItemSet.GetItemState( aItemIds.nULSpace, false,
2221 &pItem ) )
2223 SvxULSpaceItem aULItem( *static_cast<const SvxULSpaceItem*>(pItem) );
2224 aULItem.SetLower( nLower );
2225 rItemSet.Put( aULItem );
2227 else
2229 SvxULSpaceItem aULItem( aItemIds.nULSpace );
2230 aULItem.SetLower( nLower );
2231 rItemSet.Put( aULItem );
2233 rPropInfo.m_bBottomMargin = true;
2237 static void ParseCSS1_margin( const CSS1Expression *pExpr,
2238 SfxItemSet &rItemSet,
2239 SvxCSS1PropertyInfo& rPropInfo,
2240 const SvxCSS1Parser& /*rParser*/ )
2242 OSL_ENSURE( pExpr, "no expression" );
2244 long nMargins[4] = { 0, 0, 0, 0 };
2245 bool bSetMargins[4] = { false, false, false, false };
2247 for( int i=0; pExpr && i<4 && !pExpr->GetOp(); ++i )
2249 bool bSetThis = false;
2250 long nMargin = 0;
2252 switch( pExpr->GetType() )
2254 case CSS1_LENGTH:
2256 nMargin = pExpr->GetSLength();
2257 bSetThis = true;
2259 break;
2260 case CSS1_PIXLENGTH:
2262 double fMargin = pExpr->GetNumber();
2263 if (fMargin < SAL_MAX_INT32/2.0 && fMargin > SAL_MIN_INT32/2.0)
2265 nMargin = static_cast<long>(fMargin);
2266 long nPWidth = 0;
2267 SvxCSS1Parser::PixelToTwip( nPWidth, nMargin );
2268 bSetThis = true;
2270 else
2272 SAL_WARN("sw.html", "out-of-size pxlength: " << fMargin);
2275 break;
2276 case CSS1_PERCENTAGE:
2277 // we aren't able
2278 break;
2279 default:
2283 if( bSetThis )
2285 // 0 = top
2286 // 1 = right
2287 // 2 = bottom
2288 // 3 = left
2289 switch( i )
2291 case 0:
2292 nMargins[0] = nMargins[1] =nMargins[2] = nMargins[3] = nMargin;
2293 bSetMargins[0] = bSetMargins[1] =
2294 bSetMargins[2] = bSetMargins[3] = true;
2295 break;
2296 case 1:
2297 nMargins[1] = nMargins[3] = nMargin; // right + left
2298 bSetMargins[1] = bSetMargins[3] = true;
2299 break;
2300 case 2:
2301 nMargins[2] = nMargin; // bottom
2302 bSetMargins[2] = true;
2303 break;
2304 case 3:
2305 nMargins[3] = nMargin; // left
2306 bSetMargins[3] = true;
2307 break;
2310 pExpr = pExpr->GetNext();
2313 if( bSetMargins[3] || bSetMargins[1] )
2315 if( bSetMargins[3] )
2317 rPropInfo.m_bLeftMargin = true;
2318 rPropInfo.m_nLeftMargin = nMargins[3];
2319 if( nMargins[3] < 0 )
2320 nMargins[3] = 0;
2322 if( bSetMargins[1] )
2324 rPropInfo.m_bRightMargin = true;
2325 rPropInfo.m_nRightMargin = nMargins[1];
2326 if( nMargins[1] < 0 )
2327 nMargins[1] = 0;
2330 const SfxPoolItem* pItem;
2331 if( SfxItemState::SET == rItemSet.GetItemState( aItemIds.nLRSpace, false,
2332 &pItem ) )
2334 SvxLRSpaceItem aLRItem( *static_cast<const SvxLRSpaceItem*>(pItem) );
2335 if( bSetMargins[3] )
2336 aLRItem.SetLeft( static_cast<sal_uInt16>(nMargins[3]) );
2337 if( bSetMargins[1] )
2338 aLRItem.SetRight( static_cast<sal_uInt16>(nMargins[1]) );
2339 rItemSet.Put( aLRItem );
2341 else
2343 SvxLRSpaceItem aLRItem( aItemIds.nLRSpace );
2344 if( bSetMargins[3] )
2345 aLRItem.SetLeft( static_cast<sal_uInt16>(nMargins[3]) );
2346 if( bSetMargins[1] )
2347 aLRItem.SetRight( static_cast<sal_uInt16>(nMargins[1]) );
2348 rItemSet.Put( aLRItem );
2352 if( bSetMargins[0] || bSetMargins[2] )
2354 if( nMargins[0] < 0 )
2355 nMargins[0] = 0;
2356 if( nMargins[2] < 0 )
2357 nMargins[2] = 0;
2359 const SfxPoolItem* pItem;
2360 if( SfxItemState::SET == rItemSet.GetItemState( aItemIds.nULSpace, false,
2361 &pItem ) )
2363 SvxULSpaceItem aULItem( *static_cast<const SvxULSpaceItem*>(pItem) );
2364 if( bSetMargins[0] )
2365 aULItem.SetUpper( static_cast<sal_uInt16>(nMargins[0]) );
2366 if( bSetMargins[2] )
2367 aULItem.SetLower( static_cast<sal_uInt16>(nMargins[2]) );
2368 rItemSet.Put( aULItem );
2370 else
2372 SvxULSpaceItem aULItem( aItemIds.nULSpace );
2373 if( bSetMargins[0] )
2374 aULItem.SetUpper( static_cast<sal_uInt16>(nMargins[0]) );
2375 if( bSetMargins[2] )
2376 aULItem.SetLower( static_cast<sal_uInt16>(nMargins[2]) );
2377 rItemSet.Put( aULItem );
2380 rPropInfo.m_bTopMargin |= bSetMargins[0];
2381 rPropInfo.m_bBottomMargin |= bSetMargins[2];
2385 static bool ParseCSS1_padding_xxx( const CSS1Expression *pExpr,
2386 SvxCSS1PropertyInfo& rPropInfo,
2387 SvxBoxItemLine nWhichLine )
2389 OSL_ENSURE( pExpr, "no expression" );
2391 bool bSet = false;
2392 sal_uInt16 nDist = 0;
2394 switch( pExpr->GetType() )
2396 case CSS1_LENGTH:
2398 long nTmp = pExpr->GetSLength();
2399 if( nTmp < 0 )
2400 nTmp = 0;
2401 else if( nTmp > SvxCSS1PropertyInfo::UNSET_BORDER_DISTANCE-1 )
2402 nTmp = SvxCSS1PropertyInfo::UNSET_BORDER_DISTANCE-1;
2403 nDist = static_cast<sal_uInt16>(nTmp);
2404 bSet = true;
2406 break;
2407 case CSS1_PIXLENGTH:
2409 double fWidth = pExpr->GetNumber();
2410 if (fWidth < SAL_MAX_INT32/2.0 && fWidth > SAL_MIN_INT32/2.0)
2412 long nPWidth = static_cast<long>(fWidth);
2413 long nPHeight = 0;
2414 if( nPWidth < 0 )
2415 nPWidth = 0;
2416 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2417 if( nPWidth > SvxCSS1PropertyInfo::UNSET_BORDER_DISTANCE-1 )
2418 nPWidth = SvxCSS1PropertyInfo::UNSET_BORDER_DISTANCE-1;
2419 nDist = static_cast<sal_uInt16>(nPWidth);
2420 bSet = true;
2423 break;
2424 case CSS1_PERCENTAGE:
2425 // we aren't able
2426 break;
2427 default:
2431 if( bSet )
2433 switch( nWhichLine )
2435 case SvxBoxItemLine::TOP: rPropInfo.m_nTopBorderDistance = nDist; break;
2436 case SvxBoxItemLine::BOTTOM: rPropInfo.m_nBottomBorderDistance = nDist;break;
2437 case SvxBoxItemLine::LEFT: rPropInfo.m_nLeftBorderDistance = nDist; break;
2438 case SvxBoxItemLine::RIGHT: rPropInfo.m_nRightBorderDistance = nDist; break;
2442 return bSet;
2445 static void ParseCSS1_padding_top( const CSS1Expression *pExpr,
2446 SfxItemSet & /*rItemSet*/,
2447 SvxCSS1PropertyInfo& rPropInfo,
2448 const SvxCSS1Parser& /*rParser*/ )
2450 ParseCSS1_padding_xxx( pExpr, rPropInfo, SvxBoxItemLine::TOP );
2453 static void ParseCSS1_padding_bottom( const CSS1Expression *pExpr,
2454 SfxItemSet & /*rItemSet*/,
2455 SvxCSS1PropertyInfo& rPropInfo,
2456 const SvxCSS1Parser& /*rParser*/ )
2458 ParseCSS1_padding_xxx( pExpr, rPropInfo, SvxBoxItemLine::BOTTOM );
2461 static void ParseCSS1_padding_left( const CSS1Expression *pExpr,
2462 SfxItemSet & /*rItemSet*/,
2463 SvxCSS1PropertyInfo& rPropInfo,
2464 const SvxCSS1Parser& /*rParser*/ )
2466 ParseCSS1_padding_xxx( pExpr, rPropInfo, SvxBoxItemLine::LEFT );
2469 static void ParseCSS1_padding_right( const CSS1Expression *pExpr,
2470 SfxItemSet & /*rItemSet*/,
2471 SvxCSS1PropertyInfo& rPropInfo,
2472 const SvxCSS1Parser& /*rParser*/ )
2474 ParseCSS1_padding_xxx( pExpr, rPropInfo, SvxBoxItemLine::RIGHT );
2477 static void ParseCSS1_padding( const CSS1Expression *pExpr,
2478 SfxItemSet & /*rItemSet*/,
2479 SvxCSS1PropertyInfo& rPropInfo,
2480 const SvxCSS1Parser& /*rParser*/ )
2482 int n=0;
2483 while( n<4 && pExpr && !pExpr->GetOp() )
2485 SvxBoxItemLine nLine = n==0 || n==2 ? SvxBoxItemLine::BOTTOM : SvxBoxItemLine::LEFT;
2486 if( ParseCSS1_padding_xxx( pExpr, rPropInfo, nLine ) )
2488 if( n==0 )
2490 rPropInfo.m_nTopBorderDistance = rPropInfo.m_nBottomBorderDistance;
2491 rPropInfo.m_nLeftBorderDistance = rPropInfo.m_nTopBorderDistance;
2493 if( n <= 1 )
2494 rPropInfo.m_nRightBorderDistance = rPropInfo.m_nLeftBorderDistance;
2497 pExpr = pExpr->GetNext();
2498 n++;
2502 static void ParseCSS1_border_xxx( const CSS1Expression *pExpr,
2503 SfxItemSet & /*rItemSet*/,
2504 SvxCSS1PropertyInfo& rPropInfo,
2505 const SvxCSS1Parser& /*rParser*/,
2506 SvxBoxItemLine nWhichLine, bool bAll )
2508 OSL_ENSURE( pExpr, "no expression" );
2510 sal_uInt16 nWidth = USHRT_MAX; // line thickness
2511 sal_uInt16 nNWidth = 1; // named line thickness (and default)
2512 CSS1BorderStyle eStyle = CSS1_BS_NONE; // line style
2513 Color aColor;
2514 bool bColor = false;
2516 while( pExpr && !pExpr->GetOp() )
2518 switch( pExpr->GetType() )
2520 case CSS1_RGB:
2521 case CSS1_HEXCOLOR:
2522 if( pExpr->GetColor( aColor ) )
2523 bColor = true;
2524 break;
2526 case CSS1_IDENT:
2528 const OUString& rValue = pExpr->GetString();
2529 sal_uInt16 nValue;
2530 if( SvxCSS1Parser::GetEnum( aBorderWidthTable, rValue, nValue ) )
2532 nNWidth = nValue;
2534 else if( SvxCSS1Parser::GetEnum( aBorderStyleTable, rValue, nValue ) )
2536 eStyle = static_cast<CSS1BorderStyle>(nValue);
2538 else if( pExpr->GetColor( aColor ) )
2540 bColor = true;
2543 break;
2545 case CSS1_LENGTH:
2546 nWidth = static_cast<sal_uInt16>(pExpr->GetULength());
2547 break;
2549 case CSS1_PIXLENGTH:
2551 // One Pixel becomes a hairline (is prettier)
2552 double fWidth = pExpr->GetNumber();
2553 if (fWidth > 1.0 && fWidth < SAL_MAX_INT32/2.0)
2555 bool bHori = nWhichLine == SvxBoxItemLine::TOP ||
2556 nWhichLine == SvxBoxItemLine::BOTTOM;
2558 long nPWidth = bHori ? 0 : fWidth;
2559 long nPHeight = bHori ? fWidth : 0;
2560 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2561 nWidth = static_cast<sal_uInt16>(bHori ? nPHeight : nPWidth);
2563 else
2564 nWidth = 1;
2566 break;
2568 default:
2572 pExpr = pExpr->GetNext();
2575 for( int i=0; i<4; ++i )
2577 SvxBoxItemLine nLine = SvxBoxItemLine::TOP;
2578 switch( i )
2580 case 0: nLine = SvxBoxItemLine::TOP; break;
2581 case 1: nLine = SvxBoxItemLine::BOTTOM; break;
2582 case 2: nLine = SvxBoxItemLine::LEFT; break;
2583 case 3: nLine = SvxBoxItemLine::RIGHT; break;
2586 if( bAll || nLine == nWhichLine )
2588 SvxCSS1BorderInfo *pInfo = rPropInfo.GetBorderInfo( nLine );
2589 pInfo->eStyle = eStyle;
2590 pInfo->nAbsWidth = nWidth;
2591 pInfo->nNamedWidth = nNWidth;
2592 if( bColor )
2593 pInfo->aColor = aColor;
2598 static void ParseCSS1_border_xxx_width( const CSS1Expression *pExpr,
2599 SfxItemSet & /*rItemSet*/,
2600 SvxCSS1PropertyInfo& rPropInfo,
2601 const SvxCSS1Parser& /*rParser*/,
2602 SvxBoxItemLine nWhichLine )
2604 OSL_ENSURE( pExpr, "no expression" );
2606 sal_uInt16 nWidth = USHRT_MAX; // line thickness
2607 sal_uInt16 nNWidth = 1; // named line thickness (and default)
2609 switch( pExpr->GetType() )
2611 case CSS1_IDENT:
2613 sal_uInt16 nValue;
2614 if( SvxCSS1Parser::GetEnum( aBorderWidthTable, pExpr->GetString(), nValue ) )
2616 nNWidth = nValue;
2619 break;
2621 case CSS1_LENGTH:
2622 nWidth = static_cast<sal_uInt16>(pExpr->GetULength());
2623 break;
2625 case CSS1_PIXLENGTH:
2627 double fLength = pExpr->GetNumber();
2628 if (fLength < SAL_MAX_INT32/2.0 && fLength > SAL_MIN_INT32/2.0)
2630 long nWidthL = static_cast<long>(fLength);
2632 bool bHori = nWhichLine == SvxBoxItemLine::TOP ||
2633 nWhichLine == SvxBoxItemLine::BOTTOM;
2635 long nPWidth = bHori ? 0 : nWidthL;
2636 long nPHeight = bHori ? nWidthL : 0;
2637 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2638 nWidth = static_cast<sal_uInt16>(bHori ? nPHeight : nPWidth);
2641 break;
2643 default:
2647 SvxCSS1BorderInfo *pInfo = rPropInfo.GetBorderInfo( nWhichLine );
2648 pInfo->nAbsWidth = nWidth;
2649 pInfo->nNamedWidth = nNWidth;
2652 static void ParseCSS1_border_top_width( const CSS1Expression *pExpr,
2653 SfxItemSet &rItemSet,
2654 SvxCSS1PropertyInfo& rPropInfo,
2655 const SvxCSS1Parser& rParser )
2657 ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::TOP );
2660 static void ParseCSS1_border_right_width( const CSS1Expression *pExpr,
2661 SfxItemSet &rItemSet,
2662 SvxCSS1PropertyInfo& rPropInfo,
2663 const SvxCSS1Parser& rParser )
2665 ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::RIGHT );
2668 static void ParseCSS1_border_bottom_width( const CSS1Expression *pExpr,
2669 SfxItemSet &rItemSet,
2670 SvxCSS1PropertyInfo& rPropInfo,
2671 const SvxCSS1Parser& rParser )
2673 ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::BOTTOM );
2676 static void ParseCSS1_border_left_width( const CSS1Expression *pExpr,
2677 SfxItemSet &rItemSet,
2678 SvxCSS1PropertyInfo& rPropInfo,
2679 const SvxCSS1Parser& rParser )
2681 ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::LEFT );
2684 static void ParseCSS1_border_width( const CSS1Expression *pExpr,
2685 SfxItemSet &rItemSet,
2686 SvxCSS1PropertyInfo& rPropInfo,
2687 const SvxCSS1Parser& rParser )
2689 sal_uInt16 n=0;
2690 while( n<4 && pExpr && !pExpr->GetOp() )
2692 SvxBoxItemLine nLine = n==0 || n==2 ? SvxBoxItemLine::BOTTOM : SvxBoxItemLine::LEFT;
2693 ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, nLine );
2694 rPropInfo.CopyBorderInfo( n, SVX_CSS1_BORDERINFO_WIDTH );
2696 pExpr = pExpr->GetNext();
2697 n++;
2701 static void ParseCSS1_border_color( const CSS1Expression *pExpr,
2702 SfxItemSet & /*rItemSet*/,
2703 SvxCSS1PropertyInfo& rPropInfo,
2704 const SvxCSS1Parser& /*rParser*/ )
2706 sal_uInt16 n=0;
2707 while( n<4 && pExpr && !pExpr->GetOp() )
2709 SvxBoxItemLine nLine = n==0 || n==2 ? SvxBoxItemLine::BOTTOM : SvxBoxItemLine::LEFT;
2710 Color aColor;
2711 switch( pExpr->GetType() )
2713 case CSS1_RGB:
2714 case CSS1_HEXCOLOR:
2715 case CSS1_IDENT:
2716 if( pExpr->GetColor( aColor ) )
2717 rPropInfo.GetBorderInfo( nLine )->aColor = aColor;
2718 break;
2719 default:
2722 rPropInfo.CopyBorderInfo( n, SVX_CSS1_BORDERINFO_COLOR );
2724 pExpr = pExpr->GetNext();
2725 n++;
2729 static void ParseCSS1_border_style( const CSS1Expression *pExpr,
2730 SfxItemSet & /*rItemSet*/,
2731 SvxCSS1PropertyInfo& rPropInfo,
2732 const SvxCSS1Parser& /*rParser*/ )
2734 sal_uInt16 n=0;
2735 while( n<4 && pExpr && !pExpr->GetOp() )
2737 SvxBoxItemLine nLine = n==0 || n==2 ? SvxBoxItemLine::BOTTOM : SvxBoxItemLine::LEFT;
2738 sal_uInt16 nValue = 0;
2739 if( CSS1_IDENT==pExpr->GetType() &&
2740 SvxCSS1Parser::GetEnum( aBorderStyleTable, pExpr->GetString(),
2741 nValue ) )
2743 rPropInfo.GetBorderInfo( nLine )->eStyle = static_cast<CSS1BorderStyle>(nValue);
2745 rPropInfo.CopyBorderInfo( n, SVX_CSS1_BORDERINFO_STYLE );
2747 pExpr = pExpr->GetNext();
2748 n++;
2752 static void ParseCSS1_border_top( const CSS1Expression *pExpr,
2753 SfxItemSet &rItemSet,
2754 SvxCSS1PropertyInfo& rPropInfo,
2755 const SvxCSS1Parser& rParser )
2757 ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::TOP, false );
2760 static void ParseCSS1_border_right( const CSS1Expression *pExpr,
2761 SfxItemSet &rItemSet,
2762 SvxCSS1PropertyInfo& rPropInfo,
2763 const SvxCSS1Parser& rParser )
2765 ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::RIGHT, false );
2768 static void ParseCSS1_border_bottom( const CSS1Expression *pExpr,
2769 SfxItemSet &rItemSet,
2770 SvxCSS1PropertyInfo& rPropInfo,
2771 const SvxCSS1Parser& rParser )
2773 ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::BOTTOM, false );
2776 static void ParseCSS1_border_left( const CSS1Expression *pExpr,
2777 SfxItemSet &rItemSet,
2778 SvxCSS1PropertyInfo& rPropInfo,
2779 const SvxCSS1Parser& rParser )
2781 ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::LEFT, false );
2784 static void ParseCSS1_border( const CSS1Expression *pExpr,
2785 SfxItemSet &rItemSet,
2786 SvxCSS1PropertyInfo& rPropInfo,
2787 const SvxCSS1Parser& rParser )
2789 ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::TOP, true );
2792 static void ParseCSS1_float( const CSS1Expression *pExpr,
2793 SfxItemSet & /*rItemSet*/,
2794 SvxCSS1PropertyInfo& rPropInfo,
2795 const SvxCSS1Parser& /*rParser*/ )
2797 OSL_ENSURE( pExpr, "no expression" );
2799 if( CSS1_IDENT==pExpr->GetType() )
2801 sal_uInt16 nFloat;
2802 if( SvxCSS1Parser::GetEnum( aFloatTable, pExpr->GetString(), nFloat ) )
2803 rPropInfo.m_eFloat = static_cast<SvxAdjust>(nFloat);
2807 static void ParseCSS1_position( const CSS1Expression *pExpr,
2808 SfxItemSet & /*rItemSet*/,
2809 SvxCSS1PropertyInfo& rPropInfo,
2810 const SvxCSS1Parser& /*rParser*/ )
2812 OSL_ENSURE( pExpr, "no expression" );
2814 if( CSS1_IDENT==pExpr->GetType() )
2816 sal_uInt16 nPos;
2817 if( SvxCSS1Parser::GetEnum( aPositionTable, pExpr->GetString(), nPos ) )
2818 rPropInfo.m_ePosition = static_cast<SvxCSS1Position>(nPos);
2822 static void ParseCSS1_length( const CSS1Expression *pExpr,
2823 long& rLength,
2824 SvxCSS1LengthType& rLengthType,
2825 bool bHori )
2827 switch( pExpr->GetType() )
2829 case CSS1_IDENT:
2830 if( pExpr->GetString().equalsIgnoreAsciiCase( "auto" ) )
2832 rLength = 0;
2833 rLengthType = SVX_CSS1_LTYPE_AUTO;
2835 break;
2837 case CSS1_LENGTH:
2838 rLength = pExpr->GetSLength();
2839 rLengthType = SVX_CSS1_LTYPE_TWIP;
2840 break;
2842 case CSS1_PIXLENGTH:
2843 case CSS1_NUMBER: // because of Netscape and IE
2845 double fLength = pExpr->GetNumber();
2846 if (fLength < SAL_MAX_INT32/2.0 && fLength > SAL_MIN_INT32/2.0)
2848 long nWidthL = static_cast<long>(fLength);
2849 long nPWidth = bHori ? 0 : nWidthL;
2850 long nPHeight = bHori ? nWidthL : 0;
2851 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2852 rLength = (bHori ? nPHeight : nPWidth);
2853 rLengthType = SVX_CSS1_LTYPE_TWIP;
2856 break;
2858 case CSS1_PERCENTAGE:
2859 rLength = static_cast<long>(pExpr->GetNumber());
2860 if( rLength > 100 )
2861 rLength = 100;
2862 rLengthType = SVX_CSS1_LTYPE_PERCENTAGE;
2863 break;
2865 default:
2870 static void ParseCSS1_width( const CSS1Expression *pExpr,
2871 SfxItemSet & /*rItemSet*/,
2872 SvxCSS1PropertyInfo& rPropInfo,
2873 const SvxCSS1Parser& /*rParser*/ )
2875 ParseCSS1_length( pExpr, rPropInfo.m_nWidth, rPropInfo.m_eWidthType, true );
2878 static void ParseCSS1_height( const CSS1Expression *pExpr,
2879 SfxItemSet & /*rItemSet*/,
2880 SvxCSS1PropertyInfo& rPropInfo,
2881 const SvxCSS1Parser& /*rParser*/ )
2883 ParseCSS1_length( pExpr, rPropInfo.m_nHeight, rPropInfo.m_eHeightType, false );
2886 static void ParseCSS1_left( const CSS1Expression *pExpr,
2887 SfxItemSet & /*rItemSet*/,
2888 SvxCSS1PropertyInfo& rPropInfo,
2889 const SvxCSS1Parser& /*rParser*/ )
2891 ParseCSS1_length( pExpr, rPropInfo.m_nLeft, rPropInfo.m_eLeftType, true );
2894 static void ParseCSS1_top( const CSS1Expression *pExpr,
2895 SfxItemSet & /*rItemSet*/,
2896 SvxCSS1PropertyInfo& rPropInfo,
2897 const SvxCSS1Parser& /*rParser*/ )
2899 ParseCSS1_length( pExpr, rPropInfo.m_nTop, rPropInfo.m_eTopType, false );
2902 // Feature: PrintExt
2903 static void ParseCSS1_size( const CSS1Expression *pExpr,
2904 SfxItemSet & /*rItemSet*/,
2905 SvxCSS1PropertyInfo& rPropInfo,
2906 const SvxCSS1Parser& /*rParser*/ )
2908 int n=0;
2909 while( n<2 && pExpr && !pExpr->GetOp() )
2911 switch( pExpr->GetType() )
2913 case CSS1_IDENT:
2915 sal_uInt16 nValue;
2916 if( SvxCSS1Parser::GetEnum( aSizeTable, pExpr->GetString(),
2917 nValue ) )
2919 rPropInfo.m_eSizeType = static_cast<SvxCSS1SizeType>(nValue);
2922 break;
2924 case CSS1_LENGTH:
2925 rPropInfo.m_nHeight = pExpr->GetSLength();
2926 if( n==0 )
2927 rPropInfo.m_nWidth = rPropInfo.m_nHeight;
2928 rPropInfo.m_eSizeType = SVX_CSS1_STYPE_TWIP;
2929 break;
2931 case CSS1_PIXLENGTH:
2933 double fHeight = pExpr->GetNumber();
2934 if (fHeight < SAL_MAX_INT32/2.0 && fHeight > SAL_MIN_INT32/2.0)
2936 long nPHeight = static_cast<long>(fHeight);
2937 long nPWidth = n==0 ? nPHeight : 0;
2938 SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2939 rPropInfo.m_nHeight = nPHeight;
2940 if( n==0 )
2941 rPropInfo.m_nWidth = nPWidth;
2942 rPropInfo.m_eSizeType = SVX_CSS1_STYPE_TWIP;
2944 break;
2946 default:
2950 pExpr = pExpr->GetNext();
2951 n++;
2955 static void ParseCSS1_page_break_xxx( const CSS1Expression *pExpr,
2956 SvxCSS1PageBreak& rPBreak )
2958 if( CSS1_IDENT == pExpr->GetType() )
2960 sal_uInt16 nValue;
2961 if( SvxCSS1Parser::GetEnum( aPageBreakTable, pExpr->GetString(),
2962 nValue ) )
2964 rPBreak = static_cast<SvxCSS1PageBreak>(nValue);
2969 static void ParseCSS1_page_break_before( const CSS1Expression *pExpr,
2970 SfxItemSet & /*rItemSet*/,
2971 SvxCSS1PropertyInfo& rPropInfo,
2972 const SvxCSS1Parser& /*rParser*/ )
2974 ParseCSS1_page_break_xxx( pExpr, rPropInfo.m_ePageBreakBefore );
2977 static void ParseCSS1_page_break_after( const CSS1Expression *pExpr,
2978 SfxItemSet & /*rItemSet*/,
2979 SvxCSS1PropertyInfo& rPropInfo,
2980 const SvxCSS1Parser& /*rParser*/ )
2982 ParseCSS1_page_break_xxx( pExpr, rPropInfo.m_ePageBreakAfter );
2985 static void ParseCSS1_page_break_inside( const CSS1Expression *pExpr,
2986 SfxItemSet &rItemSet,
2987 SvxCSS1PropertyInfo& /*rPropInfo*/,
2988 const SvxCSS1Parser& /*rParser*/ )
2990 SvxCSS1PageBreak eBreak(SVX_CSS1_PBREAK_NONE);
2991 ParseCSS1_page_break_xxx( pExpr, eBreak );
2993 bool bSetSplit = false, bSplit = true;
2994 switch( eBreak )
2996 case SVX_CSS1_PBREAK_AUTO:
2997 bSetSplit = true;
2998 break;
2999 case SVX_CSS1_PBREAK_AVOID:
3000 bSplit = false;
3001 bSetSplit = true;
3002 break;
3003 default:
3007 if( bSetSplit )
3008 rItemSet.Put( SvxFormatSplitItem( bSplit, aItemIds.nFormatSplit ) );
3011 static void ParseCSS1_widows( const CSS1Expression *pExpr,
3012 SfxItemSet &rItemSet,
3013 SvxCSS1PropertyInfo& /*rPropInfo*/,
3014 const SvxCSS1Parser& /*rParser*/ )
3016 if( CSS1_NUMBER == pExpr->GetType() )
3018 sal_uInt8 nVal = pExpr->GetNumber() <= 255
3019 ? static_cast<sal_uInt8>(pExpr->GetNumber())
3020 : 255;
3021 SvxWidowsItem aWidowsItem( nVal, aItemIds.nWidows );
3022 rItemSet.Put( aWidowsItem );
3026 static void ParseCSS1_orphans( const CSS1Expression *pExpr,
3027 SfxItemSet &rItemSet,
3028 SvxCSS1PropertyInfo& /*rPropInfo*/,
3029 const SvxCSS1Parser& /*rParser*/ )
3031 if( CSS1_NUMBER == pExpr->GetType() )
3033 sal_uInt8 nVal = pExpr->GetNumber() <= 255
3034 ? static_cast<sal_uInt8>(pExpr->GetNumber())
3035 : 255;
3036 SvxOrphansItem aOrphansItem( nVal, aItemIds.nOrphans );
3037 rItemSet.Put( aOrphansItem );
3041 static void ParseCSS1_so_language( const CSS1Expression *pExpr,
3042 SfxItemSet &rItemSet,
3043 SvxCSS1PropertyInfo& /*rPropInfo*/,
3044 const SvxCSS1Parser& /*rParser*/ )
3046 if( CSS1_IDENT == pExpr->GetType() ||
3047 CSS1_STRING == pExpr->GetType() )
3049 LanguageType eLang = LanguageTag::convertToLanguageTypeWithFallback( pExpr->GetString() );
3050 if( LANGUAGE_DONTKNOW != eLang )
3052 SvxLanguageItem aLang( eLang, aItemIds.nLanguage );
3053 rItemSet.Put( aLang );
3054 aLang.SetWhich( aItemIds.nLanguageCJK );
3055 rItemSet.Put( aLang );
3056 aLang.SetWhich( aItemIds.nLanguageCTL );
3057 rItemSet.Put( aLang );
3062 // the assignment of property to parsing function
3063 struct CSS1PropEntry
3065 const char * pName;
3066 FnParseCSS1Prop pFunc;
3069 #define CSS1_PROP_ENTRY(p) \
3070 { sCSS1_P_##p, ParseCSS1_##p }
3072 // the table with assignments
3073 static CSS1PropEntry const aCSS1PropFnTab[] =
3075 CSS1_PROP_ENTRY(background),
3076 CSS1_PROP_ENTRY(background_color),
3077 CSS1_PROP_ENTRY(border),
3078 CSS1_PROP_ENTRY(border_bottom),
3079 CSS1_PROP_ENTRY(border_bottom_width),
3080 CSS1_PROP_ENTRY(border_color),
3081 CSS1_PROP_ENTRY(border_left),
3082 CSS1_PROP_ENTRY(border_left_width),
3083 CSS1_PROP_ENTRY(border_right),
3084 CSS1_PROP_ENTRY(border_right_width),
3085 CSS1_PROP_ENTRY(border_style),
3086 CSS1_PROP_ENTRY(border_top),
3087 CSS1_PROP_ENTRY(border_top_width),
3088 CSS1_PROP_ENTRY(border_width),
3089 CSS1_PROP_ENTRY(color),
3090 CSS1_PROP_ENTRY(column_count),
3091 CSS1_PROP_ENTRY(direction),
3092 CSS1_PROP_ENTRY(float),
3093 CSS1_PROP_ENTRY(font),
3094 CSS1_PROP_ENTRY(font_family),
3095 CSS1_PROP_ENTRY(font_size),
3096 CSS1_PROP_ENTRY(font_style),
3097 CSS1_PROP_ENTRY(font_variant),
3098 CSS1_PROP_ENTRY(font_weight),
3099 CSS1_PROP_ENTRY(height),
3100 CSS1_PROP_ENTRY(left),
3101 CSS1_PROP_ENTRY(letter_spacing),
3102 CSS1_PROP_ENTRY(line_height),
3103 CSS1_PROP_ENTRY(list_style_type),
3104 CSS1_PROP_ENTRY(margin),
3105 CSS1_PROP_ENTRY(margin_bottom),
3106 CSS1_PROP_ENTRY(margin_left),
3107 CSS1_PROP_ENTRY(margin_right),
3108 CSS1_PROP_ENTRY(margin_top),
3109 CSS1_PROP_ENTRY(orphans),
3110 CSS1_PROP_ENTRY(padding),
3111 CSS1_PROP_ENTRY(padding_bottom),
3112 CSS1_PROP_ENTRY(padding_left),
3113 CSS1_PROP_ENTRY(padding_right),
3114 CSS1_PROP_ENTRY(padding_top),
3115 CSS1_PROP_ENTRY(page_break_after),
3116 CSS1_PROP_ENTRY(page_break_before),
3117 CSS1_PROP_ENTRY(page_break_inside),
3118 CSS1_PROP_ENTRY(position),
3119 CSS1_PROP_ENTRY(size),
3120 CSS1_PROP_ENTRY(so_language),
3121 CSS1_PROP_ENTRY(text_align),
3122 CSS1_PROP_ENTRY(text_decoration),
3123 CSS1_PROP_ENTRY(text_indent),
3124 CSS1_PROP_ENTRY(text_transform),
3125 CSS1_PROP_ENTRY(top),
3126 CSS1_PROP_ENTRY(widows),
3127 CSS1_PROP_ENTRY(width),
3130 #if !defined NDEBUG
3131 static bool CSS1PropEntryCompare( const CSS1PropEntry &lhs, const CSS1PropEntry &rhs)
3133 return strcmp(lhs.pName, rhs.pName) < 0;
3135 #endif
3136 static bool CSS1PropEntryFindCompare(CSS1PropEntry const & lhs, OUString const & s)
3138 return s.compareToIgnoreAsciiCaseAscii(lhs.pName) > 0;
3141 void SvxCSS1Parser::DeclarationParsed( const OUString& rProperty,
3142 std::unique_ptr<CSS1Expression> pExpr )
3144 OSL_ENSURE( pItemSet, "DeclarationParsed() without ItemSet" );
3146 static bool bSortedPropFns = false;
3148 if( !bSortedPropFns )
3150 assert( std::is_sorted( std::begin(aCSS1PropFnTab), std::end(aCSS1PropFnTab),
3151 CSS1PropEntryCompare ) );
3152 bSortedPropFns = true;
3155 auto it = std::lower_bound( std::begin(aCSS1PropFnTab), std::end(aCSS1PropFnTab), rProperty,
3156 CSS1PropEntryFindCompare );
3157 if( it != std::end(aCSS1PropFnTab) && !CSS1PropEntryFindCompare(*it,rProperty) )
3159 it->pFunc( pExpr.get(), *pItemSet, *pPropInfo, *this );
3163 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */