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