devenum: Split the translations into separate resource files.
[wine] / dlls / gdi32 / mfdrv / text.c
1 /*
2  * metafile driver text functions
3  *
4  * Copyright 1993, 1994 Alexandre Julliard
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include <stdarg.h>
22 #include <string.h>
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "wine/wingdi16.h"
27 #include "mfdrv/metafiledrv.h"
28 #include "wine/debug.h"
29
30 WINE_DEFAULT_DEBUG_CHANNEL(metafile);
31
32
33 /******************************************************************
34  *         MFDRV_MetaExtTextOut
35  */
36 static BOOL MFDRV_MetaExtTextOut( PHYSDEV dev, short x, short y, UINT16 flags,
37                                  const RECT16 *rect, LPCSTR str, short count,
38                                  const INT16 *lpDx)
39 {
40     BOOL ret;
41     DWORD len;
42     METARECORD *mr;
43     BOOL isrect = flags & (ETO_CLIPPED | ETO_OPAQUE);
44
45     len = sizeof(METARECORD) + (((count + 1) >> 1) * 2) + 2 * sizeof(short)
46             + sizeof(UINT16);
47     if (isrect)
48         len += sizeof(RECT16);
49     if (lpDx)
50      len+=count*sizeof(INT16);
51     if (!(mr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len)))
52         return FALSE;
53
54     mr->rdSize = len / 2;
55     mr->rdFunction = META_EXTTEXTOUT;
56     *(mr->rdParm) = y;
57     *(mr->rdParm + 1) = x;
58     *(mr->rdParm + 2) = count;
59     *(mr->rdParm + 3) = flags;
60     if (isrect) memcpy(mr->rdParm + 4, rect, sizeof(RECT16));
61     memcpy(mr->rdParm + (isrect ? 8 : 4), str, count);
62     if (lpDx)
63      memcpy(mr->rdParm + (isrect ? 8 : 4) + ((count + 1) >> 1),lpDx,
64       count*sizeof(INT16));
65     ret = MFDRV_WriteRecord( dev, mr, mr->rdSize * 2);
66     HeapFree( GetProcessHeap(), 0, mr);
67     return ret;
68 }
69
70
71
72 /***********************************************************************
73  *           MFDRV_ExtTextOut
74  */
75 BOOL CDECL
76 MFDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags,
77                   const RECT *lprect, LPCWSTR str, UINT count,
78                   const INT *lpDx )
79 {
80     RECT16      rect16;
81     LPINT16     lpdx16 = NULL;
82     BOOL        ret;
83     unsigned int i, j;
84     LPSTR       ascii;
85     DWORD len;
86     CHARSETINFO csi;
87     METAFILEDRV_PDEVICE *physDev = (METAFILEDRV_PDEVICE *)dev;
88     int charset = GetTextCharset(physDev->hdc);
89     UINT cp = CP_ACP;
90
91     if(TranslateCharsetInfo(ULongToPtr(charset), &csi, TCI_SRCCHARSET))
92         cp = csi.ciACP;
93     else {
94         switch(charset) {
95         case OEM_CHARSET:
96             cp = GetOEMCP();
97             break;
98         case DEFAULT_CHARSET:
99             cp = GetACP();
100             break;
101
102         case VISCII_CHARSET:
103         case TCVN_CHARSET:
104         case KOI8_CHARSET:
105         case ISO3_CHARSET:
106         case ISO4_CHARSET:
107         case ISO10_CHARSET:
108         case CELTIC_CHARSET:
109           /* FIXME: These have no place here, but because x11drv
110              enumerates fonts with these (made up) charsets some apps
111              might use them and then the FIXME below would become
112              annoying.  Now we could pick the intended codepage for
113              each of these, but since it's broken anyway we'll just
114              use CP_ACP and hope it'll go away...
115           */
116             cp = CP_ACP;
117             break;
118
119
120         default:
121             FIXME("Can't find codepage for charset %d\n", charset);
122             break;
123         }
124     }
125
126
127     TRACE("cp == %d\n", cp);
128     len = WideCharToMultiByte(cp, 0, str, count, NULL, 0, NULL, NULL);
129     ascii = HeapAlloc(GetProcessHeap(), 0, len);
130     WideCharToMultiByte(cp, 0, str, count, ascii, len, NULL, NULL);
131     TRACE("mapped %s -> %s\n", debugstr_wn(str, count), debugstr_an(ascii, len));
132
133
134     if (lprect)
135     {
136         rect16.left   = lprect->left;
137         rect16.top    = lprect->top;
138         rect16.right  = lprect->right;
139         rect16.bottom = lprect->bottom;
140     }
141
142     if(lpDx) {
143         lpdx16 = HeapAlloc( GetProcessHeap(), 0, sizeof(INT16)*len );
144         for(i = j = 0; i < len; )
145             if(IsDBCSLeadByteEx(cp, ascii[i])) {
146                 lpdx16[i++] = lpDx[j++];
147                 lpdx16[i++] = 0;
148             } else
149                 lpdx16[i++] = lpDx[j++];
150     }
151
152     ret = MFDRV_MetaExtTextOut(dev,x,y,flags,lprect?&rect16:NULL,ascii,len,lpdx16);
153     HeapFree( GetProcessHeap(), 0, ascii );
154     HeapFree( GetProcessHeap(), 0, lpdx16 );
155     return ret;
156 }