msi: Don't set the shortcut's working directory if it's NULL.
[wine] / dlls / winex11.drv / codepage.c
1 /*
2  * X11 codepage handling
3  *
4  * Copyright 2000 Hidenori Takeshima <hidenori@a2.ctktv.ne.jp>
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 "config.h"
22
23 #include <math.h>
24 #include <stdarg.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winnls.h"
29 #include "x11font.h"
30 #include "wine/debug.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(text);
33
34 /***********************************************************************
35  *           IsLegalDBCSChar for cp932/936/949/950/euc
36  */
37 static inline
38 int IsLegalDBCSChar_cp932( BYTE lead, BYTE trail )
39 {
40     return ( ( ( lead >= (BYTE)0x81 && lead <= (BYTE)0x9f ) ||
41                ( lead >= (BYTE)0xe0 && lead <= (BYTE)0xfc ) ) &&
42              ( ( trail >= (BYTE)0x40 && trail <= (BYTE)0x7e ) ||
43                ( trail >= (BYTE)0x80 && trail <= (BYTE)0xfc ) ) );
44 }
45
46 static inline
47 int IsLegalDBCSChar_cp936( BYTE lead, BYTE trail )
48 {
49     return ( ( lead >= (BYTE)0x81 && lead <= (BYTE)0xfe ) &&
50              ( trail >= (BYTE)0x40 && trail <= (BYTE)0xfe ) );
51 }
52
53 static inline
54 int IsLegalDBCSChar_cp949( BYTE lead, BYTE trail )
55 {
56     return ( ( lead >= (BYTE)0x81 && lead <= (BYTE)0xfe ) &&
57              ( trail >= (BYTE)0x41 && trail <= (BYTE)0xfe ) );
58 }
59
60 static inline
61 int IsLegalDBCSChar_cp950( BYTE lead, BYTE trail )
62 {
63     return (   ( lead >= (BYTE)0x81 && lead <= (BYTE)0xfe ) &&
64              ( ( trail >= (BYTE)0x40 && trail <= (BYTE)0x7e ) ||
65                ( trail >= (BYTE)0xa1 && trail <= (BYTE)0xfe ) ) );
66 }
67
68 static inline
69 int IsLegalDBCSChar_euc( BYTE lead, BYTE trail )
70 {
71     return ( ( lead >= (BYTE)0xa1 && lead <= (BYTE)0xfe ) &&
72              ( trail >= (BYTE)0xa1 && trail <= (BYTE)0xfe ) );
73 }
74
75
76 /***********************************************************************
77  *           DBCSCharToXChar2b for cp932/euc
78  */
79
80 static inline
81 void DBCSCharToXChar2b_cp932( XChar2b* pch, BYTE lead, BYTE trail )
82 {
83     unsigned int  high, low;
84
85     high = (unsigned int)lead;
86     low = (unsigned int)trail;
87
88     if ( high <= 0x9f )
89         high = (high<<1) - 0xe0;
90     else
91         high = (high<<1) - 0x160;
92     if ( low < 0x9f )
93     {
94         high --;
95         if ( low < 0x7f )
96             low -= 0x1f;
97         else
98             low -= 0x20;
99     }
100     else
101     {
102         low -= 0x7e;
103     }
104
105     pch->byte1 = (unsigned char)high;
106     pch->byte2 = (unsigned char)low;
107 }
108
109 static inline
110 void DBCSCharToXChar2b_euc( XChar2b* pch, BYTE lead, BYTE trail )
111 {
112     pch->byte1 = lead & (BYTE)0x7f;
113     pch->byte2 = trail & (BYTE)0x7f;
114 }
115
116
117
118
119 static WORD X11DRV_enum_subfont_charset_normal( UINT index )
120 {
121     return DEFAULT_CHARSET;
122 }
123
124 static WORD X11DRV_enum_subfont_charset_cp932( UINT index )
125 {
126     switch ( index )
127     {
128     case 0: return X11FONT_JISX0201_CHARSET;
129     case 1: return X11FONT_JISX0212_CHARSET;
130     }
131
132     return DEFAULT_CHARSET;
133 }
134
135 static WORD X11DRV_enum_subfont_charset_cp936( UINT index )
136 {
137     switch ( index )
138     {
139     case 0: return ANSI_CHARSET;
140     }
141
142     return DEFAULT_CHARSET;
143 }
144
145 static WORD X11DRV_enum_subfont_charset_cp949( UINT index )
146 {
147     switch ( index )
148     {
149     case 0: return ANSI_CHARSET;
150     }
151
152     return DEFAULT_CHARSET;
153 }
154
155 static WORD X11DRV_enum_subfont_charset_cp950( UINT index )
156 {
157     switch ( index )
158     {
159     case 0: return ANSI_CHARSET;
160     }
161
162     return DEFAULT_CHARSET;
163 }
164
165
166 static XChar2b* X11DRV_unicode_to_char2b_sbcs( fontObject* pfo,
167                                                LPCWSTR lpwstr, UINT count )
168 {
169     XChar2b *str2b;
170     UINT i;
171     char *str;
172     UINT codepage = pfo->fi->codepage;
173     char ch = pfo->fs->default_char;
174
175     if (!(str2b = HeapAlloc( GetProcessHeap(), 0, count * sizeof(XChar2b) )))
176         return NULL;
177     if (!(str = HeapAlloc( GetProcessHeap(), 0, count )))
178     {
179         HeapFree( GetProcessHeap(), 0, str2b );
180         return NULL;
181     }
182
183     WideCharToMultiByte( codepage, 0, lpwstr, count, str, count, &ch, NULL );
184
185     for (i = 0; i < count; i++)
186     {
187         str2b[i].byte1 = 0;
188         str2b[i].byte2 = str[i];
189     }
190     HeapFree( GetProcessHeap(), 0, str );
191
192     return str2b;
193 }
194
195 static XChar2b* X11DRV_unicode_to_char2b_unicode( fontObject* pfo,
196                                                   LPCWSTR lpwstr, UINT count )
197 {
198     XChar2b *str2b;
199     UINT i;
200
201     if (!(str2b = HeapAlloc( GetProcessHeap(), 0, count * sizeof(XChar2b) )))
202         return NULL;
203
204     for (i = 0; i < count; i++)
205     {
206         str2b[i].byte1 = lpwstr[i] >> 8;
207         str2b[i].byte2 = lpwstr[i] & 0xff;
208     }
209
210     return str2b;
211 }
212
213 /* FIXME: handle jisx0212.1990... */
214 static XChar2b* X11DRV_unicode_to_char2b_cp932( fontObject* pfo,
215                                                 LPCWSTR lpwstr, UINT count )
216 {
217     XChar2b *str2b;
218     XChar2b *str2b_dst;
219     char *str;
220     BYTE *str_src;
221     UINT i;
222     char ch = pfo->fs->default_char;
223
224     if (!(str2b = HeapAlloc( GetProcessHeap(), 0, count * sizeof(XChar2b) )))
225         return NULL;
226     if (!(str = HeapAlloc( GetProcessHeap(), 0, count*2 )))
227     {
228         HeapFree( GetProcessHeap(), 0, str2b );
229         return NULL;
230     }
231
232     /* handle jisx0212.1990... */
233     WideCharToMultiByte( 932, 0, lpwstr, count, str, count*2, &ch, NULL );
234
235     str_src = (BYTE*) str;
236     str2b_dst = str2b;
237     for (i = 0; i < count; i++, str_src++, str2b_dst++)
238     {
239         if ( IsLegalDBCSChar_cp932( *str_src, *(str_src+1) ) )
240         {
241             DBCSCharToXChar2b_cp932( str2b_dst, *str_src, *(str_src+1) );
242             str_src++;
243         }
244         else
245         {
246             str2b_dst->byte1 = 0;
247             str2b_dst->byte2 = *str_src;
248         }
249     }
250
251     HeapFree( GetProcessHeap(), 0, str );
252
253     return str2b;
254 }
255
256
257 static XChar2b* X11DRV_unicode_to_char2b_cp936( fontObject* pfo,
258                                                 LPCWSTR lpwstr, UINT count )
259 {
260     XChar2b *str2b;
261     XChar2b *str2b_dst;
262     char *str;
263     BYTE *str_src;
264     UINT i;
265     char ch = pfo->fs->default_char;
266
267     if (!(str2b = HeapAlloc( GetProcessHeap(), 0, count * sizeof(XChar2b) )))
268         return NULL;
269     if (!(str = HeapAlloc( GetProcessHeap(), 0, count*2 )))
270     {
271         HeapFree( GetProcessHeap(), 0, str2b );
272         return NULL;
273     }
274     WideCharToMultiByte( 936, 0, lpwstr, count, str, count*2, &ch, NULL );
275
276     str_src = (BYTE*) str;
277     str2b_dst = str2b;
278     for (i = 0; i < count; i++, str_src++, str2b_dst++)
279     {
280         if ( IsLegalDBCSChar_cp936( *str_src, *(str_src+1) ) )
281         {
282             str2b_dst->byte1 = *str_src;
283             str2b_dst->byte2 = *(str_src+1);
284             str_src++;
285         }
286         else
287         {
288             str2b_dst->byte1 = 0;
289             str2b_dst->byte2 = *str_src;
290         }
291     }
292
293     HeapFree( GetProcessHeap(), 0, str );
294
295     return str2b;
296 }
297
298 static XChar2b* X11DRV_unicode_to_char2b_cp949( fontObject* pfo,
299                                                 LPCWSTR lpwstr, UINT count )
300 {
301     XChar2b *str2b;
302     XChar2b *str2b_dst;
303     char *str;
304     BYTE *str_src;
305     UINT i;
306     char ch = pfo->fs->default_char;
307
308     if (!(str2b = HeapAlloc( GetProcessHeap(), 0, count * sizeof(XChar2b) )))
309         return NULL;
310     if (!(str = HeapAlloc( GetProcessHeap(), 0, count*2 )))
311     {
312         HeapFree( GetProcessHeap(), 0, str2b );
313         return NULL;
314     }
315     WideCharToMultiByte( 949, 0, lpwstr, count, str, count*2, &ch, NULL );
316
317     str_src = (BYTE*) str;
318     str2b_dst = str2b;
319     for (i = 0; i < count; i++, str_src++, str2b_dst++)
320     {
321         if ( IsLegalDBCSChar_cp949( *str_src, *(str_src+1) ) )
322         {
323             str2b_dst->byte1 = *str_src;
324             str2b_dst->byte2 = *(str_src+1);
325             str_src++;
326         }
327         else
328         {
329             str2b_dst->byte1 = 0;
330             str2b_dst->byte2 = *str_src;
331         }
332     }
333
334     HeapFree( GetProcessHeap(), 0, str );
335
336     return str2b;
337 }
338
339
340 static XChar2b* X11DRV_unicode_to_char2b_cp950( fontObject* pfo,
341                                                 LPCWSTR lpwstr, UINT count )
342 {
343     XChar2b *str2b;
344     XChar2b *str2b_dst;
345     char *str;
346     BYTE *str_src;
347     UINT i;
348     char ch = pfo->fs->default_char;
349
350     if (!(str2b = HeapAlloc( GetProcessHeap(), 0, count * sizeof(XChar2b) )))
351         return NULL;
352     if (!(str = HeapAlloc( GetProcessHeap(), 0, count*2 )))
353     {
354         HeapFree( GetProcessHeap(), 0, str2b );
355         return NULL;
356     }
357     WideCharToMultiByte( 950, 0, lpwstr, count, str, count*2, &ch, NULL );
358
359     str_src = (BYTE*) str;
360     str2b_dst = str2b;
361     for (i = 0; i < count; i++, str_src++, str2b_dst++)
362     {
363         if ( IsLegalDBCSChar_cp950( *str_src, *(str_src+1) ) )
364         {
365             str2b_dst->byte1 = *str_src;
366             str2b_dst->byte2 = *(str_src+1);
367             str_src++;
368         }
369         else
370         {
371             str2b_dst->byte1 = 0;
372             str2b_dst->byte2 = *str_src;
373         }
374     }
375
376     HeapFree( GetProcessHeap(), 0, str );
377
378     return str2b;
379 }
380
381 static XChar2b* X11DRV_unicode_to_char2b_symbol( fontObject* pfo,
382                                                  LPCWSTR lpwstr, UINT count )
383 {
384     XChar2b *str2b;
385     UINT i;
386     char ch = pfo->fs->default_char;
387
388     if (!(str2b = HeapAlloc( GetProcessHeap(), 0, count * sizeof(XChar2b) )))
389         return NULL;
390
391     for (i = 0; i < count; i++)
392     {
393         str2b[i].byte1 = 0;
394         if(lpwstr[i] >= 0xf000 && lpwstr[i] < 0xf100)
395             str2b[i].byte2 = lpwstr[i] - 0xf000;
396         else if(lpwstr[i] < 0x100)
397             str2b[i].byte2 = lpwstr[i];
398         else
399             str2b[i].byte2 = ch;
400     }
401
402     return str2b;
403 }
404
405
406 static void X11DRV_DrawString_normal( fontObject* pfo, Display* pdisp,
407                                       Drawable d, GC gc, int x, int y,
408                                       XChar2b* pstr, int count )
409 {
410     wine_tsx11_lock();
411     XDrawString16( pdisp, d, gc, x, y, pstr, count );
412     wine_tsx11_unlock();
413 }
414
415 static int X11DRV_TextWidth_normal( fontObject* pfo, XChar2b* pstr, int count )
416 {
417     int ret;
418     wine_tsx11_lock();
419     ret = XTextWidth16( pfo->fs, pstr, count );
420     wine_tsx11_unlock();
421     return ret;
422 }
423
424 static void X11DRV_DrawText_normal( fontObject* pfo, Display* pdisp, Drawable d,
425                                     GC gc, int x, int y, XTextItem16* pitems,
426                                     int count )
427 {
428     wine_tsx11_lock();
429     XDrawText16( pdisp, d, gc, x, y, pitems, count );
430     wine_tsx11_unlock();
431 }
432
433 static void X11DRV_TextExtents_normal( fontObject* pfo, XChar2b* pstr, int count,
434                                        int* pdir, int* pascent, int* pdescent,
435                                        int* pwidth, int max_extent, int* pfit,
436                                        int* partial_extents )
437 {
438     XCharStruct info;
439     int ascent, descent, width;
440     int i, fit;
441
442     width = 0;
443     fit = 0;
444     *pascent = 0;
445     *pdescent = 0;
446     wine_tsx11_lock();
447     for ( i = 0; i < count; i++ )
448     {
449         XTextExtents16( pfo->fs, pstr, 1, pdir, &ascent, &descent, &info );
450         if ( *pascent < ascent ) *pascent = ascent;
451         if ( *pdescent < descent ) *pdescent = descent;
452         width += info.width;
453         if ( partial_extents ) partial_extents[i] = width;
454         if ( width < max_extent ) fit++;
455
456         pstr++;
457     }
458     wine_tsx11_unlock();
459     *pwidth = width;
460     if ( pfit ) *pfit = fit;
461 }
462
463 static void X11DRV_GetTextMetricsW_normal( fontObject* pfo, LPTEXTMETRICW pTM )
464 {
465     LPIFONTINFO16 pdf = &pfo->fi->df;
466
467     if( ! pfo->lpX11Trans ) {
468       pTM->tmAscent = pfo->fs->ascent;
469       pTM->tmDescent = pfo->fs->descent;
470     } else {
471       pTM->tmAscent = pfo->lpX11Trans->ascent;
472       pTM->tmDescent = pfo->lpX11Trans->descent;
473     }
474
475     pTM->tmAscent *= pfo->rescale;
476     pTM->tmDescent *= pfo->rescale;
477
478     pTM->tmHeight = pTM->tmAscent + pTM->tmDescent;
479
480     pTM->tmAveCharWidth = pfo->foAvgCharWidth * pfo->rescale;
481     pTM->tmMaxCharWidth = pfo->foMaxCharWidth * pfo->rescale;
482
483     pTM->tmInternalLeading = pfo->foInternalLeading * pfo->rescale;
484     pTM->tmExternalLeading = pdf->dfExternalLeading * pfo->rescale;
485
486     pTM->tmStruckOut = (pfo->fo_flags & FO_SYNTH_STRIKEOUT )
487                         ? 1 : pdf->dfStrikeOut;
488     pTM->tmUnderlined = (pfo->fo_flags & FO_SYNTH_UNDERLINE )
489                         ? 1 : pdf->dfUnderline;
490
491     pTM->tmOverhang = 0;
492     if( pfo->fo_flags & FO_SYNTH_ITALIC )
493     {
494         pTM->tmOverhang += pTM->tmHeight/3;
495         pTM->tmItalic = 1;
496     } else
497         pTM->tmItalic = pdf->dfItalic;
498
499     pTM->tmWeight = pdf->dfWeight;
500     if( pfo->fo_flags & FO_SYNTH_BOLD )
501     {
502         pTM->tmOverhang++;
503         pTM->tmWeight += 100;
504     }
505
506     pTM->tmFirstChar = pdf->dfFirstChar;
507     pTM->tmLastChar = pdf->dfLastChar;
508     pTM->tmDefaultChar = pdf->dfDefaultChar;
509     pTM->tmBreakChar = pdf->dfBreakChar;
510
511     pTM->tmCharSet = pdf->dfCharSet;
512     pTM->tmPitchAndFamily = pdf->dfPitchAndFamily;
513
514     pTM->tmDigitizedAspectX = pdf->dfHorizRes;
515     pTM->tmDigitizedAspectY = pdf->dfVertRes;
516 }
517
518
519
520 static
521 void X11DRV_DrawString_dbcs( fontObject* pfo, Display* pdisp,
522                              Drawable d, GC gc, int x, int y,
523                              XChar2b* pstr, int count )
524 {
525     XTextItem16 item;
526
527     item.chars = pstr;
528     item.delta = 0;
529     item.nchars = count;
530     item.font = None;
531     X11DRV_cptable[pfo->fi->cptable].pDrawText(
532                 pfo, pdisp, d, gc, x, y, &item, 1 );
533 }
534
535 static
536 int X11DRV_TextWidth_dbcs_2fonts( fontObject* pfo, XChar2b* pstr, int count )
537 {
538     int i;
539     int width;
540     int curfont;
541     fontObject* pfos[X11FONT_REFOBJS_MAX+1];
542
543     pfos[0] = XFONT_GetFontObject( pfo->prefobjs[0] );
544     pfos[1] = pfo;
545     if ( pfos[0] == NULL ) pfos[0] = pfo;
546
547     width = 0;
548     wine_tsx11_lock();
549     for ( i = 0; i < count; i++ )
550     {
551         curfont = ( pstr->byte1 != 0 ) ? 1 : 0;
552         width += XTextWidth16( pfos[curfont]->fs, pstr, 1 );
553         pstr ++;
554     }
555     wine_tsx11_unlock();
556     return width;
557 }
558
559 static
560 void X11DRV_DrawText_dbcs_2fonts( fontObject* pfo, Display* pdisp, Drawable d,
561                                   GC gc, int x, int y, XTextItem16* pitems,
562                                   int count )
563 {
564     int i, nitems, prevfont = -1, curfont;
565     XChar2b* pstr;
566     XTextItem16* ptibuf;
567     XTextItem16* pti;
568     fontObject* pfos[X11FONT_REFOBJS_MAX+1];
569
570     pfos[0] = XFONT_GetFontObject( pfo->prefobjs[0] );
571     pfos[1] = pfo;
572     if ( pfos[0] == NULL ) pfos[0] = pfo;
573
574     nitems = 0;
575     for ( i = 0; i < count; i++ )
576         nitems += pitems->nchars;
577     ptibuf = HeapAlloc( GetProcessHeap(), 0, sizeof(XTextItem16) * nitems );
578     if ( ptibuf == NULL )
579         return; /* out of memory */
580
581     pti = ptibuf;
582     while ( count-- > 0 )
583     {
584         pti->chars = pstr = pitems->chars;
585         pti->delta = pitems->delta;
586         pti->font = None;
587         for ( i = 0; i < pitems->nchars; i++, pstr++ )
588         {
589             curfont = ( pstr->byte1 != 0 ) ? 1 : 0;
590             if ( curfont != prevfont )
591             {
592                 if ( pstr != pti->chars )
593                 {
594                     pti->nchars = pstr - pti->chars;
595                     pti ++;
596                     pti->chars = pstr;
597                     pti->delta = 0;
598                 }
599                 pti->font = pfos[curfont]->fs->fid;
600                 prevfont = curfont;
601             }
602         }
603         pti->nchars = pstr - pti->chars;
604         pitems ++; pti ++;
605     }
606     wine_tsx11_lock();
607     XDrawText16( pdisp, d, gc, x, y, ptibuf, pti - ptibuf );
608     wine_tsx11_unlock();
609     HeapFree( GetProcessHeap(), 0, ptibuf );
610 }
611
612 static
613 void X11DRV_TextExtents_dbcs_2fonts( fontObject* pfo, XChar2b* pstr, int count,
614                                      int* pdir, int* pascent, int* pdescent,
615                                      int* pwidth, int max_extent, int* pfit,
616                                      int* partial_extents )
617 {
618     XCharStruct info;
619     int ascent, descent, width;
620     int i;
621     int fit;
622     int curfont;
623     fontObject* pfos[X11FONT_REFOBJS_MAX+1];
624
625     pfos[0] = XFONT_GetFontObject( pfo->prefobjs[0] );
626     pfos[1] = pfo;
627     if ( pfos[0] == NULL ) pfos[0] = pfo;
628
629     width = 0;
630     fit = 0;
631     *pascent = 0;
632     *pdescent = 0;
633     wine_tsx11_lock();
634     for ( i = 0; i < count; i++ )
635     {
636         curfont = ( pstr->byte1 != 0 ) ? 1 : 0;
637         XTextExtents16( pfos[curfont]->fs, pstr, 1, pdir, &ascent, &descent, &info );
638         if ( *pascent < ascent ) *pascent = ascent;
639         if ( *pdescent < descent ) *pdescent = descent;
640         width += info.width;
641         if ( partial_extents ) partial_extents[i] = width;
642         if ( width <= max_extent ) fit++;
643
644         pstr ++;
645     }
646     wine_tsx11_unlock();
647     *pwidth = width;
648     if ( pfit ) *pfit = fit;
649 }
650
651 static void X11DRV_GetTextMetricsW_cp932( fontObject* pfo, LPTEXTMETRICW pTM )
652 {
653     fontObject* pfo_ansi = XFONT_GetFontObject( pfo->prefobjs[0] );
654     LPIFONTINFO16 pdf = &pfo->fi->df;
655     LPIFONTINFO16 pdf_ansi;
656
657     pdf_ansi = ( pfo_ansi != NULL ) ? (&pfo_ansi->fi->df) : pdf;
658
659     if( ! pfo->lpX11Trans ) {
660       pTM->tmAscent = pfo->fs->ascent;
661       pTM->tmDescent = pfo->fs->descent;
662     } else {
663       pTM->tmAscent = pfo->lpX11Trans->ascent;
664       pTM->tmDescent = pfo->lpX11Trans->descent;
665     }
666
667     pTM->tmAscent *= pfo->rescale;
668     pTM->tmDescent *= pfo->rescale;
669
670     pTM->tmHeight = pTM->tmAscent + pTM->tmDescent;
671
672     if ( pfo_ansi != NULL )
673     {
674         pTM->tmAveCharWidth = floor((pfo_ansi->foAvgCharWidth * 2.0 + pfo->foAvgCharWidth) / 3.0 * pfo->rescale + 0.5);
675         pTM->tmMaxCharWidth = max(pfo_ansi->foMaxCharWidth, pfo->foMaxCharWidth) * pfo->rescale;
676     }
677     else
678     {
679         pTM->tmAveCharWidth = floor((pfo->foAvgCharWidth * pfo->rescale + 1.0) / 2.0);
680         pTM->tmMaxCharWidth = pfo->foMaxCharWidth * pfo->rescale;
681     }
682
683     pTM->tmInternalLeading = pfo->foInternalLeading * pfo->rescale;
684     pTM->tmExternalLeading = pdf->dfExternalLeading * pfo->rescale;
685
686     pTM->tmStruckOut = (pfo->fo_flags & FO_SYNTH_STRIKEOUT )
687                         ? 1 : pdf->dfStrikeOut;
688     pTM->tmUnderlined = (pfo->fo_flags & FO_SYNTH_UNDERLINE )
689                         ? 1 : pdf->dfUnderline;
690
691     pTM->tmOverhang = 0;
692     if( pfo->fo_flags & FO_SYNTH_ITALIC )
693     {
694         pTM->tmOverhang += pTM->tmHeight/3;
695         pTM->tmItalic = 1;
696     } else
697         pTM->tmItalic = pdf->dfItalic;
698
699     pTM->tmWeight = pdf->dfWeight;
700     if( pfo->fo_flags & FO_SYNTH_BOLD )
701     {
702         pTM->tmOverhang++;
703         pTM->tmWeight += 100;
704     }
705
706     pTM->tmFirstChar = pdf_ansi->dfFirstChar;
707     pTM->tmLastChar = pdf_ansi->dfLastChar;
708     pTM->tmDefaultChar = pdf_ansi->dfDefaultChar;
709     pTM->tmBreakChar = pdf_ansi->dfBreakChar;
710
711     pTM->tmCharSet = pdf->dfCharSet;
712     pTM->tmPitchAndFamily = pdf->dfPitchAndFamily;
713
714     pTM->tmDigitizedAspectX = pdf->dfHorizRes;
715     pTM->tmDigitizedAspectY = pdf->dfVertRes;
716 }
717
718
719
720
721
722 const X11DRV_CP X11DRV_cptable[X11DRV_CPTABLE_COUNT] =
723 {
724     { /* SBCS */
725         X11DRV_enum_subfont_charset_normal,
726         X11DRV_unicode_to_char2b_sbcs,
727         X11DRV_DrawString_normal,
728         X11DRV_TextWidth_normal,
729         X11DRV_DrawText_normal,
730         X11DRV_TextExtents_normal,
731         X11DRV_GetTextMetricsW_normal,
732     },
733     { /* UNICODE */
734         X11DRV_enum_subfont_charset_normal,
735         X11DRV_unicode_to_char2b_unicode,
736         X11DRV_DrawString_normal,
737         X11DRV_TextWidth_normal,
738         X11DRV_DrawText_normal,
739         X11DRV_TextExtents_normal,
740         X11DRV_GetTextMetricsW_normal,
741     },
742     { /* CP932 */
743         X11DRV_enum_subfont_charset_cp932,
744         X11DRV_unicode_to_char2b_cp932,
745         X11DRV_DrawString_dbcs,
746         X11DRV_TextWidth_dbcs_2fonts,
747         X11DRV_DrawText_dbcs_2fonts,
748         X11DRV_TextExtents_dbcs_2fonts,
749         X11DRV_GetTextMetricsW_cp932,
750     },
751     { /* CP936 */
752         X11DRV_enum_subfont_charset_cp936,
753         X11DRV_unicode_to_char2b_cp936,
754         X11DRV_DrawString_dbcs,
755         X11DRV_TextWidth_dbcs_2fonts,
756         X11DRV_DrawText_dbcs_2fonts,
757         X11DRV_TextExtents_dbcs_2fonts,
758         X11DRV_GetTextMetricsW_normal, /* FIXME */
759     },
760     { /* CP949 */
761         X11DRV_enum_subfont_charset_cp949,
762         X11DRV_unicode_to_char2b_cp949,
763         X11DRV_DrawString_dbcs,
764         X11DRV_TextWidth_dbcs_2fonts,
765         X11DRV_DrawText_dbcs_2fonts,
766         X11DRV_TextExtents_dbcs_2fonts,
767         X11DRV_GetTextMetricsW_normal, /* FIXME */
768     },
769     { /* CP950 */
770         X11DRV_enum_subfont_charset_cp950,
771         X11DRV_unicode_to_char2b_cp950,
772         X11DRV_DrawString_dbcs,
773         X11DRV_TextWidth_dbcs_2fonts,
774         X11DRV_DrawText_dbcs_2fonts,
775         X11DRV_TextExtents_dbcs_2fonts,
776         X11DRV_GetTextMetricsW_cp932,
777     },
778     { /* SYMBOL */
779         X11DRV_enum_subfont_charset_normal,
780         X11DRV_unicode_to_char2b_symbol,
781         X11DRV_DrawString_normal,
782         X11DRV_TextWidth_normal,
783         X11DRV_DrawText_normal,
784         X11DRV_TextExtents_normal,
785         X11DRV_GetTextMetricsW_normal,
786     }
787 };