1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xmlehelp.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_xmloff.hxx"
34 #include <tools/debug.hxx>
35 #include <tools/bigint.hxx>
36 #include <rtl/ustrbuf.hxx>
37 #include <vcl/outdev.hxx>
38 #include "xmlehelp.hxx"
40 #ifndef _XMLOFF_XMTOKEN_HXX
41 #include <xmloff/xmltoken.hxx>
44 using ::rtl::OUString
;
45 using ::rtl::OUStringBuffer
;
47 using namespace ::xmloff::token
;
49 void SvXMLExportHelper::AddLength( sal_Int32 nValue
, MapUnit eValueUnit
,
53 // the sign is processed seperatly
57 rOut
.append( sal_Unicode('-') );
60 // The new length is (nVal * nMul)/(nDiv*nFac*10)
61 sal_Int32 nMul
= 1000;
64 enum XMLTokenEnum eUnit
= XML_TOKEN_INVALID
;
72 DBG_ASSERT( MAP_INCH
== eOutUnit
,
73 "output unit not supported for twip values" );
75 // 0.01mm = 0.57twip (exactly)
76 nMul
= 25400; // 25.4 * 1000
77 nDiv
= 1440; // 72 * 20;
83 // 0.001cm = 0.57twip (exactly)
84 nMul
= 25400; // 2.54 * 10000
85 nDiv
= 1440; // 72 * 20;
91 // 0.01pt = 0.2twip (exactly)
100 DBG_ASSERT( MAP_INCH
== eOutUnit
,
101 "output unit not supported for twip values" );
102 // 0.0001in = 0.144twip (exactly)
104 nDiv
= 1440; // 72 * 20;
106 eUnit
= XML_UNIT_INCH
;
112 // 1pt = 1pt (exactly)
113 DBG_ASSERT( MAP_POINT
== eOutUnit
,
114 "output unit not supported for pt values" );
123 long nFac2
= (MAP_100TH_MM
== eValueUnit
) ? 100 : 10;
128 DBG_ASSERT( MAP_INCH
== eOutUnit
,
129 "output unit not supported for 1/100mm values" );
131 // 0.01mm = 1 mm/100 (exactly)
139 // 0.001mm = 1 mm/100 (exactly)
141 nDiv
= 1; // 72 * 20;
147 // 0.01pt = 0.35 mm/100 (exactly)
156 DBG_ASSERT( MAP_INCH
== eOutUnit
,
157 "output unit not supported for 1/100mm values" );
158 // 0.0001in = 0.254 mm/100 (exactly)
162 eUnit
= XML_UNIT_INCH
;
168 DBG_ASSERT( 0, "input unit not handled" );
173 sal_Int32 nLongVal
= 0;
174 BOOL bOutLongVal
= TRUE
;
175 if( nValue
> SAL_MAX_INT32
/ nMul
)
177 // A big int is required for calculation
178 BigInt
nBigVal( nValue
);
184 if( nBigVal
.IsLong() )
186 // To convert the value into a string a sal_Int32 is sufficient
187 nLongVal
= sal_Int32( nBigVal
);
191 BigInt
nBigFac( nFac
);
193 rOut
.append( (sal_Int32
)(nBigVal
/ nBigFac
) );
194 if( !(nBigVal
% nBigFac
).IsZero() )
196 rOut
.append( sal_Unicode('.') );
197 while( nFac
> 1 && !(nBigVal
% nBigFac
).IsZero() )
201 rOut
.append( (sal_Int32
)((nBigVal
/ nBigFac
) % nBig10
) );
209 nLongVal
= nValue
* nMul
;
217 rOut
.append( (sal_Int32
)(nLongVal
/ nFac
) );
218 if( nFac
> 1 && (nLongVal
% nFac
) != 0 )
220 rOut
.append( sal_Unicode('.') );
221 while( nFac
> 1 && (nLongVal
% nFac
) != 0 )
224 rOut
.append( (sal_Int32
)((nLongVal
/ nFac
) % 10) );
229 if( eUnit
!= XML_TOKEN_INVALID
)
230 rOut
.append( GetXMLToken(eUnit
) );
232 enum XMLTokenEnum eUnit
;
270 case MAP_1000TH_INCH
:
286 eUnit
= XML_UNIT_INCH
;
290 if( eValueUnit
!= eOutUnit
)
291 nValue
= OutputDevice::LogicToLogic( nValue
, eValueUnit
, eOutUnit
);
293 rOut
.append( nValue
/ nFac
);
294 if( nFac
> 1 && (nValue
% nFac
) != 0 )
296 rOut
.append( sal_Unicode('.') );
297 while( nFac
> 1 && (nValue
% nFac
) != 0 )
300 rOut
.append( (nValue
/ nFac
) % 10L );
304 rOut
.append( GetXMLToken(eUnit
) );
309 void SvXMLExportHelper::AddPercentage( sal_Int32 nValue
, OUStringBuffer
& rOut
)
311 rOut
.append( nValue
);
312 rOut
.append( sal_Unicode('%' ) );
315 double SvXMLExportHelper::GetConversionFactor(::rtl::OUStringBuffer
& rUnit
,
316 const MapUnit eCoreUnit
, const MapUnit eDestUnit
)
321 if(eCoreUnit
!= eDestUnit
)
323 enum XMLTokenEnum eUnit
= XML_TOKEN_INVALID
;
334 DBG_ASSERT(MAP_INCH
== eDestUnit
, "output unit not supported for twip values");
338 // 0.01mm = 0.57twip (exactly)
339 fRetval
= ((25400.0 / 1440.0) / 1000.0);
345 // 0.001cm = 0.57twip (exactly)
346 fRetval
= ((25400.0 / 1440.0) / 10000.0);
352 // 0.01pt = 0.2twip (exactly)
353 fRetval
= ((1000.0 / 20.0) / 1000.0);
360 DBG_ASSERT(MAP_INCH
== eDestUnit
, "output unit not supported for twip values");
361 // 0.0001in = 0.144twip (exactly)
362 fRetval
= ((100000.0 / 1440.0) / 100000.0);
363 eUnit
= XML_UNIT_INCH
;
374 // 1mm = 72 / 25.4 pt (exactly)
375 fRetval
= ( 25.4 / 72.0 );
380 // 1cm = 72 / 2.54 pt (exactly)
381 fRetval
= ( 2.54 / 72.0 );
386 // 1twip = 72 / 1440 pt (exactly)
387 fRetval
= 20.0; // 1440.0 / 72.0
393 DBG_ASSERT(MAP_INCH
== eDestUnit
, "output unit not supported for pt values");
394 // 1in = 72 pt (exactly)
395 fRetval
= ( 1.0 / 72.0 );
396 eUnit
= XML_UNIT_INCH
;
408 DBG_ASSERT(MAP_INCH
== eDestUnit
, "output unit not supported for 1/100mm values");
412 // 0.01mm = 1 mm/100 (exactly)
413 fRetval
= ((10.0 / 1.0) / 100.0);
419 // 0.001mm = 1 mm/100 (exactly)
420 fRetval
= ((10.0 / 1.0) / 1000.0);
426 // 0.01pt = 0.35 mm/100 (exactly)
427 fRetval
= ((72000.0 / 2540.0) / 100.0);
434 DBG_ASSERT(MAP_INCH
== eDestUnit
, "output unit not supported for 1/100mm values");
435 // 0.0001in = 0.254 mm/100 (exactly)
436 fRetval
= ((100000.0 / 2540.0) / 10000.0);
437 eUnit
= XML_UNIT_INCH
;
450 DBG_ASSERT(MAP_INCH
== eDestUnit
, "output unit not supported for 1/100mm values");
454 // 0.01mm = 1 mm/100 (exactly)
455 fRetval
= ((10.0 / 1.0) / 1000.0);
461 // 0.001mm = 1 mm/100 (exactly)
462 fRetval
= ((10.0 / 1.0) / 10000.0);
468 // 0.01pt = 0.35 mm/100 (exactly)
469 fRetval
= ((72000.0 / 2540.0) / 1000.0);
476 DBG_ASSERT(MAP_INCH
== eDestUnit
, "output unit not supported for 1/100mm values");
477 // 0.0001in = 0.254 mm/100 (exactly)
478 fRetval
= ((100000.0 / 2540.0) / 100000.0);
479 eUnit
= XML_UNIT_INCH
;
486 DBG_ERROR("xmloff::SvXMLExportHelper::GetConversionFactor(), illegal eCoreUnit value!");
490 if(eUnit
!= XML_TOKEN_INVALID
)
491 rUnit
.append(GetXMLToken(eUnit
));
497 MapUnit
SvXMLExportHelper::GetUnitFromString(const ::rtl::OUString
& rString
, MapUnit eDefaultUnit
)
500 sal_Int32 nLen
= rString
.getLength();
501 MapUnit eRetUnit
= eDefaultUnit
;
504 while( nPos
< nLen
&& sal_Unicode(' ') == rString
[nPos
] )
508 if( nPos
< nLen
&& sal_Unicode('-') == rString
[nPos
] )
512 while( nPos
< nLen
&& sal_Unicode('0') <= rString
[nPos
] && sal_Unicode('9') >= rString
[nPos
] )
515 if( nPos
< nLen
&& sal_Unicode('.') == rString
[nPos
] )
518 while( nPos
< nLen
&& sal_Unicode('0') <= rString
[nPos
] && sal_Unicode('9') >= rString
[nPos
] )
523 while( nPos
< nLen
&& sal_Unicode(' ') == rString
[nPos
] )
528 switch(rString
[nPos
])
530 case sal_Unicode('%') :
532 eRetUnit
= MAP_RELATIVE
;
535 case sal_Unicode('c'):
536 case sal_Unicode('C'):
538 if(nPos
+1 < nLen
&& (rString
[nPos
+1] == sal_Unicode('m')
539 || rString
[nPos
+1] == sal_Unicode('M')))
543 case sal_Unicode('e'):
544 case sal_Unicode('E'):
546 // CSS1_EMS or CSS1_EMX later
549 case sal_Unicode('i'):
550 case sal_Unicode('I'):
552 if(nPos
+1 < nLen
&& (rString
[nPos
+1] == sal_Unicode('n')
553 || rString
[nPos
+1] == sal_Unicode('n')))
557 case sal_Unicode('m'):
558 case sal_Unicode('M'):
560 if(nPos
+1 < nLen
&& (rString
[nPos
+1] == sal_Unicode('m')
561 || rString
[nPos
+1] == sal_Unicode('M')))
565 case sal_Unicode('p'):
566 case sal_Unicode('P'):
568 if(nPos
+1 < nLen
&& (rString
[nPos
+1] == sal_Unicode('t')
569 || rString
[nPos
+1] == sal_Unicode('T')))
570 eRetUnit
= MAP_POINT
;
571 if(nPos
+1 < nLen
&& (rString
[nPos
+1] == sal_Unicode('c')
572 || rString
[nPos
+1] == sal_Unicode('C')))