Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <stdlib.h>
21 :
22 : #include <o3tl/ptr_container.hxx>
23 : #include <svx/svxids.hrc>
24 : #include <i18nlangtag/languagetag.hxx>
25 : #include <svtools/ctrltool.hxx>
26 : #include <svl/urihelper.hxx>
27 : #include <editeng/udlnitem.hxx>
28 : #include <editeng/adjustitem.hxx>
29 : #include <editeng/blinkitem.hxx>
30 : #include <editeng/crossedoutitem.hxx>
31 : #include <editeng/kernitem.hxx>
32 : #include <editeng/lspcitem.hxx>
33 : #include <editeng/fontitem.hxx>
34 : #include <editeng/postitem.hxx>
35 : #include <editeng/colritem.hxx>
36 : #include <editeng/cmapitem.hxx>
37 : #include <editeng/brushitem.hxx>
38 : #include <editeng/wghtitem.hxx>
39 : #include <editeng/fhgtitem.hxx>
40 : #include <editeng/boxitem.hxx>
41 : #include <editeng/ulspitem.hxx>
42 : #include <editeng/lrspitem.hxx>
43 : #include <editeng/langitem.hxx>
44 : #include <svl/itempool.hxx>
45 : #include <editeng/spltitem.hxx>
46 : #include <editeng/widwitem.hxx>
47 : #include <editeng/frmdiritem.hxx>
48 : #include <editeng/orphitem.hxx>
49 : #include <svtools/svparser.hxx>
50 : #include <vcl/svapp.hxx>
51 : #include <vcl/wrkwin.hxx>
52 :
53 : #include "css1kywd.hxx"
54 : #include "svxcss1.hxx"
55 :
56 : #include <memory>
57 : #include <utility>
58 :
59 : using namespace ::com::sun::star;
60 :
61 : // die Funktionen zum Parsen einer CSS1-Property sind von folgendem Typ:
62 : typedef void (*FnParseCSS1Prop)( const CSS1Expression *pExpr,
63 : SfxItemSet& rItemSet,
64 : SvxCSS1PropertyInfo& rPropInfo,
65 : const SvxCSS1Parser& rParser );
66 :
67 : static CSS1PropertyEnum const aFontSizeTable[] =
68 : {
69 : { "xx-small", 0 },
70 : { "x-small", 1 },
71 : { "small", 2 },
72 : { "medium", 3 },
73 : { "large", 4 },
74 : { "x-large", 5 },
75 : { "xx-large", 6 },
76 : { 0, 0 }
77 : };
78 :
79 : static CSS1PropertyEnum const aFontWeightTable[] =
80 : {
81 : { "extra-light", WEIGHT_NORMAL }, // WEIGHT_ULTRALIGHT (OBS)
82 : { "light", WEIGHT_NORMAL }, // WEIGHT_LIGHT (OBSOLETE)
83 : { "demi-light", WEIGHT_NORMAL }, // WEIGHT_SEMILIGHT (OBS)
84 : { "medium", WEIGHT_NORMAL }, // WEIGHT_MEDIUM (OBS)
85 : { "normal", WEIGHT_NORMAL }, // WEIGHT_MEDIUM
86 : { "demi-bold", WEIGHT_NORMAL }, // WEIGHT_SEMIBOLD (OBS)
87 : { "bold", WEIGHT_BOLD }, // WEIGHT_BOLD (OBSOLETE)
88 : { "extra-bold", WEIGHT_BOLD }, // WEIGHT_ULTRABOLD (OBS)
89 : { "bolder", WEIGHT_BOLD },
90 : { "lighter", WEIGHT_NORMAL },
91 : { 0, 0 }
92 : };
93 :
94 : static CSS1PropertyEnum const aFontStyleTable[] =
95 : {
96 : { "normal", ITALIC_NONE },
97 : { "italic", ITALIC_NORMAL },
98 : { "oblique", ITALIC_NORMAL },
99 : { 0, 0 }
100 : };
101 :
102 : static CSS1PropertyEnum const aFontVariantTable[] =
103 : {
104 : { "normal", SVX_CASEMAP_NOT_MAPPED },
105 : { "small-caps", SVX_CASEMAP_KAPITAELCHEN },
106 : { 0, 0 }
107 : };
108 :
109 : static CSS1PropertyEnum const aTextTransformTable[] =
110 : {
111 : { "uppercase", SVX_CASEMAP_VERSALIEN },
112 : { "lowercase", SVX_CASEMAP_GEMEINE },
113 : { "capitalize", SVX_CASEMAP_TITEL },
114 : { 0, 0 }
115 : };
116 :
117 : static CSS1PropertyEnum const aDirectionTable[] =
118 : {
119 : { "ltr", FRMDIR_HORI_LEFT_TOP },
120 : { "rtl", FRMDIR_HORI_RIGHT_TOP },
121 : { "inherit", FRMDIR_ENVIRONMENT },
122 : { 0, 0 }
123 : };
124 :
125 : static CSS1PropertyEnum const aBGRepeatTable[] =
126 : {
127 : { "repeat", GPOS_TILED },
128 : { "repeat-x", GPOS_TILED },
129 : { "repeat-y", GPOS_TILED },
130 : { "no-repeat", GPOS_NONE },
131 : { 0, 0 }
132 : };
133 :
134 : static CSS1PropertyEnum const aBGHoriPosTable[] =
135 : {
136 : { "left", GPOS_LT },
137 : { "center", GPOS_MT },
138 : { "right", GPOS_RT },
139 : { 0, 0 }
140 : };
141 :
142 : static CSS1PropertyEnum const aBGVertPosTable[] =
143 : {
144 : { "top", GPOS_LT },
145 : { "middle", GPOS_LM },
146 : { "bottom", GPOS_LB },
147 : { 0, 0 }
148 : };
149 :
150 : static CSS1PropertyEnum const aTextAlignTable[] =
151 : {
152 : { "left", SVX_ADJUST_LEFT },
153 : { "center", SVX_ADJUST_CENTER },
154 : { "right", SVX_ADJUST_RIGHT },
155 : { "justify", SVX_ADJUST_BLOCK },
156 : { 0, 0 }
157 : };
158 :
159 : static CSS1PropertyEnum const aBorderWidthTable[] =
160 : {
161 : { "thin", 0 }, // DEF_LINE_WIDTH_0 / DEF_DOUBLE_LINE0
162 : { "medium", 1 }, // DEF_LINE_WIDTH_1 / DEF_DOUBLE_LINE1
163 : { "thick", 2 }, // DEF_LINE_WIDTH_2 / DEF_DOUBLE_LINE2
164 : { 0, 0 }
165 : };
166 :
167 : enum CSS1BorderStyle { CSS1_BS_NONE, CSS1_BS_SINGLE, CSS1_BS_DOUBLE, CSS1_BS_DOTTED, CSS1_BS_DASHED, CSS1_BS_GROOVE, CSS1_BS_RIDGE, CSS1_BS_INSET, CSS1_BS_OUTSET };
168 :
169 : static CSS1PropertyEnum const aBorderStyleTable[] =
170 : {
171 : { "none", CSS1_BS_NONE },
172 : { "dotted", CSS1_BS_DOTTED },
173 : { "dashed", CSS1_BS_DASHED },
174 : { "solid", CSS1_BS_SINGLE },
175 : { "double", CSS1_BS_DOUBLE },
176 : { "groove", CSS1_BS_GROOVE },
177 : { "ridge", CSS1_BS_RIDGE },
178 : { "inset", CSS1_BS_INSET },
179 : { "outset", CSS1_BS_OUTSET },
180 : { 0, 0 }
181 : };
182 :
183 : static CSS1PropertyEnum const aFloatTable[] =
184 : {
185 : { "left", SVX_ADJUST_LEFT },
186 : { "right", SVX_ADJUST_RIGHT },
187 : { "none", SVX_ADJUST_END },
188 : { 0, 0 }
189 : };
190 :
191 : static CSS1PropertyEnum const aPositionTable[] =
192 : {
193 : { "absolute", SVX_CSS1_POS_ABSOLUTE },
194 : { "relative", SVX_CSS1_POS_RELATIVE },
195 : { "static", SVX_CSS1_POS_STATIC },
196 : { 0, 0 }
197 : };
198 :
199 : // Feature: PrintExt
200 : static CSS1PropertyEnum const aSizeTable[] =
201 : {
202 : { "auto", SVX_CSS1_STYPE_AUTO },
203 : { "landscape", SVX_CSS1_STYPE_LANDSCAPE },
204 : { "portrait", SVX_CSS1_STYPE_PORTRAIT },
205 : { 0, 0 }
206 : };
207 :
208 : static CSS1PropertyEnum const aPageBreakTable[] =
209 : {
210 : { "auto", SVX_CSS1_PBREAK_AUTO },
211 : { "always", SVX_CSS1_PBREAK_ALWAYS },
212 : { "avoid", SVX_CSS1_PBREAK_AVOID },
213 : { "left", SVX_CSS1_PBREAK_LEFT },
214 : { "right", SVX_CSS1_PBREAK_RIGHT },
215 : { 0, 0 }
216 : };
217 :
218 : // /Feature: PrintExt
219 :
220 : static sal_uInt16 const aBorderWidths[] =
221 : {
222 : DEF_LINE_WIDTH_0,
223 : DEF_LINE_WIDTH_5,
224 : DEF_LINE_WIDTH_1
225 : };
226 :
227 : #undef SBORDER_ENTRY
228 : #undef DBORDER_ENTRY
229 :
230 : struct SvxCSS1ItemIds
231 : {
232 : sal_uInt16 nFont;
233 : sal_uInt16 nFontCJK;
234 : sal_uInt16 nFontCTL;
235 : sal_uInt16 nPosture;
236 : sal_uInt16 nPostureCJK;
237 : sal_uInt16 nPostureCTL;
238 : sal_uInt16 nWeight;
239 : sal_uInt16 nWeightCJK;
240 : sal_uInt16 nWeightCTL;
241 : sal_uInt16 nFontHeight;
242 : sal_uInt16 nFontHeightCJK;
243 : sal_uInt16 nFontHeightCTL;
244 : sal_uInt16 nUnderline;
245 : sal_uInt16 nOverline;
246 : sal_uInt16 nCrossedOut;
247 : sal_uInt16 nColor;
248 : sal_uInt16 nKerning;
249 : sal_uInt16 nCaseMap;
250 : sal_uInt16 nBlink;
251 :
252 : sal_uInt16 nLineSpacing;
253 : sal_uInt16 nAdjust;
254 : sal_uInt16 nWidows;
255 : sal_uInt16 nOrphans;
256 : sal_uInt16 nFormatSplit;
257 :
258 : sal_uInt16 nLRSpace;
259 : sal_uInt16 nULSpace;
260 : sal_uInt16 nBox;
261 : sal_uInt16 nBrush;
262 :
263 : sal_uInt16 nLanguage;
264 : sal_uInt16 nLanguageCJK;
265 : sal_uInt16 nLanguageCTL;
266 : sal_uInt16 nDirection;
267 : };
268 :
269 : static SvxCSS1ItemIds aItemIds;
270 :
271 : struct SvxCSS1BorderInfo
272 : {
273 : Color aColor;
274 : sal_uInt16 nAbsWidth;
275 : sal_uInt16 nNamedWidth;
276 : CSS1BorderStyle eStyle;
277 :
278 2230 : SvxCSS1BorderInfo() :
279 : aColor( COL_BLACK ), nAbsWidth( USHRT_MAX ),
280 2230 : nNamedWidth( USHRT_MAX ), eStyle( CSS1_BS_NONE )
281 2230 : {}
282 :
283 4 : SvxCSS1BorderInfo( const SvxCSS1BorderInfo& rInfo ) :
284 : aColor( rInfo.aColor ), nAbsWidth( rInfo.nAbsWidth ),
285 4 : nNamedWidth( rInfo.nNamedWidth ), eStyle( rInfo.eStyle )
286 4 : {}
287 :
288 : void SetBorderLine( SvxBoxItemLine nLine, SvxBoxItem &rBoxItem ) const;
289 : };
290 :
291 1117 : void SvxCSS1BorderInfo::SetBorderLine( SvxBoxItemLine nLine, SvxBoxItem &rBoxItem ) const
292 : {
293 2234 : if( CSS1_BS_NONE==eStyle || nAbsWidth==0 ||
294 1117 : (nAbsWidth==USHRT_MAX && nNamedWidth==USHRT_MAX) )
295 : {
296 0 : rBoxItem.SetLine( 0, nLine );
297 1117 : return;
298 : }
299 :
300 1117 : ::editeng::SvxBorderLine aBorderLine( &aColor );
301 :
302 : // Linien-Stil doppelt oder einfach?
303 1117 : switch ( eStyle )
304 : {
305 : case CSS1_BS_SINGLE:
306 1114 : aBorderLine.SetBorderLineStyle(table::BorderLineStyle::SOLID);
307 1114 : break;
308 : case CSS1_BS_DOUBLE:
309 1 : aBorderLine.SetBorderLineStyle(table::BorderLineStyle::DOUBLE);
310 1 : break;
311 : case CSS1_BS_DOTTED:
312 1 : aBorderLine.SetBorderLineStyle(table::BorderLineStyle::DOTTED);
313 1 : break;
314 : case CSS1_BS_DASHED:
315 1 : aBorderLine.SetBorderLineStyle(table::BorderLineStyle::DASHED);
316 1 : break;
317 : case CSS1_BS_GROOVE:
318 0 : aBorderLine.SetBorderLineStyle(table::BorderLineStyle::ENGRAVED);
319 0 : break;
320 : case CSS1_BS_RIDGE:
321 0 : aBorderLine.SetBorderLineStyle(table::BorderLineStyle::EMBOSSED);
322 0 : break;
323 : case CSS1_BS_INSET:
324 0 : aBorderLine.SetBorderLineStyle(table::BorderLineStyle::INSET);
325 0 : break;
326 : case CSS1_BS_OUTSET:
327 0 : aBorderLine.SetBorderLineStyle(table::BorderLineStyle::OUTSET);
328 0 : break;
329 : default:
330 0 : aBorderLine.SetBorderLineStyle(table::BorderLineStyle::NONE);
331 0 : break;
332 : }
333 :
334 : // benannte Breite umrechnenen, wenn keine absolute gegeben ist
335 1117 : if( nAbsWidth==USHRT_MAX )
336 0 : aBorderLine.SetWidth( aBorderWidths[ nNamedWidth ] );
337 : else
338 1117 : aBorderLine.SetWidth( nAbsWidth );
339 :
340 1117 : rBoxItem.SetLine( &aBorderLine, nLine );
341 : }
342 :
343 920 : SvxCSS1PropertyInfo::SvxCSS1PropertyInfo()
344 : {
345 4600 : for( size_t i=0; i<SAL_N_ELEMENTS(aBorderInfos); ++i )
346 3680 : aBorderInfos[i] = 0;
347 :
348 920 : Clear();
349 920 : }
350 :
351 17 : SvxCSS1PropertyInfo::SvxCSS1PropertyInfo( const SvxCSS1PropertyInfo& rProp ) :
352 : aId( rProp.aId ),
353 : bTopMargin( rProp.bTopMargin ),
354 : bBottomMargin( rProp.bBottomMargin ),
355 : bLeftMargin( rProp.bLeftMargin ),
356 : bRightMargin( rProp.bRightMargin ),
357 : bTextIndent( rProp.bTextIndent ),
358 : eFloat( rProp.eFloat ),
359 : ePosition( rProp.ePosition ),
360 : nTopBorderDistance( rProp.nTopBorderDistance ),
361 : nBottomBorderDistance( rProp.nBottomBorderDistance ),
362 : nLeftBorderDistance( rProp.nLeftBorderDistance ),
363 : nRightBorderDistance( rProp.nRightBorderDistance ),
364 : nColumnCount( rProp.nColumnCount ),
365 : nLeft( rProp.nLeft ),
366 : nTop( rProp.nTop ),
367 : nWidth( rProp.nWidth ),
368 : nHeight( rProp.nHeight ),
369 : nLeftMargin( rProp.nLeftMargin ),
370 : nRightMargin( rProp.nRightMargin ),
371 : eLeftType( rProp.eLeftType ),
372 : eTopType( rProp.eTopType ),
373 : eWidthType( rProp.eWidthType ),
374 : eHeightType( rProp.eHeightType ),
375 : // Feature: PrintExt
376 : eSizeType( rProp.eSizeType ),
377 : ePageBreakBefore( rProp.ePageBreakBefore ),
378 17 : ePageBreakAfter( rProp.ePageBreakAfter )
379 : // /Feature: PrintExt
380 : {
381 85 : for( size_t i=0; i<SAL_N_ELEMENTS(aBorderInfos); ++i )
382 68 : aBorderInfos[i] = rProp.aBorderInfos[i]
383 4 : ? new SvxCSS1BorderInfo( *rProp.aBorderInfos[i] )
384 72 : : 0;
385 17 : }
386 :
387 1874 : SvxCSS1PropertyInfo::~SvxCSS1PropertyInfo()
388 : {
389 937 : DestroyBorderInfos();
390 937 : }
391 :
392 2194 : void SvxCSS1PropertyInfo::DestroyBorderInfos()
393 : {
394 10970 : for( size_t i=0; i<SAL_N_ELEMENTS(aBorderInfos); ++i )
395 : {
396 8776 : delete aBorderInfos[i];
397 8776 : aBorderInfos[i] = 0;
398 : }
399 2194 : }
400 :
401 977 : void SvxCSS1PropertyInfo::Clear()
402 : {
403 977 : aId.clear();
404 977 : bTopMargin = bBottomMargin = false;
405 977 : bLeftMargin = bRightMargin = bTextIndent = false;
406 977 : nLeftMargin = nRightMargin = 0;
407 977 : eFloat = SVX_ADJUST_END;
408 :
409 977 : ePosition = SVX_CSS1_POS_NONE;
410 : nTopBorderDistance = nBottomBorderDistance =
411 977 : nLeftBorderDistance = nRightBorderDistance = USHRT_MAX;
412 :
413 977 : nColumnCount = 0;
414 :
415 977 : nLeft = nTop = nWidth = nHeight = 0;
416 977 : eLeftType = eTopType = eWidthType = eHeightType = SVX_CSS1_LTYPE_NONE;
417 :
418 : // Feature: PrintExt
419 977 : eSizeType = SVX_CSS1_STYPE_NONE;
420 977 : ePageBreakBefore = SVX_CSS1_PBREAK_NONE;
421 977 : ePageBreakAfter = SVX_CSS1_PBREAK_NONE;
422 :
423 977 : DestroyBorderInfos();
424 977 : }
425 :
426 3 : void SvxCSS1PropertyInfo::Merge( const SvxCSS1PropertyInfo& rProp )
427 : {
428 3 : if( rProp.bTopMargin )
429 0 : bTopMargin = true;
430 3 : if( rProp.bBottomMargin )
431 0 : bBottomMargin = true;
432 :
433 3 : if( rProp.bLeftMargin )
434 : {
435 0 : bLeftMargin = true;
436 0 : nLeftMargin = rProp.nLeftMargin;
437 : }
438 3 : if( rProp.bRightMargin )
439 : {
440 0 : bRightMargin = true;
441 0 : nRightMargin = rProp.nRightMargin;
442 : }
443 3 : if( rProp.bTextIndent )
444 0 : bTextIndent = true;
445 :
446 15 : for( size_t i=0; i<SAL_N_ELEMENTS(aBorderInfos); ++i )
447 : {
448 12 : if( rProp.aBorderInfos[i] )
449 : {
450 0 : if( aBorderInfos[i] )
451 0 : delete aBorderInfos[i];
452 :
453 0 : aBorderInfos[i] = new SvxCSS1BorderInfo( *rProp.aBorderInfos[i] );
454 : }
455 : }
456 :
457 3 : if( USHRT_MAX != rProp.nTopBorderDistance )
458 0 : nTopBorderDistance = rProp.nTopBorderDistance;
459 3 : if( USHRT_MAX != rProp.nBottomBorderDistance )
460 0 : nBottomBorderDistance = rProp.nBottomBorderDistance;
461 3 : if( USHRT_MAX != rProp.nLeftBorderDistance )
462 0 : nLeftBorderDistance = rProp.nLeftBorderDistance;
463 3 : if( USHRT_MAX != rProp.nRightBorderDistance )
464 0 : nRightBorderDistance = rProp.nRightBorderDistance;
465 :
466 3 : nColumnCount = rProp.nColumnCount;
467 :
468 3 : if( rProp.eFloat != SVX_ADJUST_END )
469 0 : eFloat = rProp.eFloat;
470 :
471 3 : if( rProp.ePosition != SVX_CSS1_POS_NONE )
472 0 : ePosition = rProp.ePosition;
473 :
474 : // Feature: PrintExt
475 3 : if( rProp.eSizeType != SVX_CSS1_STYPE_NONE )
476 : {
477 0 : eSizeType = rProp.eSizeType;
478 0 : nWidth = rProp.nWidth;
479 0 : nHeight = rProp.nHeight;
480 : }
481 :
482 3 : if( rProp.ePageBreakBefore != SVX_CSS1_PBREAK_NONE )
483 0 : ePageBreakBefore = rProp.ePageBreakBefore;
484 :
485 3 : if( rProp.ePageBreakAfter != SVX_CSS1_PBREAK_NONE )
486 0 : ePageBreakAfter = rProp.ePageBreakAfter;
487 :
488 : // /Feature: PrintExt
489 :
490 3 : if( rProp.eLeftType != SVX_CSS1_LTYPE_NONE )
491 : {
492 0 : eLeftType = rProp.eLeftType;
493 0 : nLeft = rProp.nLeft;
494 : }
495 :
496 3 : if( rProp.eTopType != SVX_CSS1_LTYPE_NONE )
497 : {
498 0 : eTopType = rProp.eTopType;
499 0 : nTop = rProp.nTop;
500 : }
501 :
502 3 : if( rProp.eWidthType != SVX_CSS1_LTYPE_NONE )
503 : {
504 0 : eWidthType = rProp.eWidthType;
505 0 : nWidth = rProp.nWidth;
506 : }
507 :
508 3 : if( rProp.eHeightType != SVX_CSS1_LTYPE_NONE )
509 : {
510 0 : eHeightType = rProp.eHeightType;
511 0 : nHeight = rProp.nHeight;
512 : }
513 3 : }
514 :
515 3354 : SvxCSS1BorderInfo *SvxCSS1PropertyInfo::GetBorderInfo( SvxBoxItemLine nLine, bool bCreate )
516 : {
517 3354 : sal_uInt16 nPos = 0;
518 3354 : switch( nLine )
519 : {
520 837 : case SvxBoxItemLine::TOP: nPos = 0; break;
521 843 : case SvxBoxItemLine::BOTTOM: nPos = 1; break;
522 837 : case SvxBoxItemLine::LEFT: nPos = 2; break;
523 837 : case SvxBoxItemLine::RIGHT: nPos = 3; break;
524 : }
525 :
526 3354 : if( !aBorderInfos[nPos] && bCreate )
527 2230 : aBorderInfos[nPos] = new SvxCSS1BorderInfo;
528 :
529 3354 : return aBorderInfos[nPos];
530 : }
531 :
532 0 : void SvxCSS1PropertyInfo::CopyBorderInfo( SvxBoxItemLine nSrcLine, SvxBoxItemLine nDstLine,
533 : sal_uInt16 nWhat )
534 : {
535 0 : SvxCSS1BorderInfo *pSrcInfo = GetBorderInfo( nSrcLine, false );
536 0 : if( !pSrcInfo )
537 0 : return;
538 :
539 0 : SvxCSS1BorderInfo *pDstInfo = GetBorderInfo( nDstLine );
540 0 : if( (nWhat & SVX_CSS1_BORDERINFO_WIDTH) != 0 )
541 : {
542 0 : pDstInfo->nAbsWidth = pSrcInfo->nAbsWidth;
543 0 : pDstInfo->nNamedWidth = pSrcInfo->nNamedWidth;
544 : }
545 :
546 0 : if( (nWhat & SVX_CSS1_BORDERINFO_COLOR) != 0 )
547 0 : pDstInfo->aColor = pSrcInfo->aColor;
548 :
549 0 : if( (nWhat & SVX_CSS1_BORDERINFO_STYLE) != 0 )
550 0 : pDstInfo->eStyle = pSrcInfo->eStyle;
551 : }
552 :
553 0 : void SvxCSS1PropertyInfo::CopyBorderInfo( sal_uInt16 nCount, sal_uInt16 nWhat )
554 : {
555 0 : if( nCount==0 )
556 : {
557 0 : CopyBorderInfo( SvxBoxItemLine::BOTTOM, SvxBoxItemLine::TOP, nWhat );
558 0 : CopyBorderInfo( SvxBoxItemLine::TOP, SvxBoxItemLine::LEFT, nWhat );
559 : }
560 0 : if( nCount<=1 )
561 : {
562 0 : CopyBorderInfo( SvxBoxItemLine::LEFT, SvxBoxItemLine::RIGHT, nWhat );
563 : }
564 0 : }
565 :
566 338 : void SvxCSS1PropertyInfo::SetBoxItem( SfxItemSet& rItemSet,
567 : sal_uInt16 nMinBorderDist,
568 : const SvxBoxItem *pDfltItem,
569 : bool bTable )
570 : {
571 412 : bool bChg = nTopBorderDistance != USHRT_MAX ||
572 148 : nBottomBorderDistance != USHRT_MAX ||
573 486 : nLeftBorderDistance != USHRT_MAX ||
574 412 : nRightBorderDistance != USHRT_MAX;
575 :
576 587 : for( size_t i=0; !bChg && i<SAL_N_ELEMENTS(aBorderInfos); ++i )
577 249 : bChg = aBorderInfos[i]!=0;
578 :
579 338 : if( !bChg )
580 396 : return;
581 :
582 280 : SvxBoxItem aBoxItem( aItemIds.nBox );
583 280 : if( pDfltItem )
584 0 : aBoxItem = *pDfltItem;
585 :
586 280 : SvxCSS1BorderInfo *pInfo = GetBorderInfo( SvxBoxItemLine::TOP, false );
587 280 : if( pInfo )
588 279 : pInfo->SetBorderLine( SvxBoxItemLine::TOP, aBoxItem );
589 :
590 280 : pInfo = GetBorderInfo( SvxBoxItemLine::BOTTOM, false );
591 280 : if( pInfo )
592 280 : pInfo->SetBorderLine( SvxBoxItemLine::BOTTOM, aBoxItem );
593 :
594 280 : pInfo = GetBorderInfo( SvxBoxItemLine::LEFT, false );
595 280 : if( pInfo )
596 279 : pInfo->SetBorderLine( SvxBoxItemLine::LEFT, aBoxItem );
597 :
598 280 : pInfo = GetBorderInfo( SvxBoxItemLine::RIGHT, false );
599 280 : if( pInfo )
600 279 : pInfo->SetBorderLine( SvxBoxItemLine::RIGHT, aBoxItem );
601 :
602 1400 : for( size_t i=0; i<SAL_N_ELEMENTS(aBorderInfos); ++i )
603 : {
604 1120 : SvxBoxItemLine nLine = SvxBoxItemLine::TOP;
605 1120 : sal_uInt16 nDist = 0;
606 1120 : switch( i )
607 : {
608 280 : case 0: nLine = SvxBoxItemLine::TOP;
609 280 : nDist = nTopBorderDistance;
610 280 : nTopBorderDistance = USHRT_MAX;
611 280 : break;
612 280 : case 1: nLine = SvxBoxItemLine::BOTTOM;
613 280 : nDist = nBottomBorderDistance;
614 280 : nBottomBorderDistance = USHRT_MAX;
615 280 : break;
616 280 : case 2: nLine = SvxBoxItemLine::LEFT;
617 280 : nDist = nLeftBorderDistance;
618 280 : nLeftBorderDistance = USHRT_MAX;
619 280 : break;
620 280 : case 3: nLine = SvxBoxItemLine::RIGHT;
621 280 : nDist = nRightBorderDistance;
622 280 : nRightBorderDistance = USHRT_MAX;
623 280 : break;
624 : }
625 :
626 1120 : if( aBoxItem.GetLine( nLine ) )
627 : {
628 1117 : if( USHRT_MAX == nDist )
629 61 : nDist = aBoxItem.GetDistance( nLine );
630 :
631 1117 : if( nDist < nMinBorderDist )
632 61 : nDist = nMinBorderDist;
633 : }
634 : else
635 : {
636 3 : if( USHRT_MAX == nDist )
637 3 : nDist = aBoxItem.GetDistance( nLine );
638 :
639 3 : if( !bTable )
640 3 : nDist = 0U;
641 0 : else if( nDist && nDist < nMinBorderDist )
642 0 : nDist = nMinBorderDist;
643 : }
644 :
645 1120 : aBoxItem.SetDistance( nDist, nLine );
646 : }
647 :
648 280 : rItemSet.Put( aBoxItem );
649 :
650 280 : DestroyBorderInfos();
651 : }
652 :
653 17 : SvxCSS1MapEntry::SvxCSS1MapEntry( const OUString& rKey, const SfxItemSet& rItemSet,
654 : const SvxCSS1PropertyInfo& rProp ) :
655 : aKey( rKey.toAsciiUpperCase() ),
656 : aItemSet( rItemSet ),
657 17 : aPropInfo( rProp )
658 17 : {}
659 :
660 0 : bool SvxCSS1Parser::StyleParsed( const CSS1Selector * /*pSelector*/,
661 : SfxItemSet& /*rItemSet*/,
662 : SvxCSS1PropertyInfo& /*rPropInfo*/ )
663 : {
664 : // wie man sieht passiert hier gar nichts
665 0 : return true;
666 : }
667 :
668 47 : bool SvxCSS1Parser::SelectorParsed( CSS1Selector *pSelector, bool bFirst )
669 : {
670 47 : if( bFirst )
671 : {
672 : OSL_ENSURE( pSheetItemSet, "Where is the Item-Set for Style-Sheets?" );
673 :
674 80 : for (size_t i = 0; i < aSelectors.size(); ++i)
675 : {
676 35 : StyleParsed( &aSelectors[i], *pSheetItemSet, *pSheetPropInfo );
677 : }
678 45 : pSheetItemSet->ClearItem();
679 45 : pSheetPropInfo->Clear();
680 :
681 : // und die naechste Rule vorbereiten
682 45 : aSelectors.clear();
683 : }
684 :
685 47 : aSelectors.push_back(pSelector);
686 :
687 47 : return false; // den Selektor haben wir gespeichert. Loeschen toedlich!
688 : }
689 :
690 2832 : bool SvxCSS1Parser::DeclarationParsed( const OUString& rProperty,
691 : const CSS1Expression *pExpr )
692 : {
693 : OSL_ENSURE( pExpr, "DeclarationParsed() without Expression" );
694 :
695 2832 : if( !pExpr )
696 0 : return true;
697 :
698 2832 : ParseProperty( rProperty, pExpr );
699 :
700 2832 : return true; // die Deklaration brauchen wir nicht mehr. Loeschen!
701 : }
702 :
703 16 : SvxCSS1Parser::SvxCSS1Parser( SfxItemPool& rPool, const OUString& rBaseURL, sal_uInt16 nMinFixLineSp,
704 : sal_uInt16 *pWhichIds, sal_uInt16 nWhichIds ) :
705 : CSS1Parser(),
706 : sBaseURL( rBaseURL ),
707 : pSheetItemSet(0),
708 : pItemSet(0),
709 : pSearchEntry( 0 ),
710 : pPropInfo( 0 ),
711 : nMinFixLineSpace( nMinFixLineSp ),
712 : eDfltEnc( RTL_TEXTENCODING_DONTKNOW ),
713 : nScriptFlags( CSS1_SCRIPT_ALL ),
714 16 : bIgnoreFontFamily( false )
715 : {
716 : // Item-Ids auch initialisieren
717 16 : aItemIds.nFont = rPool.GetTrueWhich( SID_ATTR_CHAR_FONT, false );
718 16 : aItemIds.nFontCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_FONT, false );
719 16 : aItemIds.nFontCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_FONT, false );
720 16 : aItemIds.nPosture = rPool.GetTrueWhich( SID_ATTR_CHAR_POSTURE, false );
721 16 : aItemIds.nPostureCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_POSTURE, false );
722 16 : aItemIds.nPostureCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_POSTURE, false );
723 16 : aItemIds.nWeight = rPool.GetTrueWhich( SID_ATTR_CHAR_WEIGHT, false );
724 16 : aItemIds.nWeightCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_WEIGHT, false );
725 16 : aItemIds.nWeightCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_WEIGHT, false );
726 16 : aItemIds.nFontHeight = rPool.GetTrueWhich( SID_ATTR_CHAR_FONTHEIGHT, false );
727 16 : aItemIds.nFontHeightCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT, false );
728 16 : aItemIds.nFontHeightCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT, false );
729 16 : aItemIds.nUnderline = rPool.GetTrueWhich( SID_ATTR_CHAR_UNDERLINE, false );
730 16 : aItemIds.nOverline = rPool.GetTrueWhich( SID_ATTR_CHAR_OVERLINE, false );
731 16 : aItemIds.nCrossedOut = rPool.GetTrueWhich( SID_ATTR_CHAR_STRIKEOUT, false );
732 16 : aItemIds.nColor = rPool.GetTrueWhich( SID_ATTR_CHAR_COLOR, false );
733 16 : aItemIds.nKerning = rPool.GetTrueWhich( SID_ATTR_CHAR_KERNING, false );
734 16 : aItemIds.nCaseMap = rPool.GetTrueWhich( SID_ATTR_CHAR_CASEMAP, false );
735 16 : aItemIds.nBlink = rPool.GetTrueWhich( SID_ATTR_FLASH, false );
736 :
737 16 : aItemIds.nLineSpacing = rPool.GetTrueWhich( SID_ATTR_PARA_LINESPACE, false );
738 16 : aItemIds.nAdjust = rPool.GetTrueWhich( SID_ATTR_PARA_ADJUST, false );
739 16 : aItemIds.nWidows = rPool.GetTrueWhich( SID_ATTR_PARA_WIDOWS, false );
740 16 : aItemIds.nOrphans = rPool.GetTrueWhich( SID_ATTR_PARA_ORPHANS, false );
741 16 : aItemIds.nFormatSplit = rPool.GetTrueWhich( SID_ATTR_PARA_SPLIT, false );
742 :
743 16 : aItemIds.nLRSpace = rPool.GetTrueWhich( SID_ATTR_LRSPACE, false );
744 16 : aItemIds.nULSpace = rPool.GetTrueWhich( SID_ATTR_ULSPACE, false );
745 16 : aItemIds.nBox = rPool.GetTrueWhich( SID_ATTR_BORDER_OUTER, false );
746 16 : aItemIds.nBrush = rPool.GetTrueWhich( SID_ATTR_BRUSH, false );
747 :
748 16 : aItemIds.nLanguage = rPool.GetTrueWhich( SID_ATTR_CHAR_LANGUAGE, false );
749 16 : aItemIds.nLanguageCJK = rPool.GetTrueWhich( SID_ATTR_CHAR_CJK_LANGUAGE, false );
750 16 : aItemIds.nLanguageCTL = rPool.GetTrueWhich( SID_ATTR_CHAR_CTL_LANGUAGE, false );
751 16 : aItemIds.nDirection = rPool.GetTrueWhich( SID_ATTR_FRAMEDIRECTION, false );
752 :
753 16 : aWhichMap.insert( aWhichMap.begin(), 0 );
754 : SvParser::BuildWhichTable( aWhichMap, reinterpret_cast<sal_uInt16 *>(&aItemIds),
755 16 : sizeof(aItemIds) / sizeof(sal_uInt16) );
756 16 : if( pWhichIds && nWhichIds )
757 16 : SvParser::BuildWhichTable( aWhichMap, pWhichIds, nWhichIds );
758 :
759 16 : pSheetItemSet = new SfxItemSet( rPool, &aWhichMap[0] );
760 16 : pSheetPropInfo = new SvxCSS1PropertyInfo;
761 16 : pSearchEntry = new SvxCSS1MapEntry( rPool, &aWhichMap[0] );
762 16 : }
763 :
764 32 : SvxCSS1Parser::~SvxCSS1Parser()
765 : {
766 16 : delete pSheetItemSet;
767 16 : delete pSheetPropInfo;
768 16 : delete pSearchEntry;
769 16 : }
770 :
771 0 : void SvxCSS1Parser::InsertId( const OUString& rId,
772 : const SfxItemSet& rItemSet,
773 : const SvxCSS1PropertyInfo& rProp )
774 : {
775 0 : InsertMapEntry( rId, rItemSet, rProp, aIds );
776 0 : }
777 :
778 15 : const SvxCSS1MapEntry* SvxCSS1Parser::GetId( const OUString& rId ) const
779 : {
780 15 : CSS1Map::const_iterator itr = aIds.find(rId);
781 15 : return itr == aIds.end() ? NULL : itr->second;
782 : }
783 :
784 1 : void SvxCSS1Parser::InsertClass( const OUString& rClass,
785 : const SfxItemSet& rItemSet,
786 : const SvxCSS1PropertyInfo& rProp )
787 : {
788 1 : InsertMapEntry( rClass, rItemSet, rProp, aClasses );
789 1 : }
790 :
791 14 : const SvxCSS1MapEntry* SvxCSS1Parser::GetClass( const OUString& rClass ) const
792 : {
793 14 : CSS1Map::const_iterator itr = aClasses.find(rClass);
794 14 : return itr == aClasses.end() ? NULL : itr->second;
795 : }
796 :
797 9 : void SvxCSS1Parser::InsertPage( const OUString& rPage,
798 : bool bPseudo,
799 : const SfxItemSet& rItemSet,
800 : const SvxCSS1PropertyInfo& rProp )
801 : {
802 9 : OUString aKey( rPage );
803 9 : if( bPseudo )
804 0 : aKey = ":" + aKey;
805 9 : InsertMapEntry( aKey, rItemSet, rProp, aPages );
806 9 : }
807 :
808 48 : SvxCSS1MapEntry* SvxCSS1Parser::GetPage( const OUString& rPage, bool bPseudo )
809 : {
810 48 : OUString aKey( rPage );
811 48 : if( bPseudo )
812 36 : aKey = ":" + aKey;
813 :
814 48 : CSS1Map::iterator itr = aPages.find(aKey);
815 48 : return itr == aPages.end() ? NULL : itr->second;
816 : }
817 :
818 10 : void SvxCSS1Parser::InsertTag( const OUString& rTag,
819 : const SfxItemSet& rItemSet,
820 : const SvxCSS1PropertyInfo& rProp )
821 : {
822 10 : InsertMapEntry( rTag, rItemSet, rProp, aTags );
823 10 : }
824 :
825 112 : SvxCSS1MapEntry* SvxCSS1Parser::GetTag( const OUString& rTag )
826 : {
827 112 : CSS1Map::iterator itr = aTags.find(rTag);
828 112 : return itr == aTags.end() ? NULL : itr->second;
829 : }
830 :
831 12 : bool SvxCSS1Parser::ParseStyleSheet( const OUString& rIn )
832 : {
833 12 : pItemSet = pSheetItemSet;
834 12 : pPropInfo = pSheetPropInfo;
835 :
836 12 : bool bSuccess = CSS1Parser::ParseStyleSheet( rIn );
837 :
838 24 : for (size_t i = 0; i < aSelectors.size(); ++i)
839 : {
840 12 : StyleParsed( &aSelectors[i], *pSheetItemSet, *pSheetPropInfo );
841 : }
842 :
843 : // und etwas aufrauemen
844 12 : aSelectors.clear();
845 12 : pSheetItemSet->ClearItem();
846 12 : pSheetPropInfo->Clear();
847 :
848 12 : pItemSet = 0;
849 12 : pPropInfo = 0;
850 :
851 12 : return bSuccess;
852 : }
853 :
854 606 : bool SvxCSS1Parser::ParseStyleOption( const OUString& rIn,
855 : SfxItemSet& rItemSet,
856 : SvxCSS1PropertyInfo& rPropInfo )
857 : {
858 606 : pItemSet = &rItemSet;
859 606 : pPropInfo = &rPropInfo;
860 :
861 606 : bool bSuccess = CSS1Parser::ParseStyleOption( rIn );
862 606 : rItemSet.ClearItem( aItemIds.nDirection );
863 :
864 606 : pItemSet = 0;
865 606 : pPropInfo = 0;
866 :
867 606 : return bSuccess;
868 : }
869 :
870 1179 : bool SvxCSS1Parser::GetEnum( const CSS1PropertyEnum *pPropTable,
871 : const OUString &rValue, sal_uInt16& rEnum )
872 : {
873 5922 : while( pPropTable->pName )
874 : {
875 4171 : if( !rValue.equalsIgnoreAsciiCaseAscii( pPropTable->pName ) )
876 3564 : pPropTable++;
877 : else
878 607 : break;
879 : }
880 :
881 1179 : if( pPropTable->pName )
882 607 : rEnum = pPropTable->nEnum;
883 :
884 1179 : return (pPropTable->pName != 0);
885 : }
886 :
887 21 : void SvxCSS1Parser::PixelToTwip( long &rWidth, long &rHeight )
888 : {
889 21 : if( Application::GetDefaultDevice() )
890 : {
891 21 : Size aTwipSz( rWidth, rHeight );
892 : aTwipSz = Application::GetDefaultDevice()->PixelToLogic( aTwipSz,
893 21 : MapMode(MAP_TWIP) );
894 :
895 21 : rWidth = aTwipSz.Width();
896 21 : rHeight = aTwipSz.Height();
897 : }
898 21 : }
899 :
900 0 : sal_uInt32 SvxCSS1Parser::GetFontHeight( sal_uInt16 nSize ) const
901 : {
902 : sal_uInt16 nHeight;
903 :
904 0 : switch( nSize )
905 : {
906 0 : case 0: nHeight = 8*20; break;
907 0 : case 1: nHeight = 10*20; break;
908 0 : case 2: nHeight = 11*20; break;
909 0 : case 3: nHeight = 12*20; break;
910 0 : case 4: nHeight = 17*20; break;
911 0 : case 5: nHeight = 20*20; break;
912 : case 6:
913 0 : default: nHeight = 32*20; break;
914 : }
915 :
916 0 : return nHeight;
917 : }
918 :
919 0 : const FontList *SvxCSS1Parser::GetFontList() const
920 : {
921 0 : return 0;
922 : }
923 :
924 20 : void SvxCSS1Parser::InsertMapEntry( const OUString& rKey,
925 : const SfxItemSet& rItemSet,
926 : const SvxCSS1PropertyInfo& rProp,
927 : CSS1Map& rMap )
928 : {
929 20 : CSS1Map::iterator itr = rMap.find(rKey);
930 20 : if (itr == rMap.end())
931 : {
932 17 : std::unique_ptr<SvxCSS1MapEntry> p(new SvxCSS1MapEntry(rKey, rItemSet, rProp));
933 17 : o3tl::ptr_container::insert(rMap, rKey, std::move(p));
934 : }
935 : else
936 : {
937 3 : SvxCSS1MapEntry* p = itr->second;
938 : MergeStyles( rItemSet, rProp,
939 3 : p->GetItemSet(), p->GetPropertyInfo(), true );
940 : }
941 20 : }
942 :
943 3 : void SvxCSS1Parser::MergeStyles( const SfxItemSet& rSrcSet,
944 : const SvxCSS1PropertyInfo& rSrcInfo,
945 : SfxItemSet& rTargetSet,
946 : SvxCSS1PropertyInfo& rTargetInfo,
947 : bool bSmart )
948 : {
949 3 : if( !bSmart )
950 : {
951 0 : rTargetSet.Put( rSrcSet );
952 : }
953 : else
954 : {
955 3 : SvxLRSpaceItem aLRSpace( static_cast<const SvxLRSpaceItem&>(rTargetSet.Get(aItemIds.nLRSpace)) );
956 6 : SvxULSpaceItem aULSpace( static_cast<const SvxULSpaceItem&>(rTargetSet.Get(aItemIds.nULSpace)) );
957 6 : SvxBoxItem aBox( static_cast<const SvxBoxItem&>(rTargetSet.Get(aItemIds.nBox)) );
958 :
959 3 : rTargetSet.Put( rSrcSet );
960 :
961 3 : if( rSrcInfo.bLeftMargin || rSrcInfo.bRightMargin ||
962 : rSrcInfo.bTextIndent )
963 : {
964 : const SvxLRSpaceItem& rNewLRSpace =
965 0 : static_cast<const SvxLRSpaceItem&>(rSrcSet.Get( aItemIds.nLRSpace ));
966 :
967 0 : if( rSrcInfo.bLeftMargin )
968 0 : aLRSpace.SetLeft( rNewLRSpace.GetLeft() );
969 0 : if( rSrcInfo.bRightMargin )
970 0 : aLRSpace.SetRight( rNewLRSpace.GetRight() );
971 0 : if( rSrcInfo.bTextIndent )
972 0 : aLRSpace.SetTextFirstLineOfst( rNewLRSpace.GetTextFirstLineOfst() );
973 :
974 0 : rTargetSet.Put( aLRSpace );
975 : }
976 :
977 3 : if( rSrcInfo.bTopMargin || rSrcInfo.bBottomMargin )
978 : {
979 : const SvxULSpaceItem& rNewULSpace =
980 0 : static_cast<const SvxULSpaceItem&>(rSrcSet.Get( aItemIds.nULSpace ));
981 :
982 0 : if( rSrcInfo.bTopMargin )
983 0 : aULSpace.SetUpper( rNewULSpace.GetUpper() );
984 0 : if( rSrcInfo.bBottomMargin )
985 0 : aULSpace.SetLower( rNewULSpace.GetLower() );
986 :
987 0 : rTargetSet.Put( aULSpace );
988 3 : }
989 : }
990 :
991 3 : rTargetInfo.Merge( rSrcInfo );
992 3 : }
993 :
994 16 : void SvxCSS1Parser::SetDfltEncoding( rtl_TextEncoding eEnc )
995 : {
996 16 : eDfltEnc = eEnc;
997 16 : }
998 :
999 11 : static void ParseCSS1_font_size( const CSS1Expression *pExpr,
1000 : SfxItemSet &rItemSet,
1001 : SvxCSS1PropertyInfo& /*rPropInfo*/,
1002 : const SvxCSS1Parser& rParser )
1003 : {
1004 : OSL_ENSURE( pExpr, "no expression" );
1005 :
1006 11 : sal_uLong nHeight = 0;
1007 11 : sal_uInt16 nPropHeight = 100;
1008 :
1009 11 : switch( pExpr->GetType() )
1010 : {
1011 : case CSS1_LENGTH:
1012 11 : nHeight = pExpr->GetULength();
1013 11 : break;
1014 : case CSS1_PIXLENGTH:
1015 : {
1016 0 : long nPWidth = 0;
1017 0 : long nPHeight = (long)pExpr->GetNumber();
1018 0 : SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
1019 0 : nHeight = (sal_uLong)nPHeight;
1020 : }
1021 0 : break;
1022 : case CSS1_PERCENTAGE:
1023 : // nur fuer Drop-Caps!
1024 0 : nPropHeight = (sal_uInt16)pExpr->GetNumber();
1025 0 : break;
1026 : case CSS1_IDENT:
1027 : {
1028 : sal_uInt16 nSize;
1029 :
1030 0 : if( SvxCSS1Parser::GetEnum( aFontSizeTable, pExpr->GetString(),
1031 : nSize ) )
1032 : {
1033 0 : nHeight = rParser.GetFontHeight( nSize );
1034 : }
1035 : }
1036 0 : break;
1037 :
1038 : default:
1039 : ;
1040 : }
1041 :
1042 11 : if( nHeight || nPropHeight!=100 )
1043 : {
1044 : SvxFontHeightItem aFontHeight( nHeight, nPropHeight,
1045 11 : aItemIds.nFontHeight );
1046 11 : if( rParser.IsSetWesternProps() )
1047 11 : rItemSet.Put( aFontHeight );
1048 11 : if( rParser.IsSetCJKProps() )
1049 : {
1050 11 : aFontHeight.SetWhich( aItemIds.nFontHeightCJK );
1051 11 : rItemSet.Put( aFontHeight );
1052 : }
1053 11 : if( rParser.IsSetCTLProps() )
1054 : {
1055 11 : aFontHeight.SetWhich( aItemIds.nFontHeightCTL );
1056 11 : rItemSet.Put( aFontHeight );
1057 11 : }
1058 : }
1059 11 : }
1060 :
1061 4 : static void ParseCSS1_font_family( const CSS1Expression *pExpr,
1062 : SfxItemSet &rItemSet,
1063 : SvxCSS1PropertyInfo& /*rPropInfo*/,
1064 : const SvxCSS1Parser& rParser )
1065 : {
1066 : OSL_ENSURE( pExpr, "no expression" );
1067 :
1068 8 : OUString aName, aStyleName;
1069 4 : FontFamily eFamily = FAMILY_DONTKNOW;
1070 4 : FontPitch ePitch = PITCH_DONTKNOW;
1071 4 : rtl_TextEncoding eEnc = rParser.GetDfltEncoding();
1072 4 : const FontList *pFList = rParser.GetFontList();
1073 4 : bool bFirst = true;
1074 4 : bool bFound = false;
1075 14 : while( pExpr && (bFirst || ','==pExpr->GetOp() || !pExpr->GetOp()) )
1076 : {
1077 6 : CSS1Token eType = pExpr->GetType();
1078 6 : if( CSS1_IDENT==eType || CSS1_STRING==eType )
1079 : {
1080 6 : OUString aIdent( pExpr->GetString() );
1081 :
1082 6 : if( CSS1_IDENT==eType )
1083 : {
1084 : // Alle nachfolgenden id's sammeln und mit einem
1085 : // Space getrennt hintendranhaengen
1086 5 : const CSS1Expression *pNext = pExpr->GetNext();
1087 10 : while( pNext && !pNext->GetOp() &&
1088 0 : CSS1_IDENT==pNext->GetType() )
1089 : {
1090 0 : aIdent += " " + pNext->GetString();
1091 0 : pExpr = pNext;
1092 0 : pNext = pExpr->GetNext();
1093 : }
1094 : }
1095 6 : if( !aIdent.isEmpty() )
1096 : {
1097 6 : if( !bFound && pFList )
1098 : {
1099 6 : sal_Handle hFont = pFList->GetFirstFontInfo( aIdent );
1100 6 : if( 0 != hFont )
1101 : {
1102 1 : const vcl::FontInfo& rFInfo = FontList::GetFontInfo( hFont );
1103 1 : if( RTL_TEXTENCODING_DONTKNOW != rFInfo.GetCharSet() )
1104 : {
1105 1 : bFound = true;
1106 1 : if( RTL_TEXTENCODING_SYMBOL == rFInfo.GetCharSet() )
1107 0 : eEnc = RTL_TEXTENCODING_SYMBOL;
1108 : }
1109 : }
1110 : }
1111 6 : if( !bFirst )
1112 2 : aName += ";";
1113 6 : aName += aIdent;
1114 6 : }
1115 : }
1116 :
1117 6 : pExpr = pExpr->GetNext();
1118 6 : bFirst = false;
1119 : }
1120 :
1121 4 : if( !aName.isEmpty() && !rParser.IsIgnoreFontFamily() )
1122 : {
1123 : SvxFontItem aFont( eFamily, aName, aStyleName, ePitch,
1124 4 : eEnc, aItemIds.nFont );
1125 4 : if( rParser.IsSetWesternProps() )
1126 4 : rItemSet.Put( aFont );
1127 4 : if( rParser.IsSetCJKProps() )
1128 : {
1129 4 : aFont.SetWhich( aItemIds.nFontCJK );
1130 4 : rItemSet.Put( aFont );
1131 : }
1132 4 : if( rParser.IsSetCTLProps() )
1133 : {
1134 4 : aFont.SetWhich( aItemIds.nFontCTL );
1135 4 : rItemSet.Put( aFont );
1136 4 : }
1137 4 : }
1138 4 : }
1139 :
1140 23 : static void ParseCSS1_font_weight( const CSS1Expression *pExpr,
1141 : SfxItemSet &rItemSet,
1142 : SvxCSS1PropertyInfo& /*rPropInfo*/,
1143 : const SvxCSS1Parser& rParser )
1144 : {
1145 : OSL_ENSURE( pExpr, "no expression" );
1146 :
1147 23 : switch( pExpr->GetType() )
1148 : {
1149 : case CSS1_IDENT:
1150 : case CSS1_STRING: // MS-IE, was sonst
1151 : {
1152 : sal_uInt16 nWeight;
1153 23 : if( SvxCSS1Parser::GetEnum( aFontWeightTable, pExpr->GetString(),
1154 : nWeight ) )
1155 : {
1156 23 : SvxWeightItem aWeight( (FontWeight)nWeight, aItemIds.nWeight );
1157 23 : if( rParser.IsSetWesternProps() )
1158 23 : rItemSet.Put( aWeight );
1159 23 : if( rParser.IsSetCJKProps() )
1160 : {
1161 23 : aWeight.SetWhich( aItemIds.nWeightCJK );
1162 23 : rItemSet.Put( aWeight );
1163 : }
1164 23 : if( rParser.IsSetCTLProps() )
1165 : {
1166 23 : aWeight.SetWhich( aItemIds.nWeightCTL );
1167 23 : rItemSet.Put( aWeight );
1168 23 : }
1169 : }
1170 : }
1171 23 : break;
1172 : case CSS1_NUMBER:
1173 : {
1174 0 : sal_uInt16 nWeight = (sal_uInt16)pExpr->GetNumber();
1175 : SvxWeightItem aWeight( nWeight>400 ? WEIGHT_BOLD : WEIGHT_NORMAL,
1176 0 : aItemIds.nWeight );
1177 0 : if( rParser.IsSetWesternProps() )
1178 0 : rItemSet.Put( aWeight );
1179 0 : if( rParser.IsSetCJKProps() )
1180 : {
1181 0 : aWeight.SetWhich( aItemIds.nWeightCJK );
1182 0 : rItemSet.Put( aWeight );
1183 : }
1184 0 : if( rParser.IsSetCTLProps() )
1185 : {
1186 0 : aWeight.SetWhich( aItemIds.nWeightCTL );
1187 0 : rItemSet.Put( aWeight );
1188 0 : }
1189 : }
1190 0 : break;
1191 :
1192 : default:
1193 : ;
1194 : }
1195 23 : }
1196 :
1197 0 : static void ParseCSS1_font_style( const CSS1Expression *pExpr,
1198 : SfxItemSet &rItemSet,
1199 : SvxCSS1PropertyInfo& /*rPropInfo*/,
1200 : const SvxCSS1Parser& rParser )
1201 : {
1202 : OSL_ENSURE( pExpr, "no expression" );
1203 :
1204 0 : bool bPosture = false;
1205 0 : bool bCaseMap = false;
1206 0 : FontItalic eItalic = ITALIC_NONE;
1207 0 : SvxCaseMap eCaseMap = SVX_CASEMAP_NOT_MAPPED;
1208 :
1209 : // normal | italic || small-caps | oblique || small-caps | small-caps
1210 : // (wobei nor noch normal | italic und oblique zulaessig sind
1211 :
1212 : // der Wert kann zwei Werte enthalten!
1213 0 : for( int i=0; pExpr && i<2; ++i )
1214 : {
1215 : // Auch hier hinterlaesst MS-IEs Parser seine Spuren
1216 0 : if( (CSS1_IDENT==pExpr->GetType() || CSS1_STRING==pExpr->GetType()) &&
1217 0 : !pExpr->GetOp() )
1218 : {
1219 0 : const OUString& rValue = pExpr->GetString();
1220 : // erstmal pruefen, ob es ein Italic-Wert oder 'normal' ist
1221 : sal_uInt16 nItalic;
1222 0 : if( SvxCSS1Parser::GetEnum( aFontStyleTable, rValue, nItalic ) )
1223 : {
1224 0 : eItalic = (FontItalic)nItalic;
1225 0 : if( !bCaseMap && ITALIC_NONE==eItalic )
1226 : {
1227 : // fuer 'normal' muessen wir auch die case-map aussch.
1228 0 : eCaseMap = SVX_CASEMAP_NOT_MAPPED;
1229 0 : bCaseMap = true;
1230 : }
1231 0 : bPosture = true;
1232 : }
1233 0 : else if( !bCaseMap &&
1234 0 : rValue.equalsIgnoreAsciiCase( "small-caps" ) )
1235 : {
1236 0 : eCaseMap = SVX_CASEMAP_KAPITAELCHEN;
1237 0 : bCaseMap = true;
1238 : }
1239 : }
1240 :
1241 : // den naechsten Ausdruck holen
1242 0 : pExpr = pExpr->GetNext();
1243 : }
1244 :
1245 0 : if( bPosture )
1246 : {
1247 0 : SvxPostureItem aPosture( eItalic, aItemIds.nPosture );
1248 0 : if( rParser.IsSetWesternProps() )
1249 0 : rItemSet.Put( aPosture );
1250 0 : if( rParser.IsSetCJKProps() )
1251 : {
1252 0 : aPosture.SetWhich( aItemIds.nPostureCJK );
1253 0 : rItemSet.Put( aPosture );
1254 : }
1255 0 : if( rParser.IsSetCTLProps() )
1256 : {
1257 0 : aPosture.SetWhich( aItemIds.nPostureCTL );
1258 0 : rItemSet.Put( aPosture );
1259 0 : }
1260 : }
1261 :
1262 0 : if( bCaseMap )
1263 0 : rItemSet.Put( SvxCaseMapItem( eCaseMap, aItemIds.nCaseMap ) );
1264 0 : }
1265 :
1266 6 : static void ParseCSS1_font_variant( const CSS1Expression *pExpr,
1267 : SfxItemSet &rItemSet,
1268 : SvxCSS1PropertyInfo& /*rPropInfo*/,
1269 : const SvxCSS1Parser& /*rParser*/ )
1270 : {
1271 : assert(pExpr && "no expression");
1272 :
1273 : // normal | small-caps
1274 6 : switch( pExpr->GetType() )
1275 : {
1276 : case CSS1_IDENT:
1277 : {
1278 : sal_uInt16 nCaseMap;
1279 6 : if( SvxCSS1Parser::GetEnum( aFontVariantTable, pExpr->GetString(),
1280 : nCaseMap ) )
1281 : {
1282 : rItemSet.Put( SvxCaseMapItem( (SvxCaseMap)nCaseMap,
1283 6 : aItemIds.nCaseMap ) );
1284 : }
1285 : }
1286 : default:
1287 : ;
1288 : }
1289 6 : }
1290 :
1291 0 : static void ParseCSS1_text_transform( const CSS1Expression *pExpr,
1292 : SfxItemSet &rItemSet,
1293 : SvxCSS1PropertyInfo& /*rPropInfo*/,
1294 : const SvxCSS1Parser& /*rParser*/ )
1295 : {
1296 : OSL_ENSURE( pExpr, "no expression" );
1297 :
1298 : // none | capitalize | uppercase | lowercase
1299 :
1300 0 : switch( pExpr->GetType() )
1301 : {
1302 : case CSS1_IDENT:
1303 : {
1304 : sal_uInt16 nCaseMap;
1305 0 : if( SvxCSS1Parser::GetEnum( aTextTransformTable, pExpr->GetString(),
1306 : nCaseMap ) )
1307 : {
1308 : rItemSet.Put( SvxCaseMapItem( (SvxCaseMap)nCaseMap,
1309 0 : aItemIds.nCaseMap ) );
1310 : }
1311 : }
1312 : default:
1313 : ;
1314 : }
1315 0 : }
1316 :
1317 11 : static void ParseCSS1_color( const CSS1Expression *pExpr,
1318 : SfxItemSet &rItemSet,
1319 : SvxCSS1PropertyInfo& /*rPropInfo*/,
1320 : const SvxCSS1Parser& /*rParser*/ )
1321 : {
1322 : OSL_ENSURE( pExpr, "no expression" );
1323 :
1324 11 : switch( pExpr->GetType() )
1325 : {
1326 : case CSS1_IDENT:
1327 : case CSS1_RGB:
1328 : case CSS1_HEXCOLOR:
1329 : case CSS1_STRING: // Wegen MS-IE
1330 : {
1331 11 : Color aColor;
1332 11 : if( pExpr->GetColor( aColor ) )
1333 11 : rItemSet.Put( SvxColorItem( aColor, aItemIds.nColor ) );
1334 : }
1335 11 : break;
1336 : default:
1337 : ;
1338 : }
1339 11 : }
1340 :
1341 0 : static void ParseCSS1_column_count( const CSS1Expression *pExpr,
1342 : SfxItemSet& /*rItemSet*/,
1343 : SvxCSS1PropertyInfo &rPropInfo,
1344 : const SvxCSS1Parser& /*rParser*/ )
1345 : {
1346 : assert(pExpr && "no expression");
1347 :
1348 0 : if ( pExpr->GetType() == CSS1_NUMBER )
1349 : {
1350 0 : double columnCount = pExpr->GetNumber();
1351 0 : if ( columnCount >= 2 )
1352 : {
1353 0 : rPropInfo.nColumnCount = columnCount;
1354 : }
1355 : }
1356 0 : }
1357 :
1358 1 : static void ParseCSS1_direction( const CSS1Expression *pExpr,
1359 : SfxItemSet &rItemSet,
1360 : SvxCSS1PropertyInfo& /*rPropInfo*/,
1361 : const SvxCSS1Parser& /*rParser*/ )
1362 : {
1363 : assert(pExpr && "no expression");
1364 :
1365 : sal_uInt16 nDir;
1366 1 : switch( pExpr->GetType() )
1367 : {
1368 : case CSS1_IDENT:
1369 : case CSS1_STRING:
1370 1 : if( SvxCSS1Parser::GetEnum( aDirectionTable, pExpr->GetString(),
1371 : nDir ) )
1372 : {
1373 : rItemSet.Put( SvxFrameDirectionItem(
1374 : static_cast < SvxFrameDirection >( nDir ),
1375 1 : aItemIds.nDirection ) );
1376 : }
1377 1 : break;
1378 : default:
1379 : ;
1380 : }
1381 1 : }
1382 :
1383 0 : static void MergeHori( SvxGraphicPosition& ePos, SvxGraphicPosition eHori )
1384 : {
1385 : OSL_ENSURE( GPOS_LT==eHori || GPOS_MT==eHori || GPOS_RT==eHori,
1386 : "vertical position not at the top" );
1387 :
1388 0 : switch( ePos )
1389 : {
1390 : case GPOS_LT:
1391 : case GPOS_MT:
1392 : case GPOS_RT:
1393 0 : ePos = eHori;
1394 0 : break;
1395 :
1396 : case GPOS_LM:
1397 : case GPOS_MM:
1398 : case GPOS_RM:
1399 0 : ePos = GPOS_LT==eHori ? GPOS_LM : (GPOS_MT==eHori ? GPOS_MM : GPOS_RM);
1400 0 : break;
1401 :
1402 : case GPOS_LB:
1403 : case GPOS_MB:
1404 : case GPOS_RB:
1405 0 : ePos = GPOS_LT==eHori ? GPOS_LB : (GPOS_MT==eHori ? GPOS_MB : GPOS_RB);
1406 0 : break;
1407 :
1408 : default:
1409 : ;
1410 : }
1411 0 : }
1412 :
1413 0 : static void MergeVert( SvxGraphicPosition& ePos, SvxGraphicPosition eVert )
1414 : {
1415 : OSL_ENSURE( GPOS_LT==eVert || GPOS_LM==eVert || GPOS_LB==eVert,
1416 : "horizontal position not on the left side" );
1417 :
1418 0 : switch( ePos )
1419 : {
1420 : case GPOS_LT:
1421 : case GPOS_LM:
1422 : case GPOS_LB:
1423 0 : ePos = eVert;
1424 0 : break;
1425 :
1426 : case GPOS_MT:
1427 : case GPOS_MM:
1428 : case GPOS_MB:
1429 0 : ePos = GPOS_LT==eVert ? GPOS_MT : (GPOS_LM==eVert ? GPOS_MM : GPOS_MB);
1430 0 : break;
1431 :
1432 : case GPOS_RT:
1433 : case GPOS_RM:
1434 : case GPOS_RB:
1435 0 : ePos = GPOS_LT==eVert ? GPOS_RT : (GPOS_LM==eVert ? GPOS_RM : GPOS_RB);
1436 0 : break;
1437 :
1438 : default:
1439 : ;
1440 : }
1441 0 : }
1442 :
1443 2 : static void ParseCSS1_background( const CSS1Expression *pExpr,
1444 : SfxItemSet &rItemSet,
1445 : SvxCSS1PropertyInfo& /*rPropInfo*/,
1446 : const SvxCSS1Parser& rParser )
1447 : {
1448 : OSL_ENSURE( pExpr, "no expression" );
1449 :
1450 2 : Color aColor;
1451 2 : OUString aURL;
1452 :
1453 2 : bool bColor = false, bTransparent = false;
1454 2 : SvxGraphicPosition eRepeat = GPOS_TILED;
1455 2 : SvxGraphicPosition ePos = GPOS_LT;
1456 2 : bool bHori = false, bVert = false;
1457 :
1458 6 : while( pExpr && !pExpr->GetOp() )
1459 : {
1460 2 : switch( pExpr->GetType() )
1461 : {
1462 : case CSS1_URL:
1463 0 : pExpr->GetURL( aURL );
1464 0 : break;
1465 :
1466 : case CSS1_RGB:
1467 0 : bColor = pExpr->GetColor( aColor );
1468 0 : break;
1469 :
1470 : case CSS1_LENGTH:
1471 : case CSS1_PIXLENGTH:
1472 : {
1473 : // da wir keine absolute Positionierung koennen,
1474 : // unterscheiden wir nur zwischen 0 und !0. Deshalb
1475 : // koennen Pixel auch wie alle anderen Einheiten behandelt
1476 : // werden.
1477 :
1478 0 : sal_uLong nLength = (sal_uLong)pExpr->GetNumber();
1479 0 : if( !bHori )
1480 : {
1481 0 : ePos = nLength ? GPOS_MM : GPOS_LT;
1482 0 : bHori = true;
1483 : }
1484 0 : else if( !bVert )
1485 : {
1486 0 : MergeVert( ePos, (nLength ? GPOS_LM : GPOS_LT) );
1487 0 : bVert = true;
1488 : }
1489 : }
1490 0 : break;
1491 :
1492 : case CSS1_PERCENTAGE:
1493 : {
1494 : // die %-Angabe wird auf den enum abgebildet
1495 :
1496 0 : sal_uInt16 nPerc = (sal_uInt16)pExpr->GetNumber();
1497 0 : if( !bHori )
1498 : {
1499 : ePos = nPerc < 25 ? GPOS_LT
1500 : : (nPerc < 75 ? GPOS_MM
1501 0 : : GPOS_RB);
1502 : }
1503 0 : else if( !bVert )
1504 : {
1505 : SvxGraphicPosition eVert =
1506 : nPerc < 25 ? GPOS_LT: (nPerc < 75 ? GPOS_LM
1507 0 : : GPOS_LB);
1508 0 : MergeVert( ePos, eVert );
1509 : }
1510 : }
1511 0 : break;
1512 :
1513 : case CSS1_IDENT:
1514 : case CSS1_HEXCOLOR:
1515 : case CSS1_STRING: // Wegen MS-IE
1516 : {
1517 : sal_uInt16 nEnum;
1518 2 : const OUString &rValue = pExpr->GetString();
1519 2 : if( rValue.equalsIgnoreAsciiCase( "transparent" ) )
1520 : {
1521 0 : bTransparent = true;
1522 : }
1523 2 : if( SvxCSS1Parser::GetEnum( aBGRepeatTable, rValue, nEnum ) )
1524 : {
1525 0 : eRepeat = (SvxGraphicPosition)nEnum;
1526 : }
1527 2 : else if( SvxCSS1Parser::GetEnum( aBGHoriPosTable, rValue, nEnum ) )
1528 : {
1529 : // <position>, horizontal
1530 0 : MergeHori( ePos, (SvxGraphicPosition)nEnum );
1531 : }
1532 2 : else if( SvxCSS1Parser::GetEnum( aBGVertPosTable, rValue, nEnum ) )
1533 : {
1534 : // <position>, vertikal
1535 0 : MergeVert( ePos, (SvxGraphicPosition)nEnum );
1536 : }
1537 2 : else if( !bColor )
1538 : {
1539 : // <color>
1540 2 : bColor = pExpr->GetColor( aColor );
1541 : }
1542 : // <scroll> kennen wir nicht
1543 : }
1544 2 : break;
1545 :
1546 : default:
1547 : ;
1548 : }
1549 :
1550 2 : pExpr = pExpr->GetNext();
1551 : }
1552 :
1553 : // transparent schlaegt alles
1554 2 : if( bTransparent )
1555 : {
1556 0 : bColor = false;
1557 0 : aURL.clear();
1558 : }
1559 :
1560 : // repeat hat prio gegenueber einer Position
1561 2 : if( GPOS_NONE == eRepeat )
1562 0 : eRepeat = ePos;
1563 :
1564 2 : if( bTransparent || bColor || !aURL.isEmpty() )
1565 : {
1566 2 : SvxBrushItem aBrushItem( aItemIds.nBrush );
1567 :
1568 2 : if( bTransparent )
1569 0 : aBrushItem.SetColor( Color(COL_TRANSPARENT));
1570 2 : else if( bColor )
1571 2 : aBrushItem.SetColor( aColor );
1572 :
1573 2 : if( !aURL.isEmpty() )
1574 : {
1575 0 : aBrushItem.SetGraphicLink( URIHelper::SmartRel2Abs( INetURLObject( rParser.GetBaseURL()), aURL, Link<OUString *, bool>(), false ) );
1576 0 : aBrushItem.SetGraphicPos( eRepeat );
1577 : }
1578 :
1579 2 : rItemSet.Put( aBrushItem );
1580 2 : }
1581 2 : }
1582 :
1583 0 : static void ParseCSS1_background_color( const CSS1Expression *pExpr,
1584 : SfxItemSet &rItemSet,
1585 : SvxCSS1PropertyInfo& /*rPropInfo*/,
1586 : const SvxCSS1Parser& /*rParser*/ )
1587 : {
1588 : OSL_ENSURE( pExpr, "no expression" );
1589 :
1590 0 : Color aColor;
1591 :
1592 0 : bool bColor = false, bTransparent = false;
1593 :
1594 0 : switch( pExpr->GetType() )
1595 : {
1596 : case CSS1_RGB:
1597 0 : bColor = pExpr->GetColor( aColor );
1598 0 : break;
1599 : case CSS1_IDENT:
1600 : case CSS1_HEXCOLOR:
1601 : case CSS1_STRING: // Wegen MS-IE
1602 0 : if( pExpr->GetString().equalsIgnoreAsciiCase( "transparent" ) )
1603 : {
1604 0 : bTransparent = true;
1605 : }
1606 : else
1607 : {
1608 : // <color>
1609 0 : bColor = pExpr->GetColor( aColor );
1610 : }
1611 0 : break;
1612 : default:
1613 : ;
1614 : }
1615 :
1616 0 : if( bTransparent || bColor )
1617 : {
1618 0 : SvxBrushItem aBrushItem( aItemIds.nBrush );
1619 :
1620 0 : if( bTransparent )
1621 0 : aBrushItem.SetColor( Color(COL_TRANSPARENT) );
1622 0 : else if( bColor )
1623 0 : aBrushItem.SetColor( aColor);
1624 :
1625 0 : rItemSet.Put( aBrushItem );
1626 : }
1627 0 : }
1628 :
1629 7 : static void ParseCSS1_line_height( const CSS1Expression *pExpr,
1630 : SfxItemSet &rItemSet,
1631 : SvxCSS1PropertyInfo& /*rPropInfo*/,
1632 : const SvxCSS1Parser& rParser )
1633 : {
1634 : OSL_ENSURE( pExpr, "no expression" );
1635 :
1636 7 : sal_uInt16 nHeight = 0;
1637 7 : sal_uInt8 nPropHeight = 0;
1638 :
1639 7 : switch( pExpr->GetType() )
1640 : {
1641 : case CSS1_LENGTH:
1642 0 : nHeight = (sal_uInt16)pExpr->GetULength();
1643 0 : break;
1644 : case CSS1_PIXLENGTH:
1645 : {
1646 0 : long nPWidth = 0;
1647 0 : long nPHeight = (long)pExpr->GetNumber();
1648 0 : SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
1649 0 : nHeight = (sal_uInt16)nPHeight;
1650 : }
1651 0 : break;
1652 : case CSS1_PERCENTAGE:
1653 : {
1654 7 : sal_uInt16 nPHeight = (sal_uInt16)pExpr->GetNumber();
1655 7 : nPropHeight = nPHeight <= 200 ? (sal_uInt8)nPHeight : 200;
1656 : }
1657 7 : break;
1658 : case CSS1_NUMBER:
1659 : {
1660 0 : sal_uInt16 nPHeight = (sal_uInt16)(pExpr->GetNumber() * 100);
1661 0 : nPropHeight = nPHeight <= 200 ? (sal_uInt8)nPHeight : 200;
1662 : }
1663 0 : break;
1664 : default:
1665 : ;
1666 : }
1667 :
1668 7 : if( nHeight )
1669 : {
1670 0 : if( nHeight < rParser.GetMinFixLineSpace() )
1671 0 : nHeight = rParser.GetMinFixLineSpace();
1672 0 : SvxLineSpacingItem aLSItem( nHeight, aItemIds.nLineSpacing );
1673 0 : aLSItem.SetLineHeight( nHeight );
1674 : // interpret <line-height> attribute as minimum line height
1675 0 : aLSItem.GetLineSpaceRule() = SVX_LINE_SPACE_MIN;
1676 0 : aLSItem.GetInterLineSpaceRule() = SVX_INTER_LINE_SPACE_OFF;
1677 0 : rItemSet.Put( aLSItem );
1678 : }
1679 7 : else if( nPropHeight )
1680 : {
1681 7 : SvxLineSpacingItem aLSItem( nPropHeight, aItemIds.nLineSpacing );
1682 7 : aLSItem.GetLineSpaceRule() = SVX_LINE_SPACE_AUTO;
1683 7 : if( 100 == nPropHeight )
1684 5 : aLSItem.GetInterLineSpaceRule() = SVX_INTER_LINE_SPACE_OFF;
1685 : else
1686 2 : aLSItem.SetPropLineSpace( nPropHeight );
1687 7 : rItemSet.Put( aLSItem );
1688 : }
1689 :
1690 7 : }
1691 :
1692 0 : static void ParseCSS1_font( const CSS1Expression *pExpr,
1693 : SfxItemSet &rItemSet,
1694 : SvxCSS1PropertyInfo& rPropInfo,
1695 : const SvxCSS1Parser& rParser )
1696 : {
1697 : OSL_ENSURE( pExpr, "no expression" );
1698 :
1699 0 : FontItalic eItalic = ITALIC_NONE;
1700 0 : SvxCaseMap eCaseMap = SVX_CASEMAP_NOT_MAPPED;
1701 0 : FontWeight eWeight = WEIGHT_NORMAL;
1702 :
1703 : // [ <font-style> || <font-variant> || <font-weight> ] ?
1704 0 : while( pExpr && !pExpr->GetOp() &&
1705 0 : (CSS1_IDENT==pExpr->GetType() ||
1706 0 : CSS1_STRING==pExpr->GetType() ||
1707 0 : CSS1_NUMBER==pExpr->GetType()) )
1708 : {
1709 0 : if( CSS1_IDENT==pExpr->GetType() ||
1710 0 : CSS1_STRING==pExpr->GetType() )
1711 : {
1712 0 : const OUString& rValue = pExpr->GetString();
1713 :
1714 : sal_uInt16 nEnum;
1715 :
1716 0 : if( SvxCSS1Parser::GetEnum( aFontStyleTable, rValue, nEnum ) )
1717 : {
1718 0 : eItalic = (FontItalic)nEnum;
1719 : }
1720 0 : else if( SvxCSS1Parser::GetEnum( aFontVariantTable, rValue, nEnum ) )
1721 : {
1722 0 : eCaseMap = (SvxCaseMap)nEnum;
1723 : }
1724 0 : else if( SvxCSS1Parser::GetEnum( aFontWeightTable, rValue, nEnum ) )
1725 : {
1726 0 : eWeight = (FontWeight)nEnum;
1727 : }
1728 : }
1729 : else
1730 : {
1731 0 : eWeight = (sal_uInt16)pExpr->GetNumber() > 400 ? WEIGHT_BOLD
1732 0 : : WEIGHT_NORMAL;
1733 : }
1734 :
1735 0 : pExpr = pExpr->GetNext();
1736 : }
1737 :
1738 0 : if( !pExpr || pExpr->GetOp() )
1739 0 : return;
1740 :
1741 : // Da "font" alle Werte zurecksetzt, fuer die nichts angegeben ist,
1742 : // tun wir das hier.
1743 0 : SvxPostureItem aPosture( eItalic, aItemIds.nPosture );
1744 0 : if( rParser.IsSetWesternProps() )
1745 0 : rItemSet.Put( aPosture );
1746 0 : if( rParser.IsSetCJKProps() )
1747 : {
1748 0 : aPosture.SetWhich( aItemIds.nPostureCJK );
1749 0 : rItemSet.Put( aPosture );
1750 : }
1751 0 : if( rParser.IsSetCTLProps() )
1752 : {
1753 0 : aPosture.SetWhich( aItemIds.nPostureCTL );
1754 0 : rItemSet.Put( aPosture );
1755 : }
1756 :
1757 0 : rItemSet.Put( SvxCaseMapItem( eCaseMap, aItemIds.nCaseMap ) );
1758 :
1759 0 : SvxWeightItem aWeight( eWeight, aItemIds.nWeight );
1760 0 : if( rParser.IsSetWesternProps() )
1761 0 : rItemSet.Put( aWeight );
1762 0 : if( rParser.IsSetCJKProps() )
1763 : {
1764 0 : aWeight.SetWhich( aItemIds.nWeightCJK );
1765 0 : rItemSet.Put( aWeight );
1766 : }
1767 0 : if( rParser.IsSetCTLProps() )
1768 : {
1769 0 : aWeight.SetWhich( aItemIds.nWeightCTL );
1770 0 : rItemSet.Put( aWeight );
1771 : }
1772 :
1773 : // font-size
1774 0 : CSS1Expression aExpr( pExpr->GetType(), pExpr->GetString(),
1775 0 : pExpr->GetNumber() );
1776 0 : ParseCSS1_font_size( &aExpr, rItemSet, rPropInfo, rParser );
1777 0 : pExpr = pExpr->GetNext();
1778 :
1779 0 : if( !pExpr )
1780 0 : return;
1781 :
1782 : // [ '/' line-height ]?
1783 0 : if( '/' == pExpr->GetOp() )
1784 : {
1785 : // '/' line-height
1786 0 : aExpr.Set( pExpr->GetType(), pExpr->GetString(), pExpr->GetNumber() );
1787 0 : ParseCSS1_line_height( &aExpr, rItemSet, rPropInfo, rParser );
1788 :
1789 0 : pExpr = pExpr->GetNext();
1790 : }
1791 :
1792 0 : if( !pExpr || pExpr->GetOp() )
1793 0 : return;
1794 :
1795 : // font-family
1796 0 : ParseCSS1_font_family( pExpr, rItemSet, rPropInfo, rParser );
1797 : }
1798 :
1799 0 : static void ParseCSS1_letter_spacing( const CSS1Expression *pExpr,
1800 : SfxItemSet &rItemSet,
1801 : SvxCSS1PropertyInfo& /*rPropInfo*/,
1802 : const SvxCSS1Parser& /*rParser*/ )
1803 : {
1804 : OSL_ENSURE( pExpr, "no expression" );
1805 :
1806 0 : switch( pExpr->GetType() )
1807 : {
1808 : case CSS1_LENGTH:
1809 0 : rItemSet.Put( SvxKerningItem( (short)pExpr->GetSLength(),
1810 0 : aItemIds.nKerning ) );
1811 0 : break;
1812 :
1813 : case CSS1_PIXLENGTH:
1814 : {
1815 0 : long nPWidth = (long)pExpr->GetNumber();
1816 0 : long nPHeight = 0;
1817 0 : SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
1818 0 : rItemSet.Put( SvxKerningItem( (short)nPWidth, aItemIds.nKerning ) );
1819 : }
1820 0 : break;
1821 :
1822 : case CSS1_NUMBER:
1823 0 : if( pExpr->GetNumber() == 0 )
1824 : {
1825 : // eigentlich unnoetig, aber wir sind ja tollerant
1826 0 : rItemSet.Put( SvxKerningItem( (short)0, aItemIds.nKerning ) );
1827 : }
1828 0 : break;
1829 :
1830 : case CSS1_IDENT:
1831 : case CSS1_STRING: // Vorschtshalber auch MS-IE
1832 0 : if( pExpr->GetString().equalsIgnoreAsciiCase( "normal" ) )
1833 : {
1834 0 : rItemSet.Put( SvxKerningItem( (short)0, aItemIds.nKerning ) );
1835 : }
1836 0 : break;
1837 : default:
1838 : ;
1839 : }
1840 0 : }
1841 :
1842 0 : static void ParseCSS1_text_decoration( const CSS1Expression *pExpr,
1843 : SfxItemSet &rItemSet,
1844 : SvxCSS1PropertyInfo& /*rPropInfo*/,
1845 : const SvxCSS1Parser& /*rParser*/ )
1846 : {
1847 : OSL_ENSURE( pExpr, "no expression" );
1848 :
1849 0 : bool bUnderline = false;
1850 0 : bool bOverline = false;
1851 0 : bool bCrossedOut = false;
1852 0 : bool bBlink = false;
1853 0 : bool bBlinkOn = false;
1854 0 : FontUnderline eUnderline = UNDERLINE_NONE;
1855 0 : FontUnderline eOverline = UNDERLINE_NONE;
1856 0 : FontStrikeout eCrossedOut = STRIKEOUT_NONE;
1857 :
1858 : // der Wert kann zwei Werte enthalten! Und MS-IE auch Strings
1859 0 : while( pExpr && (pExpr->GetType() == CSS1_IDENT ||
1860 0 : pExpr->GetType() == CSS1_STRING) && !pExpr->GetOp() )
1861 : {
1862 0 : OUString aValue = pExpr->GetString().toAsciiLowerCase();
1863 0 : bool bKnown = false;
1864 :
1865 0 : switch( aValue[0] )
1866 : {
1867 : case 'n':
1868 0 : if( aValue == "none" )
1869 : {
1870 0 : bUnderline = true;
1871 0 : eUnderline = UNDERLINE_NONE;
1872 :
1873 0 : bOverline = true;
1874 0 : eOverline = UNDERLINE_NONE;
1875 :
1876 0 : bCrossedOut = true;
1877 0 : eCrossedOut = STRIKEOUT_NONE;
1878 :
1879 0 : bBlink = true;
1880 0 : bBlinkOn = false;
1881 :
1882 0 : bKnown = true;
1883 : }
1884 0 : break;
1885 :
1886 : case 'u':
1887 0 : if( aValue == "underline" )
1888 : {
1889 0 : bUnderline = true;
1890 0 : eUnderline = UNDERLINE_SINGLE;
1891 :
1892 0 : bKnown = true;
1893 : }
1894 0 : break;
1895 :
1896 : case 'o':
1897 0 : if( aValue == "overline" )
1898 : {
1899 0 : bOverline = true;
1900 0 : eOverline = UNDERLINE_SINGLE;
1901 :
1902 0 : bKnown = true;
1903 : }
1904 0 : break;
1905 :
1906 : case 'l':
1907 0 : if( aValue == "line-through" )
1908 : {
1909 0 : bCrossedOut = true;
1910 0 : eCrossedOut = STRIKEOUT_SINGLE;
1911 :
1912 0 : bKnown = true;
1913 : }
1914 0 : break;
1915 :
1916 : case 'b':
1917 0 : if( aValue == "blink" )
1918 : {
1919 0 : bBlink = true;
1920 0 : bBlinkOn = true;
1921 :
1922 0 : bKnown = true;
1923 : }
1924 0 : break;
1925 : }
1926 :
1927 0 : if( !bKnown )
1928 : {
1929 0 : bUnderline = true;
1930 0 : eUnderline = UNDERLINE_SINGLE;
1931 : }
1932 :
1933 0 : pExpr = pExpr->GetNext();
1934 0 : }
1935 :
1936 0 : if( bUnderline )
1937 0 : rItemSet.Put( SvxUnderlineItem( eUnderline, aItemIds.nUnderline ) );
1938 :
1939 0 : if( bOverline )
1940 0 : rItemSet.Put( SvxOverlineItem( eOverline, aItemIds.nOverline ) );
1941 :
1942 0 : if( bCrossedOut )
1943 0 : rItemSet.Put( SvxCrossedOutItem( eCrossedOut, aItemIds.nCrossedOut ) );
1944 :
1945 0 : if( bBlink )
1946 0 : rItemSet.Put( SvxBlinkItem( bBlinkOn, aItemIds.nBlink ) );
1947 0 : }
1948 :
1949 7 : static void ParseCSS1_text_align( const CSS1Expression *pExpr,
1950 : SfxItemSet &rItemSet,
1951 : SvxCSS1PropertyInfo& /*rPropInfo*/,
1952 : const SvxCSS1Parser& /*rParser*/ )
1953 : {
1954 : OSL_ENSURE( pExpr, "no expression" );
1955 :
1956 7 : if( CSS1_IDENT==pExpr->GetType() ||
1957 0 : CSS1_STRING==pExpr->GetType() ) // MS-IE, mal wieder
1958 : {
1959 : sal_uInt16 nAdjust;
1960 7 : if( SvxCSS1Parser::GetEnum( aTextAlignTable, pExpr->GetString(),
1961 : nAdjust ) )
1962 : {
1963 : rItemSet.Put( SvxAdjustItem( (SvxAdjust)nAdjust,
1964 7 : aItemIds.nAdjust ) );
1965 : }
1966 : }
1967 7 : }
1968 :
1969 0 : static void ParseCSS1_text_indent( const CSS1Expression *pExpr,
1970 : SfxItemSet &rItemSet,
1971 : SvxCSS1PropertyInfo& rPropInfo,
1972 : const SvxCSS1Parser& /*rParser*/ )
1973 : {
1974 : OSL_ENSURE( pExpr, "no expression" );
1975 :
1976 0 : short nIndent = 0;
1977 0 : bool bSet = false;
1978 0 : switch( pExpr->GetType() )
1979 : {
1980 : case CSS1_LENGTH:
1981 0 : nIndent = (short)pExpr->GetSLength();
1982 0 : bSet = true;
1983 0 : break;
1984 : case CSS1_PIXLENGTH:
1985 : {
1986 0 : long nPWidth = (long)pExpr->GetNumber();
1987 0 : long nPHeight = 0;
1988 0 : SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
1989 0 : nIndent = (short)nPWidth;
1990 0 : bSet = true;
1991 : }
1992 0 : break;
1993 : case CSS1_PERCENTAGE:
1994 : // koennen wir nicht
1995 0 : break;
1996 : default:
1997 : ;
1998 : }
1999 :
2000 0 : if( bSet )
2001 : {
2002 : const SfxPoolItem* pItem;
2003 0 : if( SfxItemState::SET == rItemSet.GetItemState( aItemIds.nLRSpace, false,
2004 0 : &pItem ) )
2005 : {
2006 0 : SvxLRSpaceItem aLRItem( *static_cast<const SvxLRSpaceItem*>(pItem) );
2007 0 : aLRItem.SetTextFirstLineOfst( nIndent );
2008 0 : rItemSet.Put( aLRItem );
2009 : }
2010 : else
2011 : {
2012 0 : SvxLRSpaceItem aLRItem( aItemIds.nLRSpace );
2013 0 : aLRItem.SetTextFirstLineOfst( nIndent );
2014 0 : rItemSet.Put( aLRItem );
2015 : }
2016 0 : rPropInfo.bTextIndent = true;
2017 : }
2018 0 : }
2019 :
2020 4 : static void ParseCSS1_margin_left( const CSS1Expression *pExpr,
2021 : SfxItemSet &rItemSet,
2022 : SvxCSS1PropertyInfo& rPropInfo,
2023 : const SvxCSS1Parser& /*rParser*/ )
2024 : {
2025 : OSL_ENSURE( pExpr, "no expression" );
2026 :
2027 4 : long nLeft = 0;
2028 4 : bool bSet = false;
2029 4 : switch( pExpr->GetType() )
2030 : {
2031 : case CSS1_LENGTH:
2032 : {
2033 4 : nLeft = pExpr->GetSLength();
2034 4 : bSet = true;
2035 : }
2036 4 : break;
2037 : case CSS1_PIXLENGTH:
2038 : {
2039 0 : nLeft = (long)pExpr->GetNumber();
2040 0 : long nPHeight = 0;
2041 0 : SvxCSS1Parser::PixelToTwip( nLeft, nPHeight );
2042 0 : bSet = true;
2043 : }
2044 0 : break;
2045 : case CSS1_PERCENTAGE:
2046 : // koennen wir nicht
2047 0 : break;
2048 : default:
2049 : ;
2050 : }
2051 :
2052 4 : if( bSet )
2053 : {
2054 4 : rPropInfo.nLeftMargin = nLeft;
2055 4 : if( nLeft < 0 )
2056 0 : nLeft = 0;
2057 : const SfxPoolItem* pItem;
2058 4 : if( SfxItemState::SET == rItemSet.GetItemState( aItemIds.nLRSpace, false,
2059 4 : &pItem ) )
2060 : {
2061 0 : SvxLRSpaceItem aLRItem( *static_cast<const SvxLRSpaceItem*>(pItem) );
2062 0 : aLRItem.SetTextLeft( (sal_uInt16)nLeft );
2063 0 : rItemSet.Put( aLRItem );
2064 : }
2065 : else
2066 : {
2067 4 : SvxLRSpaceItem aLRItem( aItemIds.nLRSpace );
2068 4 : aLRItem.SetTextLeft( (sal_uInt16)nLeft );
2069 4 : rItemSet.Put( aLRItem );
2070 : }
2071 4 : rPropInfo.bLeftMargin = true;
2072 : }
2073 4 : }
2074 :
2075 3 : static void ParseCSS1_margin_right( const CSS1Expression *pExpr,
2076 : SfxItemSet &rItemSet,
2077 : SvxCSS1PropertyInfo& rPropInfo,
2078 : const SvxCSS1Parser& /*rParser*/ )
2079 : {
2080 : OSL_ENSURE( pExpr, "no expression" );
2081 :
2082 3 : long nRight = 0;
2083 3 : bool bSet = false;
2084 3 : switch( pExpr->GetType() )
2085 : {
2086 : case CSS1_LENGTH:
2087 : {
2088 3 : nRight = pExpr->GetSLength();
2089 3 : bSet = true;
2090 : }
2091 3 : break;
2092 : case CSS1_PIXLENGTH:
2093 : {
2094 0 : nRight = (long)pExpr->GetNumber();
2095 0 : long nPHeight = 0;
2096 0 : SvxCSS1Parser::PixelToTwip( nRight, nPHeight );
2097 0 : bSet = true;
2098 : }
2099 0 : break;
2100 : case CSS1_PERCENTAGE:
2101 : // koennen wir nicht
2102 0 : break;
2103 : default:
2104 : ;
2105 : }
2106 :
2107 3 : if( bSet )
2108 : {
2109 3 : rPropInfo.nRightMargin = nRight;
2110 3 : if( nRight < 0 )
2111 0 : nRight = 0;
2112 : const SfxPoolItem* pItem;
2113 3 : if( SfxItemState::SET == rItemSet.GetItemState( aItemIds.nLRSpace, false,
2114 3 : &pItem ) )
2115 : {
2116 3 : SvxLRSpaceItem aLRItem( *static_cast<const SvxLRSpaceItem*>(pItem) );
2117 3 : aLRItem.SetRight( (sal_uInt16)nRight );
2118 3 : rItemSet.Put( aLRItem );
2119 : }
2120 : else
2121 : {
2122 0 : SvxLRSpaceItem aLRItem( aItemIds.nLRSpace );
2123 0 : aLRItem.SetRight( (sal_uInt16)nRight );
2124 0 : rItemSet.Put( aLRItem );
2125 : }
2126 3 : rPropInfo.bRightMargin = true;
2127 : }
2128 3 : }
2129 :
2130 3 : static void ParseCSS1_margin_top( const CSS1Expression *pExpr,
2131 : SfxItemSet &rItemSet,
2132 : SvxCSS1PropertyInfo& rPropInfo,
2133 : const SvxCSS1Parser& /*rParser*/ )
2134 : {
2135 : assert(pExpr && "no expression");
2136 :
2137 3 : sal_uInt16 nUpper = 0;
2138 3 : bool bSet = false;
2139 3 : switch( pExpr->GetType() )
2140 : {
2141 : case CSS1_LENGTH:
2142 : {
2143 3 : long nTmp = pExpr->GetSLength();
2144 3 : if( nTmp < 0 )
2145 0 : nTmp = 0;
2146 3 : nUpper = (sal_uInt16)nTmp;
2147 3 : bSet = true;
2148 : }
2149 3 : break;
2150 : case CSS1_PIXLENGTH:
2151 : {
2152 0 : long nPWidth = 0;
2153 0 : long nPHeight = (long)pExpr->GetNumber();
2154 0 : if( nPHeight < 0 )
2155 0 : nPHeight = 0;
2156 0 : SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2157 0 : nUpper = (sal_uInt16)nPHeight;
2158 0 : bSet = true;
2159 : }
2160 0 : break;
2161 : case CSS1_PERCENTAGE:
2162 : // koennen wir nicht
2163 0 : break;
2164 : default:
2165 : ;
2166 : }
2167 :
2168 3 : if( bSet )
2169 : {
2170 : const SfxPoolItem* pItem;
2171 3 : if( SfxItemState::SET == rItemSet.GetItemState( aItemIds.nULSpace, false,
2172 3 : &pItem ) )
2173 : {
2174 0 : SvxULSpaceItem aULItem( *static_cast<const SvxULSpaceItem*>(pItem) );
2175 0 : aULItem.SetUpper( nUpper );
2176 0 : rItemSet.Put( aULItem );
2177 : }
2178 : else
2179 : {
2180 3 : SvxULSpaceItem aULItem( aItemIds.nULSpace );
2181 3 : aULItem.SetUpper( nUpper );
2182 3 : rItemSet.Put( aULItem );
2183 : }
2184 3 : rPropInfo.bTopMargin = true;
2185 : }
2186 3 : }
2187 :
2188 16 : static void ParseCSS1_margin_bottom( const CSS1Expression *pExpr,
2189 : SfxItemSet &rItemSet,
2190 : SvxCSS1PropertyInfo& rPropInfo,
2191 : const SvxCSS1Parser& /*rParser*/ )
2192 : {
2193 : OSL_ENSURE( pExpr, "no expression" );
2194 :
2195 16 : sal_uInt16 nLower = 0;
2196 16 : bool bSet = false;
2197 16 : switch( pExpr->GetType() )
2198 : {
2199 : case CSS1_LENGTH:
2200 : {
2201 16 : long nTmp = pExpr->GetSLength();
2202 16 : if( nTmp < 0 )
2203 0 : nTmp = 0;
2204 16 : nLower = (sal_uInt16)nTmp;
2205 16 : bSet = true;
2206 : }
2207 16 : break;
2208 : case CSS1_PIXLENGTH:
2209 : {
2210 0 : long nPWidth = 0;
2211 0 : long nPHeight = (long)pExpr->GetNumber();
2212 0 : if( nPHeight < 0 )
2213 0 : nPHeight = 0;
2214 0 : SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2215 0 : nLower = (sal_uInt16)nPHeight;
2216 0 : bSet = true;
2217 : }
2218 0 : break;
2219 : case CSS1_PERCENTAGE:
2220 : // koennen wir nicht
2221 0 : break;
2222 : default:
2223 : ;
2224 : }
2225 :
2226 16 : if( bSet )
2227 : {
2228 : const SfxPoolItem* pItem;
2229 16 : if( SfxItemState::SET == rItemSet.GetItemState( aItemIds.nULSpace, false,
2230 16 : &pItem ) )
2231 : {
2232 3 : SvxULSpaceItem aULItem( *static_cast<const SvxULSpaceItem*>(pItem) );
2233 3 : aULItem.SetLower( nLower );
2234 3 : rItemSet.Put( aULItem );
2235 : }
2236 : else
2237 : {
2238 13 : SvxULSpaceItem aULItem( aItemIds.nULSpace );
2239 13 : aULItem.SetLower( nLower );
2240 13 : rItemSet.Put( aULItem );
2241 : }
2242 16 : rPropInfo.bBottomMargin = true;
2243 : }
2244 16 : }
2245 :
2246 7 : static void ParseCSS1_margin( const CSS1Expression *pExpr,
2247 : SfxItemSet &rItemSet,
2248 : SvxCSS1PropertyInfo& rPropInfo,
2249 : const SvxCSS1Parser& /*rParser*/ )
2250 : {
2251 : OSL_ENSURE( pExpr, "no expression" );
2252 :
2253 7 : long nMargins[4] = { 0, 0, 0, 0 };
2254 7 : bool bSetMargins[4] = { false, false, false, false };
2255 :
2256 17 : for( int i=0; pExpr && i<4 && !pExpr->GetOp(); ++i )
2257 : {
2258 10 : bool bSetThis = false;
2259 10 : long nMargin = 0;
2260 :
2261 10 : switch( pExpr->GetType() )
2262 : {
2263 : case CSS1_LENGTH:
2264 : {
2265 10 : nMargin = pExpr->GetSLength();
2266 10 : bSetThis = true;
2267 : }
2268 10 : break;
2269 : case CSS1_PIXLENGTH:
2270 : {
2271 0 : long nPWidth = 0;
2272 0 : nMargin = (long)pExpr->GetNumber();
2273 0 : SvxCSS1Parser::PixelToTwip( nPWidth, nMargin );
2274 0 : bSetThis = true;
2275 : }
2276 0 : break;
2277 : case CSS1_PERCENTAGE:
2278 : // koennen wir nicht
2279 0 : break;
2280 : default:
2281 : ;
2282 : }
2283 :
2284 10 : if( bSetThis )
2285 : {
2286 : // 0 = top
2287 : // 1 = right
2288 : // 2 = bottom
2289 : // 3 = left
2290 10 : switch( i )
2291 : {
2292 : case 0:
2293 7 : nMargins[0] = nMargins[1] =nMargins[2] = nMargins[3] = nMargin;
2294 7 : bSetMargins[0] = bSetMargins[1] =
2295 14 : bSetMargins[2] = bSetMargins[3] = true;
2296 7 : break;
2297 : case 1:
2298 1 : nMargins[1] = nMargins[3] = nMargin; // right + left
2299 1 : bSetMargins[1] = bSetMargins[3] = true;
2300 1 : break;
2301 : case 2:
2302 1 : nMargins[2] = nMargin; // bottom
2303 1 : bSetMargins[2] = true;
2304 1 : break;
2305 : case 3:
2306 1 : nMargins[3] = nMargin; // left
2307 1 : bSetMargins[3] = true;
2308 1 : break;
2309 : }
2310 : }
2311 10 : pExpr = pExpr->GetNext();
2312 : }
2313 :
2314 7 : if( bSetMargins[3] || bSetMargins[1] )
2315 : {
2316 7 : if( bSetMargins[3] )
2317 : {
2318 7 : rPropInfo.bLeftMargin = true;
2319 7 : rPropInfo.nLeftMargin = nMargins[3];
2320 7 : if( nMargins[3] < 0 )
2321 0 : nMargins[3] = 0;
2322 : }
2323 7 : if( bSetMargins[1] )
2324 : {
2325 7 : rPropInfo.bRightMargin = true;
2326 7 : rPropInfo.nRightMargin = nMargins[1];
2327 7 : if( nMargins[1] < 0 )
2328 0 : nMargins[1] = 0;
2329 : }
2330 :
2331 : const SfxPoolItem* pItem;
2332 7 : if( SfxItemState::SET == rItemSet.GetItemState( aItemIds.nLRSpace, false,
2333 7 : &pItem ) )
2334 : {
2335 0 : SvxLRSpaceItem aLRItem( *static_cast<const SvxLRSpaceItem*>(pItem) );
2336 0 : if( bSetMargins[3] )
2337 0 : aLRItem.SetLeft( (sal_uInt16)nMargins[3] );
2338 0 : if( bSetMargins[1] )
2339 0 : aLRItem.SetRight( (sal_uInt16)nMargins[1] );
2340 0 : rItemSet.Put( aLRItem );
2341 : }
2342 : else
2343 : {
2344 7 : SvxLRSpaceItem aLRItem( aItemIds.nLRSpace );
2345 7 : if( bSetMargins[3] )
2346 7 : aLRItem.SetLeft( (sal_uInt16)nMargins[3] );
2347 7 : if( bSetMargins[1] )
2348 7 : aLRItem.SetRight( (sal_uInt16)nMargins[1] );
2349 7 : rItemSet.Put( aLRItem );
2350 : }
2351 : }
2352 :
2353 7 : if( bSetMargins[0] || bSetMargins[2] )
2354 : {
2355 7 : if( nMargins[0] < 0 )
2356 0 : nMargins[0] = 0;
2357 7 : if( nMargins[2] < 0 )
2358 0 : nMargins[2] = 0;
2359 :
2360 : const SfxPoolItem* pItem;
2361 7 : if( SfxItemState::SET == rItemSet.GetItemState( aItemIds.nULSpace, false,
2362 7 : &pItem ) )
2363 : {
2364 0 : SvxULSpaceItem aULItem( *static_cast<const SvxULSpaceItem*>(pItem) );
2365 0 : if( bSetMargins[0] )
2366 0 : aULItem.SetUpper( (sal_uInt16)nMargins[0] );
2367 0 : if( bSetMargins[2] )
2368 0 : aULItem.SetLower( (sal_uInt16)nMargins[2] );
2369 0 : rItemSet.Put( aULItem );
2370 : }
2371 : else
2372 : {
2373 7 : SvxULSpaceItem aULItem( aItemIds.nULSpace );
2374 7 : if( bSetMargins[0] )
2375 7 : aULItem.SetUpper( (sal_uInt16)nMargins[0] );
2376 7 : if( bSetMargins[2] )
2377 7 : aULItem.SetLower( (sal_uInt16)nMargins[2] );
2378 7 : rItemSet.Put( aULItem );
2379 : }
2380 :
2381 7 : rPropInfo.bTopMargin |= bSetMargins[0];
2382 7 : rPropInfo.bBottomMargin |= bSetMargins[2];
2383 : }
2384 7 : }
2385 :
2386 2091 : static bool ParseCSS1_padding_xxx( const CSS1Expression *pExpr,
2387 : SfxItemSet & /*rItemSet*/,
2388 : SvxCSS1PropertyInfo& rPropInfo,
2389 : const SvxCSS1Parser& /*rParser*/,
2390 : SvxBoxItemLine nWhichLine )
2391 : {
2392 : OSL_ENSURE( pExpr, "no expression" );
2393 :
2394 2091 : bool bSet = false;
2395 2091 : sal_uInt16 nDist = 0;
2396 :
2397 2091 : switch( pExpr->GetType() )
2398 : {
2399 : case CSS1_LENGTH:
2400 : {
2401 2090 : long nTmp = pExpr->GetSLength();
2402 2090 : if( nTmp < 0 )
2403 0 : nTmp = 0;
2404 2090 : else if( nTmp > USHRT_MAX-1 )
2405 0 : nTmp = USHRT_MAX-1;
2406 2090 : nDist = (sal_uInt16)nTmp;
2407 2090 : bSet = true;
2408 : }
2409 2090 : break;
2410 : case CSS1_PIXLENGTH:
2411 : {
2412 0 : long nPWidth = (long)pExpr->GetNumber();
2413 0 : long nPHeight = 0;
2414 0 : if( nPWidth < 0 )
2415 0 : nPWidth = 0;
2416 0 : SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2417 0 : if( nPWidth > USHRT_MAX-1 )
2418 0 : nPWidth = USHRT_MAX-1;
2419 0 : nDist = (sal_uInt16)nPWidth;
2420 0 : bSet = true;
2421 : }
2422 0 : break;
2423 : case CSS1_PERCENTAGE:
2424 : // koennen wir nicht
2425 1 : break;
2426 : default:
2427 : ;
2428 : }
2429 :
2430 2091 : if( bSet )
2431 : {
2432 2090 : switch( nWhichLine )
2433 : {
2434 521 : case SvxBoxItemLine::TOP: rPropInfo.nTopBorderDistance = nDist; break;
2435 527 : case SvxBoxItemLine::BOTTOM: rPropInfo.nBottomBorderDistance = nDist;break;
2436 521 : case SvxBoxItemLine::LEFT: rPropInfo.nLeftBorderDistance = nDist; break;
2437 521 : case SvxBoxItemLine::RIGHT: rPropInfo.nRightBorderDistance = nDist; break;
2438 : }
2439 : }
2440 :
2441 2091 : return bSet;
2442 : }
2443 :
2444 522 : static void ParseCSS1_padding_top( const CSS1Expression *pExpr,
2445 : SfxItemSet &rItemSet,
2446 : SvxCSS1PropertyInfo& rPropInfo,
2447 : const SvxCSS1Parser& rParser )
2448 : {
2449 522 : ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::TOP );
2450 522 : }
2451 :
2452 521 : static void ParseCSS1_padding_bottom( const CSS1Expression *pExpr,
2453 : SfxItemSet &rItemSet,
2454 : SvxCSS1PropertyInfo& rPropInfo,
2455 : const SvxCSS1Parser& rParser )
2456 : {
2457 : ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser,
2458 521 : SvxBoxItemLine::BOTTOM );
2459 521 : }
2460 :
2461 521 : static void ParseCSS1_padding_left( const CSS1Expression *pExpr,
2462 : SfxItemSet &rItemSet,
2463 : SvxCSS1PropertyInfo& rPropInfo,
2464 : const SvxCSS1Parser& rParser )
2465 : {
2466 521 : ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::LEFT );
2467 521 : }
2468 :
2469 521 : static void ParseCSS1_padding_right( const CSS1Expression *pExpr,
2470 : SfxItemSet &rItemSet,
2471 : SvxCSS1PropertyInfo& rPropInfo,
2472 : const SvxCSS1Parser& rParser )
2473 : {
2474 : ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser,
2475 521 : SvxBoxItemLine::RIGHT );
2476 521 : }
2477 :
2478 6 : static void ParseCSS1_padding( const CSS1Expression *pExpr,
2479 : SfxItemSet &rItemSet,
2480 : SvxCSS1PropertyInfo& rPropInfo,
2481 : const SvxCSS1Parser& rParser )
2482 : {
2483 6 : int n=0;
2484 18 : while( n<4 && pExpr && !pExpr->GetOp() )
2485 : {
2486 6 : SvxBoxItemLine nLine = n==0 || n==2 ? SvxBoxItemLine::BOTTOM : SvxBoxItemLine::LEFT;
2487 6 : if( ParseCSS1_padding_xxx( pExpr, rItemSet, rPropInfo, rParser,
2488 : nLine ) )
2489 : {
2490 6 : if( n==0 )
2491 : {
2492 6 : rPropInfo.nTopBorderDistance = rPropInfo.nBottomBorderDistance;
2493 6 : rPropInfo.nLeftBorderDistance = rPropInfo.nTopBorderDistance;
2494 : }
2495 6 : if( n <= 1 )
2496 6 : rPropInfo.nRightBorderDistance = rPropInfo.nLeftBorderDistance;
2497 : }
2498 :
2499 6 : pExpr = pExpr->GetNext();
2500 6 : n++;
2501 : }
2502 6 : }
2503 :
2504 566 : static void ParseCSS1_border_xxx( const CSS1Expression *pExpr,
2505 : SfxItemSet & /*rItemSet*/,
2506 : SvxCSS1PropertyInfo& rPropInfo,
2507 : const SvxCSS1Parser& /*rParser*/,
2508 : SvxBoxItemLine nWhichLine, bool bAll )
2509 : {
2510 : OSL_ENSURE( pExpr, "no expression" );
2511 :
2512 566 : sal_uInt16 nWidth = USHRT_MAX; // die Linien-Dicke
2513 566 : sal_uInt16 nNWidth = 1; // benannte Linien-Dicke (und default)
2514 566 : CSS1BorderStyle eStyle = CSS1_BS_NONE; // Linien-Style
2515 566 : Color aColor;
2516 566 : bool bColor = false;
2517 :
2518 2830 : while( pExpr && !pExpr->GetOp() )
2519 : {
2520 1698 : switch( pExpr->GetType() )
2521 : {
2522 : case CSS1_RGB:
2523 : case CSS1_HEXCOLOR:
2524 566 : if( pExpr->GetColor( aColor ) )
2525 566 : bColor = true;
2526 566 : break;
2527 :
2528 : case CSS1_IDENT:
2529 : {
2530 566 : const OUString& rValue = pExpr->GetString();
2531 : sal_uInt16 nValue;
2532 566 : if( SvxCSS1Parser::GetEnum( aBorderWidthTable, rValue, nValue ) )
2533 : {
2534 0 : nNWidth = nValue;
2535 : }
2536 566 : else if( SvxCSS1Parser::GetEnum( aBorderStyleTable, rValue, nValue ) )
2537 : {
2538 566 : eStyle = (CSS1BorderStyle)nValue;
2539 : }
2540 0 : else if( pExpr->GetColor( aColor ) )
2541 : {
2542 0 : bColor = true;
2543 : }
2544 : }
2545 566 : break;
2546 :
2547 : case CSS1_LENGTH:
2548 4 : nWidth = (sal_uInt16)pExpr->GetULength();
2549 4 : break;
2550 :
2551 : case CSS1_PIXLENGTH:
2552 : {
2553 562 : bool bHori = nWhichLine == SvxBoxItemLine::TOP ||
2554 562 : nWhichLine == SvxBoxItemLine::BOTTOM;
2555 : // Ein Pixel wird zur Haarlinie (ist huebscher)
2556 562 : long nWidthL = (long)pExpr->GetNumber();
2557 562 : if( nWidthL > 1 )
2558 : {
2559 0 : long nPWidth = bHori ? 0 : nWidthL;
2560 0 : long nPHeight = bHori ? nWidthL : 0;
2561 0 : SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2562 0 : nWidth = (sal_uInt16)(bHori ? nPHeight : nPWidth);
2563 : }
2564 : else
2565 562 : nWidth = 1;
2566 : }
2567 562 : break;
2568 :
2569 : default:
2570 : ;
2571 : }
2572 :
2573 1698 : pExpr = pExpr->GetNext();
2574 : }
2575 :
2576 2830 : for( int i=0; i<4; ++i )
2577 : {
2578 2264 : SvxBoxItemLine nLine = SvxBoxItemLine::TOP;
2579 2264 : switch( i )
2580 : {
2581 566 : case 0: nLine = SvxBoxItemLine::TOP; break;
2582 566 : case 1: nLine = SvxBoxItemLine::BOTTOM; break;
2583 566 : case 2: nLine = SvxBoxItemLine::LEFT; break;
2584 566 : case 3: nLine = SvxBoxItemLine::RIGHT; break;
2585 : }
2586 :
2587 2264 : if( bAll || nLine == nWhichLine )
2588 : {
2589 2234 : SvxCSS1BorderInfo *pInfo = rPropInfo.GetBorderInfo( nLine );
2590 2234 : pInfo->eStyle = eStyle;
2591 2234 : pInfo->nAbsWidth = nWidth;
2592 2234 : pInfo->nNamedWidth = nNWidth;
2593 2234 : if( bColor )
2594 2234 : pInfo->aColor = aColor;
2595 : }
2596 : }
2597 566 : }
2598 :
2599 0 : static void ParseCSS1_border_xxx_width( const CSS1Expression *pExpr,
2600 : SfxItemSet & /*rItemSet*/,
2601 : SvxCSS1PropertyInfo& rPropInfo,
2602 : const SvxCSS1Parser& /*rParser*/,
2603 : SvxBoxItemLine nWhichLine )
2604 : {
2605 : OSL_ENSURE( pExpr, "no expression" );
2606 :
2607 0 : sal_uInt16 nWidth = USHRT_MAX; // die Linien-Dicke
2608 0 : sal_uInt16 nNWidth = 1; // benannte Linien-Dicke (und default)
2609 :
2610 0 : switch( pExpr->GetType() )
2611 : {
2612 : case CSS1_IDENT:
2613 : {
2614 : sal_uInt16 nValue;
2615 0 : if( SvxCSS1Parser::GetEnum( aBorderWidthTable, pExpr->GetString(), nValue ) )
2616 : {
2617 0 : nNWidth = nValue;
2618 : }
2619 : }
2620 0 : break;
2621 :
2622 : case CSS1_LENGTH:
2623 0 : nWidth = (sal_uInt16)pExpr->GetULength();
2624 0 : break;
2625 :
2626 : case CSS1_PIXLENGTH:
2627 : {
2628 0 : bool bHori = nWhichLine == SvxBoxItemLine::TOP ||
2629 0 : nWhichLine == SvxBoxItemLine::BOTTOM;
2630 0 : long nWidthL = (long)pExpr->GetNumber();
2631 0 : long nPWidth = bHori ? 0 : nWidthL;
2632 0 : long nPHeight = bHori ? nWidthL : 0;
2633 0 : SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2634 0 : nWidth = (sal_uInt16)(bHori ? nPHeight : nPWidth);
2635 : }
2636 0 : break;
2637 :
2638 : default:
2639 : ;
2640 : }
2641 :
2642 0 : SvxCSS1BorderInfo *pInfo = rPropInfo.GetBorderInfo( nWhichLine );
2643 0 : pInfo->nAbsWidth = nWidth;
2644 0 : pInfo->nNamedWidth = nNWidth;
2645 0 : }
2646 :
2647 0 : static void ParseCSS1_border_top_width( const CSS1Expression *pExpr,
2648 : SfxItemSet &rItemSet,
2649 : SvxCSS1PropertyInfo& rPropInfo,
2650 : const SvxCSS1Parser& rParser )
2651 : {
2652 0 : ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::TOP );
2653 0 : }
2654 :
2655 0 : static void ParseCSS1_border_right_width( const CSS1Expression *pExpr,
2656 : SfxItemSet &rItemSet,
2657 : SvxCSS1PropertyInfo& rPropInfo,
2658 : const SvxCSS1Parser& rParser )
2659 : {
2660 0 : ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::RIGHT );
2661 0 : }
2662 :
2663 0 : static void ParseCSS1_border_bottom_width( const CSS1Expression *pExpr,
2664 : SfxItemSet &rItemSet,
2665 : SvxCSS1PropertyInfo& rPropInfo,
2666 : const SvxCSS1Parser& rParser )
2667 : {
2668 0 : ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::BOTTOM );
2669 0 : }
2670 :
2671 0 : static void ParseCSS1_border_left_width( const CSS1Expression *pExpr,
2672 : SfxItemSet &rItemSet,
2673 : SvxCSS1PropertyInfo& rPropInfo,
2674 : const SvxCSS1Parser& rParser )
2675 : {
2676 0 : ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::LEFT );
2677 0 : }
2678 :
2679 0 : static void ParseCSS1_border_width( const CSS1Expression *pExpr,
2680 : SfxItemSet &rItemSet,
2681 : SvxCSS1PropertyInfo& rPropInfo,
2682 : const SvxCSS1Parser& rParser )
2683 : {
2684 0 : sal_uInt16 n=0;
2685 0 : while( n<4 && pExpr && !pExpr->GetOp() )
2686 : {
2687 0 : SvxBoxItemLine nLine = n==0 || n==2 ? SvxBoxItemLine::BOTTOM : SvxBoxItemLine::LEFT;
2688 0 : ParseCSS1_border_xxx_width( pExpr, rItemSet, rPropInfo, rParser, nLine );
2689 0 : rPropInfo.CopyBorderInfo( n, SVX_CSS1_BORDERINFO_WIDTH );
2690 :
2691 0 : pExpr = pExpr->GetNext();
2692 0 : n++;
2693 : }
2694 0 : }
2695 :
2696 0 : static void ParseCSS1_border_color( const CSS1Expression *pExpr,
2697 : SfxItemSet & /*rItemSet*/,
2698 : SvxCSS1PropertyInfo& rPropInfo,
2699 : const SvxCSS1Parser& /*rParser*/ )
2700 : {
2701 0 : sal_uInt16 n=0;
2702 0 : while( n<4 && pExpr && !pExpr->GetOp() )
2703 : {
2704 0 : SvxBoxItemLine nLine = n==0 || n==2 ? SvxBoxItemLine::BOTTOM : SvxBoxItemLine::LEFT;
2705 0 : Color aColor;
2706 0 : switch( pExpr->GetType() )
2707 : {
2708 : case CSS1_RGB:
2709 : case CSS1_HEXCOLOR:
2710 : case CSS1_IDENT:
2711 0 : if( pExpr->GetColor( aColor ) )
2712 0 : rPropInfo.GetBorderInfo( nLine )->aColor = aColor;
2713 0 : break;
2714 : default:
2715 : ;
2716 : }
2717 0 : rPropInfo.CopyBorderInfo( n, SVX_CSS1_BORDERINFO_COLOR );
2718 :
2719 0 : pExpr = pExpr->GetNext();
2720 0 : n++;
2721 : }
2722 0 : }
2723 :
2724 0 : static void ParseCSS1_border_style( const CSS1Expression *pExpr,
2725 : SfxItemSet & /*rItemSet*/,
2726 : SvxCSS1PropertyInfo& rPropInfo,
2727 : const SvxCSS1Parser& /*rParser*/ )
2728 : {
2729 0 : sal_uInt16 n=0;
2730 0 : while( n<4 && pExpr && !pExpr->GetOp() )
2731 : {
2732 0 : SvxBoxItemLine nLine = n==0 || n==2 ? SvxBoxItemLine::BOTTOM : SvxBoxItemLine::LEFT;
2733 0 : sal_uInt16 nValue = 0;
2734 0 : if( CSS1_IDENT==pExpr->GetType() &&
2735 0 : SvxCSS1Parser::GetEnum( aBorderStyleTable, pExpr->GetString(),
2736 0 : nValue ) )
2737 : {
2738 0 : rPropInfo.GetBorderInfo( nLine )->eStyle = (CSS1BorderStyle)nValue;
2739 : }
2740 0 : rPropInfo.CopyBorderInfo( n, SVX_CSS1_BORDERINFO_STYLE );
2741 :
2742 0 : pExpr = pExpr->GetNext();
2743 0 : n++;
2744 : }
2745 0 : }
2746 :
2747 1 : static void ParseCSS1_border_top( const CSS1Expression *pExpr,
2748 : SfxItemSet &rItemSet,
2749 : SvxCSS1PropertyInfo& rPropInfo,
2750 : const SvxCSS1Parser& rParser )
2751 : {
2752 1 : ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::TOP, false );
2753 1 : }
2754 :
2755 1 : static void ParseCSS1_border_right( const CSS1Expression *pExpr,
2756 : SfxItemSet &rItemSet,
2757 : SvxCSS1PropertyInfo& rPropInfo,
2758 : const SvxCSS1Parser& rParser )
2759 : {
2760 1 : ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::RIGHT, false );
2761 1 : }
2762 :
2763 7 : static void ParseCSS1_border_bottom( const CSS1Expression *pExpr,
2764 : SfxItemSet &rItemSet,
2765 : SvxCSS1PropertyInfo& rPropInfo,
2766 : const SvxCSS1Parser& rParser )
2767 : {
2768 7 : ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::BOTTOM, false );
2769 7 : }
2770 :
2771 1 : static void ParseCSS1_border_left( const CSS1Expression *pExpr,
2772 : SfxItemSet &rItemSet,
2773 : SvxCSS1PropertyInfo& rPropInfo,
2774 : const SvxCSS1Parser& rParser )
2775 : {
2776 1 : ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::LEFT, false );
2777 1 : }
2778 :
2779 556 : static void ParseCSS1_border( const CSS1Expression *pExpr,
2780 : SfxItemSet &rItemSet,
2781 : SvxCSS1PropertyInfo& rPropInfo,
2782 : const SvxCSS1Parser& rParser )
2783 : {
2784 556 : ParseCSS1_border_xxx( pExpr, rItemSet, rPropInfo, rParser, SvxBoxItemLine::TOP, true );
2785 556 : }
2786 :
2787 0 : static void ParseCSS1_float( const CSS1Expression *pExpr,
2788 : SfxItemSet & /*rItemSet*/,
2789 : SvxCSS1PropertyInfo& rPropInfo,
2790 : const SvxCSS1Parser& /*rParser*/ )
2791 : {
2792 : OSL_ENSURE( pExpr, "no expression" );
2793 :
2794 0 : if( CSS1_IDENT==pExpr->GetType() )
2795 : {
2796 : sal_uInt16 nFloat;
2797 0 : if( SvxCSS1Parser::GetEnum( aFloatTable, pExpr->GetString(), nFloat ) )
2798 0 : rPropInfo.eFloat = (SvxAdjust)nFloat;
2799 : }
2800 0 : }
2801 :
2802 2 : static void ParseCSS1_position( const CSS1Expression *pExpr,
2803 : SfxItemSet & /*rItemSet*/,
2804 : SvxCSS1PropertyInfo& rPropInfo,
2805 : const SvxCSS1Parser& /*rParser*/ )
2806 : {
2807 : OSL_ENSURE( pExpr, "no expression" );
2808 :
2809 2 : if( CSS1_IDENT==pExpr->GetType() )
2810 : {
2811 : sal_uInt16 nPos;
2812 2 : if( SvxCSS1Parser::GetEnum( aPositionTable, pExpr->GetString(), nPos ) )
2813 2 : rPropInfo.ePosition = (SvxCSS1Position)nPos;
2814 : }
2815 2 : }
2816 :
2817 7 : static void ParseCSS1_length( const CSS1Expression *pExpr,
2818 : long& rLength,
2819 : SvxCSS1LengthType& rLengthType,
2820 : bool bHori )
2821 : {
2822 7 : switch( pExpr->GetType() )
2823 : {
2824 : case CSS1_IDENT:
2825 0 : if( pExpr->GetString().equalsIgnoreAsciiCase( "auto" ) )
2826 : {
2827 0 : rLength = 0;
2828 0 : rLengthType = SVX_CSS1_LTYPE_AUTO;
2829 : }
2830 0 : break;
2831 :
2832 : case CSS1_LENGTH:
2833 1 : rLength = pExpr->GetSLength();
2834 1 : rLengthType = SVX_CSS1_LTYPE_TWIP;
2835 1 : break;
2836 :
2837 : case CSS1_PIXLENGTH:
2838 : case CSS1_NUMBER: // wegen Netscape und IE
2839 : {
2840 6 : long nWidthL = (long)pExpr->GetNumber();
2841 6 : long nPWidth = bHori ? 0 : nWidthL;
2842 6 : long nPHeight = bHori ? nWidthL : 0;
2843 6 : SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2844 6 : rLength = (bHori ? nPHeight : nPWidth);
2845 6 : rLengthType = SVX_CSS1_LTYPE_TWIP;
2846 : }
2847 6 : break;
2848 :
2849 : case CSS1_PERCENTAGE:
2850 0 : rLength = (long)pExpr->GetNumber();
2851 0 : if( rLength > 100 )
2852 0 : rLength = 100;
2853 0 : rLengthType = SVX_CSS1_LTYPE_PERCENTAGE;
2854 0 : break;
2855 :
2856 : default:
2857 : ;
2858 : }
2859 7 : }
2860 :
2861 2 : static void ParseCSS1_width( const CSS1Expression *pExpr,
2862 : SfxItemSet & /*rItemSet*/,
2863 : SvxCSS1PropertyInfo& rPropInfo,
2864 : const SvxCSS1Parser& /*rParser*/ )
2865 : {
2866 2 : ParseCSS1_length( pExpr, rPropInfo.nWidth, rPropInfo.eWidthType, true );
2867 2 : }
2868 :
2869 1 : static void ParseCSS1_height( const CSS1Expression *pExpr,
2870 : SfxItemSet & /*rItemSet*/,
2871 : SvxCSS1PropertyInfo& rPropInfo,
2872 : const SvxCSS1Parser& /*rParser*/ )
2873 : {
2874 1 : ParseCSS1_length( pExpr, rPropInfo.nHeight, rPropInfo.eHeightType, false );
2875 1 : }
2876 :
2877 2 : static void ParseCSS1_left( const CSS1Expression *pExpr,
2878 : SfxItemSet & /*rItemSet*/,
2879 : SvxCSS1PropertyInfo& rPropInfo,
2880 : const SvxCSS1Parser& /*rParser*/ )
2881 : {
2882 2 : ParseCSS1_length( pExpr, rPropInfo.nLeft, rPropInfo.eLeftType, true );
2883 2 : }
2884 :
2885 2 : static void ParseCSS1_top( const CSS1Expression *pExpr,
2886 : SfxItemSet & /*rItemSet*/,
2887 : SvxCSS1PropertyInfo& rPropInfo,
2888 : const SvxCSS1Parser& /*rParser*/ )
2889 : {
2890 2 : ParseCSS1_length( pExpr, rPropInfo.nTop, rPropInfo.eTopType, false );
2891 2 : }
2892 :
2893 : // Feature: PrintExt
2894 6 : static void ParseCSS1_size( const CSS1Expression *pExpr,
2895 : SfxItemSet & /*rItemSet*/,
2896 : SvxCSS1PropertyInfo& rPropInfo,
2897 : const SvxCSS1Parser& /*rParser*/ )
2898 : {
2899 6 : int n=0;
2900 24 : while( n<2 && pExpr && !pExpr->GetOp() )
2901 : {
2902 12 : switch( pExpr->GetType() )
2903 : {
2904 : case CSS1_IDENT:
2905 : {
2906 : sal_uInt16 nValue;
2907 0 : if( SvxCSS1Parser::GetEnum( aSizeTable, pExpr->GetString(),
2908 : nValue ) )
2909 : {
2910 0 : rPropInfo.eSizeType = (SvxCSS1SizeType)nValue;
2911 : }
2912 : }
2913 0 : break;
2914 :
2915 : case CSS1_LENGTH:
2916 12 : rPropInfo.nHeight = pExpr->GetSLength();
2917 12 : if( n==0 )
2918 6 : rPropInfo.nWidth = rPropInfo.nHeight;
2919 12 : rPropInfo.eSizeType = SVX_CSS1_STYPE_TWIP;
2920 12 : break;
2921 :
2922 : case CSS1_PIXLENGTH:
2923 : {
2924 0 : long nPHeight = (long)pExpr->GetNumber();
2925 0 : long nPWidth = n==0 ? nPHeight : 0;
2926 0 : SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
2927 0 : rPropInfo.nHeight = nPHeight;
2928 0 : if( n==0 )
2929 0 : rPropInfo.nWidth = nPWidth;
2930 0 : rPropInfo.eSizeType = SVX_CSS1_STYPE_TWIP;
2931 : }
2932 0 : break;
2933 :
2934 : default:
2935 : ;
2936 : }
2937 :
2938 12 : pExpr = pExpr->GetNext();
2939 12 : n++;
2940 : }
2941 6 : }
2942 :
2943 : // /Feature: PrintExt
2944 :
2945 : // Feature: PrintExt
2946 :
2947 2 : static void ParseCSS1_page_break_xxx( const CSS1Expression *pExpr,
2948 : SvxCSS1PageBreak& rPBreak )
2949 : {
2950 2 : if( CSS1_IDENT == pExpr->GetType() )
2951 : {
2952 : sal_uInt16 nValue;
2953 2 : if( SvxCSS1Parser::GetEnum( aPageBreakTable, pExpr->GetString(),
2954 : nValue ) )
2955 : {
2956 2 : rPBreak = (SvxCSS1PageBreak)nValue;
2957 : }
2958 : }
2959 2 : }
2960 :
2961 2 : static void ParseCSS1_page_break_before( const CSS1Expression *pExpr,
2962 : SfxItemSet & /*rItemSet*/,
2963 : SvxCSS1PropertyInfo& rPropInfo,
2964 : const SvxCSS1Parser& /*rParser*/ )
2965 : {
2966 2 : ParseCSS1_page_break_xxx( pExpr, rPropInfo.ePageBreakBefore );
2967 2 : }
2968 :
2969 0 : static void ParseCSS1_page_break_after( const CSS1Expression *pExpr,
2970 : SfxItemSet & /*rItemSet*/,
2971 : SvxCSS1PropertyInfo& rPropInfo,
2972 : const SvxCSS1Parser& /*rParser*/ )
2973 : {
2974 0 : ParseCSS1_page_break_xxx( pExpr, rPropInfo.ePageBreakAfter );
2975 0 : }
2976 :
2977 0 : static void ParseCSS1_page_break_inside( const CSS1Expression *pExpr,
2978 : SfxItemSet &rItemSet,
2979 : SvxCSS1PropertyInfo& /*rPropInfo*/,
2980 : const SvxCSS1Parser& /*rParser*/ )
2981 : {
2982 0 : SvxCSS1PageBreak eBreak(SVX_CSS1_PBREAK_NONE);
2983 0 : ParseCSS1_page_break_xxx( pExpr, eBreak );
2984 :
2985 0 : bool bSetSplit = false, bSplit = true;
2986 0 : switch( eBreak )
2987 : {
2988 : case SVX_CSS1_PBREAK_AUTO:
2989 0 : bSetSplit = true;
2990 0 : break;
2991 : case SVX_CSS1_PBREAK_AVOID:
2992 0 : bSplit = false;
2993 0 : bSetSplit = true;
2994 0 : break;
2995 : default:
2996 : ;
2997 : }
2998 :
2999 0 : if( bSetSplit )
3000 0 : rItemSet.Put( SvxFormatSplitItem( bSplit, aItemIds.nFormatSplit ) );
3001 0 : }
3002 :
3003 1 : static void ParseCSS1_widows( const CSS1Expression *pExpr,
3004 : SfxItemSet &rItemSet,
3005 : SvxCSS1PropertyInfo& /*rPropInfo*/,
3006 : const SvxCSS1Parser& /*rParser*/ )
3007 : {
3008 1 : if( CSS1_NUMBER == pExpr->GetType() )
3009 : {
3010 1 : sal_uInt8 nVal = pExpr->GetNumber() <= 255
3011 1 : ? (sal_uInt8)pExpr->GetNumber()
3012 2 : : 255;
3013 1 : SvxWidowsItem aWidowsItem( nVal, aItemIds.nWidows );
3014 1 : rItemSet.Put( aWidowsItem );
3015 : }
3016 1 : }
3017 :
3018 1 : static void ParseCSS1_orphans( const CSS1Expression *pExpr,
3019 : SfxItemSet &rItemSet,
3020 : SvxCSS1PropertyInfo& /*rPropInfo*/,
3021 : const SvxCSS1Parser& /*rParser*/ )
3022 : {
3023 1 : if( CSS1_NUMBER == pExpr->GetType() )
3024 : {
3025 1 : sal_uInt8 nVal = pExpr->GetNumber() <= 255
3026 1 : ? (sal_uInt8)pExpr->GetNumber()
3027 2 : : 255;
3028 1 : SvxOrphansItem aOrphansItem( nVal, aItemIds.nOrphans );
3029 1 : rItemSet.Put( aOrphansItem );
3030 : }
3031 1 : }
3032 : // /Feature: PrintExt
3033 :
3034 7 : static void ParseCSS1_so_language( const CSS1Expression *pExpr,
3035 : SfxItemSet &rItemSet,
3036 : SvxCSS1PropertyInfo& /*rPropInfo*/,
3037 : const SvxCSS1Parser& rParser )
3038 : {
3039 7 : if( CSS1_IDENT == pExpr->GetType() ||
3040 0 : CSS1_STRING == pExpr->GetType() )
3041 : {
3042 7 : LanguageType eLang = LanguageTag::convertToLanguageTypeWithFallback( pExpr->GetString() );
3043 7 : if( LANGUAGE_DONTKNOW != eLang )
3044 : {
3045 7 : SvxLanguageItem aLang( eLang, aItemIds.nLanguage );
3046 7 : if( rParser.IsSetWesternProps() )
3047 7 : rItemSet.Put( aLang );
3048 7 : if( rParser.IsSetCJKProps() )
3049 : {
3050 7 : aLang.SetWhich( aItemIds.nLanguageCJK );
3051 7 : rItemSet.Put( aLang );
3052 : }
3053 7 : if( rParser.IsSetCTLProps() )
3054 : {
3055 7 : aLang.SetWhich( aItemIds.nLanguageCTL );
3056 7 : rItemSet.Put( aLang );
3057 7 : }
3058 : }
3059 : }
3060 7 : }
3061 :
3062 : // die Zuordung Property zu parsender Funktion
3063 : struct CSS1PropEntry
3064 : {
3065 : union
3066 : {
3067 : const sal_Char *sName;
3068 : OUString *pName;
3069 : };
3070 : FnParseCSS1Prop pFunc;
3071 : };
3072 :
3073 : #define CSS1_PROP_ENTRY(p) \
3074 : { { sCSS1_P_##p }, ParseCSS1_##p }
3075 :
3076 : // die Tabelle mit den Zuordnungen
3077 : static CSS1PropEntry aCSS1PropFnTab[] =
3078 : {
3079 : CSS1_PROP_ENTRY(background),
3080 : CSS1_PROP_ENTRY(background_color),
3081 : CSS1_PROP_ENTRY(border_top_width),
3082 : CSS1_PROP_ENTRY(border_right_width),
3083 : CSS1_PROP_ENTRY(border_bottom_width),
3084 : CSS1_PROP_ENTRY(border_left_width),
3085 : CSS1_PROP_ENTRY(border_width),
3086 : CSS1_PROP_ENTRY(border_color),
3087 : CSS1_PROP_ENTRY(border_style),
3088 : CSS1_PROP_ENTRY(border_top),
3089 : CSS1_PROP_ENTRY(border_right),
3090 : CSS1_PROP_ENTRY(border_bottom),
3091 : CSS1_PROP_ENTRY(border_left),
3092 : CSS1_PROP_ENTRY(border),
3093 : CSS1_PROP_ENTRY(color),
3094 : CSS1_PROP_ENTRY(column_count),
3095 : CSS1_PROP_ENTRY(direction),
3096 : CSS1_PROP_ENTRY(float),
3097 : CSS1_PROP_ENTRY(font_size),
3098 : CSS1_PROP_ENTRY(font_family),
3099 : CSS1_PROP_ENTRY(font_style),
3100 : CSS1_PROP_ENTRY(font_variant),
3101 : CSS1_PROP_ENTRY(font_weight),
3102 : CSS1_PROP_ENTRY(letter_spacing),
3103 : CSS1_PROP_ENTRY(line_height),
3104 : CSS1_PROP_ENTRY(font),
3105 : CSS1_PROP_ENTRY(text_align),
3106 : CSS1_PROP_ENTRY(text_decoration),
3107 : CSS1_PROP_ENTRY(text_indent),
3108 : CSS1_PROP_ENTRY(text_transform),
3109 : CSS1_PROP_ENTRY(margin_left),
3110 : CSS1_PROP_ENTRY(margin_right),
3111 : CSS1_PROP_ENTRY(margin_top),
3112 : CSS1_PROP_ENTRY(margin_bottom),
3113 : CSS1_PROP_ENTRY(margin),
3114 : CSS1_PROP_ENTRY(padding_top),
3115 : CSS1_PROP_ENTRY(padding_bottom),
3116 : CSS1_PROP_ENTRY(padding_left),
3117 : CSS1_PROP_ENTRY(padding_right),
3118 : CSS1_PROP_ENTRY(padding),
3119 : CSS1_PROP_ENTRY(position),
3120 : CSS1_PROP_ENTRY(left),
3121 : CSS1_PROP_ENTRY(top),
3122 : CSS1_PROP_ENTRY(width),
3123 : CSS1_PROP_ENTRY(height),
3124 : // Feature: PrintExt
3125 : CSS1_PROP_ENTRY(size),
3126 : CSS1_PROP_ENTRY(page_break_before),
3127 : CSS1_PROP_ENTRY(page_break_after),
3128 : CSS1_PROP_ENTRY(page_break_inside),
3129 : CSS1_PROP_ENTRY(widows),
3130 : CSS1_PROP_ENTRY(orphans),
3131 : // /Feature: PrintExt
3132 : CSS1_PROP_ENTRY(so_language)
3133 59 : };
3134 :
3135 : extern "C"
3136 : {
3137 15322 : static int SAL_CALL CSS1PropEntryCompare( const void *pFirst, const void *pSecond)
3138 : {
3139 : int nRet;
3140 15322 : if( static_cast<const CSS1PropEntry*>(pFirst)->pFunc )
3141 : {
3142 573 : if( static_cast<const CSS1PropEntry*>(pSecond)->pFunc )
3143 : nRet = strcmp( static_cast<const CSS1PropEntry*>(pFirst)->sName ,
3144 573 : static_cast<const CSS1PropEntry*>(pSecond)->sName );
3145 : else
3146 : nRet = -1 * static_cast<const CSS1PropEntry*>(pSecond)->pName->compareToAscii(
3147 0 : static_cast<const CSS1PropEntry*>(pFirst)->sName );
3148 : }
3149 : else
3150 : {
3151 14749 : if( static_cast<const CSS1PropEntry*>(pSecond)->pFunc )
3152 : nRet = static_cast<const CSS1PropEntry*>(pFirst)->pName->compareToAscii(
3153 14749 : static_cast<const CSS1PropEntry*>(pSecond)->sName );
3154 : else
3155 : nRet = static_cast<const CSS1PropEntry*>(pFirst)->pName->compareTo(
3156 0 : *static_cast<const CSS1PropEntry*>(pSecond)->pName );
3157 : }
3158 :
3159 15322 : return nRet;
3160 : }
3161 : }
3162 :
3163 2832 : void SvxCSS1Parser::ParseProperty( const OUString& rProperty,
3164 : const CSS1Expression *pExpr )
3165 : {
3166 : OSL_ENSURE( pItemSet, "DeclarationParsed() without ItemSet" );
3167 :
3168 : static bool bSortedPropFns = false;
3169 :
3170 2832 : if( !bSortedPropFns )
3171 : {
3172 : qsort( static_cast<void*>(aCSS1PropFnTab),
3173 : sizeof( aCSS1PropFnTab ) / sizeof( CSS1PropEntry ),
3174 : sizeof( CSS1PropEntry ),
3175 3 : CSS1PropEntryCompare );
3176 3 : bSortedPropFns = true;
3177 : }
3178 :
3179 2832 : OUString aTmp( rProperty.toAsciiLowerCase() );
3180 :
3181 : CSS1PropEntry aSrch;
3182 2832 : aSrch.pName = &aTmp;
3183 2832 : aSrch.pFunc = 0;
3184 :
3185 : void* pFound;
3186 2832 : if( 0 != ( pFound = bsearch( &aSrch,
3187 : static_cast<void*>(aCSS1PropFnTab),
3188 : sizeof( aCSS1PropFnTab ) / sizeof( CSS1PropEntry ),
3189 : sizeof( CSS1PropEntry ),
3190 2832 : CSS1PropEntryCompare )))
3191 : {
3192 2788 : (static_cast<CSS1PropEntry*>(pFound)->pFunc)( pExpr, *pItemSet, *pPropInfo, *this );
3193 2832 : }
3194 3009 : }
3195 :
3196 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|