blob: 544f4ff4792888a06e23af8df743103680654eaa [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"
#include "salcvt.hxx"
SalConverterCache::SalConverterCache()
{
}
SalConverterCache*
SalConverterCache::GetInstance ()
{
static SalConverterCache* pCvt = NULL;
if (pCvt == NULL)
pCvt = new SalConverterCache;
return pCvt;
}
SalConverterCache::~SalConverterCache()
{
}
// ---> FIXME
#include <stdio.h>
// <---
rtl_UnicodeToTextConverter
SalConverterCache::GetU2TConverter( rtl_TextEncoding nEncoding )
{
if( rtl_isOctetTextEncoding( nEncoding ) )
{
ConverterT& rConverter( m_aConverters[ nEncoding ] );
if ( rConverter.mpU2T == NULL )
{
rConverter.mpU2T =
rtl_createUnicodeToTextConverter( nEncoding );
// ---> FIXME
if ( rConverter.mpU2T == NULL )
fprintf( stderr, "failed to create Unicode -> %i converter\n", nEncoding);
// <---
}
return rConverter.mpU2T;
}
return NULL;
}
rtl_TextToUnicodeConverter
SalConverterCache::GetT2UConverter( rtl_TextEncoding nEncoding )
{
if( rtl_isOctetTextEncoding( nEncoding ) )
{
ConverterT& rConverter( m_aConverters[ nEncoding ] );
if ( rConverter.mpT2U == NULL )
{
rConverter.mpT2U =
rtl_createTextToUnicodeConverter( nEncoding );
// ---> FIXME
if ( rConverter.mpT2U == NULL )
fprintf( stderr, "failed to create %i -> Unicode converter\n", nEncoding );
// <---
}
return rConverter.mpT2U;
}
return NULL;
}
Bool
SalConverterCache::IsSingleByteEncoding( rtl_TextEncoding nEncoding )
{
if( rtl_isOctetTextEncoding( nEncoding ) )
{
ConverterT& rConverter( m_aConverters[ nEncoding ] );
if ( ! rConverter.mbValid )
{
rConverter.mbValid = True;
rtl_TextEncodingInfo aTextEncInfo;
aTextEncInfo.StructSize = sizeof( aTextEncInfo );
rtl_getTextEncodingInfo( nEncoding, &aTextEncInfo );
if ( aTextEncInfo.MinimumCharSize == aTextEncInfo.MaximumCharSize
&& aTextEncInfo.MinimumCharSize == 1)
rConverter.mbSingleByteEncoding = True;
else
rConverter.mbSingleByteEncoding = False;
}
return rConverter.mbSingleByteEncoding;
}
return False;
}
// check whether the character set nEncoding contains the unicode
// code point nChar. This list has been compiled from the according
// ttmap files in /usr/openwin/lib/X11/fonts/TrueType/ttmap/
Bool
SalConverterCache::EncodingHasChar( rtl_TextEncoding nEncoding,
sal_Unicode nChar )
{
Bool bMatch = False;
switch ( nEncoding )
{
case RTL_TEXTENCODING_DONTKNOW:
bMatch = False;
break;
case RTL_TEXTENCODING_MS_1252:
case RTL_TEXTENCODING_ISO_8859_1:
case RTL_TEXTENCODING_ISO_8859_15:
// handle iso8859-15 and iso8859-1 the same (and both with euro)
// handle them also like ms1252
// this is due to the fact that so many X fonts say they are iso8859-1
// but have the other glyphs anyway because they are really ms1252
bMatch = ( /*nChar >= 0x0000 &&*/ nChar <= 0x00ff )
|| ( nChar == 0x20ac )
|| ( nChar == 0x201a )
|| ( nChar == 0x0192 )
|| ( nChar == 0x201e )
|| ( nChar == 0x2026 )
|| ( nChar == 0x2020 )
|| ( nChar == 0x2021 )
|| ( nChar == 0x02c6 )
|| ( nChar == 0x2030 )
|| ( nChar == 0x0160 )
|| ( nChar == 0x2039 )
|| ( nChar == 0x0152 )
|| ( nChar == 0x017d )
|| ( nChar == 0x2018 )
|| ( nChar == 0x2019 )
|| ( nChar == 0x201c )
|| ( nChar == 0x201d )
|| ( nChar == 0x2022 )
|| ( nChar == 0x2013 )
|| ( nChar == 0x2014 )
|| ( nChar == 0x02dc )
|| ( nChar == 0x2122 )
|| ( nChar == 0x0161 )
|| ( nChar == 0x203a )
|| ( nChar == 0x0153 )
|| ( nChar == 0x017e )
|| ( nChar == 0x0178 )
;
break;
case RTL_TEXTENCODING_ISO_8859_2:
bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
|| ( nChar >= 0x00a0 && nChar <= 0x017e )
|| ( nChar >= 0x02c7 && nChar <= 0x02dd );
break;
case RTL_TEXTENCODING_ISO_8859_4:
bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
|| ( nChar >= 0x00a0 && nChar <= 0x017e )
|| ( nChar >= 0x02c7 && nChar <= 0x02db );
break;
case RTL_TEXTENCODING_ISO_8859_5:
bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
|| ( nChar >= 0x00a0 && nChar <= 0x00ad )
|| ( nChar >= 0x0401 && nChar <= 0x045f )
|| ( nChar == 0x2116 );
break;
case RTL_TEXTENCODING_ISO_8859_6:
bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
|| ( nChar >= 0x0600 && nChar <= 0x06ff )
|| ( nChar >= 0xfb50 && nChar <= 0xfffe );
break;
case RTL_TEXTENCODING_ISO_8859_7:
bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
|| ( nChar >= 0x00a0 && nChar <= 0x00bd )
|| ( nChar == 0x02bd )
|| ( nChar >= 0x0384 && nChar <= 0x03ce )
|| ( nChar >= 0x2014 && nChar <= 0x2019 );
break;
case RTL_TEXTENCODING_ISO_8859_8:
bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
|| ( nChar >= 0x00a0 && nChar <= 0x00f7 )
|| ( nChar >= 0x05d0 && nChar <= 0x05ea )
|| ( nChar == 0x2017 );
break;
case RTL_TEXTENCODING_ISO_8859_9:
bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
|| ( nChar >= 0x00a0 && nChar <= 0x015f );
break;
case RTL_TEXTENCODING_ISO_8859_13:
bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
|| ( nChar >= 0x00a0 && nChar <= 0x017e )
|| ( nChar >= 0x2019 && nChar <= 0x201e );
break;
/* real case for RTL_TEXTENCODING_ISO_8859_15
case RTL_TEXTENCODING_ISO_8859_15:
bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
|| ( nChar >= 0x00a0 && nChar <= 0x00ff )
|| ( nChar >= 0x0152 && nChar <= 0x017e )
|| ( nChar == 0x20ac );
break;
*/
case RTL_TEXTENCODING_JIS_X_0201:
bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
|| ( nChar >= 0xff61 && nChar <= 0xff9f );
break;
case RTL_TEXTENCODING_MS_1251:
bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
|| ( nChar >= 0x00a0 && nChar <= 0x00bb )
|| ( nChar >= 0x0401 && nChar <= 0x045f )
|| ( nChar >= 0x0490 && nChar <= 0x0491 )
|| ( nChar >= 0x2013 && nChar <= 0x203a )
|| ( nChar >= 0x2116 && nChar <= 0x2122 );
break;
case RTL_TEXTENCODING_KOI8_R:
bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
|| ( nChar >= 0x00a0 && nChar <= 0x00b7 )
|| ( nChar == 0x00f7 )
|| ( nChar >= 0x0401 && nChar <= 0x0451 )
|| ( nChar >= 0x2219 && nChar <= 0x221a )
|| ( nChar >= 0x2248 && nChar <= 0x2265 )
|| ( nChar >= 0x2320 && nChar <= 0x2321 )
|| ( nChar >= 0x2500 && nChar <= 0x25a0 );
break;
case RTL_TEXTENCODING_UNICODE:
bMatch = True;
break;
case RTL_TEXTENCODING_EUC_KR:
case RTL_TEXTENCODING_BIG5:
case RTL_TEXTENCODING_GBK:
case RTL_TEXTENCODING_GB_2312:
case RTL_TEXTENCODING_MS_1361:
case RTL_TEXTENCODING_JIS_X_0208:
// XXX Big5 and Korean EUC contain Ascii chars, but Solaris
// *-big5-1 and *-ksc5601.1992-3 fonts dont, in general CJK fonts
// are monospaced, so dont trust them for latin chars
if (nChar <= 0xFF)
{
bMatch = False;
break;
}
default:
// XXX really convert the unicode char into the encoding
// and check for conversion errors, this is expensive !
rtl_UnicodeToTextConverter aConverter;
rtl_UnicodeToTextContext aContext;
aConverter = GetU2TConverter(nEncoding);
aContext = rtl_createUnicodeToTextContext( aConverter );
// ---> FIXME
if ( aConverter == NULL )
return False;
// <---
sal_Char pConversionBuffer[ 32 ];
sal_uInt32 nConversionInfo;
sal_Size nConvertedChars;
sal_Size nSize;
nSize = rtl_convertUnicodeToText( aConverter, aContext,
&nChar, 1, pConversionBuffer, sizeof(pConversionBuffer),
RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
| RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR,
&nConversionInfo, &nConvertedChars );
rtl_destroyUnicodeToTextContext( aConverter, aContext );
bMatch = (nConvertedChars == 1)
&& (nSize == 1 || nSize == 2) // XXX Fix me this is a hack
&& ((nConversionInfo & RTL_UNICODETOTEXT_INFO_ERROR) == 0);
break;
}
return bMatch;
}
// wrapper for rtl_convertUnicodeToText that handles the usual cases for
// textconversion in drawtext and gettextwidth routines
sal_Size
SalConverterCache::ConvertStringUTF16( const sal_Unicode *pText, int nTextLen,
sal_Char *pBuffer, sal_Size nBufferSize, rtl_TextEncoding nEncoding )
{
rtl_UnicodeToTextConverter aConverter = GetU2TConverter(nEncoding);
const sal_uInt32 nCvtFlags =
RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE
| RTL_UNICODETOTEXT_FLAGS_UNDEFINED_QUESTIONMARK
| RTL_UNICODETOTEXT_FLAGS_INVALID_QUESTIONMARK ;
sal_uInt32 nCvtInfo;
sal_Size nCvtChars;
rtl_UnicodeToTextContext aContext =
rtl_createUnicodeToTextContext( aConverter );
sal_Size nSize = rtl_convertUnicodeToText( aConverter, aContext,
pText, nTextLen, pBuffer, nBufferSize,
nCvtFlags, &nCvtInfo, &nCvtChars );
rtl_destroyUnicodeToTextContext( aConverter, aContext );
return nSize;
}