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 .
20 #include <osl/diagnose.h>
21 #include "ImplHelper.hxx"
22 #include <rtl/tencinfo.h>
27 #pragma warning(push,1)
34 #include <sehandler.hxx>
39 #define FORMATETC_EXACT_MATCH 1
40 #define FORMATETC_PARTIAL_MATCH -1
41 #define FORMATETC_NO_MATCH 0
43 //------------------------------------------------------------------------
44 // namespace directives
45 //------------------------------------------------------------------------
48 //------------------------------------------------------------------------
49 // returns a windows codepage appropriate to the
50 // given mime charset parameter value
51 //------------------------------------------------------------------------
53 sal_uInt32 SAL_CALL
getWinCPFromMimeCharset( const OUString
& charset
)
55 sal_uInt32 winCP
= GetACP( );
57 if ( charset
.getLength( ) )
60 charset
.getStr( ), charset
.getLength( ), RTL_TEXTENCODING_ASCII_US
);
62 rtl_TextEncoding txtEnc
=
63 rtl_getTextEncodingFromMimeCharset( osCharset
.getStr( ) );
65 sal_uInt32 winChrs
= rtl_getBestWindowsCharsetFromTextEncoding( txtEnc
);
68 sal_Bool bRet
= TranslateCharsetInfo( (DWORD
*)winChrs
, &chrsInf
, TCI_SRCCHARSET
) ?
71 // if one of the above functions fails
72 // we will return the current ANSI codepage
75 winCP
= chrsInf
.ciACP
;
81 //--------------------------------------------------
82 // returns a windows codepage appropriate to the
83 // given locale and locale type
84 //--------------------------------------------------
86 OUString SAL_CALL
getWinCPFromLocaleId( LCID lcid
, LCTYPE lctype
)
88 OSL_ASSERT( IsValidLocale( lcid
, LCID_SUPPORTED
) );
90 // we set an default value
93 // set an default value
94 if ( LOCALE_IDEFAULTCODEPAGE
== lctype
)
96 winCP
= OUString::valueOf( static_cast<sal_Int32
>(GetOEMCP( )), 10 );
98 else if ( LOCALE_IDEFAULTANSICODEPAGE
== lctype
)
100 winCP
= OUString::valueOf( static_cast<sal_Int32
>(GetACP( )), 10 );
103 OSL_ASSERT( sal_False
);
105 // we use the GetLocaleInfoA because don't want to provide
106 // a unicode wrapper function for Win9x in sal/systools
108 sal_Int32 nResult
= GetLocaleInfoA(
109 lcid
, lctype
| LOCALE_USE_CP_ACP
, buff
, sizeof( buff
) );
111 OSL_ASSERT( nResult
);
115 sal_Int32 len
= MultiByteToWideChar(
116 CP_ACP
, 0, buff
, -1, NULL
, 0 );
118 OSL_ASSERT( len
> 0 );
120 std::vector
< sal_Unicode
> lpwchBuff(len
);
122 len
= MultiByteToWideChar(
123 CP_ACP
, 0, buff
, -1, reinterpret_cast<LPWSTR
>(&lpwchBuff
[0]), len
);
125 winCP
= OUString( &lpwchBuff
[0], (len
- 1) );
131 //--------------------------------------------------
132 // returns a mime charset parameter value appropriate
133 // to the given codepage, optional a prefix can be
134 // given, e.g. "windows-" or "cp"
135 //--------------------------------------------------
137 OUString SAL_CALL
getMimeCharsetFromWinCP( sal_uInt32 cp
, const OUString
& aPrefix
)
139 return aPrefix
+ cptostr( cp
);
142 //--------------------------------------------------
143 // returns a mime charset parameter value appropriate
144 // to the given locale id and locale type, optional a
145 // prefix can be given, e.g. "windows-" or "cp"
146 //--------------------------------------------------
148 OUString SAL_CALL
getMimeCharsetFromLocaleId( LCID lcid
, LCTYPE lctype
, const OUString
& aPrefix
)
150 OUString charset
= getWinCPFromLocaleId( lcid
, lctype
);
151 return aPrefix
+ charset
;
154 //------------------------------------------------------------------------
156 //------------------------------------------------------------------------
158 sal_Bool SAL_CALL
IsOEMCP( sal_uInt32 codepage
)
160 OSL_ASSERT( IsValidCodePage( codepage
) );
162 sal_uInt32 arrOEMCP
[] = { 437, 708, 709, 710, 720, 737,
163 775, 850, 852, 855, 857, 860,
164 861, 862, 863, 864, 865, 866,
165 869, 874, 932, 936, 949, 950, 1361 };
167 for ( size_t i
= 0; i
< SAL_N_ELEMENTS( arrOEMCP
); ++i
)
168 if ( arrOEMCP
[i
] == codepage
)
174 //------------------------------------------------------------------------
175 // converts a codepage into its string representation
176 //------------------------------------------------------------------------
178 OUString SAL_CALL
cptostr( sal_uInt32 codepage
)
180 OSL_ASSERT( IsValidCodePage( codepage
) );
182 return OUString::valueOf( static_cast<sal_Int64
>( codepage
), 10 );
185 //-------------------------------------------------------------------------
186 // OleStdDeleteTargetDevice()
193 // SCODE - S_OK if successful
194 //-------------------------------------------------------------------------
196 void SAL_CALL
DeleteTargetDevice( DVTARGETDEVICE
* ptd
)
201 if (__builtin_setjmp(jmpbuf
) == 0)
203 han
.Set(jmpbuf
, NULL
, (__SEHandler::PF
)EXCEPTION_EXECUTE_HANDLER
);
208 CoTaskMemFree( ptd
);
213 __except( EXCEPTION_EXECUTE_HANDLER
)
216 OSL_FAIL( "Error DeleteTargetDevice" );
225 //-------------------------------------------------------------------------
226 // OleStdCopyTargetDevice()
229 // duplicate a TARGETDEVICE struct. this function allocates memory for
230 // the copy. the caller MUST free the allocated copy when done with it
231 // using the standard allocator returned from CoGetMalloc.
232 // (OleStdFree can be used to free the copy).
235 // ptdSrc pointer to source TARGETDEVICE
238 // pointer to allocated copy of ptdSrc
239 // if ptdSrc==NULL then retuns NULL is returned.
240 // if ptdSrc!=NULL and memory allocation fails, then NULL is returned
241 //-------------------------------------------------------------------------
243 DVTARGETDEVICE
* SAL_CALL
CopyTargetDevice( DVTARGETDEVICE
* ptdSrc
)
245 DVTARGETDEVICE
* ptdDest
= NULL
;
250 if (__builtin_setjmp(jmpbuf
) == 0)
252 han
.Set(jmpbuf
, NULL
, (__SEHandler::PF
)EXCEPTION_EXECUTE_HANDLER
);
257 if ( NULL
!= ptdSrc
)
259 ptdDest
= static_cast< DVTARGETDEVICE
* >( CoTaskMemAlloc( ptdSrc
->tdSize
) );
260 memcpy( ptdDest
, ptdSrc
, static_cast< size_t >( ptdSrc
->tdSize
) );
266 __except( EXCEPTION_EXECUTE_HANDLER
)
275 //-------------------------------------------------------------------------
276 // OleStdCopyFormatEtc()
279 // Copies the contents of a FORMATETC structure. this function takes
280 // special care to copy correctly copying the pointer to the TARGETDEVICE
281 // contained within the source FORMATETC structure.
282 // if the source FORMATETC has a non-NULL TARGETDEVICE, then a copy
283 // of the TARGETDEVICE will be allocated for the destination of the
284 // FORMATETC (petcDest).
286 // NOTE: the caller MUST free the allocated copy of the TARGETDEVICE
287 // within the destination FORMATETC when done with it
288 // using the standard allocator returned from CoGetMalloc.
289 // (OleStdFree can be used to free the copy).
292 // petcDest pointer to destination FORMATETC
293 // petcSrc pointer to source FORMATETC
296 // returns TRUE if copy was successful;
297 // retuns FALSE if not successful, e.g. one or both of the pointers
298 // were invalid or the pointers were equal
299 //-------------------------------------------------------------------------
301 sal_Bool SAL_CALL
CopyFormatEtc( LPFORMATETC petcDest
, LPFORMATETC petcSrc
)
303 sal_Bool bRet
= sal_False
;
308 if (__builtin_setjmp(jmpbuf
) == 0)
310 han
.Set(jmpbuf
, NULL
, (__SEHandler::PF
)EXCEPTION_EXECUTE_HANDLER
);
315 if ( petcDest
!= petcSrc
)
318 petcDest
->cfFormat
= petcSrc
->cfFormat
;
320 petcDest
->ptd
= NULL
;
321 if ( NULL
!= petcSrc
->ptd
)
322 petcDest
->ptd
= CopyTargetDevice(petcSrc
->ptd
);
324 petcDest
->dwAspect
= petcSrc
->dwAspect
;
325 petcDest
->lindex
= petcSrc
->lindex
;
326 petcDest
->tymed
= petcSrc
->tymed
;
334 __except( EXCEPTION_EXECUTE_HANDLER
)
337 OSL_FAIL( "Error CopyFormatEtc" );
346 //-------------------------------------------------------------------------
348 // 1 for exact match,
350 // -1 for partial match (which is defined to mean the left is a subset
351 // of the right: fewer aspects, null target device, fewer medium).
352 //-------------------------------------------------------------------------
354 sal_Int32 SAL_CALL
CompareFormatEtc( const FORMATETC
* pFetcLhs
, const FORMATETC
* pFetcRhs
)
356 sal_Int32 nMatch
= FORMATETC_EXACT_MATCH
;
361 if (__builtin_setjmp(jmpbuf
) == 0)
363 han
.Set(jmpbuf
, NULL
, (__SEHandler::PF
)EXCEPTION_EXECUTE_HANDLER
);
368 if ( pFetcLhs
!= pFetcRhs
)
370 if ( ( pFetcLhs
->cfFormat
!= pFetcRhs
->cfFormat
) ||
371 ( pFetcLhs
->lindex
!= pFetcRhs
->lindex
) ||
372 !CompareTargetDevice( pFetcLhs
->ptd
, pFetcRhs
->ptd
) )
374 nMatch
= FORMATETC_NO_MATCH
;
377 else if ( pFetcLhs
->dwAspect
== pFetcRhs
->dwAspect
)
378 // same aspects; equal
380 else if ( ( pFetcLhs
->dwAspect
& ~pFetcRhs
->dwAspect
) != 0 )
382 // left not subset of aspects of right; not equal
383 nMatch
= FORMATETC_NO_MATCH
;
386 // left subset of right
387 nMatch
= FORMATETC_PARTIAL_MATCH
;
389 if ( nMatch
== FORMATETC_EXACT_MATCH
|| nMatch
== FORMATETC_PARTIAL_MATCH
)
391 if ( pFetcLhs
->tymed
== pFetcRhs
->tymed
)
392 // same medium flags; equal
394 else if ( ( pFetcLhs
->tymed
& ~pFetcRhs
->tymed
) != 0 )
396 // left not subset of medium flags of right; not equal
397 nMatch
= FORMATETC_NO_MATCH
;
400 // left subset of right
401 nMatch
= FORMATETC_PARTIAL_MATCH
;
408 __except( EXCEPTION_EXECUTE_HANDLER
)
411 OSL_FAIL( "Error CompareFormatEtc" );
412 nMatch
= FORMATETC_NO_MATCH
;
422 //-------------------------------------------------------------------------
424 //-------------------------------------------------------------------------
426 sal_Bool SAL_CALL
CompareTargetDevice( DVTARGETDEVICE
* ptdLeft
, DVTARGETDEVICE
* ptdRight
)
428 sal_Bool bRet
= sal_False
;
433 if (__builtin_setjmp(jmpbuf
) == 0)
435 han
.Set(jmpbuf
, NULL
, (__SEHandler::PF
)EXCEPTION_EXECUTE_HANDLER
);
440 if ( ptdLeft
== ptdRight
)
442 // same address of td; must be same (handles NULL case)
446 // one ot the two is NULL
447 else if ( ( NULL
!= ptdRight
) && ( NULL
!= ptdLeft
) )
449 if ( ptdLeft
->tdSize
== ptdRight
->tdSize
)
451 if ( memcmp( ptdLeft
, ptdRight
, ptdLeft
->tdSize
) == 0 )
457 __except( EXCEPTION_EXECUTE_HANDLER
)
460 OSL_FAIL( "Error CompareTargetDevice" );
470 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */