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