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
.GetTrueWhichIDFromSlotID(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 assert(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 assert(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 assert(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 assert(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 assert(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 assert(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 assert(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 assert(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 assert(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 assert(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(SvxIndentValue::twips(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 assert(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(
2050 SvxIndentValue::twips(o3tl::narrowing
<sal_uInt16
>(nLeft
)), RES_MARGIN_TEXTLEFT
);
2051 rItemSet
.Put(leftMargin
);
2052 rPropInfo
.m_bLeftMargin
= true;
2055 static void ParseCSS1_margin_right( const CSS1Expression
*pExpr
,
2056 SfxItemSet
&rItemSet
,
2057 SvxCSS1PropertyInfo
& rPropInfo
,
2058 const SvxCSS1Parser
& /*rParser*/ )
2060 assert(pExpr
&& "no expression");
2062 tools::Long nRight
= 0;
2064 switch( pExpr
->GetType() )
2068 nRight
= pExpr
->GetSLength();
2072 case CSS1_PIXLENGTH
:
2074 double fRight
= pExpr
->GetNumber();
2075 if (fRight
< SAL_MAX_INT32
/2.0 && fRight
> SAL_MIN_INT32
/2.0)
2077 nRight
= static_cast<tools::Long
>(fRight
);
2078 tools::Long nPHeight
= 0;
2079 SvxCSS1Parser::PixelToTwip( nRight
, nPHeight
);
2084 case CSS1_PERCENTAGE
:
2091 if (pExpr
->GetString() == "auto")
2093 rPropInfo
.m_bRightMargin
= true;
2094 rPropInfo
.m_eRightMarginType
= SVX_CSS1_LTYPE_AUTO
;
2100 rPropInfo
.m_nRightMargin
= nRight
;
2104 SvxRightMarginItem
rightMargin(SvxIndentValue::twips(o3tl::narrowing
<sal_uInt16
>(nRight
)),
2106 rItemSet
.Put(rightMargin
);
2107 rPropInfo
.m_bRightMargin
= true;
2110 static void ParseCSS1_margin_top( const CSS1Expression
*pExpr
,
2111 SfxItemSet
&rItemSet
,
2112 SvxCSS1PropertyInfo
& rPropInfo
,
2113 const SvxCSS1Parser
& /*rParser*/ )
2115 assert(pExpr
&& "no expression");
2117 sal_uInt16 nUpper
= 0;
2119 switch( pExpr
->GetType() )
2123 tools::Long nTmp
= pExpr
->GetSLength();
2126 nUpper
= o3tl::narrowing
<sal_uInt16
>(nTmp
);
2130 case CSS1_PIXLENGTH
:
2132 double fHeight
= pExpr
->GetNumber();
2133 if (fHeight
< SAL_MAX_INT32
/2.0 && fHeight
> SAL_MIN_INT32
/2.0)
2135 tools::Long nPWidth
= 0;
2136 tools::Long nPHeight
= static_cast<tools::Long
>(fHeight
);
2139 SvxCSS1Parser::PixelToTwip( nPWidth
, nPHeight
);
2140 nUpper
= o3tl::narrowing
<sal_uInt16
>(nPHeight
);
2145 case CSS1_PERCENTAGE
:
2155 if( const SvxULSpaceItem
* pItem
= rItemSet
.GetItemIfSet( aItemIds
.nULSpace
, false ) )
2157 SvxULSpaceItem
aULItem( *pItem
);
2158 aULItem
.SetUpper( nUpper
);
2159 rItemSet
.Put( aULItem
);
2163 SvxULSpaceItem
aULItem( aItemIds
.nULSpace
);
2164 aULItem
.SetUpper( nUpper
);
2165 rItemSet
.Put( aULItem
);
2167 rPropInfo
.m_bTopMargin
= true;
2170 static void ParseCSS1_margin_bottom( const CSS1Expression
*pExpr
,
2171 SfxItemSet
&rItemSet
,
2172 SvxCSS1PropertyInfo
& rPropInfo
,
2173 const SvxCSS1Parser
& /*rParser*/ )
2175 assert(pExpr
&& "no expression");
2177 sal_uInt16 nLower
= 0;
2179 switch( pExpr
->GetType() )
2183 tools::Long nTmp
= pExpr
->GetSLength();
2186 nLower
= o3tl::narrowing
<sal_uInt16
>(nTmp
);
2190 case CSS1_PIXLENGTH
:
2192 double fHeight
= pExpr
->GetNumber();
2193 if (fHeight
< SAL_MAX_INT32
/2.0 && fHeight
> SAL_MIN_INT32
/2.0)
2195 tools::Long nPWidth
= 0;
2196 tools::Long nPHeight
= static_cast<tools::Long
>(fHeight
);
2199 SvxCSS1Parser::PixelToTwip( nPWidth
, nPHeight
);
2200 nLower
= o3tl::narrowing
<sal_uInt16
>(nPHeight
);
2205 case CSS1_PERCENTAGE
:
2215 if( const SvxULSpaceItem
* pItem
= rItemSet
.GetItemIfSet( aItemIds
.nULSpace
, false ) )
2217 SvxULSpaceItem
aULItem( *pItem
);
2218 aULItem
.SetLower( nLower
);
2219 rItemSet
.Put( aULItem
);
2223 SvxULSpaceItem
aULItem( aItemIds
.nULSpace
);
2224 aULItem
.SetLower( nLower
);
2225 rItemSet
.Put( aULItem
);
2227 rPropInfo
.m_bBottomMargin
= true;
2230 static void ParseCSS1_margin( const CSS1Expression
*pExpr
,
2231 SfxItemSet
&rItemSet
,
2232 SvxCSS1PropertyInfo
& rPropInfo
,
2233 const SvxCSS1Parser
& /*rParser*/ )
2235 OSL_ENSURE( pExpr
, "no expression" );
2237 tools::Long nMargins
[4] = { 0, 0, 0, 0 };
2238 bool bSetMargins
[4] = { false, false, false, false };
2240 for( int i
=0; pExpr
&& i
<4 && !pExpr
->GetOp(); ++i
)
2242 bool bSetThis
= false;
2243 tools::Long nMargin
= 0;
2245 switch( pExpr
->GetType() )
2249 nMargin
= pExpr
->GetSLength();
2253 case CSS1_PIXLENGTH
:
2255 double fMargin
= pExpr
->GetNumber();
2256 if (fMargin
< SAL_MAX_INT32
/2.0 && fMargin
> SAL_MIN_INT32
/2.0)
2258 nMargin
= static_cast<tools::Long
>(fMargin
);
2259 tools::Long nPWidth
= 0;
2260 SvxCSS1Parser::PixelToTwip( nPWidth
, nMargin
);
2265 SAL_WARN("sw.html", "out-of-size pxlength: " << fMargin
);
2269 case CSS1_PERCENTAGE
:
2285 nMargins
[0] = nMargins
[1] =nMargins
[2] = nMargins
[3] = nMargin
;
2286 bSetMargins
[0] = bSetMargins
[1] =
2287 bSetMargins
[2] = bSetMargins
[3] = true;
2290 nMargins
[1] = nMargins
[3] = nMargin
; // right + left
2291 bSetMargins
[1] = bSetMargins
[3] = true;
2294 nMargins
[2] = nMargin
; // bottom
2295 bSetMargins
[2] = true;
2298 nMargins
[3] = nMargin
; // left
2299 bSetMargins
[3] = true;
2303 pExpr
= pExpr
->GetNext();
2306 if( bSetMargins
[3] || bSetMargins
[1] )
2308 if( bSetMargins
[3] )
2310 rPropInfo
.m_bLeftMargin
= true;
2311 rPropInfo
.m_nLeftMargin
= nMargins
[3];
2312 if( nMargins
[3] < 0 )
2315 if( bSetMargins
[1] )
2317 rPropInfo
.m_bRightMargin
= true;
2318 rPropInfo
.m_nRightMargin
= nMargins
[1];
2319 if( nMargins
[1] < 0 )
2325 SvxTextLeftMarginItem
const leftMargin(
2326 SvxIndentValue::twips(o3tl::narrowing
<sal_uInt16
>(nMargins
[3])),
2327 RES_MARGIN_TEXTLEFT
);
2328 rItemSet
.Put(leftMargin
);
2332 SvxRightMarginItem
const rightMargin(
2333 SvxIndentValue::twips(o3tl::narrowing
<sal_uInt16
>(nMargins
[1])), RES_MARGIN_RIGHT
);
2334 rItemSet
.Put(rightMargin
);
2338 if( !(bSetMargins
[0] || bSetMargins
[2]) )
2341 if( nMargins
[0] < 0 )
2343 if( nMargins
[2] < 0 )
2346 if( const SvxULSpaceItem
* pItem
= rItemSet
.GetItemIfSet( aItemIds
.nULSpace
, false ) )
2348 SvxULSpaceItem
aULItem( *pItem
);
2349 if( bSetMargins
[0] )
2350 aULItem
.SetUpper( o3tl::narrowing
<sal_uInt16
>(nMargins
[0]) );
2351 if( bSetMargins
[2] )
2352 aULItem
.SetLower( o3tl::narrowing
<sal_uInt16
>(nMargins
[2]) );
2353 rItemSet
.Put( aULItem
);
2357 SvxULSpaceItem
aULItem( aItemIds
.nULSpace
);
2358 if( bSetMargins
[0] )
2359 aULItem
.SetUpper( o3tl::narrowing
<sal_uInt16
>(nMargins
[0]) );
2360 if( bSetMargins
[2] )
2361 aULItem
.SetLower( o3tl::narrowing
<sal_uInt16
>(nMargins
[2]) );
2362 rItemSet
.Put( aULItem
);
2365 rPropInfo
.m_bTopMargin
|= bSetMargins
[0];
2366 rPropInfo
.m_bBottomMargin
|= bSetMargins
[2];
2369 static bool ParseCSS1_padding_xxx( const CSS1Expression
*pExpr
,
2370 SvxCSS1PropertyInfo
& rPropInfo
,
2371 SvxBoxItemLine nWhichLine
)
2373 assert(pExpr
&& "no expression");
2376 sal_uInt16 nDist
= 0;
2378 switch( pExpr
->GetType() )
2382 tools::Long nTmp
= pExpr
->GetSLength();
2385 else if( nTmp
> SvxCSS1PropertyInfo::UNSET_BORDER_DISTANCE
-1 )
2386 nTmp
= SvxCSS1PropertyInfo::UNSET_BORDER_DISTANCE
-1;
2387 nDist
= o3tl::narrowing
<sal_uInt16
>(nTmp
);
2391 case CSS1_PIXLENGTH
:
2393 double fWidth
= pExpr
->GetNumber();
2394 if (fWidth
< SAL_MAX_INT32
/2.0 && fWidth
> SAL_MIN_INT32
/2.0)
2396 tools::Long nPWidth
= static_cast<tools::Long
>(fWidth
);
2397 tools::Long nPHeight
= 0;
2400 SvxCSS1Parser::PixelToTwip( nPWidth
, nPHeight
);
2401 if( nPWidth
> SvxCSS1PropertyInfo::UNSET_BORDER_DISTANCE
-1 )
2402 nPWidth
= SvxCSS1PropertyInfo::UNSET_BORDER_DISTANCE
-1;
2403 nDist
= o3tl::narrowing
<sal_uInt16
>(nPWidth
);
2408 case CSS1_PERCENTAGE
:
2417 switch( nWhichLine
)
2419 case SvxBoxItemLine::TOP
: rPropInfo
.m_nTopBorderDistance
= nDist
; break;
2420 case SvxBoxItemLine::BOTTOM
: rPropInfo
.m_nBottomBorderDistance
= nDist
;break;
2421 case SvxBoxItemLine::LEFT
: rPropInfo
.m_nLeftBorderDistance
= nDist
; break;
2422 case SvxBoxItemLine::RIGHT
: rPropInfo
.m_nRightBorderDistance
= nDist
; break;
2429 static void ParseCSS1_padding_top( const CSS1Expression
*pExpr
,
2430 SfxItemSet
& /*rItemSet*/,
2431 SvxCSS1PropertyInfo
& rPropInfo
,
2432 const SvxCSS1Parser
& /*rParser*/ )
2434 ParseCSS1_padding_xxx( pExpr
, rPropInfo
, SvxBoxItemLine::TOP
);
2437 static void ParseCSS1_padding_bottom( const CSS1Expression
*pExpr
,
2438 SfxItemSet
& /*rItemSet*/,
2439 SvxCSS1PropertyInfo
& rPropInfo
,
2440 const SvxCSS1Parser
& /*rParser*/ )
2442 ParseCSS1_padding_xxx( pExpr
, rPropInfo
, SvxBoxItemLine::BOTTOM
);
2445 static void ParseCSS1_padding_left( const CSS1Expression
*pExpr
,
2446 SfxItemSet
& /*rItemSet*/,
2447 SvxCSS1PropertyInfo
& rPropInfo
,
2448 const SvxCSS1Parser
& /*rParser*/ )
2450 ParseCSS1_padding_xxx( pExpr
, rPropInfo
, SvxBoxItemLine::LEFT
);
2453 static void ParseCSS1_padding_right( const CSS1Expression
*pExpr
,
2454 SfxItemSet
& /*rItemSet*/,
2455 SvxCSS1PropertyInfo
& rPropInfo
,
2456 const SvxCSS1Parser
& /*rParser*/ )
2458 ParseCSS1_padding_xxx( pExpr
, rPropInfo
, SvxBoxItemLine::RIGHT
);
2461 static void ParseCSS1_padding( const CSS1Expression
*pExpr
,
2462 SfxItemSet
& /*rItemSet*/,
2463 SvxCSS1PropertyInfo
& rPropInfo
,
2464 const SvxCSS1Parser
& /*rParser*/ )
2467 while( n
<4 && pExpr
&& !pExpr
->GetOp() )
2469 SvxBoxItemLine nLine
= n
==0 || n
==2 ? SvxBoxItemLine::BOTTOM
: SvxBoxItemLine::LEFT
;
2470 if( ParseCSS1_padding_xxx( pExpr
, rPropInfo
, nLine
) )
2474 rPropInfo
.m_nTopBorderDistance
= rPropInfo
.m_nBottomBorderDistance
;
2475 rPropInfo
.m_nLeftBorderDistance
= rPropInfo
.m_nTopBorderDistance
;
2478 rPropInfo
.m_nRightBorderDistance
= rPropInfo
.m_nLeftBorderDistance
;
2481 pExpr
= pExpr
->GetNext();
2486 static void ParseCSS1_border_xxx( const CSS1Expression
*pExpr
,
2487 SfxItemSet
& /*rItemSet*/,
2488 SvxCSS1PropertyInfo
& rPropInfo
,
2489 const SvxCSS1Parser
& /*rParser*/,
2490 SvxBoxItemLine nWhichLine
, bool bAll
)
2492 assert(pExpr
&& "no expression");
2494 sal_uInt16 nWidth
= USHRT_MAX
; // line thickness
2495 sal_uInt16 nNWidth
= 1; // named line thickness (and default)
2496 CSS1BorderStyle eStyle
= CSS1_BS_NONE
; // line style
2498 bool bColor
= false;
2500 while( pExpr
&& !pExpr
->GetOp() )
2502 switch( pExpr
->GetType() )
2506 if( pExpr
->GetColor( aColor
) )
2512 const OUString
& rValue
= pExpr
->GetString();
2514 if( SvxCSS1Parser::GetEnum( aBorderWidthTable
, rValue
, nValue
) )
2518 else if( SvxCSS1Parser::GetEnum( aBorderStyleTable
, rValue
, nValue
) )
2520 eStyle
= static_cast<CSS1BorderStyle
>(nValue
);
2522 else if( pExpr
->GetColor( aColor
) )
2530 nWidth
= o3tl::narrowing
<sal_uInt16
>(pExpr
->GetULength());
2533 case CSS1_PIXLENGTH
:
2535 // One Pixel becomes a hairline (is prettier)
2536 double fWidth
= pExpr
->GetNumber();
2537 if (fWidth
> 1.0 && fWidth
< SAL_MAX_INT32
/2.0)
2539 bool bHori
= nWhichLine
== SvxBoxItemLine::TOP
||
2540 nWhichLine
== SvxBoxItemLine::BOTTOM
;
2542 tools::Long nPWidth
= bHori
? 0 : fWidth
;
2543 tools::Long nPHeight
= bHori
? fWidth
: 0;
2544 SvxCSS1Parser::PixelToTwip( nPWidth
, nPHeight
);
2545 nWidth
= o3tl::narrowing
<sal_uInt16
>(bHori
? nPHeight
: nPWidth
);
2556 pExpr
= pExpr
->GetNext();
2559 for( int i
=0; i
<4; ++i
)
2561 SvxBoxItemLine nLine
= SvxBoxItemLine::TOP
;
2564 case 0: nLine
= SvxBoxItemLine::TOP
; break;
2565 case 1: nLine
= SvxBoxItemLine::BOTTOM
; break;
2566 case 2: nLine
= SvxBoxItemLine::LEFT
; break;
2567 case 3: nLine
= SvxBoxItemLine::RIGHT
; break;
2570 if( bAll
|| nLine
== nWhichLine
)
2572 SvxCSS1BorderInfo
*pInfo
= rPropInfo
.GetBorderInfo( nLine
);
2573 pInfo
->eStyle
= eStyle
;
2574 pInfo
->nAbsWidth
= nWidth
;
2575 pInfo
->nNamedWidth
= nNWidth
;
2577 pInfo
->aColor
= aColor
;
2582 static void ParseCSS1_border_xxx_width( const CSS1Expression
*pExpr
,
2583 SfxItemSet
& /*rItemSet*/,
2584 SvxCSS1PropertyInfo
& rPropInfo
,
2585 const SvxCSS1Parser
& /*rParser*/,
2586 SvxBoxItemLine nWhichLine
)
2588 assert(pExpr
&& "no expression");
2590 sal_uInt16 nWidth
= USHRT_MAX
; // line thickness
2591 sal_uInt16 nNWidth
= 1; // named line thickness (and default)
2593 switch( pExpr
->GetType() )
2598 if( SvxCSS1Parser::GetEnum( aBorderWidthTable
, pExpr
->GetString(), nValue
) )
2606 nWidth
= o3tl::narrowing
<sal_uInt16
>(pExpr
->GetULength());
2609 case CSS1_PIXLENGTH
:
2611 double fLength
= pExpr
->GetNumber();
2612 if (fLength
< SAL_MAX_INT32
/2.0 && fLength
> SAL_MIN_INT32
/2.0)
2614 tools::Long nWidthL
= static_cast<tools::Long
>(fLength
);
2616 bool bHori
= nWhichLine
== SvxBoxItemLine::TOP
||
2617 nWhichLine
== SvxBoxItemLine::BOTTOM
;
2619 tools::Long nPWidth
= bHori
? 0 : nWidthL
;
2620 tools::Long nPHeight
= bHori
? nWidthL
: 0;
2621 SvxCSS1Parser::PixelToTwip( nPWidth
, nPHeight
);
2622 nWidth
= o3tl::narrowing
<sal_uInt16
>(bHori
? nPHeight
: nPWidth
);
2631 SvxCSS1BorderInfo
*pInfo
= rPropInfo
.GetBorderInfo( nWhichLine
);
2632 pInfo
->nAbsWidth
= nWidth
;
2633 pInfo
->nNamedWidth
= nNWidth
;
2636 static void ParseCSS1_border_top_width( const CSS1Expression
*pExpr
,
2637 SfxItemSet
&rItemSet
,
2638 SvxCSS1PropertyInfo
& rPropInfo
,
2639 const SvxCSS1Parser
& rParser
)
2641 ParseCSS1_border_xxx_width( pExpr
, rItemSet
, rPropInfo
, rParser
, SvxBoxItemLine::TOP
);
2644 static void ParseCSS1_border_right_width( const CSS1Expression
*pExpr
,
2645 SfxItemSet
&rItemSet
,
2646 SvxCSS1PropertyInfo
& rPropInfo
,
2647 const SvxCSS1Parser
& rParser
)
2649 ParseCSS1_border_xxx_width( pExpr
, rItemSet
, rPropInfo
, rParser
, SvxBoxItemLine::RIGHT
);
2652 static void ParseCSS1_border_bottom_width( const CSS1Expression
*pExpr
,
2653 SfxItemSet
&rItemSet
,
2654 SvxCSS1PropertyInfo
& rPropInfo
,
2655 const SvxCSS1Parser
& rParser
)
2657 ParseCSS1_border_xxx_width( pExpr
, rItemSet
, rPropInfo
, rParser
, SvxBoxItemLine::BOTTOM
);
2660 static void ParseCSS1_border_left_width( const CSS1Expression
*pExpr
,
2661 SfxItemSet
&rItemSet
,
2662 SvxCSS1PropertyInfo
& rPropInfo
,
2663 const SvxCSS1Parser
& rParser
)
2665 ParseCSS1_border_xxx_width( pExpr
, rItemSet
, rPropInfo
, rParser
, SvxBoxItemLine::LEFT
);
2668 static void ParseCSS1_border_width( const CSS1Expression
*pExpr
,
2669 SfxItemSet
&rItemSet
,
2670 SvxCSS1PropertyInfo
& rPropInfo
,
2671 const SvxCSS1Parser
& rParser
)
2674 while( n
<4 && pExpr
&& !pExpr
->GetOp() )
2676 SvxBoxItemLine nLine
= n
==0 || n
==2 ? SvxBoxItemLine::BOTTOM
: SvxBoxItemLine::LEFT
;
2677 ParseCSS1_border_xxx_width( pExpr
, rItemSet
, rPropInfo
, rParser
, nLine
);
2678 rPropInfo
.CopyBorderInfo( n
, SVX_CSS1_BORDERINFO_WIDTH
);
2680 pExpr
= pExpr
->GetNext();
2685 static void ParseCSS1_border_color( const CSS1Expression
*pExpr
,
2686 SfxItemSet
& /*rItemSet*/,
2687 SvxCSS1PropertyInfo
& rPropInfo
,
2688 const SvxCSS1Parser
& /*rParser*/ )
2691 while( n
<4 && pExpr
&& !pExpr
->GetOp() )
2693 SvxBoxItemLine nLine
= n
==0 || n
==2 ? SvxBoxItemLine::BOTTOM
: SvxBoxItemLine::LEFT
;
2695 switch( pExpr
->GetType() )
2700 if( pExpr
->GetColor( aColor
) )
2701 rPropInfo
.GetBorderInfo( nLine
)->aColor
= aColor
;
2706 rPropInfo
.CopyBorderInfo( n
, SVX_CSS1_BORDERINFO_COLOR
);
2708 pExpr
= pExpr
->GetNext();
2713 static void ParseCSS1_border_style( const CSS1Expression
*pExpr
,
2714 SfxItemSet
& /*rItemSet*/,
2715 SvxCSS1PropertyInfo
& rPropInfo
,
2716 const SvxCSS1Parser
& /*rParser*/ )
2719 while( n
<4 && pExpr
&& !pExpr
->GetOp() )
2721 SvxBoxItemLine nLine
= n
==0 || n
==2 ? SvxBoxItemLine::BOTTOM
: SvxBoxItemLine::LEFT
;
2722 sal_uInt16 nValue
= 0;
2723 if( CSS1_IDENT
==pExpr
->GetType() &&
2724 SvxCSS1Parser::GetEnum( aBorderStyleTable
, pExpr
->GetString(),
2727 rPropInfo
.GetBorderInfo( nLine
)->eStyle
= static_cast<CSS1BorderStyle
>(nValue
);
2729 rPropInfo
.CopyBorderInfo( n
, SVX_CSS1_BORDERINFO_STYLE
);
2731 pExpr
= pExpr
->GetNext();
2736 static void ParseCSS1_border_top( const CSS1Expression
*pExpr
,
2737 SfxItemSet
&rItemSet
,
2738 SvxCSS1PropertyInfo
& rPropInfo
,
2739 const SvxCSS1Parser
& rParser
)
2741 ParseCSS1_border_xxx( pExpr
, rItemSet
, rPropInfo
, rParser
, SvxBoxItemLine::TOP
, false );
2744 static void ParseCSS1_border_right( const CSS1Expression
*pExpr
,
2745 SfxItemSet
&rItemSet
,
2746 SvxCSS1PropertyInfo
& rPropInfo
,
2747 const SvxCSS1Parser
& rParser
)
2749 ParseCSS1_border_xxx( pExpr
, rItemSet
, rPropInfo
, rParser
, SvxBoxItemLine::RIGHT
, false );
2752 static void ParseCSS1_border_bottom( const CSS1Expression
*pExpr
,
2753 SfxItemSet
&rItemSet
,
2754 SvxCSS1PropertyInfo
& rPropInfo
,
2755 const SvxCSS1Parser
& rParser
)
2757 ParseCSS1_border_xxx( pExpr
, rItemSet
, rPropInfo
, rParser
, SvxBoxItemLine::BOTTOM
, false );
2760 static void ParseCSS1_border_left( const CSS1Expression
*pExpr
,
2761 SfxItemSet
&rItemSet
,
2762 SvxCSS1PropertyInfo
& rPropInfo
,
2763 const SvxCSS1Parser
& rParser
)
2765 ParseCSS1_border_xxx( pExpr
, rItemSet
, rPropInfo
, rParser
, SvxBoxItemLine::LEFT
, false );
2768 static void ParseCSS1_border( const CSS1Expression
*pExpr
,
2769 SfxItemSet
&rItemSet
,
2770 SvxCSS1PropertyInfo
& rPropInfo
,
2771 const SvxCSS1Parser
& rParser
)
2773 ParseCSS1_border_xxx( pExpr
, rItemSet
, rPropInfo
, rParser
, SvxBoxItemLine::TOP
, true );
2776 static void ParseCSS1_float( const CSS1Expression
*pExpr
,
2777 SfxItemSet
& /*rItemSet*/,
2778 SvxCSS1PropertyInfo
& rPropInfo
,
2779 const SvxCSS1Parser
& /*rParser*/ )
2781 assert(pExpr
&& "no expression");
2783 if( CSS1_IDENT
==pExpr
->GetType() )
2786 if( SvxCSS1Parser::GetEnum( aFloatTable
, pExpr
->GetString(), nFloat
) )
2787 rPropInfo
.m_eFloat
= static_cast<SvxAdjust
>(nFloat
);
2791 static void ParseCSS1_position( const CSS1Expression
*pExpr
,
2792 SfxItemSet
& /*rItemSet*/,
2793 SvxCSS1PropertyInfo
& rPropInfo
,
2794 const SvxCSS1Parser
& /*rParser*/ )
2796 assert(pExpr
&& "no expression");
2798 if( CSS1_IDENT
==pExpr
->GetType() )
2801 if( SvxCSS1Parser::GetEnum( aPositionTable
, pExpr
->GetString(), nPos
) )
2802 rPropInfo
.m_ePosition
= static_cast<SvxCSS1Position
>(nPos
);
2806 static void ParseCSS1_length( const CSS1Expression
*pExpr
,
2807 tools::Long
& rLength
,
2808 SvxCSS1LengthType
& rLengthType
,
2811 switch( pExpr
->GetType() )
2814 if( pExpr
->GetString().equalsIgnoreAsciiCase( "auto" ) )
2817 rLengthType
= SVX_CSS1_LTYPE_AUTO
;
2822 rLength
= pExpr
->GetSLength();
2823 rLengthType
= SVX_CSS1_LTYPE_TWIP
;
2826 case CSS1_PIXLENGTH
:
2827 case CSS1_NUMBER
: // because of Netscape and IE
2829 double fLength
= pExpr
->GetNumber();
2830 if (fLength
< SAL_MAX_INT32
/2.0 && fLength
> SAL_MIN_INT32
/2.0)
2832 tools::Long nWidthL
= static_cast<tools::Long
>(fLength
);
2833 tools::Long nPWidth
= bHori
? 0 : nWidthL
;
2834 tools::Long nPHeight
= bHori
? nWidthL
: 0;
2835 SvxCSS1Parser::PixelToTwip( nPWidth
, nPHeight
);
2836 rLength
= (bHori
? nPHeight
: nPWidth
);
2837 rLengthType
= SVX_CSS1_LTYPE_TWIP
;
2842 case CSS1_PERCENTAGE
:
2843 rLength
= static_cast<tools::Long
>(std::min(pExpr
->GetNumber(), 100.0));
2844 rLengthType
= SVX_CSS1_LTYPE_PERCENTAGE
;
2852 static void ParseCSS1_width( const CSS1Expression
*pExpr
,
2853 SfxItemSet
& /*rItemSet*/,
2854 SvxCSS1PropertyInfo
& rPropInfo
,
2855 const SvxCSS1Parser
& /*rParser*/ )
2857 ParseCSS1_length( pExpr
, rPropInfo
.m_nWidth
, rPropInfo
.m_eWidthType
, true );
2860 static void ParseCSS1_height( const CSS1Expression
*pExpr
,
2861 SfxItemSet
& /*rItemSet*/,
2862 SvxCSS1PropertyInfo
& rPropInfo
,
2863 const SvxCSS1Parser
& /*rParser*/ )
2865 ParseCSS1_length( pExpr
, rPropInfo
.m_nHeight
, rPropInfo
.m_eHeightType
, false );
2868 static void ParseCSS1_left( const CSS1Expression
*pExpr
,
2869 SfxItemSet
& /*rItemSet*/,
2870 SvxCSS1PropertyInfo
& rPropInfo
,
2871 const SvxCSS1Parser
& /*rParser*/ )
2873 ParseCSS1_length( pExpr
, rPropInfo
.m_nLeft
, rPropInfo
.m_eLeftType
, true );
2876 static void ParseCSS1_top( const CSS1Expression
*pExpr
,
2877 SfxItemSet
& /*rItemSet*/,
2878 SvxCSS1PropertyInfo
& rPropInfo
,
2879 const SvxCSS1Parser
& /*rParser*/ )
2881 ParseCSS1_length( pExpr
, rPropInfo
.m_nTop
, rPropInfo
.m_eTopType
, false );
2884 // Feature: PrintExt
2885 static void ParseCSS1_size( const CSS1Expression
*pExpr
,
2886 SfxItemSet
& /*rItemSet*/,
2887 SvxCSS1PropertyInfo
& rPropInfo
,
2888 const SvxCSS1Parser
& /*rParser*/ )
2891 while( n
<2 && pExpr
&& !pExpr
->GetOp() )
2893 switch( pExpr
->GetType() )
2898 if( SvxCSS1Parser::GetEnum( aSizeTable
, pExpr
->GetString(),
2901 rPropInfo
.m_eSizeType
= static_cast<SvxCSS1SizeType
>(nValue
);
2907 rPropInfo
.m_nHeight
= pExpr
->GetSLength();
2909 rPropInfo
.m_nWidth
= rPropInfo
.m_nHeight
;
2910 rPropInfo
.m_eSizeType
= SVX_CSS1_STYPE_TWIP
;
2913 case CSS1_PIXLENGTH
:
2915 double fHeight
= pExpr
->GetNumber();
2916 if (fHeight
< SAL_MAX_INT32
/2.0 && fHeight
> SAL_MIN_INT32
/2.0)
2918 tools::Long nPHeight
= static_cast<tools::Long
>(fHeight
);
2919 tools::Long nPWidth
= n
==0 ? nPHeight
: 0;
2920 SvxCSS1Parser::PixelToTwip( nPWidth
, nPHeight
);
2921 rPropInfo
.m_nHeight
= nPHeight
;
2923 rPropInfo
.m_nWidth
= nPWidth
;
2924 rPropInfo
.m_eSizeType
= SVX_CSS1_STYPE_TWIP
;
2932 pExpr
= pExpr
->GetNext();
2937 static void ParseCSS1_page_break_xxx( const CSS1Expression
*pExpr
,
2938 SvxCSS1PageBreak
& rPBreak
)
2940 if( CSS1_IDENT
== pExpr
->GetType() )
2943 if( SvxCSS1Parser::GetEnum( aPageBreakTable
, pExpr
->GetString(),
2946 rPBreak
= static_cast<SvxCSS1PageBreak
>(nValue
);
2951 static void ParseCSS1_page_break_before( const CSS1Expression
*pExpr
,
2952 SfxItemSet
& /*rItemSet*/,
2953 SvxCSS1PropertyInfo
& rPropInfo
,
2954 const SvxCSS1Parser
& /*rParser*/ )
2956 ParseCSS1_page_break_xxx( pExpr
, rPropInfo
.m_ePageBreakBefore
);
2959 static void ParseCSS1_page_break_after( const CSS1Expression
*pExpr
,
2960 SfxItemSet
& /*rItemSet*/,
2961 SvxCSS1PropertyInfo
& rPropInfo
,
2962 const SvxCSS1Parser
& /*rParser*/ )
2964 ParseCSS1_page_break_xxx( pExpr
, rPropInfo
.m_ePageBreakAfter
);
2967 static void ParseCSS1_page_break_inside( const CSS1Expression
*pExpr
,
2968 SfxItemSet
&rItemSet
,
2969 SvxCSS1PropertyInfo
& /*rPropInfo*/,
2970 const SvxCSS1Parser
& /*rParser*/ )
2972 SvxCSS1PageBreak
eBreak(SVX_CSS1_PBREAK_NONE
);
2973 ParseCSS1_page_break_xxx( pExpr
, eBreak
);
2975 bool bSetSplit
= false, bSplit
= true;
2978 case SVX_CSS1_PBREAK_AUTO
:
2981 case SVX_CSS1_PBREAK_AVOID
:
2990 rItemSet
.Put( SvxFormatSplitItem( bSplit
, aItemIds
.nFormatSplit
) );
2993 static void ParseCSS1_widows( const CSS1Expression
*pExpr
,
2994 SfxItemSet
&rItemSet
,
2995 SvxCSS1PropertyInfo
& /*rPropInfo*/,
2996 const SvxCSS1Parser
& /*rParser*/ )
2998 if( CSS1_NUMBER
== pExpr
->GetType() )
3000 sal_uInt8 nVal
= pExpr
->GetNumber() <= 255
3001 ? static_cast<sal_uInt8
>(pExpr
->GetNumber())
3003 SvxWidowsItem
aWidowsItem( nVal
, aItemIds
.nWidows
);
3004 rItemSet
.Put( aWidowsItem
);
3008 static void ParseCSS1_orphans( const CSS1Expression
*pExpr
,
3009 SfxItemSet
&rItemSet
,
3010 SvxCSS1PropertyInfo
& /*rPropInfo*/,
3011 const SvxCSS1Parser
& /*rParser*/ )
3013 if( CSS1_NUMBER
== pExpr
->GetType() )
3015 sal_uInt8 nVal
= pExpr
->GetNumber() <= 255
3016 ? static_cast<sal_uInt8
>(pExpr
->GetNumber())
3018 SvxOrphansItem
aOrphansItem( nVal
, aItemIds
.nOrphans
);
3019 rItemSet
.Put( aOrphansItem
);
3023 static void ParseCSS1_so_language( const CSS1Expression
*pExpr
,
3024 SfxItemSet
&rItemSet
,
3025 SvxCSS1PropertyInfo
& /*rPropInfo*/,
3026 const SvxCSS1Parser
& /*rParser*/ )
3028 if( CSS1_IDENT
!= pExpr
->GetType() && CSS1_STRING
!= pExpr
->GetType() )
3031 LanguageType eLang
= LanguageTag::convertToLanguageTypeWithFallback( pExpr
->GetString() );
3032 if( LANGUAGE_DONTKNOW
!= eLang
)
3034 SvxLanguageItem
aLang( eLang
, aItemIds
.nLanguage
);
3035 rItemSet
.Put( aLang
);
3036 aLang
.SetWhich( aItemIds
.nLanguageCJK
);
3037 rItemSet
.Put( aLang
);
3038 aLang
.SetWhich( aItemIds
.nLanguageCTL
);
3039 rItemSet
.Put( aLang
);
3043 static void ParseCSS1_visibility(const CSS1Expression
* pExpr
, SfxItemSet
& /*rItemSet*/,
3044 SvxCSS1PropertyInfo
& rPropInfo
, const SvxCSS1Parser
& /*rParser*/)
3046 if (pExpr
->GetType() != CSS1_IDENT
)
3049 rPropInfo
.m_bVisible
= pExpr
->GetString() != "hidden";
3052 static void ParseCSS1_white_space(const CSS1Expression
* pExpr
, SfxItemSet
& /*rItemSet*/,
3053 SvxCSS1PropertyInfo
& rPropInfo
, const SvxCSS1Parser
& /*rParser*/)
3055 if (pExpr
->GetType() == CSS1_IDENT
)
3057 if (pExpr
->GetString().equalsIgnoreAsciiCase("pre")
3058 || pExpr
->GetString().equalsIgnoreAsciiCase("pre-wrap"))
3060 rPropInfo
.m_bPreserveSpace
= true;
3067 // the assignment of property to parsing function
3068 struct CSS1PropEntry
3070 std::string_view pName
;
3071 FnParseCSS1Prop pFunc
;
3076 // the table with assignments
3077 CSS1PropEntry
constexpr aCSS1PropFnTab
[] =
3079 { sCSS1_P_background
, ParseCSS1_background
},
3080 { sCSS1_P_background_color
, ParseCSS1_background_color
},
3081 { sCSS1_P_border
, ParseCSS1_border
},
3082 { sCSS1_P_border_bottom
, ParseCSS1_border_bottom
},
3083 { sCSS1_P_border_bottom_width
, ParseCSS1_border_bottom_width
},
3084 { sCSS1_P_border_color
, ParseCSS1_border_color
},
3085 { sCSS1_P_border_left
, ParseCSS1_border_left
},
3086 { sCSS1_P_border_left_width
, ParseCSS1_border_left_width
},
3087 { sCSS1_P_border_right
, ParseCSS1_border_right
},
3088 { sCSS1_P_border_right_width
, ParseCSS1_border_right_width
},
3089 { sCSS1_P_border_style
, ParseCSS1_border_style
},
3090 { sCSS1_P_border_top
, ParseCSS1_border_top
},
3091 { sCSS1_P_border_top_width
, ParseCSS1_border_top_width
},
3092 { sCSS1_P_border_width
, ParseCSS1_border_width
},
3093 { sCSS1_P_color
, ParseCSS1_color
},
3094 { sCSS1_P_column_count
, ParseCSS1_column_count
},
3095 { sCSS1_P_direction
, ParseCSS1_direction
},
3096 { sCSS1_P_float
, ParseCSS1_float
},
3097 { sCSS1_P_font
, ParseCSS1_font
},
3098 { sCSS1_P_font_family
, ParseCSS1_font_family
},
3099 { sCSS1_P_font_size
, ParseCSS1_font_size
},
3100 { sCSS1_P_font_style
, ParseCSS1_font_style
},
3101 { sCSS1_P_font_variant
, ParseCSS1_font_variant
},
3102 { sCSS1_P_font_weight
, ParseCSS1_font_weight
},
3103 { sCSS1_P_height
, ParseCSS1_height
},
3104 { sCSS1_P_left
, ParseCSS1_left
},
3105 { sCSS1_P_letter_spacing
, ParseCSS1_letter_spacing
},
3106 { sCSS1_P_line_height
, ParseCSS1_line_height
},
3107 { sCSS1_P_list_style_type
, ParseCSS1_list_style_type
},
3108 { sCSS1_P_margin
, ParseCSS1_margin
},
3109 { sCSS1_P_margin_bottom
, ParseCSS1_margin_bottom
},
3110 { sCSS1_P_margin_left
, ParseCSS1_margin_left
},
3111 { sCSS1_P_margin_right
, ParseCSS1_margin_right
},
3112 { sCSS1_P_margin_top
, ParseCSS1_margin_top
},
3113 { sCSS1_P_orphans
, ParseCSS1_orphans
},
3114 { sCSS1_P_padding
, ParseCSS1_padding
},
3115 { sCSS1_P_padding_bottom
, ParseCSS1_padding_bottom
},
3116 { sCSS1_P_padding_left
, ParseCSS1_padding_left
},
3117 { sCSS1_P_padding_right
, ParseCSS1_padding_right
},
3118 { sCSS1_P_padding_top
, ParseCSS1_padding_top
},
3119 { sCSS1_P_page_break_after
, ParseCSS1_page_break_after
},
3120 { sCSS1_P_page_break_before
, ParseCSS1_page_break_before
},
3121 { sCSS1_P_page_break_inside
, ParseCSS1_page_break_inside
},
3122 { sCSS1_P_position
, ParseCSS1_position
},
3123 { sCSS1_P_size
, ParseCSS1_size
},
3124 { sCSS1_P_so_language
, ParseCSS1_so_language
},
3125 { sCSS1_P_text_align
, ParseCSS1_text_align
},
3126 { sCSS1_P_text_decoration
, ParseCSS1_text_decoration
},
3127 { sCSS1_P_text_indent
, ParseCSS1_text_indent
},
3128 { sCSS1_P_text_transform
, ParseCSS1_text_transform
},
3129 { sCSS1_P_top
, ParseCSS1_top
},
3130 { sCSS1_P_visibility
, ParseCSS1_visibility
},
3131 { sCSS1_white_space
, ParseCSS1_white_space
},
3132 { sCSS1_P_widows
, ParseCSS1_widows
},
3133 { sCSS1_P_width
, ParseCSS1_width
},
3136 static_assert(std::is_sorted(std::begin(aCSS1PropFnTab
), std::end(aCSS1PropFnTab
),
3137 [](const auto& lhs
, const auto& rhs
) constexpr
3138 { return lhs
.pName
< rhs
.pName
; }));
3140 static bool CSS1PropEntryFindCompare(CSS1PropEntry
const & lhs
, OUString
const & s
)
3142 return s
.compareToIgnoreAsciiCaseAscii(lhs
.pName
) > 0;
3145 void SvxCSS1Parser::DeclarationParsed( const OUString
& rProperty
,
3146 std::unique_ptr
<CSS1Expression
> pExpr
)
3148 assert(m_pItemSet
&& "DeclarationParsed() without ItemSet");
3150 auto it
= std::lower_bound( std::begin(aCSS1PropFnTab
), std::end(aCSS1PropFnTab
), rProperty
,
3151 CSS1PropEntryFindCompare
);
3152 if( it
!= std::end(aCSS1PropFnTab
) && !CSS1PropEntryFindCompare(*it
,rProperty
) )
3154 it
->pFunc( pExpr
.get(), *m_pItemSet
, *m_pPropInfo
, *this );
3158 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */