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