xref: /trunk/main/sw/source/filter/xml/xmlithlp.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 #include "xmlithlp.hxx"
27 #include "hintids.hxx"
28 #include "unomid.h"
29 #include <svx/unomid.hxx>
30 #include <editeng/lrspitem.hxx>
31 #include <editeng/ulspitem.hxx>
32 #include <editeng/shaditem.hxx>
33 #include <editeng/boxitem.hxx>
34 #include <editeng/brkitem.hxx>
35 #include <editeng/keepitem.hxx>
36 #include <editeng/brshitem.hxx>
37 #include "fmtpdsc.hxx"
38 #include "fmtornt.hxx"
39 #include "fmtfsize.hxx"
40 
41 #ifndef _FMTLSPLT_HXX
42 #include "fmtlsplt.hxx"
43 #endif
44 #include <xmloff/xmluconv.hxx>
45 
46 using ::rtl::OUString;
47 using namespace ::xmloff::token;
48 using namespace ::com::sun::star;
49 
50 
51 #define SVX_XML_BORDER_STYLE_NONE 0
52 #define SVX_XML_BORDER_STYLE_SOLID 1
53 #define SVX_XML_BORDER_STYLE_DOUBLE 2
54 
55 #define SVX_XML_BORDER_WIDTH_THIN 0
56 #define SVX_XML_BORDER_WIDTH_MIDDLE 1
57 #define SVX_XML_BORDER_WIDTH_THICK 2
58 
59 
60 const struct SvXMLEnumMapEntry psXML_BorderStyles[] =
61 {
62     { XML_NONE,       SVX_XML_BORDER_STYLE_NONE },
63     { XML_HIDDEN,     SVX_XML_BORDER_STYLE_NONE },
64     { XML_SOLID,      SVX_XML_BORDER_STYLE_SOLID },
65     { XML_DOUBLE,     SVX_XML_BORDER_STYLE_DOUBLE },
66     { XML_DOTTED,     SVX_XML_BORDER_STYLE_SOLID },
67     { XML_DASHED,     SVX_XML_BORDER_STYLE_SOLID },
68     { XML_GROOVE,     SVX_XML_BORDER_STYLE_SOLID },
69     { XML_RIDGE,      SVX_XML_BORDER_STYLE_SOLID },
70     { XML_INSET,      SVX_XML_BORDER_STYLE_SOLID },
71     { XML_OUTSET,     SVX_XML_BORDER_STYLE_SOLID },
72     { XML_TOKEN_INVALID, 0 }
73 };
74 
75 const struct SvXMLEnumMapEntry psXML_NamedBorderWidths[] =
76 {
77         { XML_THIN,         SVX_XML_BORDER_WIDTH_THIN   },
78         { XML_MIDDLE,   SVX_XML_BORDER_WIDTH_MIDDLE     },
79         { XML_THICK,    SVX_XML_BORDER_WIDTH_THICK      },
80         { XML_TOKEN_INVALID, 0 }
81 };
82 // mapping tables to map external xml input to intarnal box line widths
83 
84 // Ein Eintrag besteht aus vier USHORTs. Der erste ist die Gesamtbreite,
85 // die anderen sind die 3 Einzelbreiten
86 
87 #define SBORDER_ENTRY( n ) \
88         DEF_LINE_WIDTH_##n, DEF_LINE_WIDTH_##n, 0, 0
89 
90 #define DBORDER_ENTRY( n ) \
91         DEF_DOUBLE_LINE##n##_OUT + DEF_DOUBLE_LINE##n##_IN + \
92         DEF_DOUBLE_LINE##n##_DIST, \
93         DEF_DOUBLE_LINE##n##_OUT, \
94         DEF_DOUBLE_LINE##n##_IN, \
95         DEF_DOUBLE_LINE##n##_DIST
96 
97 #define TDBORDER_ENTRY( n ) \
98         DEF_DOUBLE_LINE##n##_OUT, \
99         DEF_DOUBLE_LINE##n##_OUT, \
100         DEF_DOUBLE_LINE##n##_IN, \
101         DEF_DOUBLE_LINE##n##_DIST
102 
103 
104 const sal_uInt16 aSBorderWidths[] =
105 {
106         SBORDER_ENTRY( 0 ), SBORDER_ENTRY( 5 ), SBORDER_ENTRY( 1 ),
107         SBORDER_ENTRY( 2 ), SBORDER_ENTRY( 3 ), SBORDER_ENTRY( 4 )
108 };
109 
110 const sal_uInt16 aDBorderWidths[5*11] =
111 {
112         DBORDER_ENTRY( 0 ),
113         DBORDER_ENTRY( 7 ),
114         DBORDER_ENTRY( 1 ),
115         DBORDER_ENTRY( 8 ),
116         DBORDER_ENTRY( 4 ),
117         DBORDER_ENTRY( 9 ),
118         DBORDER_ENTRY( 3 ),
119         DBORDER_ENTRY( 10 ),
120         DBORDER_ENTRY( 2 ),
121         DBORDER_ENTRY( 6 ),
122         DBORDER_ENTRY( 5 )
123 };
124 
lcl_frmitems_parseXMLBorder(const OUString & rValue,const SvXMLUnitConverter & rUnitConverter,sal_Bool & rHasStyle,sal_uInt16 & rStyle,sal_Bool & rHasWidth,sal_uInt16 & rWidth,sal_uInt16 & rNamedWidth,sal_Bool & rHasColor,Color & rColor)125 sal_Bool lcl_frmitems_parseXMLBorder( const OUString& rValue,
126                                       const SvXMLUnitConverter& rUnitConverter,
127                                       sal_Bool& rHasStyle, sal_uInt16& rStyle,
128                                       sal_Bool& rHasWidth, sal_uInt16& rWidth,
129                                       sal_uInt16& rNamedWidth,
130                                       sal_Bool& rHasColor, Color& rColor )
131 {
132     OUString aToken;
133     SvXMLTokenEnumerator aTokens( rValue );
134 
135     rHasStyle = sal_False;
136     rHasWidth = sal_False;
137     rHasColor = sal_False;
138 
139     rStyle = USHRT_MAX;
140     rWidth = 0;
141     rNamedWidth = USHRT_MAX;
142 
143     sal_Int32 nTemp;
144     while( aTokens.getNextToken( aToken ) && aToken.getLength() != 0 )
145     {
146         if( !rHasWidth &&
147             rUnitConverter.convertEnum( rNamedWidth, aToken,
148                                         psXML_NamedBorderWidths ) )
149         {
150             rHasWidth = sal_True;
151         }
152         else if( !rHasStyle &&
153                  rUnitConverter.convertEnum( rStyle, aToken,
154                                              psXML_BorderStyles ) )
155         {
156             rHasStyle = sal_True;
157         }
158         else if( !rHasColor && rUnitConverter.convertColor( rColor, aToken ) )
159         {
160             rHasColor = sal_True;
161         }
162         else if( !rHasWidth &&
163                  rUnitConverter.convertMeasure( nTemp, aToken, 0, USHRT_MAX ) )
164         {
165             rWidth = (sal_uInt16)nTemp;
166             rHasWidth = sal_True;
167         }
168         else
169         {
170             // missformed
171             return sal_False;
172         }
173     }
174 
175     return rHasStyle || rHasWidth || rHasColor;
176 }
177 
lcl_frmitems_setXMLBorderWidth(SvxBorderLine & rLine,sal_uInt16 nOutWidth,sal_uInt16 nInWidth,sal_uInt16 nDistance)178 void lcl_frmitems_setXMLBorderWidth( SvxBorderLine& rLine,
179                                      sal_uInt16 nOutWidth, sal_uInt16 nInWidth,
180                                      sal_uInt16 nDistance )
181 {
182     rLine.SetOutWidth( nOutWidth );
183     rLine.SetInWidth( nInWidth );
184     rLine.SetDistance( nDistance );
185 }
186 
lcl_frmitems_setXMLBorderWidth(SvxBorderLine & rLine,sal_uInt16 nWidth,sal_Bool bDouble)187 void lcl_frmitems_setXMLBorderWidth( SvxBorderLine& rLine,
188                                      sal_uInt16 nWidth, sal_Bool bDouble )
189 {
190     const sal_uInt16 *aWidths;
191     sal_uInt16 nSize;
192     if( !bDouble )
193     {
194         aWidths = aSBorderWidths;
195         nSize = sizeof( aSBorderWidths );
196     }
197     else
198     {
199         aWidths = aDBorderWidths;
200         nSize = sizeof( aDBorderWidths );
201     }
202 
203     sal_uInt16 i = (nSize / sizeof(sal_uInt16)) - 4;
204     while( i>0 &&
205            nWidth <= ((aWidths[i] + aWidths[i-4]) / 2)  )
206     {
207         DBG_ASSERT( aWidths[i] >= aWidths[i-4], "line widths are unordered!" );
208         i -= 4;
209     }
210 
211     rLine.SetOutWidth( aWidths[i+1] );
212     rLine.SetInWidth( aWidths[i+2] );
213     rLine.SetDistance( aWidths[i+3] );
214 }
215 
lcl_frmitems_setXMLBorder(SvxBorderLine * & rpLine,sal_Bool bHasStyle,sal_uInt16 nStyle,sal_Bool bHasWidth,sal_uInt16 nWidth,sal_uInt16 nNamedWidth,sal_Bool bHasColor,const Color & rColor)216 sal_Bool lcl_frmitems_setXMLBorder( SvxBorderLine*& rpLine,
217                                     sal_Bool bHasStyle, sal_uInt16 nStyle,
218                                     sal_Bool bHasWidth, sal_uInt16 nWidth,
219                                     sal_uInt16 nNamedWidth,
220                                     sal_Bool bHasColor, const Color& rColor )
221 {
222     // first of all, delete an empty line
223     if( (bHasStyle && SVX_XML_BORDER_STYLE_NONE == nStyle) ||
224         (bHasWidth && USHRT_MAX == nNamedWidth && 0 == nWidth) )
225     {
226         sal_Bool bRet = 0 != rpLine;
227         if( rpLine )
228         {
229             delete rpLine;
230             rpLine = 0;
231         }
232 
233         return bRet;
234     }
235 
236     // if there is no line and no style and no with, there will never be a line
237     if( !rpLine && !(bHasStyle && bHasWidth) )
238         return sal_False;
239 
240     // We now do know that there will be a line
241     if( !rpLine )
242         rpLine = new SvxBorderLine;
243 
244 
245     if( ( bHasWidth &&
246           (USHRT_MAX != nNamedWidth || (nWidth != rpLine->GetOutWidth() +
247                                         rpLine->GetInWidth() +
248                                         rpLine->GetDistance()) ) ) ||
249         ( bHasStyle &&
250           ((SVX_XML_BORDER_STYLE_SOLID == nStyle && rpLine->GetDistance()) ||
251             (SVX_XML_BORDER_STYLE_DOUBLE == nStyle && !rpLine->GetDistance())) ))
252    {
253        sal_Bool bDouble = (bHasWidth && SVX_XML_BORDER_STYLE_DOUBLE == nStyle ) ||
254            rpLine->GetDistance();
255 
256        // The width has to be changed
257        if( bHasWidth && USHRT_MAX != nNamedWidth )
258        {
259            const sal_uInt16 *aWidths = bDouble ? aDBorderWidths :aSBorderWidths;
260 
261            sal_uInt16 nNWidth = nNamedWidth * 4;
262            rpLine->SetOutWidth( aWidths[nNWidth+1] );
263            rpLine->SetInWidth( aWidths[nNWidth+2] );
264            rpLine->SetDistance( aWidths[nNWidth+3] );
265 
266        }
267        else
268        {
269            if( !bHasWidth )
270                nWidth = rpLine->GetInWidth() + rpLine->GetDistance() +
271                    rpLine->GetOutWidth();
272 
273            lcl_frmitems_setXMLBorderWidth( *rpLine, nWidth, bDouble );
274        }
275    }
276 
277     // set color
278     if( bHasColor )
279         rpLine->SetColor( rColor );
280 
281     return sal_True;
282 }
283 
lcl_frmitems_setXMLBorder(SvxBorderLine * & rpLine,sal_uInt16 nWidth,sal_uInt16 nOutWidth,sal_uInt16 nInWidth,sal_uInt16 nDistance)284 void lcl_frmitems_setXMLBorder( SvxBorderLine*& rpLine,
285   sal_uInt16 nWidth, sal_uInt16 nOutWidth,
286   sal_uInt16 nInWidth, sal_uInt16 nDistance )
287 {
288     if( !rpLine )
289         rpLine = new SvxBorderLine;
290 
291     if( nWidth > 0 )
292         lcl_frmitems_setXMLBorderWidth( *rpLine, nWidth, sal_True );
293     else
294         lcl_frmitems_setXMLBorderWidth( *rpLine, nOutWidth, nInWidth,
295                                         nDistance );
296 }
297 
298 const struct SvXMLEnumMapEntry psXML_BrushRepeat[] =
299 {
300 	{ XML_BACKGROUND_REPEAT,		GPOS_TILED	},
301 	{ XML_BACKGROUND_NO_REPEAT,     GPOS_MM		},
302 	{ XML_BACKGROUND_STRETCH,		GPOS_AREA	},
303 	{ XML_TOKEN_INVALID, 0 }
304 };
305 
306 const struct SvXMLEnumMapEntry psXML_BrushHoriPos[] =
307 {
308 	{ XML_LEFT,		    GPOS_LM	},
309 	{ XML_RIGHT,		GPOS_RM	},
310 	{ XML_TOKEN_INVALID, 0 }
311 };
312 
313 const struct SvXMLEnumMapEntry psXML_BrushVertPos[] =
314 {
315 	{ XML_TOP,			GPOS_MT	},
316 	{ XML_BOTTOM,		GPOS_MB	},
317 	{ XML_TOKEN_INVALID, 0 }
318 };
319 
lcl_frmitems_MergeXMLHoriPos(SvxGraphicPosition & ePos,SvxGraphicPosition eHori)320 void lcl_frmitems_MergeXMLHoriPos( SvxGraphicPosition& ePos,
321 								   SvxGraphicPosition eHori )
322 {
323 	DBG_ASSERT( GPOS_LM==eHori || GPOS_MM==eHori || GPOS_RM==eHori,
324 				"lcl_frmitems_MergeXMLHoriPos: vertical pos must be middle" );
325 
326 	switch( ePos )
327 	{
328 	case GPOS_LT:
329 	case GPOS_MT:
330 	case GPOS_RT:
331 		ePos = GPOS_LM==eHori ? GPOS_LT : (GPOS_MM==eHori ? GPOS_MT : GPOS_RT);
332 		break;
333 
334 	case GPOS_LM:
335 	case GPOS_MM:
336 	case GPOS_RM:
337 		ePos = eHori;
338 		break;
339 
340 	case GPOS_LB:
341 	case GPOS_MB:
342 	case GPOS_RB:
343 		ePos = GPOS_LM==eHori ? GPOS_LB : (GPOS_MM==eHori ? GPOS_MB : GPOS_RB);
344 		break;
345 	default:
346 		;
347 	}
348 }
349 
lcl_frmitems_MergeXMLVertPos(SvxGraphicPosition & ePos,SvxGraphicPosition eVert)350 void lcl_frmitems_MergeXMLVertPos( SvxGraphicPosition& ePos,
351 							  	   SvxGraphicPosition eVert )
352 {
353 	DBG_ASSERT( GPOS_MT==eVert || GPOS_MM==eVert || GPOS_MB==eVert,
354 				"lcl_frmitems_MergeXMLVertPos: horizontal pos must be middle" );
355 
356 	switch( ePos )
357 	{
358 	case GPOS_LT:
359 	case GPOS_LM:
360 	case GPOS_LB:
361 		ePos = GPOS_MT==eVert ? GPOS_LT : (GPOS_MM==eVert ? GPOS_LM : GPOS_LB);
362 		ePos = eVert;
363 		break;
364 
365 	case GPOS_MT:
366 	case GPOS_MM:
367 	case GPOS_MB:
368 		ePos = eVert;
369 		break;
370 
371 	case GPOS_RT:
372 	case GPOS_RM:
373 	case GPOS_RB:
374 		ePos = GPOS_MT==eVert ? GPOS_RT : (GPOS_MM==eVert ? GPOS_RM : GPOS_RB);
375 		break;
376 	default:
377 		;
378 	}
379 }
380 
381 
382 const struct SvXMLEnumMapEntry psXML_BreakType[] =
383 {
384         { XML_AUTO,         0 },
385         { XML_COLUMN,       1 },
386         { XML_PAGE,         2 },
387         { XML_EVEN_PAGE,    2 },
388         { XML_ODD_PAGE,     2 },
389         { XML_TOKEN_INVALID, 0}
390 };
391 
392 const struct  SvXMLEnumMapEntry aXMLTableAlignMap[] =
393 {
394     { XML_LEFT,             text::HoriOrientation::LEFT           },
395     { XML_LEFT,             text::HoriOrientation::LEFT_AND_WIDTH },
396     { XML_CENTER,           text::HoriOrientation::CENTER         },
397     { XML_RIGHT,            text::HoriOrientation::RIGHT          },
398     { XML_MARGINS,          text::HoriOrientation::FULL           },
399     { XML_MARGINS,          text::HoriOrientation::NONE           },
400 	{ XML_TOKEN_INVALID, 0 }
401 };
402 
403 const struct  SvXMLEnumMapEntry aXMLTableVAlignMap[] =
404 {
405     { XML_TOP,                  text::VertOrientation::TOP        },
406     { XML_MIDDLE,               text::VertOrientation::CENTER     },
407     { XML_BOTTOM,               text::VertOrientation::BOTTOM     },
408 	{ XML_TOKEN_INVALID, 0 }
409 };
410 
411 const struct SvXMLEnumMapEntry aXML_KeepTogetherType[] =
412 {
413         { XML_ALWAYS,       0 },
414         { XML_AUTO,         1 },
415         { XML_TOKEN_INVALID, 0}
416 };
417 
418 
419