1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
28 #include <svx/svxids.hrc>
29 #include <i18nlangtag/languagetag.hxx>
30 #include <svtools/ctrltool.hxx>
31 #include <svl/urihelper.hxx>
32 #include <editeng/udlnitem.hxx>
33 #include <editeng/adjustitem.hxx>
34 #include <editeng/blinkitem.hxx>
35 #include <editeng/crossedoutitem.hxx>
36 #include <editeng/kernitem.hxx>
37 #include <editeng/lspcitem.hxx>
38 #include <editeng/fontitem.hxx>
39 #include <editeng/postitem.hxx>
40 #include <editeng/colritem.hxx>
41 #include <editeng/cmapitem.hxx>
42 #include <editeng/brushitem.hxx>
43 #include <editeng/wghtitem.hxx>
44 #include <editeng/fhgtitem.hxx>
45 #include <editeng/borderline.hxx>
46 #include <editeng/boxitem.hxx>
47 #include <editeng/ulspitem.hxx>
48 #include <editeng/lrspitem.hxx>
49 #include <editeng/langitem.hxx>
50 #include <svl/itempool.hxx>
51 #include <editeng/spltitem.hxx>
52 #include <editeng/widwitem.hxx>
53 #include <editeng/frmdiritem.hxx>
54 #include <editeng/orphitem.hxx>
56 #include <vcl/svapp.hxx>
57 #include <sal/log.hxx>
58 #include <osl/diagnose.h>
59 #include <o3tl/string_view.hxx>
61 #include <hintids.hxx>
63 #include "css1kywd.hxx"
64 #include "svxcss1.hxx"
65 #include "htmlnum.hxx"
67 using namespace ::com::sun::star
;
69 /// type of functions to parse CSS1 properties
70 typedef void (*FnParseCSS1Prop
)( const CSS1Expression
*pExpr
,
72 SvxCSS1PropertyInfo
& rPropInfo
,
73 const SvxCSS1Parser
& rParser
);
75 CSS1PropertyEnum
const aFontSizeTable
[] =
87 CSS1PropertyEnum
const aFontWeightTable
[] =
89 { "extra-light", WEIGHT_NORMAL
}, // WEIGHT_ULTRALIGHT (OBS)
90 { "light", WEIGHT_NORMAL
}, // WEIGHT_LIGHT (OBSOLETE)
91 { "demi-light", WEIGHT_NORMAL
}, // WEIGHT_SEMILIGHT (OBS)
92 { "medium", WEIGHT_NORMAL
}, // WEIGHT_MEDIUM (OBS)
93 { "normal", WEIGHT_NORMAL
}, // WEIGHT_MEDIUM
94 { "demi-bold", WEIGHT_NORMAL
}, // WEIGHT_SEMIBOLD (OBS)
95 { "bold", WEIGHT_BOLD
}, // WEIGHT_BOLD (OBSOLETE)
96 { "extra-bold", WEIGHT_BOLD
}, // WEIGHT_ULTRABOLD (OBS)
97 { "bolder", WEIGHT_BOLD
},
98 { "lighter", WEIGHT_NORMAL
},
102 CSS1PropertyEnum
const aFontStyleTable
[] =
104 { "normal", ITALIC_NONE
},
105 { "italic", ITALIC_NORMAL
},
106 { "oblique", ITALIC_NORMAL
},
110 CSS1PropertyEnum
const aFontVariantTable
[] =
112 { "normal", sal_uInt16(SvxCaseMap::NotMapped
) },
113 { "small-caps", sal_uInt16(SvxCaseMap::SmallCaps
) },
117 CSS1PropertyEnum
const aTextTransformTable
[] =
119 { "uppercase", sal_uInt16(SvxCaseMap::Uppercase
) },
120 { "lowercase", sal_uInt16(SvxCaseMap::Lowercase
) },
121 { "capitalize", sal_uInt16(SvxCaseMap::Capitalize
) },
125 CSS1PropertyEnum
const aDirectionTable
[] =
127 { "ltr", sal_uInt16(SvxFrameDirection::Horizontal_LR_TB
) },
128 { "rtl", sal_uInt16(SvxFrameDirection::Horizontal_RL_TB
) },
129 { "inherit", sal_uInt16(SvxFrameDirection::Environment
) },
133 CSS1PropertyEnum
const aBGRepeatTable
[] =
135 { "repeat", GPOS_TILED
},
136 { "repeat-x", GPOS_TILED
},
137 { "repeat-y", GPOS_TILED
},
138 { "no-repeat", GPOS_NONE
},
142 CSS1PropertyEnum
const aBGHoriPosTable
[] =
145 { "center", GPOS_MT
},
146 { "right", GPOS_RT
},
150 CSS1PropertyEnum
const aBGVertPosTable
[] =
153 { "middle", GPOS_LM
},
154 { "bottom", GPOS_LB
},
158 CSS1PropertyEnum
const aTextAlignTable
[] =
160 { "left", sal_uInt16(SvxAdjust::Left
) },
161 { "center", sal_uInt16(SvxAdjust::Center
) },
162 { "right", sal_uInt16(SvxAdjust::Right
) },
163 { "justify", sal_uInt16(SvxAdjust::Block
) },
167 CSS1PropertyEnum
const aBorderWidthTable
[] =
169 { "thin", 0 }, // DEF_LINE_WIDTH_0 / DEF_DOUBLE_LINE0
170 { "medium", 1 }, // DEF_LINE_WIDTH_1 / DEF_DOUBLE_LINE1
171 { "thick", 2 }, // DEF_LINE_WIDTH_2 / DEF_DOUBLE_LINE2
177 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
};
181 CSS1PropertyEnum
const aBorderStyleTable
[] =
183 { "none", CSS1_BS_NONE
},
184 { "dotted", CSS1_BS_DOTTED
},
185 { "dashed", CSS1_BS_DASHED
},
186 { "solid", CSS1_BS_SINGLE
},
187 { "double", CSS1_BS_DOUBLE
},
188 { "groove", CSS1_BS_GROOVE
},
189 { "ridge", CSS1_BS_RIDGE
},
190 { "inset", CSS1_BS_INSET
},
191 { "outset", CSS1_BS_OUTSET
},
195 CSS1PropertyEnum
const aFloatTable
[] =
197 { "left", sal_uInt16(SvxAdjust::Left
) },
198 { "right", sal_uInt16(SvxAdjust::Right
) },
199 { "none", sal_uInt16(SvxAdjust::End
) },
203 CSS1PropertyEnum
const aPositionTable
[] =
205 { "absolute", SVX_CSS1_POS_ABSOLUTE
},
206 { "relative", SVX_CSS1_POS_RELATIVE
},
207 { "static", SVX_CSS1_POS_STATIC
},
212 CSS1PropertyEnum
const aSizeTable
[] =
214 { "auto", SVX_CSS1_STYPE_AUTO
},
215 { "landscape", SVX_CSS1_STYPE_LANDSCAPE
},
216 { "portrait", SVX_CSS1_STYPE_PORTRAIT
},
220 CSS1PropertyEnum
const aPageBreakTable
[] =
222 { "auto", SVX_CSS1_PBREAK_AUTO
},
223 { "always", SVX_CSS1_PBREAK_ALWAYS
},
224 { "avoid", SVX_CSS1_PBREAK_AVOID
},
225 { "left", SVX_CSS1_PBREAK_LEFT
},
226 { "right", SVX_CSS1_PBREAK_RIGHT
},
230 CSS1PropertyEnum
const aNumberStyleTable
[] =
232 { "decimal", SVX_NUM_ARABIC
},
233 { "lower-alpha", SVX_NUM_CHARS_LOWER_LETTER
},
234 { "lower-latin", SVX_NUM_CHARS_LOWER_LETTER
},
235 { "lower-roman", SVX_NUM_ROMAN_LOWER
},
236 { "upper-alpha", SVX_NUM_CHARS_UPPER_LETTER
},
237 { "upper-latin", SVX_NUM_CHARS_UPPER_LETTER
},
238 { "upper-roman", SVX_NUM_ROMAN_UPPER
},
242 CSS1PropertyEnum
const aBulletStyleTable
[] =
244 { "circle", HTML_BULLETCHAR_CIRCLE
},
245 { "disc", HTML_BULLETCHAR_DISC
},
246 { "square", HTML_BULLETCHAR_SQUARE
},
250 sal_uInt16
const aBorderWidths
[] =
252 SvxBorderLineWidth::Hairline
,
253 SvxBorderLineWidth::VeryThin
,
254 SvxBorderLineWidth::Thin
262 struct SvxCSS1ItemIds
268 sal_uInt16 nPostureCJK
;
269 sal_uInt16 nPostureCTL
;
271 sal_uInt16 nWeightCJK
;
272 sal_uInt16 nWeightCTL
;
273 sal_uInt16 nFontHeight
;
274 sal_uInt16 nFontHeightCJK
;
275 sal_uInt16 nFontHeightCTL
;
276 sal_uInt16 nUnderline
;
277 sal_uInt16 nOverline
;
278 sal_uInt16 nCrossedOut
;
284 sal_uInt16 nLineSpacing
;
288 sal_uInt16 nFormatSplit
;
290 // this looks a bit superfluous? TypedWhichId<SvxLRSpaceItem> nLRSpace{0};
291 TypedWhichId
<SvxULSpaceItem
> nULSpace
{0};
295 sal_uInt16 nLanguage
;
296 sal_uInt16 nLanguageCJK
;
297 sal_uInt16 nLanguageCTL
;
298 sal_uInt16 nDirection
;
303 static SvxCSS1ItemIds aItemIds
;
305 struct SvxCSS1BorderInfo
308 sal_uInt16 nAbsWidth
;
309 sal_uInt16 nNamedWidth
;
310 CSS1BorderStyle eStyle
;
312 SvxCSS1BorderInfo() :
313 aColor( COL_BLACK
), nAbsWidth( USHRT_MAX
),
314 nNamedWidth( USHRT_MAX
), eStyle( CSS1_BS_NONE
)
317 void SetBorderLine( SvxBoxItemLine nLine
, SvxBoxItem
&rBoxItem
) const;
320 void SvxCSS1BorderInfo::SetBorderLine( SvxBoxItemLine nLine
, SvxBoxItem
&rBoxItem
) const
322 if( CSS1_BS_NONE
==eStyle
|| nAbsWidth
==0 ||
323 (nAbsWidth
==USHRT_MAX
&& nNamedWidth
==USHRT_MAX
) )
325 rBoxItem
.SetLine( nullptr, nLine
);
329 ::editeng::SvxBorderLine
aBorderLine( &aColor
);
331 // Line style double or single?
335 aBorderLine
.SetBorderLineStyle(SvxBorderLineStyle::SOLID
);
338 aBorderLine
.SetBorderLineStyle(SvxBorderLineStyle::DOUBLE
);
341 aBorderLine
.SetBorderLineStyle(SvxBorderLineStyle::DOTTED
);
344 aBorderLine
.SetBorderLineStyle(SvxBorderLineStyle::DASHED
);
347 aBorderLine
.SetBorderLineStyle(SvxBorderLineStyle::ENGRAVED
);
350 aBorderLine
.SetBorderLineStyle(SvxBorderLineStyle::EMBOSSED
);
353 aBorderLine
.SetBorderLineStyle(SvxBorderLineStyle::INSET
);
356 aBorderLine
.SetBorderLineStyle(SvxBorderLineStyle::OUTSET
);
359 aBorderLine
.SetBorderLineStyle(SvxBorderLineStyle::NONE
);
363 // convert named width, if no absolute is given
364 if( nAbsWidth
==USHRT_MAX
)
365 aBorderLine
.SetWidth( aBorderWidths
[ nNamedWidth
] );
367 aBorderLine
.SetWidth( nAbsWidth
);
369 rBoxItem
.SetLine( &aBorderLine
, nLine
);
372 SvxCSS1PropertyInfo::SvxCSS1PropertyInfo()
377 SvxCSS1PropertyInfo::SvxCSS1PropertyInfo( const SvxCSS1PropertyInfo
& rProp
) :
378 m_aId( rProp
.m_aId
),
379 m_bTopMargin( rProp
.m_bTopMargin
),
380 m_bBottomMargin( rProp
.m_bBottomMargin
),
381 m_bLeftMargin( rProp
.m_bLeftMargin
),
382 m_bRightMargin( rProp
.m_bRightMargin
),
383 m_bTextIndent( rProp
.m_bTextIndent
),
384 m_bNumbering ( rProp
.m_bNumbering
),
385 m_bBullet ( rProp
.m_bBullet
),
386 m_eFloat( rProp
.m_eFloat
),
387 m_ePosition( rProp
.m_ePosition
),
388 m_nTopBorderDistance( rProp
.m_nTopBorderDistance
),
389 m_nBottomBorderDistance( rProp
.m_nBottomBorderDistance
),
390 m_nLeftBorderDistance( rProp
.m_nLeftBorderDistance
),
391 m_nRightBorderDistance( rProp
.m_nRightBorderDistance
),
392 m_nNumberingType ( rProp
.m_nNumberingType
),
393 m_cBulletChar( rProp
.m_cBulletChar
),
394 m_nColumnCount( rProp
.m_nColumnCount
),
395 m_nLeft( rProp
.m_nLeft
),
396 m_nTop( rProp
.m_nTop
),
397 m_nWidth( rProp
.m_nWidth
),
398 m_nHeight( rProp
.m_nHeight
),
399 m_nLeftMargin( rProp
.m_nLeftMargin
),
400 m_nRightMargin( rProp
.m_nRightMargin
),
401 m_eLeftType( rProp
.m_eLeftType
),
402 m_eTopType( rProp
.m_eTopType
),
403 m_eWidthType( rProp
.m_eWidthType
),
404 m_eHeightType( rProp
.m_eHeightType
),
405 m_eLeftMarginType( rProp
.m_eLeftMarginType
),
406 m_eRightMarginType( rProp
.m_eRightMarginType
),
407 m_eSizeType( rProp
.m_eSizeType
),
408 m_ePageBreakBefore( rProp
.m_ePageBreakBefore
),
409 m_ePageBreakAfter( rProp
.m_ePageBreakAfter
)
411 for( size_t i
=0; i
<m_aBorderInfos
.size(); ++i
)
412 if (rProp
.m_aBorderInfos
[i
])
413 m_aBorderInfos
[i
].reset( new SvxCSS1BorderInfo( *rProp
.m_aBorderInfos
[i
] ) );
416 SvxCSS1PropertyInfo::~SvxCSS1PropertyInfo()
420 void SvxCSS1PropertyInfo::DestroyBorderInfos()
422 for(auto & rp
: m_aBorderInfos
)
426 void SvxCSS1PropertyInfo::Clear()
429 m_bTopMargin
= m_bBottomMargin
= false;
430 m_bLeftMargin
= m_bRightMargin
= m_bTextIndent
= false;
431 m_bNumbering
= m_bBullet
= false;
432 m_nLeftMargin
= m_nRightMargin
= 0;
433 m_eFloat
= SvxAdjust::End
;
435 m_ePosition
= SVX_CSS1_POS_NONE
;
436 m_nTopBorderDistance
= m_nBottomBorderDistance
=
437 m_nLeftBorderDistance
= m_nRightBorderDistance
= UNSET_BORDER_DISTANCE
;
439 m_nNumberingType
= SVX_NUM_CHARS_UPPER_LETTER
;
444 m_nLeft
= m_nTop
= m_nWidth
= m_nHeight
= 0;
445 m_eLeftType
= m_eTopType
= m_eWidthType
= m_eHeightType
= SVX_CSS1_LTYPE_NONE
;
446 m_eLeftMarginType
= SVX_CSS1_LTYPE_NONE
;
447 m_eRightMarginType
= SVX_CSS1_LTYPE_NONE
;
450 m_eSizeType
= SVX_CSS1_STYPE_NONE
;
451 m_ePageBreakBefore
= SVX_CSS1_PBREAK_NONE
;
452 m_ePageBreakAfter
= SVX_CSS1_PBREAK_NONE
;
454 DestroyBorderInfos();
457 void SvxCSS1PropertyInfo::Merge( const SvxCSS1PropertyInfo
& rProp
)
459 if( rProp
.m_bTopMargin
)
461 if( rProp
.m_bBottomMargin
)
462 m_bBottomMargin
= true;
464 if( rProp
.m_bLeftMargin
)
466 m_bLeftMargin
= true;
467 m_nLeftMargin
= rProp
.m_nLeftMargin
;
469 if( rProp
.m_bRightMargin
)
471 m_bRightMargin
= true;
472 m_nRightMargin
= rProp
.m_nRightMargin
;
474 if( rProp
.m_bTextIndent
)
475 m_bTextIndent
= true;
477 for( size_t i
=0; i
<m_aBorderInfos
.size(); ++i
)
479 if( rProp
.m_aBorderInfos
[i
] )
480 m_aBorderInfos
[i
].reset( new SvxCSS1BorderInfo( *rProp
.m_aBorderInfos
[i
] ) );
483 if( UNSET_BORDER_DISTANCE
!= rProp
.m_nTopBorderDistance
)
484 m_nTopBorderDistance
= rProp
.m_nTopBorderDistance
;
485 if( UNSET_BORDER_DISTANCE
!= rProp
.m_nBottomBorderDistance
)
486 m_nBottomBorderDistance
= rProp
.m_nBottomBorderDistance
;
487 if( UNSET_BORDER_DISTANCE
!= rProp
.m_nLeftBorderDistance
)
488 m_nLeftBorderDistance
= rProp
.m_nLeftBorderDistance
;
489 if( UNSET_BORDER_DISTANCE
!= rProp
.m_nRightBorderDistance
)
490 m_nRightBorderDistance
= rProp
.m_nRightBorderDistance
;
492 m_nColumnCount
= rProp
.m_nColumnCount
;
494 if( rProp
.m_eFloat
!= SvxAdjust::End
)
495 m_eFloat
= rProp
.m_eFloat
;
497 if( rProp
.m_ePosition
!= SVX_CSS1_POS_NONE
)
498 m_ePosition
= rProp
.m_ePosition
;
501 if( rProp
.m_eSizeType
!= SVX_CSS1_STYPE_NONE
)
503 m_eSizeType
= rProp
.m_eSizeType
;
504 m_nWidth
= rProp
.m_nWidth
;
505 m_nHeight
= rProp
.m_nHeight
;
508 if( rProp
.m_ePageBreakBefore
!= SVX_CSS1_PBREAK_NONE
)
509 m_ePageBreakBefore
= rProp
.m_ePageBreakBefore
;
511 if( rProp
.m_ePageBreakAfter
!= SVX_CSS1_PBREAK_NONE
)
512 m_ePageBreakAfter
= rProp
.m_ePageBreakAfter
;
514 if( rProp
.m_eLeftType
!= SVX_CSS1_LTYPE_NONE
)
516 m_eLeftType
= rProp
.m_eLeftType
;
517 m_nLeft
= rProp
.m_nLeft
;
520 if( rProp
.m_eTopType
!= SVX_CSS1_LTYPE_NONE
)
522 m_eTopType
= rProp
.m_eTopType
;
523 m_nTop
= rProp
.m_nTop
;
526 if( rProp
.m_eWidthType
!= SVX_CSS1_LTYPE_NONE
)
528 m_eWidthType
= rProp
.m_eWidthType
;
529 m_nWidth
= rProp
.m_nWidth
;
532 if( rProp
.m_eHeightType
!= SVX_CSS1_LTYPE_NONE
)
534 m_eHeightType
= rProp
.m_eHeightType
;
535 m_nHeight
= rProp
.m_nHeight
;
539 SvxCSS1BorderInfo
*SvxCSS1PropertyInfo::GetBorderInfo( SvxBoxItemLine nLine
, bool bCreate
)
544 case SvxBoxItemLine::TOP
: nPos
= 0; break;
545 case SvxBoxItemLine::BOTTOM
: nPos
= 1; break;
546 case SvxBoxItemLine::LEFT
: nPos
= 2; break;
547 case SvxBoxItemLine::RIGHT
: nPos
= 3; break;
550 if( !m_aBorderInfos
[nPos
] && bCreate
)
551 m_aBorderInfos
[nPos
].reset( new SvxCSS1BorderInfo
);
553 return m_aBorderInfos
[nPos
].get();
556 void SvxCSS1PropertyInfo::CopyBorderInfo( SvxBoxItemLine nSrcLine
, SvxBoxItemLine nDstLine
,
559 SvxCSS1BorderInfo
*pSrcInfo
= GetBorderInfo( nSrcLine
, false );
563 SvxCSS1BorderInfo
*pDstInfo
= GetBorderInfo( nDstLine
);
564 if( (nWhat
& SVX_CSS1_BORDERINFO_WIDTH
) != 0 )
566 pDstInfo
->nAbsWidth
= pSrcInfo
->nAbsWidth
;
567 pDstInfo
->nNamedWidth
= pSrcInfo
->nNamedWidth
;
570 if( (nWhat
& SVX_CSS1_BORDERINFO_COLOR
) != 0 )
571 pDstInfo
->aColor
= pSrcInfo
->aColor
;
573 if( (nWhat
& SVX_CSS1_BORDERINFO_STYLE
) != 0 )
574 pDstInfo
->eStyle
= pSrcInfo
->eStyle
;
577 void SvxCSS1PropertyInfo::CopyBorderInfo( sal_uInt16 nCount
, sal_uInt16 nWhat
)
581 CopyBorderInfo( SvxBoxItemLine::BOTTOM
, SvxBoxItemLine::TOP
, nWhat
);
582 CopyBorderInfo( SvxBoxItemLine::TOP
, SvxBoxItemLine::LEFT
, nWhat
);
586 CopyBorderInfo( SvxBoxItemLine::LEFT
, SvxBoxItemLine::RIGHT
, nWhat
);
590 void SvxCSS1PropertyInfo::SetBoxItem( SfxItemSet
& rItemSet
,
591 sal_uInt16 nMinBorderDist
,
592 const SvxBoxItem
*pDfltItem
)
594 bool bChg
= m_nTopBorderDistance
!= UNSET_BORDER_DISTANCE
||
595 m_nBottomBorderDistance
!= UNSET_BORDER_DISTANCE
||
596 m_nLeftBorderDistance
!= UNSET_BORDER_DISTANCE
||
597 m_nRightBorderDistance
!= UNSET_BORDER_DISTANCE
;
599 for( size_t i
=0; !bChg
&& i
<m_aBorderInfos
.size(); ++i
)
600 bChg
= m_aBorderInfos
[i
]!=nullptr;
605 std::shared_ptr
<SvxBoxItem
> aBoxItem(std::make_shared
<SvxBoxItem
>(aItemIds
.nBox
));
607 aBoxItem
.reset(pDfltItem
->Clone());
609 SvxCSS1BorderInfo
*pInfo
= GetBorderInfo( SvxBoxItemLine::TOP
, false );
611 pInfo
->SetBorderLine( SvxBoxItemLine::TOP
, *aBoxItem
);
613 pInfo
= GetBorderInfo( SvxBoxItemLine::BOTTOM
, false );
615 pInfo
->SetBorderLine( SvxBoxItemLine::BOTTOM
, *aBoxItem
);
617 pInfo
= GetBorderInfo( SvxBoxItemLine::LEFT
, false );
619 pInfo
->SetBorderLine( SvxBoxItemLine::LEFT
, *aBoxItem
);
621 pInfo
= GetBorderInfo( SvxBoxItemLine::RIGHT
, false );
623 pInfo
->SetBorderLine( SvxBoxItemLine::RIGHT
, *aBoxItem
);
625 for( size_t i
=0; i
<m_aBorderInfos
.size(); ++i
)
627 SvxBoxItemLine nLine
= SvxBoxItemLine::TOP
;
628 sal_uInt16 nDist
= 0;
631 case 0: nLine
= SvxBoxItemLine::TOP
;
632 nDist
= m_nTopBorderDistance
;
633 m_nTopBorderDistance
= UNSET_BORDER_DISTANCE
;
635 case 1: nLine
= SvxBoxItemLine::BOTTOM
;
636 nDist
= m_nBottomBorderDistance
;
637 m_nBottomBorderDistance
= UNSET_BORDER_DISTANCE
;
639 case 2: nLine
= SvxBoxItemLine::LEFT
;
640 nDist
= m_nLeftBorderDistance
;
641 m_nLeftBorderDistance
= UNSET_BORDER_DISTANCE
;
643 case 3: nLine
= SvxBoxItemLine::RIGHT
;
644 nDist
= m_nRightBorderDistance
;
645 m_nRightBorderDistance
= UNSET_BORDER_DISTANCE
;
649 if( aBoxItem
->GetLine( nLine
) )
651 if( UNSET_BORDER_DISTANCE
== nDist
)
652 nDist
= aBoxItem
->GetDistance( nLine
);
654 if( nDist
< nMinBorderDist
)
655 nDist
= nMinBorderDist
;
662 aBoxItem
->SetDistance( nDist
, nLine
);
665 rItemSet
.Put( *aBoxItem
);
667 DestroyBorderInfos();
670 SvxCSS1MapEntry::SvxCSS1MapEntry( SfxItemSet aItemSet
,
671 const SvxCSS1PropertyInfo
& rProp
) :
672 m_aItemSet(std::move( aItemSet
)),
676 void SvxCSS1Parser::StyleParsed( const CSS1Selector
* /*pSelector*/,
677 SfxItemSet
& /*rItemSet*/,
678 SvxCSS1PropertyInfo
& /*rPropInfo*/ )
680 // you see nothing is happening here
683 void SvxCSS1Parser::SelectorParsed( std::unique_ptr
<CSS1Selector
> pSelector
, bool bFirst
)
687 OSL_ENSURE( m_pSheetItemSet
, "Where is the Item-Set for Style-Sheets?" );
689 for (const std::unique_ptr
<CSS1Selector
> & rpSelection
: m_Selectors
)
691 StyleParsed(rpSelection
.get(), *m_pSheetItemSet
, *m_pSheetPropInfo
);
693 m_pSheetItemSet
->ClearItem();
694 m_pSheetPropInfo
->Clear();
696 // prepare the next rule
700 m_Selectors
.push_back(std::move(pSelector
));
703 SvxCSS1Parser::SvxCSS1Parser( SfxItemPool
& rPool
, OUString aBaseURL
,
704 sal_uInt16
const *pWhichIds
, sal_uInt16 nWhichIds
) :
705 m_sBaseURL(std::move( aBaseURL
)),
707 m_pPropInfo( nullptr ),
708 m_eDefaultEnc( RTL_TEXTENCODING_DONTKNOW
),
709 m_bIgnoreFontFamily( false )
711 // also initialize item IDs
712 auto initTrueWhich
= [&rPool
, this](sal_uInt16 rWid
)
714 rWid
= rPool
.GetTrueWhich(rWid
, false);
715 m_aWhichMap
= m_aWhichMap
.MergeRange(rWid
, rWid
);
719 aItemIds
.nFont
= initTrueWhich( SID_ATTR_CHAR_FONT
);
720 aItemIds
.nFontCJK
= initTrueWhich( SID_ATTR_CHAR_CJK_FONT
);
721 aItemIds
.nFontCTL
= initTrueWhich( SID_ATTR_CHAR_CTL_FONT
);
722 aItemIds
.nPosture
= initTrueWhich( SID_ATTR_CHAR_POSTURE
);
723 aItemIds
.nPostureCJK
= initTrueWhich( SID_ATTR_CHAR_CJK_POSTURE
);
724 aItemIds
.nPostureCTL
= initTrueWhich( SID_ATTR_CHAR_CTL_POSTURE
);
725 aItemIds
.nWeight
= initTrueWhich( SID_ATTR_CHAR_WEIGHT
);
726 aItemIds
.nWeightCJK
= initTrueWhich( SID_ATTR_CHAR_CJK_WEIGHT
);
727 aItemIds
.nWeightCTL
= initTrueWhich( SID_ATTR_CHAR_CTL_WEIGHT
);
728 aItemIds
.nFontHeight
= initTrueWhich( SID_ATTR_CHAR_FONTHEIGHT
);
729 aItemIds
.nFontHeightCJK
= initTrueWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT
);
730 aItemIds
.nFontHeightCTL
= initTrueWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT
);
731 aItemIds
.nUnderline
= initTrueWhich( SID_ATTR_CHAR_UNDERLINE
);
732 aItemIds
.nOverline
= initTrueWhich( SID_ATTR_CHAR_OVERLINE
);
733 aItemIds
.nCrossedOut
= initTrueWhich( SID_ATTR_CHAR_STRIKEOUT
);
734 aItemIds
.nColor
= initTrueWhich( SID_ATTR_CHAR_COLOR
);
735 aItemIds
.nKerning
= initTrueWhich( SID_ATTR_CHAR_KERNING
);
736 aItemIds
.nCaseMap
= initTrueWhich( SID_ATTR_CHAR_CASEMAP
);
737 aItemIds
.nBlink
= initTrueWhich( SID_ATTR_FLASH
);
739 aItemIds
.nLineSpacing
= initTrueWhich( SID_ATTR_PARA_LINESPACE
);
740 aItemIds
.nAdjust
= initTrueWhich( SID_ATTR_PARA_ADJUST
);
741 aItemIds
.nWidows
= initTrueWhich( SID_ATTR_PARA_WIDOWS
);
742 aItemIds
.nOrphans
= initTrueWhich( SID_ATTR_PARA_ORPHANS
);
743 aItemIds
.nFormatSplit
= initTrueWhich( SID_ATTR_PARA_SPLIT
);
745 // every id that is used must be added
746 m_aWhichMap
= m_aWhichMap
.MergeRange(RES_MARGIN_FIRSTLINE
, RES_MARGIN_FIRSTLINE
);
747 m_aWhichMap
= m_aWhichMap
.MergeRange(RES_MARGIN_TEXTLEFT
, RES_MARGIN_TEXTLEFT
);
748 m_aWhichMap
= m_aWhichMap
.MergeRange(RES_MARGIN_RIGHT
, RES_MARGIN_RIGHT
);
749 aItemIds
.nULSpace
= TypedWhichId
<SvxULSpaceItem
>(initTrueWhich( SID_ATTR_ULSPACE
));
750 aItemIds
.nBox
= initTrueWhich( SID_ATTR_BORDER_OUTER
);
751 aItemIds
.nBrush
= initTrueWhich( SID_ATTR_BRUSH
);
753 aItemIds
.nLanguage
= initTrueWhich( SID_ATTR_CHAR_LANGUAGE
);
754 aItemIds
.nLanguageCJK
= initTrueWhich( SID_ATTR_CHAR_CJK_LANGUAGE
);
755 aItemIds
.nLanguageCTL
= initTrueWhich( SID_ATTR_CHAR_CTL_LANGUAGE
);
756 aItemIds
.nDirection
= initTrueWhich( SID_ATTR_FRAMEDIRECTION
);
758 if( pWhichIds
&& nWhichIds
)
759 for (sal_uInt16 i
= 0; i
< nWhichIds
; ++i
)
760 m_aWhichMap
= m_aWhichMap
.MergeRange(pWhichIds
[i
], pWhichIds
[i
]);
762 m_pSheetItemSet
.reset( new SfxItemSet( rPool
, m_aWhichMap
) );
763 m_pSheetPropInfo
.reset( new SvxCSS1PropertyInfo
);
766 SvxCSS1Parser::~SvxCSS1Parser()
768 m_pSheetItemSet
.reset();
769 m_pSheetPropInfo
.reset();
772 void SvxCSS1Parser::InsertId( const OUString
& rId
,
773 const SfxItemSet
& rItemSet
,
774 const SvxCSS1PropertyInfo
& rProp
)
776 InsertMapEntry( rId
, rItemSet
, rProp
, m_Ids
);
779 const SvxCSS1MapEntry
* SvxCSS1Parser::GetId( const OUString
& rId
) const
781 CSS1Map::const_iterator itr
= m_Ids
.find(rId
);
782 return itr
== m_Ids
.end() ? nullptr : itr
->second
.get();
785 void SvxCSS1Parser::InsertClass( const OUString
& rClass
,
786 const SfxItemSet
& rItemSet
,
787 const SvxCSS1PropertyInfo
& rProp
)
789 InsertMapEntry( rClass
, rItemSet
, rProp
, m_Classes
);
792 const SvxCSS1MapEntry
* SvxCSS1Parser::GetClass( const OUString
& rClass
) const
794 CSS1Map::const_iterator itr
= m_Classes
.find(rClass
);
795 return itr
== m_Classes
.end() ? nullptr : itr
->second
.get();
798 void SvxCSS1Parser::InsertPage( const OUString
& rPage
,
800 const SfxItemSet
& rItemSet
,
801 const SvxCSS1PropertyInfo
& rProp
)
803 OUString
aKey( rPage
);
806 InsertMapEntry( aKey
, rItemSet
, rProp
, m_Pages
);
809 SvxCSS1MapEntry
* SvxCSS1Parser::GetPage( const OUString
& rPage
, bool bPseudo
)
811 OUString
aKey( rPage
);
815 CSS1Map::iterator itr
= m_Pages
.find(aKey
);
816 return itr
== m_Pages
.end() ? nullptr : itr
->second
.get();
819 void SvxCSS1Parser::InsertTag( const OUString
& rTag
,
820 const SfxItemSet
& rItemSet
,
821 const SvxCSS1PropertyInfo
& rProp
)
823 InsertMapEntry( rTag
, rItemSet
, rProp
, m_Tags
);
826 SvxCSS1MapEntry
* SvxCSS1Parser::GetTag( const OUString
& rTag
)
828 CSS1Map::iterator itr
= m_Tags
.find(rTag
);
829 return itr
== m_Tags
.end() ? nullptr : itr
->second
.get();
832 bool SvxCSS1Parser::ParseStyleSheet( const OUString
& rIn
)
834 m_pItemSet
= m_pSheetItemSet
.get();
835 m_pPropInfo
= m_pSheetPropInfo
.get();
837 CSS1Parser::ParseStyleSheet( rIn
);
839 for (const std::unique_ptr
<CSS1Selector
> & rpSelector
: m_Selectors
)
841 StyleParsed(rpSelector
.get(), *m_pSheetItemSet
, *m_pSheetPropInfo
);
844 // and clean up a little bit
846 m_pSheetItemSet
->ClearItem();
847 m_pSheetPropInfo
->Clear();
849 m_pItemSet
= nullptr;
850 m_pPropInfo
= nullptr;
855 void SvxCSS1Parser::ParseStyleOption( const OUString
& rIn
,
856 SfxItemSet
& rItemSet
,
857 SvxCSS1PropertyInfo
& rPropInfo
)
859 m_pItemSet
= &rItemSet
;
860 m_pPropInfo
= &rPropInfo
;
862 CSS1Parser::ParseStyleOption( rIn
);
863 rItemSet
.ClearItem( aItemIds
.nDirection
);
865 m_pItemSet
= nullptr;
866 m_pPropInfo
= nullptr;
869 bool SvxCSS1Parser::GetEnum( const CSS1PropertyEnum
*pPropTable
,
870 std::u16string_view rValue
, sal_uInt16
& rEnum
)
872 while( pPropTable
->pName
)
874 if( !o3tl::equalsIgnoreAsciiCase( rValue
, pPropTable
->pName
) )
880 if( pPropTable
->pName
)
881 rEnum
= pPropTable
->nEnum
;
883 return (pPropTable
->pName
!= nullptr);
886 void SvxCSS1Parser::PixelToTwip( tools::Long
&rWidth
, tools::Long
&rHeight
)
888 rWidth
= o3tl::convert(rWidth
, o3tl::Length::px
, o3tl::Length::twip
);
889 rHeight
= o3tl::convert(rHeight
, o3tl::Length::px
, o3tl::Length::twip
);
892 sal_uInt32
SvxCSS1Parser::GetFontHeight( sal_uInt16 nSize
) const
898 case 0: nHeight
= 8*20; break;
899 case 1: nHeight
= 10*20; break;
900 case 2: nHeight
= 11*20; break;
901 case 3: nHeight
= 12*20; break;
902 case 4: nHeight
= 17*20; break;
903 case 5: nHeight
= 20*20; break;
905 default: nHeight
= 32*20; break;
911 const FontList
*SvxCSS1Parser::GetFontList() const
916 void SvxCSS1Parser::InsertMapEntry( const OUString
& rKey
,
917 const SfxItemSet
& rItemSet
,
918 const SvxCSS1PropertyInfo
& rProp
,
921 auto [itr
,inserted
] = rMap
.insert(std::make_pair(rKey
, nullptr));
923 itr
->second
= std::make_unique
<SvxCSS1MapEntry
>(rItemSet
, rProp
);
926 SvxCSS1MapEntry
*const p
= itr
->second
.get();
927 MergeStyles( rItemSet
, rProp
,
928 p
->GetItemSet(), p
->GetPropertyInfo(), true );
932 void SvxCSS1Parser::MergeStyles( const SfxItemSet
& rSrcSet
,
933 const SvxCSS1PropertyInfo
& rSrcInfo
,
934 SfxItemSet
& rTargetSet
,
935 SvxCSS1PropertyInfo
& rTargetInfo
,
940 rTargetSet
.Put( rSrcSet
);
944 // not sure if this is really necessary?
945 SfxItemSet
copy(rSrcSet
);
946 if (!rSrcInfo
.m_bTextIndent
)
948 copy
.ClearItem(RES_MARGIN_FIRSTLINE
);
950 if (!rSrcInfo
.m_bLeftMargin
)
952 copy
.ClearItem(RES_MARGIN_TEXTLEFT
);
954 if (!rSrcInfo
.m_bRightMargin
)
956 copy
.ClearItem(RES_MARGIN_RIGHT
);
959 SvxULSpaceItem
aULSpace( rTargetSet
.Get(aItemIds
.nULSpace
) );
961 rTargetSet
.Put(copy
);
963 if( rSrcInfo
.m_bTopMargin
|| rSrcInfo
.m_bBottomMargin
)
965 const SvxULSpaceItem
& rNewULSpace
= rSrcSet
.Get( aItemIds
.nULSpace
);
967 if( rSrcInfo
.m_bTopMargin
)
968 aULSpace
.SetUpper( rNewULSpace
.GetUpper() );
969 if( rSrcInfo
.m_bBottomMargin
)
970 aULSpace
.SetLower( rNewULSpace
.GetLower() );
972 rTargetSet
.Put( aULSpace
);
976 rTargetInfo
.Merge( rSrcInfo
);
979 void SvxCSS1Parser::SetDfltEncoding( rtl_TextEncoding eEnc
)
981 m_eDefaultEnc
= eEnc
;
984 static void ParseCSS1_font_size( const CSS1Expression
*pExpr
,
985 SfxItemSet
&rItemSet
,
986 SvxCSS1PropertyInfo
& /*rPropInfo*/,
987 const SvxCSS1Parser
& rParser
)
989 OSL_ENSURE( pExpr
, "no expression" );
991 sal_uLong nHeight
= 0;
992 sal_uInt16 nPropHeight
= 100;
994 switch( pExpr
->GetType() )
997 nHeight
= pExpr
->GetULength();
1001 double fHeight
= pExpr
->GetNumber();
1002 if (fHeight
< SAL_MAX_INT32
/2.0 && fHeight
> SAL_MIN_INT32
/2.0)
1004 tools::Long nPHeight
= static_cast<tools::Long
>(fHeight
);
1005 tools::Long nPWidth
= 0;
1006 SvxCSS1Parser::PixelToTwip(nPWidth
, nPHeight
);
1007 nHeight
= static_cast<sal_uLong
>(nPHeight
);
1011 SAL_WARN("sw.html", "out-of-size pxlength: " << fHeight
);
1015 case CSS1_PERCENTAGE
:
1016 // only for drop caps!
1017 nPropHeight
= o3tl::narrowing
<sal_uInt16
>(pExpr
->GetNumber());
1023 if( SvxCSS1Parser::GetEnum( aFontSizeTable
, pExpr
->GetString(),
1026 nHeight
= rParser
.GetFontHeight( nSize
);
1035 if( nHeight
|| nPropHeight
!=100 )
1037 SvxFontHeightItem
aFontHeight( nHeight
, nPropHeight
,
1038 aItemIds
.nFontHeight
);
1039 rItemSet
.Put( aFontHeight
);
1040 aFontHeight
.SetWhich( aItemIds
.nFontHeightCJK
);
1041 rItemSet
.Put( aFontHeight
);
1042 aFontHeight
.SetWhich( aItemIds
.nFontHeightCTL
);
1043 rItemSet
.Put( aFontHeight
);
1047 static void ParseCSS1_font_family( const CSS1Expression
*pExpr
,
1048 SfxItemSet
&rItemSet
,
1049 SvxCSS1PropertyInfo
& /*rPropInfo*/,
1050 const SvxCSS1Parser
& rParser
)
1052 OSL_ENSURE( pExpr
, "no expression" );
1054 OUStringBuffer aName
;
1055 rtl_TextEncoding eEnc
= rParser
.GetDfltEncoding();
1056 const FontList
*pFList
= rParser
.GetFontList();
1058 bool bFound
= false;
1059 while( pExpr
&& (bFirst
|| ','==pExpr
->GetOp() || !pExpr
->GetOp()) )
1061 CSS1Token eType
= pExpr
->GetType();
1062 if( CSS1_IDENT
==eType
|| CSS1_STRING
==eType
)
1064 OUString
aIdent( pExpr
->GetString() );
1066 if( CSS1_IDENT
==eType
)
1068 // Collect all following IDs and append them with a space
1069 const CSS1Expression
*pNext
= pExpr
->GetNext();
1070 while( pNext
&& !pNext
->GetOp() &&
1071 CSS1_IDENT
==pNext
->GetType() )
1073 aIdent
+= " " + pNext
->GetString();
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() )
1089 if( RTL_TEXTENCODING_SYMBOL
== rFMetric
.GetCharSet() )
1090 eEnc
= RTL_TEXTENCODING_SYMBOL
;
1096 aName
.append(aIdent
);
1100 pExpr
= pExpr
->GetNext();
1104 if( !aName
.isEmpty() && !rParser
.IsIgnoreFontFamily() )
1106 SvxFontItem
aFont( FAMILY_DONTKNOW
, aName
.makeStringAndClear(), OUString(), PITCH_DONTKNOW
,
1107 eEnc
, aItemIds
.nFont
);
1108 rItemSet
.Put( aFont
);
1109 aFont
.SetWhich( aItemIds
.nFontCJK
);
1110 rItemSet
.Put( aFont
);
1111 aFont
.SetWhich( aItemIds
.nFontCTL
);
1112 rItemSet
.Put( aFont
);
1116 static void ParseCSS1_font_weight( const CSS1Expression
*pExpr
,
1117 SfxItemSet
&rItemSet
,
1118 SvxCSS1PropertyInfo
& /*rPropInfo*/,
1119 const SvxCSS1Parser
& /*rParser*/ )
1121 OSL_ENSURE( pExpr
, "no expression" );
1123 switch( pExpr
->GetType() )
1126 case CSS1_STRING
: // MS-IE, what else
1129 if( SvxCSS1Parser::GetEnum( aFontWeightTable
, pExpr
->GetString(),
1132 SvxWeightItem
aWeight( static_cast<FontWeight
>(nWeight
), aItemIds
.nWeight
);
1133 rItemSet
.Put( aWeight
);
1134 aWeight
.SetWhich( aItemIds
.nWeightCJK
);
1135 rItemSet
.Put( aWeight
);
1136 aWeight
.SetWhich( aItemIds
.nWeightCTL
);
1137 rItemSet
.Put( aWeight
);
1143 sal_uInt16 nWeight
= o3tl::narrowing
<sal_uInt16
>(pExpr
->GetNumber());
1144 SvxWeightItem
aWeight( nWeight
>400 ? WEIGHT_BOLD
: WEIGHT_NORMAL
,
1146 rItemSet
.Put( aWeight
);
1147 aWeight
.SetWhich( aItemIds
.nWeightCJK
);
1148 rItemSet
.Put( aWeight
);
1149 aWeight
.SetWhich( aItemIds
.nWeightCTL
);
1150 rItemSet
.Put( aWeight
);
1159 static void ParseCSS1_font_style( const CSS1Expression
*pExpr
,
1160 SfxItemSet
&rItemSet
,
1161 SvxCSS1PropertyInfo
& /*rPropInfo*/,
1162 const SvxCSS1Parser
& /*rParser*/ )
1164 OSL_ENSURE( pExpr
, "no expression" );
1166 bool bPosture
= false;
1167 bool bCaseMap
= false;
1168 FontItalic eItalic
= ITALIC_NONE
;
1169 SvxCaseMap eCaseMap
= SvxCaseMap::NotMapped
;
1171 // normal | italic || small-caps | oblique || small-caps | small-caps
1172 // (only normal, italic and oblique are valid)
1174 // the value can have two values!
1175 for( int i
=0; pExpr
&& i
<2; ++i
)
1177 // also here MS-IE parser leaves traces
1178 if( (CSS1_IDENT
==pExpr
->GetType() || CSS1_STRING
==pExpr
->GetType()) &&
1181 const OUString
& rValue
= pExpr
->GetString();
1182 // first check if the value is italic or 'normal'
1184 if( SvxCSS1Parser::GetEnum( aFontStyleTable
, rValue
, nItalic
) )
1186 eItalic
= static_cast<FontItalic
>(nItalic
);
1187 if( !bCaseMap
&& ITALIC_NONE
==eItalic
)
1189 // for 'normal' we must also exclude case-map
1190 eCaseMap
= SvxCaseMap::NotMapped
;
1195 else if( !bCaseMap
&&
1196 rValue
.equalsIgnoreAsciiCase( "small-caps" ) )
1198 eCaseMap
= SvxCaseMap::SmallCaps
;
1203 // fetch next expression
1204 pExpr
= pExpr
->GetNext();
1209 SvxPostureItem
aPosture( eItalic
, aItemIds
.nPosture
);
1210 rItemSet
.Put( aPosture
);
1211 aPosture
.SetWhich( aItemIds
.nPostureCJK
);
1212 rItemSet
.Put( aPosture
);
1213 aPosture
.SetWhich( aItemIds
.nPostureCTL
);
1214 rItemSet
.Put( aPosture
);
1218 rItemSet
.Put( SvxCaseMapItem( eCaseMap
, aItemIds
.nCaseMap
) );
1221 static void ParseCSS1_font_variant( const CSS1Expression
*pExpr
,
1222 SfxItemSet
&rItemSet
,
1223 SvxCSS1PropertyInfo
& /*rPropInfo*/,
1224 const SvxCSS1Parser
& /*rParser*/ )
1226 assert(pExpr
&& "no expression");
1228 // normal | small-caps
1229 switch( pExpr
->GetType() )
1233 sal_uInt16 nCaseMap
;
1234 if( SvxCSS1Parser::GetEnum( aFontVariantTable
, pExpr
->GetString(),
1237 rItemSet
.Put( SvxCaseMapItem( static_cast<SvxCaseMap
>(nCaseMap
),
1238 aItemIds
.nCaseMap
) );
1247 static void ParseCSS1_text_transform( const CSS1Expression
*pExpr
,
1248 SfxItemSet
&rItemSet
,
1249 SvxCSS1PropertyInfo
& /*rPropInfo*/,
1250 const SvxCSS1Parser
& /*rParser*/ )
1252 OSL_ENSURE( pExpr
, "no expression" );
1254 // none | capitalize | uppercase | lowercase
1256 switch( pExpr
->GetType() )
1260 sal_uInt16 nCaseMap
;
1261 if( SvxCSS1Parser::GetEnum( aTextTransformTable
, pExpr
->GetString(),
1264 rItemSet
.Put( SvxCaseMapItem( static_cast<SvxCaseMap
>(nCaseMap
),
1265 aItemIds
.nCaseMap
) );
1274 static void ParseCSS1_color( const CSS1Expression
*pExpr
,
1275 SfxItemSet
&rItemSet
,
1276 SvxCSS1PropertyInfo
& /*rPropInfo*/,
1277 const SvxCSS1Parser
& /*rParser*/ )
1279 OSL_ENSURE( pExpr
, "no expression" );
1281 switch( pExpr
->GetType() )
1286 case CSS1_STRING
: // because MS-IE
1289 if( pExpr
->GetColor( aColor
) )
1290 rItemSet
.Put( SvxColorItem( aColor
, aItemIds
.nColor
) );
1298 static void ParseCSS1_column_count( const CSS1Expression
*pExpr
,
1299 SfxItemSet
& /*rItemSet*/,
1300 SvxCSS1PropertyInfo
&rPropInfo
,
1301 const SvxCSS1Parser
& /*rParser*/ )
1303 assert(pExpr
&& "no expression");
1305 if ( pExpr
->GetType() == CSS1_NUMBER
)
1307 double columnCount
= pExpr
->GetNumber();
1308 if ( columnCount
>= 2 )
1310 rPropInfo
.m_nColumnCount
= columnCount
;
1315 static void ParseCSS1_direction( const CSS1Expression
*pExpr
,
1316 SfxItemSet
&rItemSet
,
1317 SvxCSS1PropertyInfo
& /*rPropInfo*/,
1318 const SvxCSS1Parser
& /*rParser*/ )
1320 assert(pExpr
&& "no expression");
1323 switch( pExpr
->GetType() )
1327 if( SvxCSS1Parser::GetEnum( aDirectionTable
, pExpr
->GetString(),
1330 rItemSet
.Put( SvxFrameDirectionItem(
1331 static_cast < SvxFrameDirection
>( nDir
),
1332 aItemIds
.nDirection
) );
1340 static void MergeHori( SvxGraphicPosition
& ePos
, SvxGraphicPosition eHori
)
1342 OSL_ENSURE( GPOS_LT
==eHori
|| GPOS_MT
==eHori
|| GPOS_RT
==eHori
,
1343 "vertical position not at the top" );
1356 ePos
= GPOS_LT
==eHori
? GPOS_LM
: (GPOS_MT
==eHori
? GPOS_MM
: GPOS_RM
);
1362 ePos
= GPOS_LT
==eHori
? GPOS_LB
: (GPOS_MT
==eHori
? GPOS_MB
: GPOS_RB
);
1370 static void MergeVert( SvxGraphicPosition
& ePos
, SvxGraphicPosition eVert
)
1372 OSL_ENSURE( GPOS_LT
==eVert
|| GPOS_LM
==eVert
|| GPOS_LB
==eVert
,
1373 "horizontal position not on the left side" );
1386 ePos
= GPOS_LT
==eVert
? GPOS_MT
: (GPOS_LM
==eVert
? GPOS_MM
: GPOS_MB
);
1392 ePos
= GPOS_LT
==eVert
? GPOS_RT
: (GPOS_LM
==eVert
? GPOS_RM
: GPOS_RB
);
1400 static void ParseCSS1_background( const CSS1Expression
*pExpr
,
1401 SfxItemSet
&rItemSet
,
1402 SvxCSS1PropertyInfo
& /*rPropInfo*/,
1403 const SvxCSS1Parser
& rParser
)
1405 OSL_ENSURE( pExpr
, "no expression" );
1410 bool bColor
= false, bTransparent
= false;
1411 SvxGraphicPosition eRepeat
= GPOS_TILED
;
1412 SvxGraphicPosition ePos
= GPOS_LT
;
1413 bool bHori
= false, bVert
= false;
1415 while( pExpr
&& !pExpr
->GetOp() )
1417 switch( pExpr
->GetType() )
1420 pExpr
->GetURL( aURL
);
1424 bColor
= pExpr
->GetColor( aColor
);
1428 case CSS1_PIXLENGTH
:
1430 // since we don't know any absolute position, we
1431 // only distinguish between 0 and !0. Therefore pixel
1432 // can be handled like all other units.
1434 bool nonZero
= std::trunc(pExpr
->GetNumber()) != 0.0;
1437 ePos
= nonZero
? GPOS_MM
: GPOS_LT
;
1442 MergeVert( ePos
, (nonZero
? GPOS_LM
: GPOS_LT
) );
1448 case CSS1_PERCENTAGE
:
1450 // the percentage is converted to an enum
1452 sal_uInt16 nPerc
= o3tl::narrowing
<sal_uInt16
>(pExpr
->GetNumber());
1455 ePos
= nPerc
< 25 ? GPOS_LT
1456 : (nPerc
< 75 ? GPOS_MM
1461 SvxGraphicPosition eVert
=
1462 nPerc
< 25 ? GPOS_LT
: (nPerc
< 75 ? GPOS_LM
1464 MergeVert( ePos
, eVert
);
1471 case CSS1_STRING
: // because of MS-IE
1474 const OUString
&rValue
= pExpr
->GetString();
1475 if( rValue
.equalsIgnoreAsciiCase( "transparent" ) )
1477 bTransparent
= true;
1479 if( SvxCSS1Parser::GetEnum( aBGRepeatTable
, rValue
, nEnum
) )
1481 eRepeat
= static_cast<SvxGraphicPosition
>(nEnum
);
1483 else if( SvxCSS1Parser::GetEnum( aBGHoriPosTable
, rValue
, nEnum
) )
1485 // <position>, horizontal
1486 MergeHori( ePos
, static_cast<SvxGraphicPosition
>(nEnum
) );
1488 else if( SvxCSS1Parser::GetEnum( aBGVertPosTable
, rValue
, nEnum
) )
1490 // <position>, vertical
1491 MergeVert( ePos
, static_cast<SvxGraphicPosition
>(nEnum
) );
1496 bColor
= pExpr
->GetColor( aColor
);
1498 // <scroll> we don't know
1506 pExpr
= pExpr
->GetNext();
1509 // transparent beats everything
1516 // repeat has priority over a position
1517 if( GPOS_NONE
== eRepeat
)
1520 if( !bTransparent
&& !bColor
&& aURL
.isEmpty() )
1523 SvxBrushItem
aBrushItem( aItemIds
.nBrush
);
1526 aBrushItem
.SetColor( COL_TRANSPARENT
);
1528 aBrushItem
.SetColor( aColor
);
1530 if( !aURL
.isEmpty() )
1532 aBrushItem
.SetGraphicLink( URIHelper::SmartRel2Abs( INetURLObject( rParser
.GetBaseURL()), aURL
, Link
<OUString
*, bool>(), false ) );
1533 aBrushItem
.SetGraphicPos( eRepeat
);
1536 rItemSet
.Put( aBrushItem
);
1539 static void ParseCSS1_background_color( const CSS1Expression
*pExpr
,
1540 SfxItemSet
&rItemSet
,
1541 SvxCSS1PropertyInfo
& /*rPropInfo*/,
1542 const SvxCSS1Parser
& /*rParser*/ )
1544 OSL_ENSURE( pExpr
, "no expression" );
1548 bool bColor
= false, bTransparent
= false;
1550 switch( pExpr
->GetType() )
1553 bColor
= pExpr
->GetColor( aColor
);
1557 case CSS1_STRING
: // because of MS-IE
1558 if( pExpr
->GetString().equalsIgnoreAsciiCase( "transparent" ) )
1560 bTransparent
= true;
1565 bColor
= pExpr
->GetColor( aColor
);
1572 if( bTransparent
|| bColor
)
1574 SvxBrushItem
aBrushItem( aItemIds
.nBrush
);
1577 aBrushItem
.SetColor( COL_TRANSPARENT
);
1579 aBrushItem
.SetColor( aColor
);
1581 rItemSet
.Put( aBrushItem
);
1585 static void ParseCSS1_line_height( const CSS1Expression
*pExpr
,
1586 SfxItemSet
&rItemSet
,
1587 SvxCSS1PropertyInfo
& /*rPropInfo*/,
1588 const SvxCSS1Parser
& )
1590 OSL_ENSURE( pExpr
, "no expression" );
1592 sal_uInt16 nHeight
= 0;
1593 sal_uInt16 nPropHeight
= 0;
1595 switch( pExpr
->GetType() )
1598 nHeight
= o3tl::narrowing
<sal_uInt16
>(pExpr
->GetULength());
1600 case CSS1_PIXLENGTH
:
1602 double fHeight
= pExpr
->GetNumber();
1603 if (fHeight
< SAL_MAX_INT32
/2.0 && fHeight
> SAL_MIN_INT32
/2.0)
1605 tools::Long nPHeight
= static_cast<tools::Long
>(fHeight
);
1606 tools::Long nPWidth
= 0;
1607 SvxCSS1Parser::PixelToTwip(nPWidth
, nPHeight
);
1608 nHeight
= o3tl::narrowing
<sal_uInt16
>(nPHeight
);
1612 case CSS1_PERCENTAGE
:
1614 nPropHeight
= o3tl::narrowing
<sal_uInt16
>(pExpr
->GetNumber());
1619 nPropHeight
= o3tl::narrowing
<sal_uInt16
>(pExpr
->GetNumber() * 100);
1628 if( nHeight
< SvxCSS1Parser::GetMinFixLineSpace() )
1629 nHeight
= SvxCSS1Parser::GetMinFixLineSpace();
1630 SvxLineSpacingItem
aLSItem( nHeight
, aItemIds
.nLineSpacing
);
1631 aLSItem
.SetLineHeight( nHeight
);
1632 // interpret <line-height> attribute as minimum line height
1633 aLSItem
.SetLineSpaceRule( SvxLineSpaceRule::Min
);
1634 aLSItem
.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off
);
1635 rItemSet
.Put( aLSItem
);
1637 else if( nPropHeight
)
1639 SvxLineSpacingItem
aLSItem( nPropHeight
, aItemIds
.nLineSpacing
);
1640 aLSItem
.SetLineSpaceRule( SvxLineSpaceRule::Auto
);
1641 if( 100 == nPropHeight
)
1642 aLSItem
.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off
);
1644 aLSItem
.SetPropLineSpace( nPropHeight
);
1645 rItemSet
.Put( aLSItem
);
1650 static void ParseCSS1_list_style_type( const CSS1Expression
*pExpr
,
1651 SfxItemSet
& /*rItemSet*/,
1652 SvxCSS1PropertyInfo
& rPropInfo
,
1653 const SvxCSS1Parser
& /*rParser*/ )
1655 OSL_ENSURE( pExpr
, "no expression" );
1657 if( pExpr
->GetType() != CSS1_IDENT
)
1660 const OUString
& rValue
= pExpr
->GetString();
1662 // values are context-dependent, so fill both
1664 if( SvxCSS1Parser::GetEnum( aNumberStyleTable
, rValue
, nEnum
) )
1666 rPropInfo
.m_bNumbering
= true;
1667 rPropInfo
.m_nNumberingType
= static_cast<SvxNumType
>(nEnum
);
1669 if( SvxCSS1Parser::GetEnum( aBulletStyleTable
, rValue
, nEnum
) )
1671 rPropInfo
.m_bBullet
= true;
1672 rPropInfo
.m_cBulletChar
= nEnum
;
1676 static void ParseCSS1_font( const CSS1Expression
*pExpr
,
1677 SfxItemSet
&rItemSet
,
1678 SvxCSS1PropertyInfo
& rPropInfo
,
1679 const SvxCSS1Parser
& rParser
)
1681 OSL_ENSURE( pExpr
, "no expression" );
1683 FontItalic eItalic
= ITALIC_NONE
;
1684 SvxCaseMap eCaseMap
= SvxCaseMap::NotMapped
;
1685 FontWeight eWeight
= WEIGHT_NORMAL
;
1687 // [ <font-style> || <font-variant> || <font-weight> ] ?
1688 while( pExpr
&& !pExpr
->GetOp() &&
1689 (CSS1_IDENT
==pExpr
->GetType() ||
1690 CSS1_STRING
==pExpr
->GetType() ||
1691 CSS1_NUMBER
==pExpr
->GetType()) )
1693 if( CSS1_IDENT
==pExpr
->GetType() ||
1694 CSS1_STRING
==pExpr
->GetType() )
1696 const OUString
& rValue
= pExpr
->GetString();
1700 if( SvxCSS1Parser::GetEnum( aFontStyleTable
, rValue
, nEnum
) )
1702 eItalic
= static_cast<FontItalic
>(nEnum
);
1704 else if( SvxCSS1Parser::GetEnum( aFontVariantTable
, rValue
, nEnum
) )
1706 eCaseMap
= static_cast<SvxCaseMap
>(nEnum
);
1708 else if( SvxCSS1Parser::GetEnum( aFontWeightTable
, rValue
, nEnum
) )
1710 eWeight
= static_cast<FontWeight
>(nEnum
);
1715 eWeight
= o3tl::narrowing
<sal_uInt16
>(pExpr
->GetNumber()) > 400 ? WEIGHT_BOLD
1719 pExpr
= pExpr
->GetNext();
1722 if( !pExpr
|| pExpr
->GetOp() )
1725 // Since "font" resets all values for which nothing is specified,
1727 SvxPostureItem
aPosture( eItalic
, aItemIds
.nPosture
);
1728 rItemSet
.Put( aPosture
);
1729 aPosture
.SetWhich( aItemIds
.nPostureCJK
);
1730 rItemSet
.Put( aPosture
);
1731 aPosture
.SetWhich( aItemIds
.nPostureCTL
);
1732 rItemSet
.Put( aPosture
);
1734 rItemSet
.Put( SvxCaseMapItem( eCaseMap
, aItemIds
.nCaseMap
) );
1736 SvxWeightItem
aWeight( eWeight
, aItemIds
.nWeight
);
1737 rItemSet
.Put( aWeight
);
1738 aWeight
.SetWhich( aItemIds
.nWeightCJK
);
1739 rItemSet
.Put( aWeight
);
1740 aWeight
.SetWhich( aItemIds
.nWeightCTL
);
1741 rItemSet
.Put( aWeight
);
1744 CSS1Expression
aExpr( pExpr
->GetType(), pExpr
->GetString(),
1745 pExpr
->GetNumber() );
1746 ParseCSS1_font_size( &aExpr
, rItemSet
, rPropInfo
, rParser
);
1747 pExpr
= pExpr
->GetNext();
1752 // [ '/' line-height ]?
1753 if( '/' == pExpr
->GetOp() )
1756 aExpr
.Set( pExpr
->GetType(), pExpr
->GetString(), pExpr
->GetNumber() );
1757 ParseCSS1_line_height( &aExpr
, rItemSet
, rPropInfo
, rParser
);
1759 pExpr
= pExpr
->GetNext();
1762 if( !pExpr
|| pExpr
->GetOp() )
1766 ParseCSS1_font_family( pExpr
, rItemSet
, rPropInfo
, rParser
);
1769 static void ParseCSS1_letter_spacing( const CSS1Expression
*pExpr
,
1770 SfxItemSet
&rItemSet
,
1771 SvxCSS1PropertyInfo
& /*rPropInfo*/,
1772 const SvxCSS1Parser
& /*rParser*/ )
1774 OSL_ENSURE( pExpr
, "no expression" );
1776 switch( pExpr
->GetType() )
1779 rItemSet
.Put( SvxKerningItem( static_cast<short>(pExpr
->GetSLength()),
1780 aItemIds
.nKerning
) );
1783 case CSS1_PIXLENGTH
:
1785 double fHeight
= pExpr
->GetNumber();
1786 if (fHeight
< SAL_MAX_INT32
/2.0 && fHeight
> SAL_MIN_INT32
/2.0)
1788 tools::Long nPWidth
= static_cast<tools::Long
>(fHeight
);
1789 tools::Long nPHeight
= 0;
1790 SvxCSS1Parser::PixelToTwip( nPWidth
, nPHeight
);
1791 rItemSet
.Put( SvxKerningItem( static_cast<short>(nPWidth
), aItemIds
.nKerning
) );
1797 if( pExpr
->GetNumber() == 0 )
1799 // normally unnecessary, but we are tolerant
1800 rItemSet
.Put( SvxKerningItem( short(0), aItemIds
.nKerning
) );
1805 case CSS1_STRING
: // As a precaution also MS-IE
1806 if( pExpr
->GetString().equalsIgnoreAsciiCase( "normal" ) )
1808 rItemSet
.Put( SvxKerningItem( short(0), aItemIds
.nKerning
) );
1816 static void ParseCSS1_text_decoration( const CSS1Expression
*pExpr
,
1817 SfxItemSet
&rItemSet
,
1818 SvxCSS1PropertyInfo
& /*rPropInfo*/,
1819 const SvxCSS1Parser
& /*rParser*/ )
1821 OSL_ENSURE( pExpr
, "no expression" );
1823 bool bUnderline
= false;
1824 bool bOverline
= false;
1825 bool bCrossedOut
= false;
1826 bool bBlink
= false;
1827 bool bBlinkOn
= false;
1828 FontLineStyle eUnderline
= LINESTYLE_NONE
;
1829 FontLineStyle eOverline
= LINESTYLE_NONE
;
1830 FontStrikeout eCrossedOut
= STRIKEOUT_NONE
;
1832 // the value can contain two values! And MS-IE also strings
1833 while( pExpr
&& (pExpr
->GetType() == CSS1_IDENT
||
1834 pExpr
->GetType() == CSS1_STRING
) && !pExpr
->GetOp() )
1836 OUString aValue
= pExpr
->GetString().toAsciiLowerCase();
1837 bool bKnown
= false;
1842 if( aValue
== "none" )
1845 eUnderline
= LINESTYLE_NONE
;
1848 eOverline
= LINESTYLE_NONE
;
1851 eCrossedOut
= STRIKEOUT_NONE
;
1861 if( aValue
== "underline" )
1864 eUnderline
= LINESTYLE_SINGLE
;
1871 if( aValue
== "overline" )
1874 eOverline
= LINESTYLE_SINGLE
;
1881 if( aValue
== "line-through" )
1884 eCrossedOut
= STRIKEOUT_SINGLE
;
1891 if( aValue
== "blink" )
1904 eUnderline
= LINESTYLE_SINGLE
;
1907 pExpr
= pExpr
->GetNext();
1911 rItemSet
.Put( SvxUnderlineItem( eUnderline
, aItemIds
.nUnderline
) );
1914 rItemSet
.Put( SvxOverlineItem( eOverline
, aItemIds
.nOverline
) );
1917 rItemSet
.Put( SvxCrossedOutItem( eCrossedOut
, aItemIds
.nCrossedOut
) );
1920 rItemSet
.Put( SvxBlinkItem( bBlinkOn
, aItemIds
.nBlink
) );
1923 static void ParseCSS1_text_align( const CSS1Expression
*pExpr
,
1924 SfxItemSet
&rItemSet
,
1925 SvxCSS1PropertyInfo
& /*rPropInfo*/,
1926 const SvxCSS1Parser
& /*rParser*/ )
1928 OSL_ENSURE( pExpr
, "no expression" );
1930 if( CSS1_IDENT
==pExpr
->GetType() ||
1931 CSS1_STRING
==pExpr
->GetType() ) // MS-IE, again
1934 if( SvxCSS1Parser::GetEnum( aTextAlignTable
, pExpr
->GetString(),
1937 rItemSet
.Put( SvxAdjustItem( static_cast<SvxAdjust
>(nAdjust
),
1938 aItemIds
.nAdjust
) );
1943 static void ParseCSS1_text_indent( const CSS1Expression
*pExpr
,
1944 SfxItemSet
&rItemSet
,
1945 SvxCSS1PropertyInfo
& rPropInfo
,
1946 const SvxCSS1Parser
& /*rParser*/ )
1948 OSL_ENSURE( pExpr
, "no expression" );
1952 switch( pExpr
->GetType() )
1956 double n
= std::round(pExpr
->GetNumber());
1958 n
< std::numeric_limits
<short>::min() || n
> std::numeric_limits
<short>::max(),
1959 "sw.html", "clamping length " << n
<< " to short range");
1960 nIndent
= static_cast<short>(
1962 n
, double(std::numeric_limits
<short>::min()),
1963 double(std::numeric_limits
<short>::max())));
1967 case CSS1_PIXLENGTH
:
1969 double fWidth
= pExpr
->GetNumber();
1970 if (fWidth
< SAL_MAX_INT32
/2.0 && fWidth
> SAL_MIN_INT32
/2.0)
1972 tools::Long nPWidth
= static_cast<tools::Long
>(fWidth
);
1973 tools::Long nPHeight
= 0;
1974 SvxCSS1Parser::PixelToTwip( nPWidth
, nPHeight
);
1975 nIndent
= static_cast<short>(nPWidth
);
1980 case CSS1_PERCENTAGE
:
1990 SvxFirstLineIndentItem
const firstLine(nIndent
, RES_MARGIN_FIRSTLINE
);
1991 rItemSet
.Put(firstLine
);
1992 rPropInfo
.m_bTextIndent
= true;
1995 static void ParseCSS1_margin_left( const CSS1Expression
*pExpr
,
1996 SfxItemSet
&rItemSet
,
1997 SvxCSS1PropertyInfo
& rPropInfo
,
1998 const SvxCSS1Parser
& /*rParser*/ )
2000 OSL_ENSURE( pExpr
, "no expression" );
2002 tools::Long nLeft
= 0;
2004 switch( pExpr
->GetType() )
2008 nLeft
= pExpr
->GetSLength();
2012 case CSS1_PIXLENGTH
:
2014 double fLeft
= pExpr
->GetNumber();
2015 if (fLeft
< SAL_MAX_INT32
/2.0 && fLeft
> SAL_MIN_INT32
/2.0)
2017 nLeft
= static_cast<tools::Long
>(fLeft
);
2018 tools::Long nPHeight
= 0;
2019 SvxCSS1Parser::PixelToTwip( nLeft
, nPHeight
);
2024 SAL_WARN("sw.html", "out-of-size pxlength: " << fLeft
);
2028 case CSS1_PERCENTAGE
:
2035 if (pExpr
->GetString() == "auto")
2037 rPropInfo
.m_bLeftMargin
= true;
2038 rPropInfo
.m_eLeftMarginType
= SVX_CSS1_LTYPE_AUTO
;
2044 rPropInfo
.m_nLeftMargin
= nLeft
;
2048 // TODO: other things may need a SvxLeftMarginItem ? but they currently convert it anyway so they can convert that too.
2049 SvxTextLeftMarginItem
const leftMargin(o3tl::narrowing
<sal_uInt16
>(nLeft
), RES_MARGIN_TEXTLEFT
);
2050 rItemSet
.Put(leftMargin
);
2051 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 tools::Long nRight
= 0;
2063 switch( pExpr
->GetType() )
2067 nRight
= pExpr
->GetSLength();
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<tools::Long
>(fRight
);
2077 tools::Long nPHeight
= 0;
2078 SvxCSS1Parser::PixelToTwip( nRight
, nPHeight
);
2083 case CSS1_PERCENTAGE
:
2090 if (pExpr
->GetString() == "auto")
2092 rPropInfo
.m_bRightMargin
= true;
2093 rPropInfo
.m_eRightMarginType
= SVX_CSS1_LTYPE_AUTO
;
2099 rPropInfo
.m_nRightMargin
= nRight
;
2103 SvxRightMarginItem
rightMargin(o3tl::narrowing
<sal_uInt16
>(nRight
), RES_MARGIN_RIGHT
);
2104 rItemSet
.Put(rightMargin
);
2105 rPropInfo
.m_bRightMargin
= true;
2108 static void ParseCSS1_margin_top( const CSS1Expression
*pExpr
,
2109 SfxItemSet
&rItemSet
,
2110 SvxCSS1PropertyInfo
& rPropInfo
,
2111 const SvxCSS1Parser
& /*rParser*/ )
2113 assert(pExpr
&& "no expression");
2115 sal_uInt16 nUpper
= 0;
2117 switch( pExpr
->GetType() )
2121 tools::Long nTmp
= pExpr
->GetSLength();
2124 nUpper
= o3tl::narrowing
<sal_uInt16
>(nTmp
);
2128 case CSS1_PIXLENGTH
:
2130 double fHeight
= pExpr
->GetNumber();
2131 if (fHeight
< SAL_MAX_INT32
/2.0 && fHeight
> SAL_MIN_INT32
/2.0)
2133 tools::Long nPWidth
= 0;
2134 tools::Long nPHeight
= static_cast<tools::Long
>(fHeight
);
2137 SvxCSS1Parser::PixelToTwip( nPWidth
, nPHeight
);
2138 nUpper
= o3tl::narrowing
<sal_uInt16
>(nPHeight
);
2143 case CSS1_PERCENTAGE
:
2153 if( const SvxULSpaceItem
* pItem
= rItemSet
.GetItemIfSet( aItemIds
.nULSpace
, false ) )
2155 SvxULSpaceItem
aULItem( *pItem
);
2156 aULItem
.SetUpper( nUpper
);
2157 rItemSet
.Put( aULItem
);
2161 SvxULSpaceItem
aULItem( aItemIds
.nULSpace
);
2162 aULItem
.SetUpper( nUpper
);
2163 rItemSet
.Put( aULItem
);
2165 rPropInfo
.m_bTopMargin
= true;
2168 static void ParseCSS1_margin_bottom( const CSS1Expression
*pExpr
,
2169 SfxItemSet
&rItemSet
,
2170 SvxCSS1PropertyInfo
& rPropInfo
,
2171 const SvxCSS1Parser
& /*rParser*/ )
2173 OSL_ENSURE( pExpr
, "no expression" );
2175 sal_uInt16 nLower
= 0;
2177 switch( pExpr
->GetType() )
2181 tools::Long nTmp
= pExpr
->GetSLength();
2184 nLower
= o3tl::narrowing
<sal_uInt16
>(nTmp
);
2188 case CSS1_PIXLENGTH
:
2190 double fHeight
= pExpr
->GetNumber();
2191 if (fHeight
< SAL_MAX_INT32
/2.0 && fHeight
> SAL_MIN_INT32
/2.0)
2193 tools::Long nPWidth
= 0;
2194 tools::Long nPHeight
= static_cast<tools::Long
>(fHeight
);
2197 SvxCSS1Parser::PixelToTwip( nPWidth
, nPHeight
);
2198 nLower
= o3tl::narrowing
<sal_uInt16
>(nPHeight
);
2203 case CSS1_PERCENTAGE
:
2213 if( const SvxULSpaceItem
* pItem
= rItemSet
.GetItemIfSet( aItemIds
.nULSpace
, false ) )
2215 SvxULSpaceItem
aULItem( *pItem
);
2216 aULItem
.SetLower( nLower
);
2217 rItemSet
.Put( aULItem
);
2221 SvxULSpaceItem
aULItem( aItemIds
.nULSpace
);
2222 aULItem
.SetLower( nLower
);
2223 rItemSet
.Put( aULItem
);
2225 rPropInfo
.m_bBottomMargin
= true;
2228 static void ParseCSS1_margin( const CSS1Expression
*pExpr
,
2229 SfxItemSet
&rItemSet
,
2230 SvxCSS1PropertyInfo
& rPropInfo
,
2231 const SvxCSS1Parser
& /*rParser*/ )
2233 OSL_ENSURE( pExpr
, "no expression" );
2235 tools::Long nMargins
[4] = { 0, 0, 0, 0 };
2236 bool bSetMargins
[4] = { false, false, false, false };
2238 for( int i
=0; pExpr
&& i
<4 && !pExpr
->GetOp(); ++i
)
2240 bool bSetThis
= false;
2241 tools::Long nMargin
= 0;
2243 switch( pExpr
->GetType() )
2247 nMargin
= pExpr
->GetSLength();
2251 case CSS1_PIXLENGTH
:
2253 double fMargin
= pExpr
->GetNumber();
2254 if (fMargin
< SAL_MAX_INT32
/2.0 && fMargin
> SAL_MIN_INT32
/2.0)
2256 nMargin
= static_cast<tools::Long
>(fMargin
);
2257 tools::Long nPWidth
= 0;
2258 SvxCSS1Parser::PixelToTwip( nPWidth
, nMargin
);
2263 SAL_WARN("sw.html", "out-of-size pxlength: " << fMargin
);
2267 case CSS1_PERCENTAGE
:
2283 nMargins
[0] = nMargins
[1] =nMargins
[2] = nMargins
[3] = nMargin
;
2284 bSetMargins
[0] = bSetMargins
[1] =
2285 bSetMargins
[2] = bSetMargins
[3] = true;
2288 nMargins
[1] = nMargins
[3] = nMargin
; // right + left
2289 bSetMargins
[1] = bSetMargins
[3] = true;
2292 nMargins
[2] = nMargin
; // bottom
2293 bSetMargins
[2] = true;
2296 nMargins
[3] = nMargin
; // left
2297 bSetMargins
[3] = true;
2301 pExpr
= pExpr
->GetNext();
2304 if( bSetMargins
[3] || bSetMargins
[1] )
2306 if( bSetMargins
[3] )
2308 rPropInfo
.m_bLeftMargin
= true;
2309 rPropInfo
.m_nLeftMargin
= nMargins
[3];
2310 if( nMargins
[3] < 0 )
2313 if( bSetMargins
[1] )
2315 rPropInfo
.m_bRightMargin
= true;
2316 rPropInfo
.m_nRightMargin
= nMargins
[1];
2317 if( nMargins
[1] < 0 )
2323 SvxTextLeftMarginItem
const leftMargin(o3tl::narrowing
<sal_uInt16
>(nMargins
[3]), RES_MARGIN_TEXTLEFT
);
2324 rItemSet
.Put(leftMargin
);
2328 SvxRightMarginItem
const rightMargin(o3tl::narrowing
<sal_uInt16
>(nMargins
[1]), RES_MARGIN_RIGHT
);
2329 rItemSet
.Put(rightMargin
);
2333 if( !(bSetMargins
[0] || bSetMargins
[2]) )
2336 if( nMargins
[0] < 0 )
2338 if( nMargins
[2] < 0 )
2341 if( const SvxULSpaceItem
* pItem
= rItemSet
.GetItemIfSet( aItemIds
.nULSpace
, false ) )
2343 SvxULSpaceItem
aULItem( *pItem
);
2344 if( bSetMargins
[0] )
2345 aULItem
.SetUpper( o3tl::narrowing
<sal_uInt16
>(nMargins
[0]) );
2346 if( bSetMargins
[2] )
2347 aULItem
.SetLower( o3tl::narrowing
<sal_uInt16
>(nMargins
[2]) );
2348 rItemSet
.Put( aULItem
);
2352 SvxULSpaceItem
aULItem( aItemIds
.nULSpace
);
2353 if( bSetMargins
[0] )
2354 aULItem
.SetUpper( o3tl::narrowing
<sal_uInt16
>(nMargins
[0]) );
2355 if( bSetMargins
[2] )
2356 aULItem
.SetLower( o3tl::narrowing
<sal_uInt16
>(nMargins
[2]) );
2357 rItemSet
.Put( aULItem
);
2360 rPropInfo
.m_bTopMargin
|= bSetMargins
[0];
2361 rPropInfo
.m_bBottomMargin
|= bSetMargins
[2];
2364 static bool ParseCSS1_padding_xxx( const CSS1Expression
*pExpr
,
2365 SvxCSS1PropertyInfo
& rPropInfo
,
2366 SvxBoxItemLine nWhichLine
)
2368 OSL_ENSURE( pExpr
, "no expression" );
2371 sal_uInt16 nDist
= 0;
2373 switch( pExpr
->GetType() )
2377 tools::Long nTmp
= pExpr
->GetSLength();
2380 else if( nTmp
> SvxCSS1PropertyInfo::UNSET_BORDER_DISTANCE
-1 )
2381 nTmp
= SvxCSS1PropertyInfo::UNSET_BORDER_DISTANCE
-1;
2382 nDist
= o3tl::narrowing
<sal_uInt16
>(nTmp
);
2386 case CSS1_PIXLENGTH
:
2388 double fWidth
= pExpr
->GetNumber();
2389 if (fWidth
< SAL_MAX_INT32
/2.0 && fWidth
> SAL_MIN_INT32
/2.0)
2391 tools::Long nPWidth
= static_cast<tools::Long
>(fWidth
);
2392 tools::Long nPHeight
= 0;
2395 SvxCSS1Parser::PixelToTwip( nPWidth
, nPHeight
);
2396 if( nPWidth
> SvxCSS1PropertyInfo::UNSET_BORDER_DISTANCE
-1 )
2397 nPWidth
= SvxCSS1PropertyInfo::UNSET_BORDER_DISTANCE
-1;
2398 nDist
= o3tl::narrowing
<sal_uInt16
>(nPWidth
);
2403 case CSS1_PERCENTAGE
:
2412 switch( nWhichLine
)
2414 case SvxBoxItemLine::TOP
: rPropInfo
.m_nTopBorderDistance
= nDist
; break;
2415 case SvxBoxItemLine::BOTTOM
: rPropInfo
.m_nBottomBorderDistance
= nDist
;break;
2416 case SvxBoxItemLine::LEFT
: rPropInfo
.m_nLeftBorderDistance
= nDist
; break;
2417 case SvxBoxItemLine::RIGHT
: rPropInfo
.m_nRightBorderDistance
= nDist
; break;
2424 static void ParseCSS1_padding_top( const CSS1Expression
*pExpr
,
2425 SfxItemSet
& /*rItemSet*/,
2426 SvxCSS1PropertyInfo
& rPropInfo
,
2427 const SvxCSS1Parser
& /*rParser*/ )
2429 ParseCSS1_padding_xxx( pExpr
, rPropInfo
, SvxBoxItemLine::TOP
);
2432 static void ParseCSS1_padding_bottom( const CSS1Expression
*pExpr
,
2433 SfxItemSet
& /*rItemSet*/,
2434 SvxCSS1PropertyInfo
& rPropInfo
,
2435 const SvxCSS1Parser
& /*rParser*/ )
2437 ParseCSS1_padding_xxx( pExpr
, rPropInfo
, SvxBoxItemLine::BOTTOM
);
2440 static void ParseCSS1_padding_left( const CSS1Expression
*pExpr
,
2441 SfxItemSet
& /*rItemSet*/,
2442 SvxCSS1PropertyInfo
& rPropInfo
,
2443 const SvxCSS1Parser
& /*rParser*/ )
2445 ParseCSS1_padding_xxx( pExpr
, rPropInfo
, SvxBoxItemLine::LEFT
);
2448 static void ParseCSS1_padding_right( const CSS1Expression
*pExpr
,
2449 SfxItemSet
& /*rItemSet*/,
2450 SvxCSS1PropertyInfo
& rPropInfo
,
2451 const SvxCSS1Parser
& /*rParser*/ )
2453 ParseCSS1_padding_xxx( pExpr
, rPropInfo
, SvxBoxItemLine::RIGHT
);
2456 static void ParseCSS1_padding( const CSS1Expression
*pExpr
,
2457 SfxItemSet
& /*rItemSet*/,
2458 SvxCSS1PropertyInfo
& rPropInfo
,
2459 const SvxCSS1Parser
& /*rParser*/ )
2462 while( n
<4 && pExpr
&& !pExpr
->GetOp() )
2464 SvxBoxItemLine nLine
= n
==0 || n
==2 ? SvxBoxItemLine::BOTTOM
: SvxBoxItemLine::LEFT
;
2465 if( ParseCSS1_padding_xxx( pExpr
, rPropInfo
, nLine
) )
2469 rPropInfo
.m_nTopBorderDistance
= rPropInfo
.m_nBottomBorderDistance
;
2470 rPropInfo
.m_nLeftBorderDistance
= rPropInfo
.m_nTopBorderDistance
;
2473 rPropInfo
.m_nRightBorderDistance
= rPropInfo
.m_nLeftBorderDistance
;
2476 pExpr
= pExpr
->GetNext();
2481 static void ParseCSS1_border_xxx( const CSS1Expression
*pExpr
,
2482 SfxItemSet
& /*rItemSet*/,
2483 SvxCSS1PropertyInfo
& rPropInfo
,
2484 const SvxCSS1Parser
& /*rParser*/,
2485 SvxBoxItemLine nWhichLine
, bool bAll
)
2487 OSL_ENSURE( pExpr
, "no expression" );
2489 sal_uInt16 nWidth
= USHRT_MAX
; // line thickness
2490 sal_uInt16 nNWidth
= 1; // named line thickness (and default)
2491 CSS1BorderStyle eStyle
= CSS1_BS_NONE
; // line style
2493 bool bColor
= false;
2495 while( pExpr
&& !pExpr
->GetOp() )
2497 switch( pExpr
->GetType() )
2501 if( pExpr
->GetColor( aColor
) )
2507 const OUString
& rValue
= pExpr
->GetString();
2509 if( SvxCSS1Parser::GetEnum( aBorderWidthTable
, rValue
, nValue
) )
2513 else if( SvxCSS1Parser::GetEnum( aBorderStyleTable
, rValue
, nValue
) )
2515 eStyle
= static_cast<CSS1BorderStyle
>(nValue
);
2517 else if( pExpr
->GetColor( aColor
) )
2525 nWidth
= o3tl::narrowing
<sal_uInt16
>(pExpr
->GetULength());
2528 case CSS1_PIXLENGTH
:
2530 // One Pixel becomes a hairline (is prettier)
2531 double fWidth
= pExpr
->GetNumber();
2532 if (fWidth
> 1.0 && fWidth
< SAL_MAX_INT32
/2.0)
2534 bool bHori
= nWhichLine
== SvxBoxItemLine::TOP
||
2535 nWhichLine
== SvxBoxItemLine::BOTTOM
;
2537 tools::Long nPWidth
= bHori
? 0 : fWidth
;
2538 tools::Long nPHeight
= bHori
? fWidth
: 0;
2539 SvxCSS1Parser::PixelToTwip( nPWidth
, nPHeight
);
2540 nWidth
= o3tl::narrowing
<sal_uInt16
>(bHori
? nPHeight
: nPWidth
);
2551 pExpr
= pExpr
->GetNext();
2554 for( int i
=0; i
<4; ++i
)
2556 SvxBoxItemLine nLine
= SvxBoxItemLine::TOP
;
2559 case 0: nLine
= SvxBoxItemLine::TOP
; break;
2560 case 1: nLine
= SvxBoxItemLine::BOTTOM
; break;
2561 case 2: nLine
= SvxBoxItemLine::LEFT
; break;
2562 case 3: nLine
= SvxBoxItemLine::RIGHT
; break;
2565 if( bAll
|| nLine
== nWhichLine
)
2567 SvxCSS1BorderInfo
*pInfo
= rPropInfo
.GetBorderInfo( nLine
);
2568 pInfo
->eStyle
= eStyle
;
2569 pInfo
->nAbsWidth
= nWidth
;
2570 pInfo
->nNamedWidth
= nNWidth
;
2572 pInfo
->aColor
= aColor
;
2577 static void ParseCSS1_border_xxx_width( const CSS1Expression
*pExpr
,
2578 SfxItemSet
& /*rItemSet*/,
2579 SvxCSS1PropertyInfo
& rPropInfo
,
2580 const SvxCSS1Parser
& /*rParser*/,
2581 SvxBoxItemLine nWhichLine
)
2583 OSL_ENSURE( pExpr
, "no expression" );
2585 sal_uInt16 nWidth
= USHRT_MAX
; // line thickness
2586 sal_uInt16 nNWidth
= 1; // named line thickness (and default)
2588 switch( pExpr
->GetType() )
2593 if( SvxCSS1Parser::GetEnum( aBorderWidthTable
, pExpr
->GetString(), nValue
) )
2601 nWidth
= o3tl::narrowing
<sal_uInt16
>(pExpr
->GetULength());
2604 case CSS1_PIXLENGTH
:
2606 double fLength
= pExpr
->GetNumber();
2607 if (fLength
< SAL_MAX_INT32
/2.0 && fLength
> SAL_MIN_INT32
/2.0)
2609 tools::Long nWidthL
= static_cast<tools::Long
>(fLength
);
2611 bool bHori
= nWhichLine
== SvxBoxItemLine::TOP
||
2612 nWhichLine
== SvxBoxItemLine::BOTTOM
;
2614 tools::Long nPWidth
= bHori
? 0 : nWidthL
;
2615 tools::Long nPHeight
= bHori
? nWidthL
: 0;
2616 SvxCSS1Parser::PixelToTwip( nPWidth
, nPHeight
);
2617 nWidth
= o3tl::narrowing
<sal_uInt16
>(bHori
? nPHeight
: nPWidth
);
2626 SvxCSS1BorderInfo
*pInfo
= rPropInfo
.GetBorderInfo( nWhichLine
);
2627 pInfo
->nAbsWidth
= nWidth
;
2628 pInfo
->nNamedWidth
= nNWidth
;
2631 static void ParseCSS1_border_top_width( const CSS1Expression
*pExpr
,
2632 SfxItemSet
&rItemSet
,
2633 SvxCSS1PropertyInfo
& rPropInfo
,
2634 const SvxCSS1Parser
& rParser
)
2636 ParseCSS1_border_xxx_width( pExpr
, rItemSet
, rPropInfo
, rParser
, SvxBoxItemLine::TOP
);
2639 static void ParseCSS1_border_right_width( const CSS1Expression
*pExpr
,
2640 SfxItemSet
&rItemSet
,
2641 SvxCSS1PropertyInfo
& rPropInfo
,
2642 const SvxCSS1Parser
& rParser
)
2644 ParseCSS1_border_xxx_width( pExpr
, rItemSet
, rPropInfo
, rParser
, SvxBoxItemLine::RIGHT
);
2647 static void ParseCSS1_border_bottom_width( const CSS1Expression
*pExpr
,
2648 SfxItemSet
&rItemSet
,
2649 SvxCSS1PropertyInfo
& rPropInfo
,
2650 const SvxCSS1Parser
& rParser
)
2652 ParseCSS1_border_xxx_width( pExpr
, rItemSet
, rPropInfo
, rParser
, SvxBoxItemLine::BOTTOM
);
2655 static void ParseCSS1_border_left_width( const CSS1Expression
*pExpr
,
2656 SfxItemSet
&rItemSet
,
2657 SvxCSS1PropertyInfo
& rPropInfo
,
2658 const SvxCSS1Parser
& rParser
)
2660 ParseCSS1_border_xxx_width( pExpr
, rItemSet
, rPropInfo
, rParser
, SvxBoxItemLine::LEFT
);
2663 static void ParseCSS1_border_width( const CSS1Expression
*pExpr
,
2664 SfxItemSet
&rItemSet
,
2665 SvxCSS1PropertyInfo
& rPropInfo
,
2666 const SvxCSS1Parser
& rParser
)
2669 while( n
<4 && pExpr
&& !pExpr
->GetOp() )
2671 SvxBoxItemLine nLine
= n
==0 || n
==2 ? SvxBoxItemLine::BOTTOM
: SvxBoxItemLine::LEFT
;
2672 ParseCSS1_border_xxx_width( pExpr
, rItemSet
, rPropInfo
, rParser
, nLine
);
2673 rPropInfo
.CopyBorderInfo( n
, SVX_CSS1_BORDERINFO_WIDTH
);
2675 pExpr
= pExpr
->GetNext();
2680 static void ParseCSS1_border_color( const CSS1Expression
*pExpr
,
2681 SfxItemSet
& /*rItemSet*/,
2682 SvxCSS1PropertyInfo
& rPropInfo
,
2683 const SvxCSS1Parser
& /*rParser*/ )
2686 while( n
<4 && pExpr
&& !pExpr
->GetOp() )
2688 SvxBoxItemLine nLine
= n
==0 || n
==2 ? SvxBoxItemLine::BOTTOM
: SvxBoxItemLine::LEFT
;
2690 switch( pExpr
->GetType() )
2695 if( pExpr
->GetColor( aColor
) )
2696 rPropInfo
.GetBorderInfo( nLine
)->aColor
= aColor
;
2701 rPropInfo
.CopyBorderInfo( n
, SVX_CSS1_BORDERINFO_COLOR
);
2703 pExpr
= pExpr
->GetNext();
2708 static void ParseCSS1_border_style( const CSS1Expression
*pExpr
,
2709 SfxItemSet
& /*rItemSet*/,
2710 SvxCSS1PropertyInfo
& rPropInfo
,
2711 const SvxCSS1Parser
& /*rParser*/ )
2714 while( n
<4 && pExpr
&& !pExpr
->GetOp() )
2716 SvxBoxItemLine nLine
= n
==0 || n
==2 ? SvxBoxItemLine::BOTTOM
: SvxBoxItemLine::LEFT
;
2717 sal_uInt16 nValue
= 0;
2718 if( CSS1_IDENT
==pExpr
->GetType() &&
2719 SvxCSS1Parser::GetEnum( aBorderStyleTable
, pExpr
->GetString(),
2722 rPropInfo
.GetBorderInfo( nLine
)->eStyle
= static_cast<CSS1BorderStyle
>(nValue
);
2724 rPropInfo
.CopyBorderInfo( n
, SVX_CSS1_BORDERINFO_STYLE
);
2726 pExpr
= pExpr
->GetNext();
2731 static void ParseCSS1_border_top( const CSS1Expression
*pExpr
,
2732 SfxItemSet
&rItemSet
,
2733 SvxCSS1PropertyInfo
& rPropInfo
,
2734 const SvxCSS1Parser
& rParser
)
2736 ParseCSS1_border_xxx( pExpr
, rItemSet
, rPropInfo
, rParser
, SvxBoxItemLine::TOP
, false );
2739 static void ParseCSS1_border_right( const CSS1Expression
*pExpr
,
2740 SfxItemSet
&rItemSet
,
2741 SvxCSS1PropertyInfo
& rPropInfo
,
2742 const SvxCSS1Parser
& rParser
)
2744 ParseCSS1_border_xxx( pExpr
, rItemSet
, rPropInfo
, rParser
, SvxBoxItemLine::RIGHT
, false );
2747 static void ParseCSS1_border_bottom( const CSS1Expression
*pExpr
,
2748 SfxItemSet
&rItemSet
,
2749 SvxCSS1PropertyInfo
& rPropInfo
,
2750 const SvxCSS1Parser
& rParser
)
2752 ParseCSS1_border_xxx( pExpr
, rItemSet
, rPropInfo
, rParser
, SvxBoxItemLine::BOTTOM
, false );
2755 static void ParseCSS1_border_left( const CSS1Expression
*pExpr
,
2756 SfxItemSet
&rItemSet
,
2757 SvxCSS1PropertyInfo
& rPropInfo
,
2758 const SvxCSS1Parser
& rParser
)
2760 ParseCSS1_border_xxx( pExpr
, rItemSet
, rPropInfo
, rParser
, SvxBoxItemLine::LEFT
, false );
2763 static void ParseCSS1_border( const CSS1Expression
*pExpr
,
2764 SfxItemSet
&rItemSet
,
2765 SvxCSS1PropertyInfo
& rPropInfo
,
2766 const SvxCSS1Parser
& rParser
)
2768 ParseCSS1_border_xxx( pExpr
, rItemSet
, rPropInfo
, rParser
, SvxBoxItemLine::TOP
, true );
2771 static void ParseCSS1_float( const CSS1Expression
*pExpr
,
2772 SfxItemSet
& /*rItemSet*/,
2773 SvxCSS1PropertyInfo
& rPropInfo
,
2774 const SvxCSS1Parser
& /*rParser*/ )
2776 OSL_ENSURE( pExpr
, "no expression" );
2778 if( CSS1_IDENT
==pExpr
->GetType() )
2781 if( SvxCSS1Parser::GetEnum( aFloatTable
, pExpr
->GetString(), nFloat
) )
2782 rPropInfo
.m_eFloat
= static_cast<SvxAdjust
>(nFloat
);
2786 static void ParseCSS1_position( const CSS1Expression
*pExpr
,
2787 SfxItemSet
& /*rItemSet*/,
2788 SvxCSS1PropertyInfo
& rPropInfo
,
2789 const SvxCSS1Parser
& /*rParser*/ )
2791 OSL_ENSURE( pExpr
, "no expression" );
2793 if( CSS1_IDENT
==pExpr
->GetType() )
2796 if( SvxCSS1Parser::GetEnum( aPositionTable
, pExpr
->GetString(), nPos
) )
2797 rPropInfo
.m_ePosition
= static_cast<SvxCSS1Position
>(nPos
);
2801 static void ParseCSS1_length( const CSS1Expression
*pExpr
,
2802 tools::Long
& rLength
,
2803 SvxCSS1LengthType
& rLengthType
,
2806 switch( pExpr
->GetType() )
2809 if( pExpr
->GetString().equalsIgnoreAsciiCase( "auto" ) )
2812 rLengthType
= SVX_CSS1_LTYPE_AUTO
;
2817 rLength
= pExpr
->GetSLength();
2818 rLengthType
= SVX_CSS1_LTYPE_TWIP
;
2821 case CSS1_PIXLENGTH
:
2822 case CSS1_NUMBER
: // because of Netscape and IE
2824 double fLength
= pExpr
->GetNumber();
2825 if (fLength
< SAL_MAX_INT32
/2.0 && fLength
> SAL_MIN_INT32
/2.0)
2827 tools::Long nWidthL
= static_cast<tools::Long
>(fLength
);
2828 tools::Long nPWidth
= bHori
? 0 : nWidthL
;
2829 tools::Long nPHeight
= bHori
? nWidthL
: 0;
2830 SvxCSS1Parser::PixelToTwip( nPWidth
, nPHeight
);
2831 rLength
= (bHori
? nPHeight
: nPWidth
);
2832 rLengthType
= SVX_CSS1_LTYPE_TWIP
;
2837 case CSS1_PERCENTAGE
:
2838 rLength
= static_cast<tools::Long
>(std::min(pExpr
->GetNumber(), 100.0));
2839 rLengthType
= SVX_CSS1_LTYPE_PERCENTAGE
;
2847 static void ParseCSS1_width( const CSS1Expression
*pExpr
,
2848 SfxItemSet
& /*rItemSet*/,
2849 SvxCSS1PropertyInfo
& rPropInfo
,
2850 const SvxCSS1Parser
& /*rParser*/ )
2852 ParseCSS1_length( pExpr
, rPropInfo
.m_nWidth
, rPropInfo
.m_eWidthType
, true );
2855 static void ParseCSS1_height( const CSS1Expression
*pExpr
,
2856 SfxItemSet
& /*rItemSet*/,
2857 SvxCSS1PropertyInfo
& rPropInfo
,
2858 const SvxCSS1Parser
& /*rParser*/ )
2860 ParseCSS1_length( pExpr
, rPropInfo
.m_nHeight
, rPropInfo
.m_eHeightType
, false );
2863 static void ParseCSS1_left( const CSS1Expression
*pExpr
,
2864 SfxItemSet
& /*rItemSet*/,
2865 SvxCSS1PropertyInfo
& rPropInfo
,
2866 const SvxCSS1Parser
& /*rParser*/ )
2868 ParseCSS1_length( pExpr
, rPropInfo
.m_nLeft
, rPropInfo
.m_eLeftType
, true );
2871 static void ParseCSS1_top( const CSS1Expression
*pExpr
,
2872 SfxItemSet
& /*rItemSet*/,
2873 SvxCSS1PropertyInfo
& rPropInfo
,
2874 const SvxCSS1Parser
& /*rParser*/ )
2876 ParseCSS1_length( pExpr
, rPropInfo
.m_nTop
, rPropInfo
.m_eTopType
, false );
2879 // Feature: PrintExt
2880 static void ParseCSS1_size( const CSS1Expression
*pExpr
,
2881 SfxItemSet
& /*rItemSet*/,
2882 SvxCSS1PropertyInfo
& rPropInfo
,
2883 const SvxCSS1Parser
& /*rParser*/ )
2886 while( n
<2 && pExpr
&& !pExpr
->GetOp() )
2888 switch( pExpr
->GetType() )
2893 if( SvxCSS1Parser::GetEnum( aSizeTable
, pExpr
->GetString(),
2896 rPropInfo
.m_eSizeType
= static_cast<SvxCSS1SizeType
>(nValue
);
2902 rPropInfo
.m_nHeight
= pExpr
->GetSLength();
2904 rPropInfo
.m_nWidth
= rPropInfo
.m_nHeight
;
2905 rPropInfo
.m_eSizeType
= SVX_CSS1_STYPE_TWIP
;
2908 case CSS1_PIXLENGTH
:
2910 double fHeight
= pExpr
->GetNumber();
2911 if (fHeight
< SAL_MAX_INT32
/2.0 && fHeight
> SAL_MIN_INT32
/2.0)
2913 tools::Long nPHeight
= static_cast<tools::Long
>(fHeight
);
2914 tools::Long nPWidth
= n
==0 ? nPHeight
: 0;
2915 SvxCSS1Parser::PixelToTwip( nPWidth
, nPHeight
);
2916 rPropInfo
.m_nHeight
= nPHeight
;
2918 rPropInfo
.m_nWidth
= nPWidth
;
2919 rPropInfo
.m_eSizeType
= SVX_CSS1_STYPE_TWIP
;
2927 pExpr
= pExpr
->GetNext();
2932 static void ParseCSS1_page_break_xxx( const CSS1Expression
*pExpr
,
2933 SvxCSS1PageBreak
& rPBreak
)
2935 if( CSS1_IDENT
== pExpr
->GetType() )
2938 if( SvxCSS1Parser::GetEnum( aPageBreakTable
, pExpr
->GetString(),
2941 rPBreak
= static_cast<SvxCSS1PageBreak
>(nValue
);
2946 static void ParseCSS1_page_break_before( const CSS1Expression
*pExpr
,
2947 SfxItemSet
& /*rItemSet*/,
2948 SvxCSS1PropertyInfo
& rPropInfo
,
2949 const SvxCSS1Parser
& /*rParser*/ )
2951 ParseCSS1_page_break_xxx( pExpr
, rPropInfo
.m_ePageBreakBefore
);
2954 static void ParseCSS1_page_break_after( const CSS1Expression
*pExpr
,
2955 SfxItemSet
& /*rItemSet*/,
2956 SvxCSS1PropertyInfo
& rPropInfo
,
2957 const SvxCSS1Parser
& /*rParser*/ )
2959 ParseCSS1_page_break_xxx( pExpr
, rPropInfo
.m_ePageBreakAfter
);
2962 static void ParseCSS1_page_break_inside( const CSS1Expression
*pExpr
,
2963 SfxItemSet
&rItemSet
,
2964 SvxCSS1PropertyInfo
& /*rPropInfo*/,
2965 const SvxCSS1Parser
& /*rParser*/ )
2967 SvxCSS1PageBreak
eBreak(SVX_CSS1_PBREAK_NONE
);
2968 ParseCSS1_page_break_xxx( pExpr
, eBreak
);
2970 bool bSetSplit
= false, bSplit
= true;
2973 case SVX_CSS1_PBREAK_AUTO
:
2976 case SVX_CSS1_PBREAK_AVOID
:
2985 rItemSet
.Put( SvxFormatSplitItem( bSplit
, aItemIds
.nFormatSplit
) );
2988 static void ParseCSS1_widows( const CSS1Expression
*pExpr
,
2989 SfxItemSet
&rItemSet
,
2990 SvxCSS1PropertyInfo
& /*rPropInfo*/,
2991 const SvxCSS1Parser
& /*rParser*/ )
2993 if( CSS1_NUMBER
== pExpr
->GetType() )
2995 sal_uInt8 nVal
= pExpr
->GetNumber() <= 255
2996 ? static_cast<sal_uInt8
>(pExpr
->GetNumber())
2998 SvxWidowsItem
aWidowsItem( nVal
, aItemIds
.nWidows
);
2999 rItemSet
.Put( aWidowsItem
);
3003 static void ParseCSS1_orphans( const CSS1Expression
*pExpr
,
3004 SfxItemSet
&rItemSet
,
3005 SvxCSS1PropertyInfo
& /*rPropInfo*/,
3006 const SvxCSS1Parser
& /*rParser*/ )
3008 if( CSS1_NUMBER
== pExpr
->GetType() )
3010 sal_uInt8 nVal
= pExpr
->GetNumber() <= 255
3011 ? static_cast<sal_uInt8
>(pExpr
->GetNumber())
3013 SvxOrphansItem
aOrphansItem( nVal
, aItemIds
.nOrphans
);
3014 rItemSet
.Put( aOrphansItem
);
3018 static void ParseCSS1_so_language( const CSS1Expression
*pExpr
,
3019 SfxItemSet
&rItemSet
,
3020 SvxCSS1PropertyInfo
& /*rPropInfo*/,
3021 const SvxCSS1Parser
& /*rParser*/ )
3023 if( CSS1_IDENT
!= pExpr
->GetType() && CSS1_STRING
!= pExpr
->GetType() )
3026 LanguageType eLang
= LanguageTag::convertToLanguageTypeWithFallback( pExpr
->GetString() );
3027 if( LANGUAGE_DONTKNOW
!= eLang
)
3029 SvxLanguageItem
aLang( eLang
, aItemIds
.nLanguage
);
3030 rItemSet
.Put( aLang
);
3031 aLang
.SetWhich( aItemIds
.nLanguageCJK
);
3032 rItemSet
.Put( aLang
);
3033 aLang
.SetWhich( aItemIds
.nLanguageCTL
);
3034 rItemSet
.Put( aLang
);
3038 static void ParseCSS1_visibility(const CSS1Expression
* pExpr
, SfxItemSet
& /*rItemSet*/,
3039 SvxCSS1PropertyInfo
& rPropInfo
, const SvxCSS1Parser
& /*rParser*/)
3041 if (pExpr
->GetType() != CSS1_IDENT
)
3044 rPropInfo
.m_bVisible
= pExpr
->GetString() != "hidden";
3049 // the assignment of property to parsing function
3050 struct CSS1PropEntry
3052 std::string_view pName
;
3053 FnParseCSS1Prop pFunc
;
3058 // the table with assignments
3059 CSS1PropEntry
const aCSS1PropFnTab
[] =
3061 { sCSS1_P_background
, ParseCSS1_background
},
3062 { sCSS1_P_background_color
, ParseCSS1_background_color
},
3063 { sCSS1_P_border
, ParseCSS1_border
},
3064 { sCSS1_P_border_bottom
, ParseCSS1_border_bottom
},
3065 { sCSS1_P_border_bottom_width
, ParseCSS1_border_bottom_width
},
3066 { sCSS1_P_border_color
, ParseCSS1_border_color
},
3067 { sCSS1_P_border_left
, ParseCSS1_border_left
},
3068 { sCSS1_P_border_left_width
, ParseCSS1_border_left_width
},
3069 { sCSS1_P_border_right
, ParseCSS1_border_right
},
3070 { sCSS1_P_border_right_width
, ParseCSS1_border_right_width
},
3071 { sCSS1_P_border_style
, ParseCSS1_border_style
},
3072 { sCSS1_P_border_top
, ParseCSS1_border_top
},
3073 { sCSS1_P_border_top_width
, ParseCSS1_border_top_width
},
3074 { sCSS1_P_border_width
, ParseCSS1_border_width
},
3075 { sCSS1_P_color
, ParseCSS1_color
},
3076 { sCSS1_P_column_count
, ParseCSS1_column_count
},
3077 { sCSS1_P_direction
, ParseCSS1_direction
},
3078 { sCSS1_P_float
, ParseCSS1_float
},
3079 { sCSS1_P_font
, ParseCSS1_font
},
3080 { sCSS1_P_font_family
, ParseCSS1_font_family
},
3081 { sCSS1_P_font_size
, ParseCSS1_font_size
},
3082 { sCSS1_P_font_style
, ParseCSS1_font_style
},
3083 { sCSS1_P_font_variant
, ParseCSS1_font_variant
},
3084 { sCSS1_P_font_weight
, ParseCSS1_font_weight
},
3085 { sCSS1_P_height
, ParseCSS1_height
},
3086 { sCSS1_P_left
, ParseCSS1_left
},
3087 { sCSS1_P_letter_spacing
, ParseCSS1_letter_spacing
},
3088 { sCSS1_P_line_height
, ParseCSS1_line_height
},
3089 { sCSS1_P_list_style_type
, ParseCSS1_list_style_type
},
3090 { sCSS1_P_margin
, ParseCSS1_margin
},
3091 { sCSS1_P_margin_bottom
, ParseCSS1_margin_bottom
},
3092 { sCSS1_P_margin_left
, ParseCSS1_margin_left
},
3093 { sCSS1_P_margin_right
, ParseCSS1_margin_right
},
3094 { sCSS1_P_margin_top
, ParseCSS1_margin_top
},
3095 { sCSS1_P_orphans
, ParseCSS1_orphans
},
3096 { sCSS1_P_padding
, ParseCSS1_padding
},
3097 { sCSS1_P_padding_bottom
, ParseCSS1_padding_bottom
},
3098 { sCSS1_P_padding_left
, ParseCSS1_padding_left
},
3099 { sCSS1_P_padding_right
, ParseCSS1_padding_right
},
3100 { sCSS1_P_padding_top
, ParseCSS1_padding_top
},
3101 { sCSS1_P_page_break_after
, ParseCSS1_page_break_after
},
3102 { sCSS1_P_page_break_before
, ParseCSS1_page_break_before
},
3103 { sCSS1_P_page_break_inside
, ParseCSS1_page_break_inside
},
3104 { sCSS1_P_position
, ParseCSS1_position
},
3105 { sCSS1_P_size
, ParseCSS1_size
},
3106 { sCSS1_P_so_language
, ParseCSS1_so_language
},
3107 { sCSS1_P_text_align
, ParseCSS1_text_align
},
3108 { sCSS1_P_text_decoration
, ParseCSS1_text_decoration
},
3109 { sCSS1_P_text_indent
, ParseCSS1_text_indent
},
3110 { sCSS1_P_text_transform
, ParseCSS1_text_transform
},
3111 { sCSS1_P_top
, ParseCSS1_top
},
3112 { sCSS1_P_visibility
, ParseCSS1_visibility
},
3113 { sCSS1_P_widows
, ParseCSS1_widows
},
3114 { sCSS1_P_width
, ParseCSS1_width
},
3117 static bool CSS1PropEntryFindCompare(CSS1PropEntry
const & lhs
, OUString
const & s
)
3119 return s
.compareToIgnoreAsciiCaseAscii(lhs
.pName
) > 0;
3122 void SvxCSS1Parser::DeclarationParsed( const OUString
& rProperty
,
3123 std::unique_ptr
<CSS1Expression
> pExpr
)
3125 OSL_ENSURE( m_pItemSet
, "DeclarationParsed() without ItemSet" );
3127 // TODO: convert to static_assert, when C++20 constexpr std::is_sorted is available
3128 [[maybe_unused
]] static const bool bSortedPropFns
= []() {
3129 assert( std::is_sorted( std::begin(aCSS1PropFnTab
), std::end(aCSS1PropFnTab
),
3130 [](const auto& lhs
, const auto& rhs
) constexpr { return lhs
.pName
< rhs
.pName
; } ) );
3134 auto it
= std::lower_bound( std::begin(aCSS1PropFnTab
), std::end(aCSS1PropFnTab
), rProperty
,
3135 CSS1PropEntryFindCompare
);
3136 if( it
!= std::end(aCSS1PropFnTab
) && !CSS1PropEntryFindCompare(*it
,rProperty
) )
3138 it
->pFunc( pExpr
.get(), *m_pItemSet
, *m_pPropInfo
, *this );
3142 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */