1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <xmloff/xmluconv.hxx>
23 #include <com/sun/star/util/DateTime.hpp>
24 #include <com/sun/star/util/Date.hpp>
25 #include <tools/debug.hxx>
26 #include <rtl/ustrbuf.hxx>
27 #include <osl/diagnose.h>
28 #include <xmloff/xmlement.hxx>
29 #include <xmloff/xmltoken.hxx>
30 #include <rtl/math.hxx>
32 #include <tools/date.hxx>
33 #include <tools/time.hxx>
34 #include <tools/fldunit.hxx>
36 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
37 #include <com/sun/star/style/NumberingType.hpp>
38 #include <com/sun/star/text/DefaultNumberingProvider.hpp>
39 #include <com/sun/star/text/XDefaultNumberingProvider.hpp>
40 #include <com/sun/star/text/XNumberingTypeInfo.hpp>
41 #include <com/sun/star/i18n/CharacterClassification.hpp>
42 #include <com/sun/star/i18n/UnicodeType.hpp>
43 #include <basegfx/vector/b3dvector.hxx>
44 #include <comphelper/processfactory.hxx>
46 #include <sax/tools/converter.hxx>
49 using namespace com::sun::star
;
50 using namespace com::sun::star::uno
;
51 using namespace com::sun::star::lang
;
52 using namespace com::sun::star::text
;
53 using namespace com::sun::star::style
;
54 using namespace ::com::sun::star::i18n
;
55 using namespace ::xmloff::token
;
58 const sal_Int8 XML_MAXDIGITSCOUNT_TIME
= 11;
59 #define XML_NULLDATE "NullDate"
61 struct SvXMLUnitConverter::Impl
63 sal_Int16 m_eCoreMeasureUnit
; /*css::util::MeasureUnit*/
64 sal_Int16 m_eXMLMeasureUnit
; /*css::util::MeasureUnit*/
65 util::Date m_aNullDate
;
66 mutable uno::Reference
< text::XNumberingTypeInfo
> m_xNumTypeInfo
;
67 mutable uno::Reference
< i18n::XCharacterClassification
> m_xCharClass
;
68 uno::Reference
< uno::XComponentContext
> m_xContext
;
70 Impl(uno::Reference
<uno::XComponentContext
> const& xContext
,
71 sal_Int16
const eCoreMeasureUnit
,
72 sal_Int16
const eXMLMeasureUnit
)
73 : m_eCoreMeasureUnit(eCoreMeasureUnit
)
74 , m_eXMLMeasureUnit(eXMLMeasureUnit
)
75 , m_aNullDate(30, 12, 1899)
76 , m_xContext(xContext
)
78 OSL_ENSURE( m_xContext
.is(), "got no service manager" );
81 void createNumTypeInfo() const;
85 void SvXMLUnitConverter::Impl::createNumTypeInfo() const
87 Reference
<XDefaultNumberingProvider
> xDefNum
= DefaultNumberingProvider::create(m_xContext
);
88 m_xNumTypeInfo
= Reference
<XNumberingTypeInfo
>(xDefNum
, uno::UNO_QUERY
);
91 const uno::Reference
< text::XNumberingTypeInfo
>&
92 SvXMLUnitConverter::getNumTypeInfo() const
94 if (!m_pImpl
->m_xNumTypeInfo
.is())
96 m_pImpl
->createNumTypeInfo();
98 return m_pImpl
->m_xNumTypeInfo
;
101 void SvXMLUnitConverter::SetCoreMeasureUnit(sal_Int16
const eCoreMeasureUnit
/*css::util::MeasureUnit*/)
103 m_pImpl
->m_eCoreMeasureUnit
= eCoreMeasureUnit
;
106 void SvXMLUnitConverter::SetXMLMeasureUnit(sal_Int16
const eXMLMeasureUnit
/*css::util::MeasureUnit*/)
108 m_pImpl
->m_eXMLMeasureUnit
= eXMLMeasureUnit
;
111 sal_Int16
SvXMLUnitConverter::GetXMLMeasureUnit() const
113 return m_pImpl
->m_eXMLMeasureUnit
;
116 /** constructs a SvXMLUnitConverter. The core measure unit is the
117 default unit for numerical measures, the XML measure unit is
118 the default unit for textual measures
121 SvXMLUnitConverter::SvXMLUnitConverter(
122 const uno::Reference
<uno::XComponentContext
>& xContext
,
123 sal_Int16
const eCoreMeasureUnit
,
124 sal_Int16
const eXMLMeasureUnit
)
125 : m_pImpl(new Impl(xContext
, eCoreMeasureUnit
, eXMLMeasureUnit
))
129 SvXMLUnitConverter::~SvXMLUnitConverter()
133 sal_Int16
SvXMLUnitConverter::GetMeasureUnit(FieldUnit
const nFieldUnit
)
135 sal_Int16 eUnit
= util::MeasureUnit::INCH
;
139 eUnit
= util::MeasureUnit::MM
;
144 eUnit
= util::MeasureUnit::CM
;
147 eUnit
= util::MeasureUnit::TWIP
;
151 eUnit
= util::MeasureUnit::POINT
;
154 eUnit
= util::MeasureUnit::MM_100TH
;
157 eUnit
= util::MeasureUnit::INCH
;
166 /** convert string to measure using optional min and max values*/
167 bool SvXMLUnitConverter::convertMeasureToCore( sal_Int32
& nValue
,
168 const OUString
& rString
,
169 sal_Int32 nMin
, sal_Int32 nMax
) const
171 return ::sax::Converter::convertMeasure( nValue
, rString
,
172 m_pImpl
->m_eCoreMeasureUnit
,
176 /** convert measure to string */
177 void SvXMLUnitConverter::convertMeasureToXML( OUStringBuffer
& rString
,
178 sal_Int32 nMeasure
) const
180 ::sax::Converter::convertMeasure( rString
, nMeasure
,
181 m_pImpl
->m_eCoreMeasureUnit
,
182 m_pImpl
->m_eXMLMeasureUnit
);
185 /** convert string to enum using given enum map, if the enum is
186 not found in the map, this method will return false
188 bool SvXMLUnitConverter::convertEnum( sal_uInt16
& rEnum
,
189 const OUString
& rValue
,
190 const SvXMLEnumStringMapEntry
*pMap
)
194 if( rValue
.equalsAsciiL( pMap
->pName
, pMap
->nNameLength
) )
196 rEnum
= pMap
->nValue
;
205 /** convert string to enum using given token map, if the enum is
206 not found in the map, this method will return false */
207 bool SvXMLUnitConverter::convertEnum(
209 const OUString
& rValue
,
210 const SvXMLEnumMapEntry
*pMap
)
212 while( pMap
->eToken
!= XML_TOKEN_INVALID
)
214 if( IsXMLToken( rValue
, pMap
->eToken
) )
216 rEnum
= pMap
->nValue
;
224 /** convert enum to string using given token map with an optional
225 default token. If the enum is not found in the map,
226 this method will either use the given default or return
227 false if no default is set */
228 bool SvXMLUnitConverter::convertEnum(
229 OUStringBuffer
& rBuffer
,
231 const SvXMLEnumMapEntry
*pMap
,
232 enum XMLTokenEnum eDefault
)
234 enum XMLTokenEnum eTok
= eDefault
;
236 while( pMap
->eToken
!= XML_TOKEN_INVALID
)
238 if( pMap
->nValue
== nValue
)
246 // the map may have contained XML_TOKEN_INVALID
247 if( eTok
== XML_TOKEN_INVALID
)
250 if( eTok
!= XML_TOKEN_INVALID
)
251 rBuffer
.append( GetXMLToken(eTok
) );
253 return (eTok
!= XML_TOKEN_INVALID
);
256 static int lcl_gethex( int nChar
)
258 if( nChar
>= '0' && nChar
<= '9' )
260 else if( nChar
>= 'a' && nChar
<= 'f' )
261 return nChar
- 'a' + 10;
262 else if( nChar
>= 'A' && nChar
<= 'F' )
263 return nChar
- 'A' + 10;
268 static sal_Char aHexTab
[] = "0123456789abcdef";
271 /** convert double number to string (using ::rtl::math) */
272 void SvXMLUnitConverter::convertDouble(OUStringBuffer
& rBuffer
,
273 double fNumber
, bool bWriteUnits
) const
275 ::sax::Converter::convertDouble(rBuffer
, fNumber
,
276 bWriteUnits
, m_pImpl
->m_eCoreMeasureUnit
, m_pImpl
->m_eXMLMeasureUnit
);
279 /** convert string to double number (using ::rtl::math) */
280 bool SvXMLUnitConverter::convertDouble(double& rValue
,
281 const OUString
& rString
, bool bLookForUnits
) const
285 sal_Int16
const eSrcUnit
= ::sax::Converter::GetUnitFromString(
286 rString
, m_pImpl
->m_eCoreMeasureUnit
);
288 return ::sax::Converter::convertDouble(rValue
, rString
,
289 eSrcUnit
, m_pImpl
->m_eCoreMeasureUnit
);
293 return ::sax::Converter::convertDouble(rValue
, rString
);
297 /** get the Null Date of the XModel and set it to the UnitConverter */
298 bool SvXMLUnitConverter::setNullDate(const com::sun::star::uno::Reference
<com::sun::star::frame::XModel
>& xModel
)
300 com::sun::star::uno::Reference
<com::sun::star::util::XNumberFormatsSupplier
> xNumberFormatsSupplier (xModel
, com::sun::star::uno::UNO_QUERY
);
301 if (xNumberFormatsSupplier
.is())
303 const com::sun::star::uno::Reference
<com::sun::star::beans::XPropertySet
> xPropertySet
= xNumberFormatsSupplier
->getNumberFormatSettings();
304 return xPropertySet
.is() && (xPropertySet
->getPropertyValue(OUString(XML_NULLDATE
)) >>= m_pImpl
->m_aNullDate
);
309 /** convert double to ISO Date Time String */
310 void SvXMLUnitConverter::convertDateTime(OUStringBuffer
& rBuffer
,
311 const double& fDateTime
, bool const bAddTimeIf0AM
)
313 convertDateTime(rBuffer
, fDateTime
, m_pImpl
->m_aNullDate
, bAddTimeIf0AM
);
316 /** convert ISO Date Time String to double */
317 bool SvXMLUnitConverter::convertDateTime(double& fDateTime
,
318 const OUString
& rString
)
320 return convertDateTime(fDateTime
, rString
, m_pImpl
->m_aNullDate
);
323 /** convert double to ISO Date Time String */
324 void SvXMLUnitConverter::convertDateTime( OUStringBuffer
& rBuffer
,
325 const double& fDateTime
,
326 const com::sun::star::util::Date
& aTempNullDate
,
329 double fValue
= fDateTime
;
330 sal_Int32 nValue
= static_cast <sal_Int32
> (::rtl::math::approxFloor (fValue
));
331 Date
aDate (aTempNullDate
.Day
, aTempNullDate
.Month
, aTempNullDate
.Year
);
336 fCount
= ::rtl::math::approxFloor (log10((double)nValue
)) + 1;
338 fCount
= ::rtl::math::approxFloor (log10((double)(nValue
* -1))) + 1;
341 sal_Int16 nCount
= sal_Int16(fCount
);
342 bool bHasTime(false);
343 double fHoursValue
= 0;
344 double fMinsValue
= 0;
345 double fSecsValue
= 0;
346 double f100SecsValue
= 0;
351 fHoursValue
= ::rtl::math::approxFloor (fValue
);
352 fValue
-= fHoursValue
;
354 fMinsValue
= ::rtl::math::approxFloor (fValue
);
355 fValue
-= fMinsValue
;
357 fSecsValue
= ::rtl::math::approxFloor (fValue
);
358 fValue
-= fSecsValue
;
360 f100SecsValue
= ::rtl::math::round( fValue
, XML_MAXDIGITSCOUNT_TIME
- nCount
);
364 if (f100SecsValue
== 1.0)
369 if (fSecsValue
>= 60.0)
374 if (fMinsValue
>= 60.0)
379 if (fHoursValue
>= 24.0)
385 sal_uInt16 nTemp
= aDate
.GetYear();
387 rBuffer
.append( '0');
389 rBuffer
.append( '0');
391 rBuffer
.append( '0');
392 rBuffer
.append( sal_Int32( nTemp
));
393 rBuffer
.append( '-');
394 nTemp
= aDate
.GetMonth();
396 rBuffer
.append( '0');
397 rBuffer
.append( sal_Int32( nTemp
));
398 rBuffer
.append( '-');
399 nTemp
= aDate
.GetDay();
401 rBuffer
.append( '0');
402 rBuffer
.append( sal_Int32( nTemp
));
403 if(bHasTime
|| bAddTimeIf0AM
)
405 rBuffer
.append( 'T');
406 if (fHoursValue
< 10)
407 rBuffer
.append( '0');
408 rBuffer
.append( sal_Int32( fHoursValue
));
409 rBuffer
.append( ':');
411 rBuffer
.append( '0');
412 rBuffer
.append( sal_Int32( fMinsValue
));
413 rBuffer
.append( ':');
415 rBuffer
.append( '0');
416 rBuffer
.append( sal_Int32( fSecsValue
));
417 if (f100SecsValue
> 0.0)
419 OUString
a100th( ::rtl::math::doubleToUString( fValue
,
420 rtl_math_StringFormat_F
,
421 XML_MAXDIGITSCOUNT_TIME
- nCount
, '.', true));
422 if ( a100th
.getLength() > 2 )
424 rBuffer
.append( '.');
425 rBuffer
.append( a100th
.copy( 2 ) ); // strip 0.
431 /** convert ISO Date Time String to double */
432 bool SvXMLUnitConverter::convertDateTime( double& fDateTime
,
433 const OUString
& rString
, const com::sun::star::util::Date
& aTempNullDate
)
435 com::sun::star::util::DateTime aDateTime
;
436 bool bSuccess
= ::sax::Converter::parseDateTime(aDateTime
, 0, rString
);
440 const Date
aTmpNullDate(aTempNullDate
.Day
, aTempNullDate
.Month
, aTempNullDate
.Year
);
441 const Date
aTempDate((sal_uInt16
)aDateTime
.Day
, (sal_uInt16
)aDateTime
.Month
, (sal_uInt16
)aDateTime
.Year
);
442 const sal_Int32 nTage
= aTempDate
- aTmpNullDate
;
443 double fTempDateTime
= nTage
;
444 double Hour
= aDateTime
.Hours
;
445 double Min
= aDateTime
.Minutes
;
446 double Sec
= aDateTime
.Seconds
;
447 double NanoSec
= aDateTime
.NanoSeconds
;
448 fTempDateTime
+= Hour
/ ::tools::Time::hourPerDay
;
449 fTempDateTime
+= Min
/ ::tools::Time::minutePerDay
;
450 fTempDateTime
+= Sec
/ ::tools::Time::secondPerDay
;
451 fTempDateTime
+= NanoSec
/ ::tools::Time::nanoSecPerDay
;
452 fDateTime
= fTempDateTime
;
458 SvXMLTokenEnumerator::SvXMLTokenEnumerator( const OUString
& rString
, sal_Unicode cSeparator
/* = ' ' */ )
459 : maTokenString( rString
), mnNextTokenPos(0), mcSeparator( cSeparator
)
463 bool SvXMLTokenEnumerator::getNextToken( OUString
& rToken
)
465 if( -1 == mnNextTokenPos
)
468 int nTokenEndPos
= maTokenString
.indexOf( mcSeparator
, mnNextTokenPos
);
469 if( nTokenEndPos
!= -1 )
471 rToken
= maTokenString
.copy( mnNextTokenPos
,
472 nTokenEndPos
- mnNextTokenPos
);
473 mnNextTokenPos
= nTokenEndPos
+ 1;
475 // if the mnNextTokenPos is at the end of the string, we have
476 // to deliver an empty token
477 if( mnNextTokenPos
> maTokenString
.getLength() )
482 rToken
= maTokenString
.copy( mnNextTokenPos
);
489 static bool lcl_getPositions(const OUString
& _sValue
,OUString
& _rContentX
,OUString
& _rContentY
,OUString
& _rContentZ
)
491 if(_sValue
.isEmpty() || _sValue
[0] != '(')
495 sal_Int32 nFound
= _sValue
.indexOf(' ', nPos
);
497 if(nFound
== -1 || nFound
<= nPos
)
500 _rContentX
= _sValue
.copy(nPos
, nFound
- nPos
);
503 nFound
= _sValue
.indexOf(' ', nPos
);
505 if(nFound
== -1 || nFound
<= nPos
)
508 _rContentY
= _sValue
.copy(nPos
, nFound
- nPos
);
511 nFound
= _sValue
.indexOf(')', nPos
);
513 if(nFound
== -1 || nFound
<= nPos
)
516 _rContentZ
= _sValue
.copy(nPos
, nFound
- nPos
);
520 /** convert string to ::basegfx::B3DVector */
521 bool SvXMLUnitConverter::convertB3DVector( ::basegfx::B3DVector
& rVector
, const OUString
& rValue
)
523 OUString aContentX
,aContentY
,aContentZ
;
524 if ( !lcl_getPositions(rValue
,aContentX
,aContentY
,aContentZ
) )
527 rtl_math_ConversionStatus eStatus
;
529 rVector
.setX(::rtl::math::stringToDouble(aContentX
, '.',
530 ',', &eStatus
, NULL
));
532 if( eStatus
!= rtl_math_ConversionStatus_Ok
)
535 rVector
.setY(::rtl::math::stringToDouble(aContentY
, '.',
536 ',', &eStatus
, NULL
));
538 if( eStatus
!= rtl_math_ConversionStatus_Ok
)
541 rVector
.setZ(::rtl::math::stringToDouble(aContentZ
, '.',
542 ',', &eStatus
, NULL
));
545 return ( eStatus
== rtl_math_ConversionStatus_Ok
);
548 /** convert ::basegfx::B3DVector to string */
549 void SvXMLUnitConverter::convertB3DVector( OUStringBuffer
&rBuffer
, const ::basegfx::B3DVector
& rVector
)
552 ::sax::Converter::convertDouble(rBuffer
, rVector
.getX());
554 ::sax::Converter::convertDouble(rBuffer
, rVector
.getY());
556 ::sax::Converter::convertDouble(rBuffer
, rVector
.getZ());
560 /** convert string to Position3D */
561 bool SvXMLUnitConverter::convertPosition3D( drawing::Position3D
& rPosition
,
562 const OUString
& rValue
)
564 OUString aContentX
,aContentY
,aContentZ
;
565 if ( !lcl_getPositions(rValue
,aContentX
,aContentY
,aContentZ
) )
568 if ( !convertDouble( rPosition
.PositionX
, aContentX
, true ) )
570 if ( !convertDouble( rPosition
.PositionY
, aContentY
, true ) )
572 return convertDouble( rPosition
.PositionZ
, aContentZ
, true );
575 /** convert Position3D to string */
576 void SvXMLUnitConverter::convertPosition3D( OUStringBuffer
&rBuffer
,
577 const drawing::Position3D
& rPosition
)
579 rBuffer
.append( '(' );
580 convertDouble( rBuffer
, rPosition
.PositionX
, true );
581 rBuffer
.append( ' ' );
582 convertDouble( rBuffer
, rPosition
.PositionY
, true );
583 rBuffer
.append( ' ' );
584 convertDouble( rBuffer
, rPosition
.PositionZ
, true );
585 rBuffer
.append( ')' );
588 bool SvXMLUnitConverter::convertNumFormat(
590 const OUString
& rNumFmt
,
591 const OUString
& rNumLetterSync
,
592 bool bNumberNone
) const
597 sal_Int32 nLen
= rNumFmt
.getLength();
601 rType
= NumberingType::NUMBER_NONE
;
609 case '1': rType
= NumberingType::ARABIC
; break;
610 case 'a': rType
= NumberingType::CHARS_LOWER_LETTER
; break;
611 case 'A': rType
= NumberingType::CHARS_UPPER_LETTER
; break;
612 case 'i': rType
= NumberingType::ROMAN_LOWER
; break;
613 case 'I': rType
= NumberingType::ROMAN_UPPER
; break;
614 default: bExt
= true; break;
616 if( !bExt
&& IsXMLToken( rNumLetterSync
, XML_TRUE
) )
620 case NumberingType::CHARS_LOWER_LETTER
:
621 rType
= NumberingType::CHARS_LOWER_LETTER_N
;
623 case NumberingType::CHARS_UPPER_LETTER
:
624 rType
= NumberingType::CHARS_UPPER_LETTER_N
;
635 Reference
< XNumberingTypeInfo
> xInfo
= getNumTypeInfo();
636 if( xInfo
.is() && xInfo
->hasNumberingType( rNumFmt
) )
638 rType
= xInfo
->getNumberingType( rNumFmt
);
642 rType
= NumberingType::ARABIC
;
649 void SvXMLUnitConverter::convertNumFormat( OUStringBuffer
& rBuffer
,
650 sal_Int16 nType
) const
652 enum XMLTokenEnum eFormat
= XML_TOKEN_INVALID
;
655 case NumberingType::CHARS_UPPER_LETTER
: eFormat
= XML_A_UPCASE
; break;
656 case NumberingType::CHARS_LOWER_LETTER
: eFormat
= XML_A
; break;
657 case NumberingType::ROMAN_UPPER
: eFormat
= XML_I_UPCASE
; break;
658 case NumberingType::ROMAN_LOWER
: eFormat
= XML_I
; break;
659 case NumberingType::ARABIC
: eFormat
= XML_1
; break;
660 case NumberingType::CHARS_UPPER_LETTER_N
: eFormat
= XML_A_UPCASE
; break;
661 case NumberingType::CHARS_LOWER_LETTER_N
: eFormat
= XML_A
; break;
662 case NumberingType::NUMBER_NONE
: eFormat
= XML__EMPTY
; break;
664 case NumberingType::CHAR_SPECIAL
:
665 case NumberingType::PAGE_DESCRIPTOR
:
666 case NumberingType::BITMAP
:
667 DBG_ASSERT( eFormat
!= XML_TOKEN_INVALID
, "invalid number format" );
673 if( eFormat
!= XML_TOKEN_INVALID
)
675 rBuffer
.append( GetXMLToken(eFormat
) );
679 Reference
< XNumberingTypeInfo
> xInfo
= getNumTypeInfo();
681 rBuffer
.append( xInfo
->getNumberingIdentifier( nType
) );
685 void SvXMLUnitConverter::convertNumLetterSync( OUStringBuffer
& rBuffer
,
688 enum XMLTokenEnum eSync
= XML_TOKEN_INVALID
;
691 case NumberingType::CHARS_UPPER_LETTER
:
692 case NumberingType::CHARS_LOWER_LETTER
:
693 case NumberingType::ROMAN_UPPER
:
694 case NumberingType::ROMAN_LOWER
:
695 case NumberingType::ARABIC
:
696 case NumberingType::NUMBER_NONE
:
699 case NumberingType::CHARS_UPPER_LETTER_N
:
700 case NumberingType::CHARS_LOWER_LETTER_N
:
704 case NumberingType::CHAR_SPECIAL
:
705 case NumberingType::PAGE_DESCRIPTOR
:
706 case NumberingType::BITMAP
:
707 DBG_ASSERT( eSync
!= XML_TOKEN_INVALID
, "invalid number format" );
710 if( eSync
!= XML_TOKEN_INVALID
)
711 rBuffer
.append( GetXMLToken(eSync
) );
714 void SvXMLUnitConverter::convertPropertySet(uno::Sequence
<beans::PropertyValue
>& rProps
,
715 const uno::Reference
<beans::XPropertySet
>& aProperties
)
717 uno::Reference
< beans::XPropertySetInfo
> xPropertySetInfo
= aProperties
->getPropertySetInfo();
718 if (xPropertySetInfo
.is())
720 uno::Sequence
< beans::Property
> aProps
= xPropertySetInfo
->getProperties();
721 const sal_Int32
nCount(aProps
.getLength());
724 rProps
.realloc(nCount
);
725 beans::PropertyValue
* pProps
= rProps
.getArray();
726 for (sal_Int32 i
= 0; i
< nCount
; i
++, ++pProps
)
728 pProps
->Name
= aProps
[i
].Name
;
729 pProps
->Value
= aProperties
->getPropertyValue(aProps
[i
].Name
);
735 void SvXMLUnitConverter::convertPropertySet(uno::Reference
<beans::XPropertySet
>& rProperties
,
736 const uno::Sequence
<beans::PropertyValue
>& aProps
)
738 sal_Int32
nCount(aProps
.getLength());
741 uno::Reference
< beans::XPropertySetInfo
> xPropertySetInfo
= rProperties
->getPropertySetInfo();
742 if (xPropertySetInfo
.is())
744 for (sal_Int32 i
= 0; i
< nCount
; i
++)
746 if (xPropertySetInfo
->hasPropertyByName(aProps
[i
].Name
))
747 rProperties
->setPropertyValue(aProps
[i
].Name
, aProps
[i
].Value
);
754 OUString
SvXMLUnitConverter::encodeStyleName(
755 const OUString
& rName
,
756 bool *pEncoded
) const
761 sal_Int32 nLen
= rName
.getLength();
762 OUStringBuffer
aBuffer( nLen
);
764 for( sal_Int32 i
= 0; i
< nLen
; i
++ )
766 sal_Unicode c
= rName
[i
];
767 bool bValidChar
= false;
771 (c
>= 0x0041 && c
<= 0x005a) ||
772 (c
>= 0x0061 && c
<= 0x007a) ||
773 (c
>= 0x00c0 && c
<= 0x00d6) ||
774 (c
>= 0x00d8 && c
<= 0x00f6) ||
775 (c
>= 0x00f8 && c
<= 0x00ff) ||
776 ( i
> 0 && ( (c
>= 0x0030 && c
<= 0x0039) ||
777 c
== 0x00b7 || c
== '-' || c
== '.') );
781 if( (c
>= 0xf900U
&& c
<= 0xfffeU
) ||
782 (c
>= 0x20ddU
&& c
<= 0x20e0U
))
786 else if( (c
>= 0x02bbU
&& c
<= 0x02c1U
) || c
== 0x0559 ||
787 c
== 0x06e5 || c
== 0x06e6 )
791 else if( c
== 0x0387 )
797 if (!m_pImpl
->m_xCharClass
.is())
799 this->m_pImpl
->m_xCharClass
= CharacterClassification::create( m_pImpl
->m_xContext
);
801 sal_Int16 nType
= m_pImpl
->m_xCharClass
->getType(rName
, i
);
805 case UnicodeType::UPPERCASE_LETTER
: // Lu
806 case UnicodeType::LOWERCASE_LETTER
: // Ll
807 case UnicodeType::TITLECASE_LETTER
: // Lt
808 case UnicodeType::OTHER_LETTER
: // Lo
809 case UnicodeType::LETTER_NUMBER
: // Nl
812 case UnicodeType::NON_SPACING_MARK
: // Ms
813 case UnicodeType::ENCLOSING_MARK
: // Me
814 case UnicodeType::COMBINING_SPACING_MARK
: //Mc
815 case UnicodeType::MODIFIER_LETTER
: // Lm
816 case UnicodeType::DECIMAL_DIGIT_NUMBER
: // Nd
828 aBuffer
.append( '_' );
830 aBuffer
.append( static_cast< sal_Unicode
>(
831 aHexTab
[ (c
>> 12) & 0x0f ] ) );
833 aBuffer
.append( static_cast< sal_Unicode
>(
834 aHexTab
[ (c
>> 8) & 0x0f ] ) );
836 aBuffer
.append( static_cast< sal_Unicode
>(
837 aHexTab
[ (c
>> 4) & 0x0f ] ) );
838 aBuffer
.append( static_cast< sal_Unicode
>(
839 aHexTab
[ c
& 0x0f ] ) );
840 aBuffer
.append( '_' );
847 if( aBuffer
.getLength() > ((1<<15)-1) )
855 return aBuffer
.makeStringAndClear();
858 /** convert string (hex) to number (sal_uInt32) */
859 bool SvXMLUnitConverter::convertHex( sal_uInt32
& nVal
,
860 const OUString
& rValue
)
862 if( rValue
.getLength() != 8 )
866 for ( int i
= 0; i
< 8; i
++ )
869 | sal::static_int_cast
< sal_uInt32
>( lcl_gethex( rValue
[i
] ) );
875 /** convert number (sal_uInt32) to string (hex) */
876 void SvXMLUnitConverter::convertHex( OUStringBuffer
& rBuffer
,
879 for ( int i
= 0; i
< 8; i
++ )
881 rBuffer
.append( sal_Unicode( aHexTab
[ nVal
>> 28 ] ) );
886 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */