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)
36 #define FORMATETC_EXACT_MATCH 1
37 #define FORMATETC_PARTIAL_MATCH -1
38 #define FORMATETC_NO_MATCH 0
40 // returns a windows codepage appropriate to the
41 // given mime charset parameter value
43 sal_uInt32 SAL_CALL
getWinCPFromMimeCharset( const OUString
& charset
)
45 sal_uInt32 winCP
= GetACP( );
47 if ( charset
.getLength( ) )
50 charset
.getStr( ), charset
.getLength( ), RTL_TEXTENCODING_ASCII_US
);
52 rtl_TextEncoding txtEnc
=
53 rtl_getTextEncodingFromMimeCharset( osCharset
.getStr( ) );
55 sal_uIntPtr winChrs
= rtl_getBestWindowsCharsetFromTextEncoding( txtEnc
);
58 bool bRet
= TranslateCharsetInfo( reinterpret_cast<DWORD
*>(winChrs
), &chrsInf
, TCI_SRCCHARSET
);
60 // if one of the above functions fails
61 // we will return the current ANSI codepage
64 winCP
= chrsInf
.ciACP
;
70 // returns a windows codepage appropriate to the
71 // given locale and locale type
73 OUString SAL_CALL
getWinCPFromLocaleId( LCID lcid
, LCTYPE lctype
)
75 OSL_ASSERT( IsValidLocale( lcid
, LCID_SUPPORTED
) );
77 // we set an default value
80 // set an default value
81 if ( LOCALE_IDEFAULTCODEPAGE
== lctype
)
83 winCP
= OUString::number( static_cast<sal_Int32
>(GetOEMCP( )) );
85 else if ( LOCALE_IDEFAULTANSICODEPAGE
== lctype
)
87 winCP
= OUString::number( static_cast<sal_Int32
>(GetACP( )) );
92 // we use the GetLocaleInfoA because don't want to provide
93 // a unicode wrapper function for Win9x in sal/systools
95 sal_Int32 nResult
= GetLocaleInfoA(
96 lcid
, lctype
| LOCALE_USE_CP_ACP
, buff
, sizeof( buff
) );
98 OSL_ASSERT( nResult
);
102 sal_Int32 len
= MultiByteToWideChar(
103 CP_ACP
, 0, buff
, -1, nullptr, 0 );
105 OSL_ASSERT( len
> 0 );
107 std::vector
< sal_Unicode
> lpwchBuff(len
);
109 len
= MultiByteToWideChar(
110 CP_ACP
, 0, buff
, -1, reinterpret_cast<LPWSTR
>(&lpwchBuff
[0]), len
);
112 winCP
= OUString( &lpwchBuff
[0], (len
- 1) );
118 // returns a mime charset parameter value appropriate
119 // to the given codepage, optional a prefix can be
120 // given, e.g. "windows-" or "cp"
122 OUString SAL_CALL
getMimeCharsetFromWinCP( sal_uInt32 cp
, const OUString
& aPrefix
)
124 return aPrefix
+ cptostr( cp
);
127 // returns a mime charset parameter value appropriate
128 // to the given locale id and locale type, optional a
129 // prefix can be given, e.g. "windows-" or "cp"
131 OUString SAL_CALL
getMimeCharsetFromLocaleId( LCID lcid
, LCTYPE lctype
, const OUString
& aPrefix
)
133 OUString charset
= getWinCPFromLocaleId( lcid
, lctype
);
134 return aPrefix
+ charset
;
139 bool SAL_CALL
IsOEMCP( sal_uInt32 codepage
)
141 OSL_ASSERT( IsValidCodePage( codepage
) );
143 sal_uInt32 arrOEMCP
[] = { 437, 708, 709, 710, 720, 737,
144 775, 850, 852, 855, 857, 860,
145 861, 862, 863, 864, 865, 866,
146 869, 874, 932, 936, 949, 950, 1361 };
148 for ( size_t i
= 0; i
< SAL_N_ELEMENTS( arrOEMCP
); ++i
)
149 if ( arrOEMCP
[i
] == codepage
)
155 // converts a codepage into its string representation
157 OUString SAL_CALL
cptostr( sal_uInt32 codepage
)
159 OSL_ASSERT( IsValidCodePage( codepage
) );
161 return OUString::number( static_cast<sal_Int64
>( codepage
) );
164 // OleStdDeleteTargetDevice()
171 // SCODE - S_OK if successful
172 void SAL_CALL
DeleteTargetDevice( DVTARGETDEVICE
* ptd
)
176 CoTaskMemFree( ptd
);
178 __except( EXCEPTION_EXECUTE_HANDLER
)
180 OSL_FAIL( "Error DeleteTargetDevice" );
184 // OleStdCopyTargetDevice()
187 // duplicate a TARGETDEVICE struct. this function allocates memory for
188 // the copy. the caller MUST free the allocated copy when done with it
189 // using the standard allocator returned from CoGetMalloc.
190 // (OleStdFree can be used to free the copy).
193 // ptdSrc pointer to source TARGETDEVICE
196 // pointer to allocated copy of ptdSrc
197 // if ptdSrc==NULL then returns NULL is returned.
198 // if ptdSrc!=NULL and memory allocation fails, then NULL is returned
199 DVTARGETDEVICE
* SAL_CALL
CopyTargetDevice( DVTARGETDEVICE
* ptdSrc
)
201 DVTARGETDEVICE
* ptdDest
= nullptr;
205 if ( nullptr != ptdSrc
)
207 ptdDest
= static_cast< DVTARGETDEVICE
* >( CoTaskMemAlloc( ptdSrc
->tdSize
) );
208 memcpy( ptdDest
, ptdSrc
, static_cast< size_t >( ptdSrc
->tdSize
) );
211 __except( EXCEPTION_EXECUTE_HANDLER
)
218 // OleStdCopyFormatEtc()
221 // Copies the contents of a FORMATETC structure. this function takes
222 // special care to copy correctly copying the pointer to the TARGETDEVICE
223 // contained within the source FORMATETC structure.
224 // if the source FORMATETC has a non-NULL TARGETDEVICE, then a copy
225 // of the TARGETDEVICE will be allocated for the destination of the
226 // FORMATETC (petcDest).
228 // NOTE: the caller MUST free the allocated copy of the TARGETDEVICE
229 // within the destination FORMATETC when done with it
230 // using the standard allocator returned from CoGetMalloc.
231 // (OleStdFree can be used to free the copy).
234 // petcDest pointer to destination FORMATETC
235 // petcSrc pointer to source FORMATETC
238 // returns TRUE if copy was successful;
239 // returns FALSE if not successful, e.g. one or both of the pointers
240 // were invalid or the pointers were equal
241 bool SAL_CALL
CopyFormatEtc( LPFORMATETC petcDest
, LPFORMATETC petcSrc
)
247 if ( petcDest
!= petcSrc
)
250 petcDest
->cfFormat
= petcSrc
->cfFormat
;
252 petcDest
->ptd
= nullptr;
253 if ( nullptr != petcSrc
->ptd
)
254 petcDest
->ptd
= CopyTargetDevice(petcSrc
->ptd
);
256 petcDest
->dwAspect
= petcSrc
->dwAspect
;
257 petcDest
->lindex
= petcSrc
->lindex
;
258 petcDest
->tymed
= petcSrc
->tymed
;
263 __except( EXCEPTION_EXECUTE_HANDLER
)
265 OSL_FAIL( "Error CopyFormatEtc" );
272 // 1 for exact match,
274 // -1 for partial match (which is defined to mean the left is a subset
275 // of the right: fewer aspects, null target device, fewer medium).
277 sal_Int32 SAL_CALL
CompareFormatEtc( const FORMATETC
* pFetcLhs
, const FORMATETC
* pFetcRhs
)
279 sal_Int32 nMatch
= FORMATETC_EXACT_MATCH
;
283 if ( pFetcLhs
!= pFetcRhs
)
285 if ( ( pFetcLhs
->cfFormat
!= pFetcRhs
->cfFormat
) ||
286 ( pFetcLhs
->lindex
!= pFetcRhs
->lindex
) ||
287 !CompareTargetDevice( pFetcLhs
->ptd
, pFetcRhs
->ptd
) )
289 nMatch
= FORMATETC_NO_MATCH
;
292 else if ( pFetcLhs
->dwAspect
== pFetcRhs
->dwAspect
)
293 // same aspects; equal
295 else if ( ( pFetcLhs
->dwAspect
& ~pFetcRhs
->dwAspect
) != 0 )
297 // left not subset of aspects of right; not equal
298 nMatch
= FORMATETC_NO_MATCH
;
301 // left subset of right
302 nMatch
= FORMATETC_PARTIAL_MATCH
;
304 if ( nMatch
== FORMATETC_EXACT_MATCH
|| nMatch
== FORMATETC_PARTIAL_MATCH
)
306 if ( pFetcLhs
->tymed
== pFetcRhs
->tymed
)
307 // same medium flags; equal
309 else if ( ( pFetcLhs
->tymed
& ~pFetcRhs
->tymed
) != 0 )
311 // left not subset of medium flags of right; not equal
312 nMatch
= FORMATETC_NO_MATCH
;
315 // left subset of right
316 nMatch
= FORMATETC_PARTIAL_MATCH
;
320 __except( EXCEPTION_EXECUTE_HANDLER
)
322 OSL_FAIL( "Error CompareFormatEtc" );
323 nMatch
= FORMATETC_NO_MATCH
;
329 bool SAL_CALL
CompareTargetDevice( DVTARGETDEVICE
* ptdLeft
, DVTARGETDEVICE
* ptdRight
)
335 if ( ptdLeft
== ptdRight
)
337 // same address of td; must be same (handles NULL case)
341 // one ot the two is NULL
342 else if ( ( nullptr != ptdRight
) && ( nullptr != ptdLeft
) )
344 if ( ptdLeft
->tdSize
== ptdRight
->tdSize
)
346 if ( memcmp( ptdLeft
, ptdRight
, ptdLeft
->tdSize
) == 0 )
349 __except( EXCEPTION_EXECUTE_HANDLER
)
351 OSL_FAIL( "Error CompareTargetDevice" );
358 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */