2 * X11 codepage handling
4 * Copyright 2000 Hidenori Takeshima <hidenori@a2.ctktv.ne.jp>
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(text
);
36 /***********************************************************************
37 * IsLegalDBCSChar for cp932/936/949/950/euc
40 int IsLegalDBCSChar_cp932( BYTE lead
, BYTE trail
)
42 return ( ( ( lead
>= (BYTE
)0x81 && lead
<= (BYTE
)0x9f ) ||
43 ( lead
>= (BYTE
)0xe0 && lead
<= (BYTE
)0xfc ) ) &&
44 ( ( trail
>= (BYTE
)0x40 && trail
<= (BYTE
)0x7e ) ||
45 ( trail
>= (BYTE
)0x80 && trail
<= (BYTE
)0xfc ) ) );
49 int IsLegalDBCSChar_cp936( BYTE lead
, BYTE trail
)
51 return ( ( lead
>= (BYTE
)0x81 && lead
<= (BYTE
)0xfe ) &&
52 ( trail
>= (BYTE
)0x40 && trail
<= (BYTE
)0xfe ) );
56 int IsLegalDBCSChar_cp949( BYTE lead
, BYTE trail
)
58 return ( ( lead
>= (BYTE
)0x81 && lead
<= (BYTE
)0xfe ) &&
59 ( trail
>= (BYTE
)0x41 && trail
<= (BYTE
)0xfe ) );
63 int IsLegalDBCSChar_cp950( BYTE lead
, BYTE trail
)
65 return ( ( lead
>= (BYTE
)0x81 && lead
<= (BYTE
)0xfe ) &&
66 ( ( trail
>= (BYTE
)0x40 && trail
<= (BYTE
)0x7e ) ||
67 ( trail
>= (BYTE
)0xa1 && trail
<= (BYTE
)0xfe ) ) );
71 int IsLegalDBCSChar_euc( BYTE lead
, BYTE trail
)
73 return ( ( lead
>= (BYTE
)0xa1 && lead
<= (BYTE
)0xfe ) &&
74 ( trail
>= (BYTE
)0xa1 && trail
<= (BYTE
)0xfe ) );
78 /***********************************************************************
79 * DBCSCharToXChar2b for cp932/euc
83 void DBCSCharToXChar2b_cp932( XChar2b
* pch
, BYTE lead
, BYTE trail
)
85 unsigned int high
, low
;
87 high
= (unsigned int)lead
;
88 low
= (unsigned int)trail
;
91 high
= (high
<<1) - 0xe0;
93 high
= (high
<<1) - 0x160;
107 pch
->byte1
= (unsigned char)high
;
108 pch
->byte2
= (unsigned char)low
;
112 void DBCSCharToXChar2b_euc( XChar2b
* pch
, BYTE lead
, BYTE trail
)
114 pch
->byte1
= lead
& (BYTE
)0x7f;
115 pch
->byte2
= trail
& (BYTE
)0x7f;
121 static WORD
X11DRV_enum_subfont_charset_normal( UINT index
)
123 return DEFAULT_CHARSET
;
126 static WORD
X11DRV_enum_subfont_charset_cp932( UINT index
)
130 case 0: return X11FONT_JISX0201_CHARSET
;
131 case 1: return X11FONT_JISX0212_CHARSET
;
134 return DEFAULT_CHARSET
;
137 static WORD
X11DRV_enum_subfont_charset_cp936( UINT index
)
141 case 0: return ANSI_CHARSET
;
144 return DEFAULT_CHARSET
;
147 static WORD
X11DRV_enum_subfont_charset_cp949( UINT index
)
151 case 0: return ANSI_CHARSET
;
154 return DEFAULT_CHARSET
;
157 static WORD
X11DRV_enum_subfont_charset_cp950( UINT index
)
161 case 0: return ANSI_CHARSET
;
164 return DEFAULT_CHARSET
;
168 static XChar2b
* X11DRV_unicode_to_char2b_sbcs( fontObject
* pfo
,
169 LPCWSTR lpwstr
, UINT count
)
174 UINT codepage
= pfo
->fi
->codepage
;
175 char ch
= pfo
->fs
->default_char
;
177 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
179 if (!(str
= HeapAlloc( GetProcessHeap(), 0, count
)))
181 HeapFree( GetProcessHeap(), 0, str2b
);
185 WideCharToMultiByte( codepage
, 0, lpwstr
, count
, str
, count
, &ch
, NULL
);
187 for (i
= 0; i
< count
; i
++)
190 str2b
[i
].byte2
= str
[i
];
192 HeapFree( GetProcessHeap(), 0, str
);
197 static XChar2b
* X11DRV_unicode_to_char2b_unicode( fontObject
* pfo
,
198 LPCWSTR lpwstr
, UINT count
)
203 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
206 for (i
= 0; i
< count
; i
++)
208 str2b
[i
].byte1
= lpwstr
[i
] >> 8;
209 str2b
[i
].byte2
= lpwstr
[i
] & 0xff;
215 /* FIXME: handle jisx0212.1990... */
216 static XChar2b
* X11DRV_unicode_to_char2b_cp932( fontObject
* pfo
,
217 LPCWSTR lpwstr
, UINT count
)
224 char ch
= pfo
->fs
->default_char
;
226 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
228 if (!(str
= HeapAlloc( GetProcessHeap(), 0, count
*2 )))
230 HeapFree( GetProcessHeap(), 0, str2b
);
234 /* handle jisx0212.1990... */
235 WideCharToMultiByte( 932, 0, lpwstr
, count
, str
, count
*2, &ch
, NULL
);
239 for (i
= 0; i
< count
; i
++, str_src
++, str2b_dst
++)
241 if ( IsLegalDBCSChar_cp932( *str_src
, *(str_src
+1) ) )
243 DBCSCharToXChar2b_cp932( str2b_dst
, *str_src
, *(str_src
+1) );
248 str2b_dst
->byte1
= 0;
249 str2b_dst
->byte2
= *str_src
;
253 HeapFree( GetProcessHeap(), 0, str
);
259 static XChar2b
* X11DRV_unicode_to_char2b_cp936( fontObject
* pfo
,
260 LPCWSTR lpwstr
, UINT count
)
267 char ch
= pfo
->fs
->default_char
;
269 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
271 if (!(str
= HeapAlloc( GetProcessHeap(), 0, count
*2 )))
273 HeapFree( GetProcessHeap(), 0, str2b
);
276 WideCharToMultiByte( 936, 0, lpwstr
, count
, str
, count
*2, &ch
, NULL
);
280 for (i
= 0; i
< count
; i
++, str_src
++, str2b_dst
++)
282 if ( IsLegalDBCSChar_cp936( *str_src
, *(str_src
+1) ) )
284 str2b_dst
->byte1
= *str_src
;
285 str2b_dst
->byte2
= *(str_src
+1);
290 str2b_dst
->byte1
= 0;
291 str2b_dst
->byte2
= *str_src
;
295 HeapFree( GetProcessHeap(), 0, str
);
300 static XChar2b
* X11DRV_unicode_to_char2b_cp949( fontObject
* pfo
,
301 LPCWSTR lpwstr
, UINT count
)
308 char ch
= pfo
->fs
->default_char
;
310 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
312 if (!(str
= HeapAlloc( GetProcessHeap(), 0, count
*2 )))
314 HeapFree( GetProcessHeap(), 0, str2b
);
317 WideCharToMultiByte( 949, 0, lpwstr
, count
, str
, count
*2, &ch
, NULL
);
321 for (i
= 0; i
< count
; i
++, str_src
++, str2b_dst
++)
323 if ( IsLegalDBCSChar_cp949( *str_src
, *(str_src
+1) ) )
325 str2b_dst
->byte1
= *str_src
;
326 str2b_dst
->byte2
= *(str_src
+1);
331 str2b_dst
->byte1
= 0;
332 str2b_dst
->byte2
= *str_src
;
336 HeapFree( GetProcessHeap(), 0, str
);
342 static XChar2b
* X11DRV_unicode_to_char2b_cp950( fontObject
* pfo
,
343 LPCWSTR lpwstr
, UINT count
)
350 char ch
= pfo
->fs
->default_char
;
352 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
354 if (!(str
= HeapAlloc( GetProcessHeap(), 0, count
*2 )))
356 HeapFree( GetProcessHeap(), 0, str2b
);
359 WideCharToMultiByte( 950, 0, lpwstr
, count
, str
, count
*2, &ch
, NULL
);
363 for (i
= 0; i
< count
; i
++, str_src
++, str2b_dst
++)
365 if ( IsLegalDBCSChar_cp950( *str_src
, *(str_src
+1) ) )
367 str2b_dst
->byte1
= *str_src
;
368 str2b_dst
->byte2
= *(str_src
+1);
373 str2b_dst
->byte1
= 0;
374 str2b_dst
->byte2
= *str_src
;
378 HeapFree( GetProcessHeap(), 0, str
);
383 static XChar2b
* X11DRV_unicode_to_char2b_symbol( fontObject
* pfo
,
384 LPCWSTR lpwstr
, UINT count
)
388 char ch
= pfo
->fs
->default_char
;
390 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
393 for (i
= 0; i
< count
; i
++)
396 if(lpwstr
[i
] >= 0xf000 && lpwstr
[i
] < 0xf100)
397 str2b
[i
].byte2
= lpwstr
[i
] - 0xf000;
398 else if(lpwstr
[i
] < 0x100)
399 str2b
[i
].byte2
= lpwstr
[i
];
408 static void X11DRV_DrawString_normal( fontObject
* pfo
, Display
* pdisp
,
409 Drawable d
, GC gc
, int x
, int y
,
410 XChar2b
* pstr
, int count
)
412 TSXDrawString16( pdisp
, d
, gc
, x
, y
, pstr
, count
);
415 static int X11DRV_TextWidth_normal( fontObject
* pfo
, XChar2b
* pstr
, int count
)
417 return TSXTextWidth16( pfo
->fs
, pstr
, count
);
420 static void X11DRV_DrawText_normal( fontObject
* pfo
, Display
* pdisp
, Drawable d
,
421 GC gc
, int x
, int y
, XTextItem16
* pitems
,
424 TSXDrawText16( pdisp
, d
, gc
, x
, y
, pitems
, count
);
427 static void X11DRV_TextExtents_normal( fontObject
* pfo
, XChar2b
* pstr
, int count
,
428 int* pdir
, int* pascent
, int* pdescent
,
433 TSXTextExtents16( pfo
->fs
, pstr
, count
, pdir
, pascent
, pdescent
, &info
);
434 *pwidth
= info
.width
;
437 static void X11DRV_GetTextMetricsW_normal( fontObject
* pfo
, LPTEXTMETRICW pTM
)
439 LPIFONTINFO16 pdf
= &pfo
->fi
->df
;
441 if( ! pfo
->lpX11Trans
) {
442 pTM
->tmAscent
= pfo
->fs
->ascent
;
443 pTM
->tmDescent
= pfo
->fs
->descent
;
445 pTM
->tmAscent
= pfo
->lpX11Trans
->ascent
;
446 pTM
->tmDescent
= pfo
->lpX11Trans
->descent
;
449 pTM
->tmAscent
*= pfo
->rescale
;
450 pTM
->tmDescent
*= pfo
->rescale
;
452 pTM
->tmHeight
= pTM
->tmAscent
+ pTM
->tmDescent
;
454 pTM
->tmAveCharWidth
= pfo
->foAvgCharWidth
* pfo
->rescale
;
455 pTM
->tmMaxCharWidth
= pfo
->foMaxCharWidth
* pfo
->rescale
;
457 pTM
->tmInternalLeading
= pfo
->foInternalLeading
* pfo
->rescale
;
458 pTM
->tmExternalLeading
= pdf
->dfExternalLeading
* pfo
->rescale
;
460 pTM
->tmStruckOut
= (pfo
->fo_flags
& FO_SYNTH_STRIKEOUT
)
461 ? 1 : pdf
->dfStrikeOut
;
462 pTM
->tmUnderlined
= (pfo
->fo_flags
& FO_SYNTH_UNDERLINE
)
463 ? 1 : pdf
->dfUnderline
;
466 if( pfo
->fo_flags
& FO_SYNTH_ITALIC
)
468 pTM
->tmOverhang
+= pTM
->tmHeight
/3;
471 pTM
->tmItalic
= pdf
->dfItalic
;
473 pTM
->tmWeight
= pdf
->dfWeight
;
474 if( pfo
->fo_flags
& FO_SYNTH_BOLD
)
477 pTM
->tmWeight
+= 100;
480 pTM
->tmFirstChar
= pdf
->dfFirstChar
;
481 pTM
->tmLastChar
= pdf
->dfLastChar
;
482 pTM
->tmDefaultChar
= pdf
->dfDefaultChar
;
483 pTM
->tmBreakChar
= pdf
->dfBreakChar
;
485 pTM
->tmCharSet
= pdf
->dfCharSet
;
486 pTM
->tmPitchAndFamily
= pdf
->dfPitchAndFamily
;
488 pTM
->tmDigitizedAspectX
= pdf
->dfHorizRes
;
489 pTM
->tmDigitizedAspectY
= pdf
->dfVertRes
;
495 void X11DRV_DrawString_dbcs( fontObject
* pfo
, Display
* pdisp
,
496 Drawable d
, GC gc
, int x
, int y
,
497 XChar2b
* pstr
, int count
)
505 X11DRV_cptable
[pfo
->fi
->cptable
].pDrawText(
506 pfo
, pdisp
, d
, gc
, x
, y
, &item
, 1 );
510 int X11DRV_TextWidth_dbcs_2fonts( fontObject
* pfo
, XChar2b
* pstr
, int count
)
515 fontObject
* pfos
[X11FONT_REFOBJS_MAX
+1];
517 pfos
[0] = XFONT_GetFontObject( pfo
->prefobjs
[0] );
519 if ( pfos
[0] == NULL
) pfos
[0] = pfo
;
522 for ( i
= 0; i
< count
; i
++ )
524 curfont
= ( pstr
->byte1
!= 0 ) ? 1 : 0;
525 width
+= TSXTextWidth16( pfos
[curfont
]->fs
, pstr
, 1 );
533 void X11DRV_DrawText_dbcs_2fonts( fontObject
* pfo
, Display
* pdisp
, Drawable d
,
534 GC gc
, int x
, int y
, XTextItem16
* pitems
,
537 int i
, nitems
, prevfont
= -1, curfont
;
541 fontObject
* pfos
[X11FONT_REFOBJS_MAX
+1];
543 pfos
[0] = XFONT_GetFontObject( pfo
->prefobjs
[0] );
545 if ( pfos
[0] == NULL
) pfos
[0] = pfo
;
548 for ( i
= 0; i
< count
; i
++ )
549 nitems
+= pitems
->nchars
;
550 ptibuf
= HeapAlloc( GetProcessHeap(), 0, sizeof(XTextItem16
) * nitems
);
551 if ( ptibuf
== NULL
)
552 return; /* out of memory */
555 while ( count
-- > 0 )
557 pti
->chars
= pstr
= pitems
->chars
;
558 pti
->delta
= pitems
->delta
;
560 for ( i
= 0; i
< pitems
->nchars
; i
++, pstr
++ )
562 curfont
= ( pstr
->byte1
!= 0 ) ? 1 : 0;
563 if ( curfont
!= prevfont
)
565 if ( pstr
!= pti
->chars
)
567 pti
->nchars
= pstr
- pti
->chars
;
572 pti
->font
= pfos
[curfont
]->fs
->fid
;
576 pti
->nchars
= pstr
- pti
->chars
;
579 TSXDrawText16( pdisp
, d
, gc
, x
, y
, ptibuf
, pti
- ptibuf
);
580 HeapFree( GetProcessHeap(), 0, ptibuf
);
584 void X11DRV_TextExtents_dbcs_2fonts( fontObject
* pfo
, XChar2b
* pstr
, int count
,
585 int* pdir
, int* pascent
, int* pdescent
,
589 int ascent
, descent
, width
;
592 fontObject
* pfos
[X11FONT_REFOBJS_MAX
+1];
594 pfos
[0] = XFONT_GetFontObject( pfo
->prefobjs
[0] );
596 if ( pfos
[0] == NULL
) pfos
[0] = pfo
;
601 for ( i
= 0; i
< count
; i
++ )
603 curfont
= ( pstr
->byte1
!= 0 ) ? 1 : 0;
604 TSXTextExtents16( pfos
[curfont
]->fs
, pstr
, 1, pdir
,
605 &ascent
, &descent
, &info
);
606 if ( *pascent
< ascent
) *pascent
= ascent
;
607 if ( *pdescent
< descent
) *pdescent
= descent
;
616 static void X11DRV_GetTextMetricsW_cp932( fontObject
* pfo
, LPTEXTMETRICW pTM
)
618 fontObject
* pfo_ansi
= XFONT_GetFontObject( pfo
->prefobjs
[0] );
619 LPIFONTINFO16 pdf
= &pfo
->fi
->df
;
620 LPIFONTINFO16 pdf_ansi
;
622 pdf_ansi
= ( pfo_ansi
!= NULL
) ? (&pfo_ansi
->fi
->df
) : pdf
;
624 if( ! pfo
->lpX11Trans
) {
625 pTM
->tmAscent
= pfo
->fs
->ascent
;
626 pTM
->tmDescent
= pfo
->fs
->descent
;
628 pTM
->tmAscent
= pfo
->lpX11Trans
->ascent
;
629 pTM
->tmDescent
= pfo
->lpX11Trans
->descent
;
632 pTM
->tmAscent
*= pfo
->rescale
;
633 pTM
->tmDescent
*= pfo
->rescale
;
635 pTM
->tmHeight
= pTM
->tmAscent
+ pTM
->tmDescent
;
637 if ( pfo_ansi
!= NULL
)
639 pTM
->tmAveCharWidth
= floor((pfo_ansi
->foAvgCharWidth
* 2.0 + pfo
->foAvgCharWidth
) / 3.0 * pfo
->rescale
+ 0.5);
640 pTM
->tmMaxCharWidth
= max(pfo_ansi
->foMaxCharWidth
, pfo
->foMaxCharWidth
) * pfo
->rescale
;
644 pTM
->tmAveCharWidth
= floor((pfo
->foAvgCharWidth
* pfo
->rescale
+ 1.0) / 2.0);
645 pTM
->tmMaxCharWidth
= pfo
->foMaxCharWidth
* pfo
->rescale
;
648 pTM
->tmInternalLeading
= pfo
->foInternalLeading
* pfo
->rescale
;
649 pTM
->tmExternalLeading
= pdf
->dfExternalLeading
* pfo
->rescale
;
651 pTM
->tmStruckOut
= (pfo
->fo_flags
& FO_SYNTH_STRIKEOUT
)
652 ? 1 : pdf
->dfStrikeOut
;
653 pTM
->tmUnderlined
= (pfo
->fo_flags
& FO_SYNTH_UNDERLINE
)
654 ? 1 : pdf
->dfUnderline
;
657 if( pfo
->fo_flags
& FO_SYNTH_ITALIC
)
659 pTM
->tmOverhang
+= pTM
->tmHeight
/3;
662 pTM
->tmItalic
= pdf
->dfItalic
;
664 pTM
->tmWeight
= pdf
->dfWeight
;
665 if( pfo
->fo_flags
& FO_SYNTH_BOLD
)
668 pTM
->tmWeight
+= 100;
671 pTM
->tmFirstChar
= pdf_ansi
->dfFirstChar
;
672 pTM
->tmLastChar
= pdf_ansi
->dfLastChar
;
673 pTM
->tmDefaultChar
= pdf_ansi
->dfDefaultChar
;
674 pTM
->tmBreakChar
= pdf_ansi
->dfBreakChar
;
676 pTM
->tmCharSet
= pdf
->dfCharSet
;
677 pTM
->tmPitchAndFamily
= pdf
->dfPitchAndFamily
;
679 pTM
->tmDigitizedAspectX
= pdf
->dfHorizRes
;
680 pTM
->tmDigitizedAspectY
= pdf
->dfVertRes
;
687 const X11DRV_CP X11DRV_cptable
[X11DRV_CPTABLE_COUNT
] =
690 X11DRV_enum_subfont_charset_normal
,
691 X11DRV_unicode_to_char2b_sbcs
,
692 X11DRV_DrawString_normal
,
693 X11DRV_TextWidth_normal
,
694 X11DRV_DrawText_normal
,
695 X11DRV_TextExtents_normal
,
696 X11DRV_GetTextMetricsW_normal
,
699 X11DRV_enum_subfont_charset_normal
,
700 X11DRV_unicode_to_char2b_unicode
,
701 X11DRV_DrawString_normal
,
702 X11DRV_TextWidth_normal
,
703 X11DRV_DrawText_normal
,
704 X11DRV_TextExtents_normal
,
705 X11DRV_GetTextMetricsW_normal
,
708 X11DRV_enum_subfont_charset_cp932
,
709 X11DRV_unicode_to_char2b_cp932
,
710 X11DRV_DrawString_dbcs
,
711 X11DRV_TextWidth_dbcs_2fonts
,
712 X11DRV_DrawText_dbcs_2fonts
,
713 X11DRV_TextExtents_dbcs_2fonts
,
714 X11DRV_GetTextMetricsW_cp932
,
717 X11DRV_enum_subfont_charset_cp936
,
718 X11DRV_unicode_to_char2b_cp936
,
719 X11DRV_DrawString_dbcs
,
720 X11DRV_TextWidth_dbcs_2fonts
,
721 X11DRV_DrawText_dbcs_2fonts
,
722 X11DRV_TextExtents_dbcs_2fonts
,
723 X11DRV_GetTextMetricsW_normal
, /* FIXME */
726 X11DRV_enum_subfont_charset_cp949
,
727 X11DRV_unicode_to_char2b_cp949
,
728 X11DRV_DrawString_dbcs
,
729 X11DRV_TextWidth_dbcs_2fonts
,
730 X11DRV_DrawText_dbcs_2fonts
,
731 X11DRV_TextExtents_dbcs_2fonts
,
732 X11DRV_GetTextMetricsW_normal
, /* FIXME */
735 X11DRV_enum_subfont_charset_cp950
,
736 X11DRV_unicode_to_char2b_cp950
,
737 X11DRV_DrawString_dbcs
,
738 X11DRV_TextWidth_dbcs_2fonts
,
739 X11DRV_DrawText_dbcs_2fonts
,
740 X11DRV_TextExtents_dbcs_2fonts
,
741 X11DRV_GetTextMetricsW_cp932
,
744 X11DRV_enum_subfont_charset_normal
,
745 X11DRV_unicode_to_char2b_symbol
,
746 X11DRV_DrawString_normal
,
747 X11DRV_TextWidth_normal
,
748 X11DRV_DrawText_normal
,
749 X11DRV_TextExtents_normal
,
750 X11DRV_GetTextMetricsW_normal
,