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
30 #include "wine/debug.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(text
);
34 /***********************************************************************
35 * IsLegalDBCSChar for cp932/936/949/950/euc
38 int IsLegalDBCSChar_cp932( BYTE lead
, BYTE trail
)
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 ) ) );
47 int IsLegalDBCSChar_cp936( BYTE lead
, BYTE trail
)
49 return ( ( lead
>= (BYTE
)0x81 && lead
<= (BYTE
)0xfe ) &&
50 ( trail
>= (BYTE
)0x40 && trail
<= (BYTE
)0xfe ) );
54 int IsLegalDBCSChar_cp949( BYTE lead
, BYTE trail
)
56 return ( ( lead
>= (BYTE
)0x81 && lead
<= (BYTE
)0xfe ) &&
57 ( trail
>= (BYTE
)0x41 && trail
<= (BYTE
)0xfe ) );
61 int IsLegalDBCSChar_cp950( BYTE lead
, BYTE trail
)
63 return ( ( lead
>= (BYTE
)0x81 && lead
<= (BYTE
)0xfe ) &&
64 ( ( trail
>= (BYTE
)0x40 && trail
<= (BYTE
)0x7e ) ||
65 ( trail
>= (BYTE
)0xa1 && trail
<= (BYTE
)0xfe ) ) );
69 int IsLegalDBCSChar_euc( BYTE lead
, BYTE trail
)
71 return ( ( lead
>= (BYTE
)0xa1 && lead
<= (BYTE
)0xfe ) &&
72 ( trail
>= (BYTE
)0xa1 && trail
<= (BYTE
)0xfe ) );
76 /***********************************************************************
77 * DBCSCharToXChar2b for cp932/euc
81 void DBCSCharToXChar2b_cp932( XChar2b
* pch
, BYTE lead
, BYTE trail
)
83 unsigned int high
, low
;
85 high
= (unsigned int)lead
;
86 low
= (unsigned int)trail
;
89 high
= (high
<<1) - 0xe0;
91 high
= (high
<<1) - 0x160;
105 pch
->byte1
= (unsigned char)high
;
106 pch
->byte2
= (unsigned char)low
;
110 void DBCSCharToXChar2b_euc( XChar2b
* pch
, BYTE lead
, BYTE trail
)
112 pch
->byte1
= lead
& (BYTE
)0x7f;
113 pch
->byte2
= trail
& (BYTE
)0x7f;
119 static WORD
X11DRV_enum_subfont_charset_normal( UINT index
)
121 return DEFAULT_CHARSET
;
124 static WORD
X11DRV_enum_subfont_charset_cp932( UINT index
)
128 case 0: return X11FONT_JISX0201_CHARSET
;
129 case 1: return X11FONT_JISX0212_CHARSET
;
132 return DEFAULT_CHARSET
;
135 static WORD
X11DRV_enum_subfont_charset_cp936( UINT index
)
139 case 0: return ANSI_CHARSET
;
142 return DEFAULT_CHARSET
;
145 static WORD
X11DRV_enum_subfont_charset_cp949( UINT index
)
149 case 0: return ANSI_CHARSET
;
152 return DEFAULT_CHARSET
;
155 static WORD
X11DRV_enum_subfont_charset_cp950( UINT index
)
159 case 0: return ANSI_CHARSET
;
162 return DEFAULT_CHARSET
;
166 static XChar2b
* X11DRV_unicode_to_char2b_sbcs( fontObject
* pfo
,
167 LPCWSTR lpwstr
, UINT count
)
172 UINT codepage
= pfo
->fi
->codepage
;
173 char ch
= pfo
->fs
->default_char
;
175 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
177 if (!(str
= HeapAlloc( GetProcessHeap(), 0, count
)))
179 HeapFree( GetProcessHeap(), 0, str2b
);
183 WideCharToMultiByte( codepage
, 0, lpwstr
, count
, str
, count
, &ch
, NULL
);
185 for (i
= 0; i
< count
; i
++)
188 str2b
[i
].byte2
= str
[i
];
190 HeapFree( GetProcessHeap(), 0, str
);
195 static XChar2b
* X11DRV_unicode_to_char2b_unicode( fontObject
* pfo
,
196 LPCWSTR lpwstr
, UINT count
)
201 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
204 for (i
= 0; i
< count
; i
++)
206 str2b
[i
].byte1
= lpwstr
[i
] >> 8;
207 str2b
[i
].byte2
= lpwstr
[i
] & 0xff;
213 /* FIXME: handle jisx0212.1990... */
214 static XChar2b
* X11DRV_unicode_to_char2b_cp932( fontObject
* pfo
,
215 LPCWSTR lpwstr
, UINT count
)
222 char ch
= pfo
->fs
->default_char
;
224 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
226 if (!(str
= HeapAlloc( GetProcessHeap(), 0, count
*2 )))
228 HeapFree( GetProcessHeap(), 0, str2b
);
232 /* handle jisx0212.1990... */
233 WideCharToMultiByte( 932, 0, lpwstr
, count
, str
, count
*2, &ch
, NULL
);
237 for (i
= 0; i
< count
; i
++, str_src
++, str2b_dst
++)
239 if ( IsLegalDBCSChar_cp932( *str_src
, *(str_src
+1) ) )
241 DBCSCharToXChar2b_cp932( str2b_dst
, *str_src
, *(str_src
+1) );
246 str2b_dst
->byte1
= 0;
247 str2b_dst
->byte2
= *str_src
;
251 HeapFree( GetProcessHeap(), 0, str
);
257 static XChar2b
* X11DRV_unicode_to_char2b_cp936( fontObject
* pfo
,
258 LPCWSTR lpwstr
, UINT count
)
265 char ch
= pfo
->fs
->default_char
;
267 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
269 if (!(str
= HeapAlloc( GetProcessHeap(), 0, count
*2 )))
271 HeapFree( GetProcessHeap(), 0, str2b
);
274 WideCharToMultiByte( 936, 0, lpwstr
, count
, str
, count
*2, &ch
, NULL
);
278 for (i
= 0; i
< count
; i
++, str_src
++, str2b_dst
++)
280 if ( IsLegalDBCSChar_cp936( *str_src
, *(str_src
+1) ) )
282 str2b_dst
->byte1
= *str_src
;
283 str2b_dst
->byte2
= *(str_src
+1);
288 str2b_dst
->byte1
= 0;
289 str2b_dst
->byte2
= *str_src
;
293 HeapFree( GetProcessHeap(), 0, str
);
298 static XChar2b
* X11DRV_unicode_to_char2b_cp949( fontObject
* pfo
,
299 LPCWSTR lpwstr
, UINT count
)
306 char ch
= pfo
->fs
->default_char
;
308 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
310 if (!(str
= HeapAlloc( GetProcessHeap(), 0, count
*2 )))
312 HeapFree( GetProcessHeap(), 0, str2b
);
315 WideCharToMultiByte( 949, 0, lpwstr
, count
, str
, count
*2, &ch
, NULL
);
319 for (i
= 0; i
< count
; i
++, str_src
++, str2b_dst
++)
321 if ( IsLegalDBCSChar_cp949( *str_src
, *(str_src
+1) ) )
323 str2b_dst
->byte1
= *str_src
;
324 str2b_dst
->byte2
= *(str_src
+1);
329 str2b_dst
->byte1
= 0;
330 str2b_dst
->byte2
= *str_src
;
334 HeapFree( GetProcessHeap(), 0, str
);
340 static XChar2b
* X11DRV_unicode_to_char2b_cp950( fontObject
* pfo
,
341 LPCWSTR lpwstr
, UINT count
)
348 char ch
= pfo
->fs
->default_char
;
350 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
352 if (!(str
= HeapAlloc( GetProcessHeap(), 0, count
*2 )))
354 HeapFree( GetProcessHeap(), 0, str2b
);
357 WideCharToMultiByte( 950, 0, lpwstr
, count
, str
, count
*2, &ch
, NULL
);
361 for (i
= 0; i
< count
; i
++, str_src
++, str2b_dst
++)
363 if ( IsLegalDBCSChar_cp950( *str_src
, *(str_src
+1) ) )
365 str2b_dst
->byte1
= *str_src
;
366 str2b_dst
->byte2
= *(str_src
+1);
371 str2b_dst
->byte1
= 0;
372 str2b_dst
->byte2
= *str_src
;
376 HeapFree( GetProcessHeap(), 0, str
);
381 static XChar2b
* X11DRV_unicode_to_char2b_symbol( fontObject
* pfo
,
382 LPCWSTR lpwstr
, UINT count
)
386 char ch
= pfo
->fs
->default_char
;
388 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
391 for (i
= 0; i
< count
; i
++)
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
];
406 static void X11DRV_DrawString_normal( fontObject
* pfo
, Display
* pdisp
,
407 Drawable d
, GC gc
, int x
, int y
,
408 XChar2b
* pstr
, int count
)
410 TSXDrawString16( pdisp
, d
, gc
, x
, y
, pstr
, count
);
413 static int X11DRV_TextWidth_normal( fontObject
* pfo
, XChar2b
* pstr
, int count
)
415 return TSXTextWidth16( pfo
->fs
, pstr
, count
);
418 static void X11DRV_DrawText_normal( fontObject
* pfo
, Display
* pdisp
, Drawable d
,
419 GC gc
, int x
, int y
, XTextItem16
* pitems
,
422 TSXDrawText16( pdisp
, d
, gc
, x
, y
, pitems
, count
);
425 static void X11DRV_TextExtents_normal( fontObject
* pfo
, XChar2b
* pstr
, int count
,
426 int* pdir
, int* pascent
, int* pdescent
,
431 TSXTextExtents16( pfo
->fs
, pstr
, count
, pdir
, pascent
, pdescent
, &info
);
432 *pwidth
= info
.width
;
435 static void X11DRV_GetTextMetricsW_normal( fontObject
* pfo
, LPTEXTMETRICW pTM
)
437 LPIFONTINFO16 pdf
= &pfo
->fi
->df
;
439 if( ! pfo
->lpX11Trans
) {
440 pTM
->tmAscent
= pfo
->fs
->ascent
;
441 pTM
->tmDescent
= pfo
->fs
->descent
;
443 pTM
->tmAscent
= pfo
->lpX11Trans
->ascent
;
444 pTM
->tmDescent
= pfo
->lpX11Trans
->descent
;
447 pTM
->tmAscent
*= pfo
->rescale
;
448 pTM
->tmDescent
*= pfo
->rescale
;
450 pTM
->tmHeight
= pTM
->tmAscent
+ pTM
->tmDescent
;
452 pTM
->tmAveCharWidth
= pfo
->foAvgCharWidth
* pfo
->rescale
;
453 pTM
->tmMaxCharWidth
= pfo
->foMaxCharWidth
* pfo
->rescale
;
455 pTM
->tmInternalLeading
= pfo
->foInternalLeading
* pfo
->rescale
;
456 pTM
->tmExternalLeading
= pdf
->dfExternalLeading
* pfo
->rescale
;
458 pTM
->tmStruckOut
= (pfo
->fo_flags
& FO_SYNTH_STRIKEOUT
)
459 ? 1 : pdf
->dfStrikeOut
;
460 pTM
->tmUnderlined
= (pfo
->fo_flags
& FO_SYNTH_UNDERLINE
)
461 ? 1 : pdf
->dfUnderline
;
464 if( pfo
->fo_flags
& FO_SYNTH_ITALIC
)
466 pTM
->tmOverhang
+= pTM
->tmHeight
/3;
469 pTM
->tmItalic
= pdf
->dfItalic
;
471 pTM
->tmWeight
= pdf
->dfWeight
;
472 if( pfo
->fo_flags
& FO_SYNTH_BOLD
)
475 pTM
->tmWeight
+= 100;
478 pTM
->tmFirstChar
= pdf
->dfFirstChar
;
479 pTM
->tmLastChar
= pdf
->dfLastChar
;
480 pTM
->tmDefaultChar
= pdf
->dfDefaultChar
;
481 pTM
->tmBreakChar
= pdf
->dfBreakChar
;
483 pTM
->tmCharSet
= pdf
->dfCharSet
;
484 pTM
->tmPitchAndFamily
= pdf
->dfPitchAndFamily
;
486 pTM
->tmDigitizedAspectX
= pdf
->dfHorizRes
;
487 pTM
->tmDigitizedAspectY
= pdf
->dfVertRes
;
493 void X11DRV_DrawString_dbcs( fontObject
* pfo
, Display
* pdisp
,
494 Drawable d
, GC gc
, int x
, int y
,
495 XChar2b
* pstr
, int count
)
503 X11DRV_cptable
[pfo
->fi
->cptable
].pDrawText(
504 pfo
, pdisp
, d
, gc
, x
, y
, &item
, 1 );
508 int X11DRV_TextWidth_dbcs_2fonts( fontObject
* pfo
, XChar2b
* pstr
, int count
)
513 fontObject
* pfos
[X11FONT_REFOBJS_MAX
+1];
515 pfos
[0] = XFONT_GetFontObject( pfo
->prefobjs
[0] );
517 if ( pfos
[0] == NULL
) pfos
[0] = pfo
;
520 for ( i
= 0; i
< count
; i
++ )
522 curfont
= ( pstr
->byte1
!= 0 ) ? 1 : 0;
523 width
+= TSXTextWidth16( pfos
[curfont
]->fs
, pstr
, 1 );
531 void X11DRV_DrawText_dbcs_2fonts( fontObject
* pfo
, Display
* pdisp
, Drawable d
,
532 GC gc
, int x
, int y
, XTextItem16
* pitems
,
535 int i
, nitems
, prevfont
= -1, curfont
;
539 fontObject
* pfos
[X11FONT_REFOBJS_MAX
+1];
541 pfos
[0] = XFONT_GetFontObject( pfo
->prefobjs
[0] );
543 if ( pfos
[0] == NULL
) pfos
[0] = pfo
;
546 for ( i
= 0; i
< count
; i
++ )
547 nitems
+= pitems
->nchars
;
548 ptibuf
= HeapAlloc( GetProcessHeap(), 0, sizeof(XTextItem16
) * nitems
);
549 if ( ptibuf
== NULL
)
550 return; /* out of memory */
553 while ( count
-- > 0 )
555 pti
->chars
= pstr
= pitems
->chars
;
556 pti
->delta
= pitems
->delta
;
558 for ( i
= 0; i
< pitems
->nchars
; i
++, pstr
++ )
560 curfont
= ( pstr
->byte1
!= 0 ) ? 1 : 0;
561 if ( curfont
!= prevfont
)
563 if ( pstr
!= pti
->chars
)
565 pti
->nchars
= pstr
- pti
->chars
;
570 pti
->font
= pfos
[curfont
]->fs
->fid
;
574 pti
->nchars
= pstr
- pti
->chars
;
577 TSXDrawText16( pdisp
, d
, gc
, x
, y
, ptibuf
, pti
- ptibuf
);
578 HeapFree( GetProcessHeap(), 0, ptibuf
);
582 void X11DRV_TextExtents_dbcs_2fonts( fontObject
* pfo
, XChar2b
* pstr
, int count
,
583 int* pdir
, int* pascent
, int* pdescent
,
587 int ascent
, descent
, width
;
590 fontObject
* pfos
[X11FONT_REFOBJS_MAX
+1];
592 pfos
[0] = XFONT_GetFontObject( pfo
->prefobjs
[0] );
594 if ( pfos
[0] == NULL
) pfos
[0] = pfo
;
599 for ( i
= 0; i
< count
; i
++ )
601 curfont
= ( pstr
->byte1
!= 0 ) ? 1 : 0;
602 TSXTextExtents16( pfos
[curfont
]->fs
, pstr
, 1, pdir
,
603 &ascent
, &descent
, &info
);
604 if ( *pascent
< ascent
) *pascent
= ascent
;
605 if ( *pdescent
< descent
) *pdescent
= descent
;
614 static void X11DRV_GetTextMetricsW_cp932( fontObject
* pfo
, LPTEXTMETRICW pTM
)
616 fontObject
* pfo_ansi
= XFONT_GetFontObject( pfo
->prefobjs
[0] );
617 LPIFONTINFO16 pdf
= &pfo
->fi
->df
;
618 LPIFONTINFO16 pdf_ansi
;
620 pdf_ansi
= ( pfo_ansi
!= NULL
) ? (&pfo_ansi
->fi
->df
) : pdf
;
622 if( ! pfo
->lpX11Trans
) {
623 pTM
->tmAscent
= pfo
->fs
->ascent
;
624 pTM
->tmDescent
= pfo
->fs
->descent
;
626 pTM
->tmAscent
= pfo
->lpX11Trans
->ascent
;
627 pTM
->tmDescent
= pfo
->lpX11Trans
->descent
;
630 pTM
->tmAscent
*= pfo
->rescale
;
631 pTM
->tmDescent
*= pfo
->rescale
;
633 pTM
->tmHeight
= pTM
->tmAscent
+ pTM
->tmDescent
;
635 if ( pfo_ansi
!= NULL
)
637 pTM
->tmAveCharWidth
= floor((pfo_ansi
->foAvgCharWidth
* 2.0 + pfo
->foAvgCharWidth
) / 3.0 * pfo
->rescale
+ 0.5);
638 pTM
->tmMaxCharWidth
= max(pfo_ansi
->foMaxCharWidth
, pfo
->foMaxCharWidth
) * pfo
->rescale
;
642 pTM
->tmAveCharWidth
= floor((pfo
->foAvgCharWidth
* pfo
->rescale
+ 1.0) / 2.0);
643 pTM
->tmMaxCharWidth
= pfo
->foMaxCharWidth
* pfo
->rescale
;
646 pTM
->tmInternalLeading
= pfo
->foInternalLeading
* pfo
->rescale
;
647 pTM
->tmExternalLeading
= pdf
->dfExternalLeading
* pfo
->rescale
;
649 pTM
->tmStruckOut
= (pfo
->fo_flags
& FO_SYNTH_STRIKEOUT
)
650 ? 1 : pdf
->dfStrikeOut
;
651 pTM
->tmUnderlined
= (pfo
->fo_flags
& FO_SYNTH_UNDERLINE
)
652 ? 1 : pdf
->dfUnderline
;
655 if( pfo
->fo_flags
& FO_SYNTH_ITALIC
)
657 pTM
->tmOverhang
+= pTM
->tmHeight
/3;
660 pTM
->tmItalic
= pdf
->dfItalic
;
662 pTM
->tmWeight
= pdf
->dfWeight
;
663 if( pfo
->fo_flags
& FO_SYNTH_BOLD
)
666 pTM
->tmWeight
+= 100;
669 pTM
->tmFirstChar
= pdf_ansi
->dfFirstChar
;
670 pTM
->tmLastChar
= pdf_ansi
->dfLastChar
;
671 pTM
->tmDefaultChar
= pdf_ansi
->dfDefaultChar
;
672 pTM
->tmBreakChar
= pdf_ansi
->dfBreakChar
;
674 pTM
->tmCharSet
= pdf
->dfCharSet
;
675 pTM
->tmPitchAndFamily
= pdf
->dfPitchAndFamily
;
677 pTM
->tmDigitizedAspectX
= pdf
->dfHorizRes
;
678 pTM
->tmDigitizedAspectY
= pdf
->dfVertRes
;
685 const X11DRV_CP X11DRV_cptable
[X11DRV_CPTABLE_COUNT
] =
688 X11DRV_enum_subfont_charset_normal
,
689 X11DRV_unicode_to_char2b_sbcs
,
690 X11DRV_DrawString_normal
,
691 X11DRV_TextWidth_normal
,
692 X11DRV_DrawText_normal
,
693 X11DRV_TextExtents_normal
,
694 X11DRV_GetTextMetricsW_normal
,
697 X11DRV_enum_subfont_charset_normal
,
698 X11DRV_unicode_to_char2b_unicode
,
699 X11DRV_DrawString_normal
,
700 X11DRV_TextWidth_normal
,
701 X11DRV_DrawText_normal
,
702 X11DRV_TextExtents_normal
,
703 X11DRV_GetTextMetricsW_normal
,
706 X11DRV_enum_subfont_charset_cp932
,
707 X11DRV_unicode_to_char2b_cp932
,
708 X11DRV_DrawString_dbcs
,
709 X11DRV_TextWidth_dbcs_2fonts
,
710 X11DRV_DrawText_dbcs_2fonts
,
711 X11DRV_TextExtents_dbcs_2fonts
,
712 X11DRV_GetTextMetricsW_cp932
,
715 X11DRV_enum_subfont_charset_cp936
,
716 X11DRV_unicode_to_char2b_cp936
,
717 X11DRV_DrawString_dbcs
,
718 X11DRV_TextWidth_dbcs_2fonts
,
719 X11DRV_DrawText_dbcs_2fonts
,
720 X11DRV_TextExtents_dbcs_2fonts
,
721 X11DRV_GetTextMetricsW_normal
, /* FIXME */
724 X11DRV_enum_subfont_charset_cp949
,
725 X11DRV_unicode_to_char2b_cp949
,
726 X11DRV_DrawString_dbcs
,
727 X11DRV_TextWidth_dbcs_2fonts
,
728 X11DRV_DrawText_dbcs_2fonts
,
729 X11DRV_TextExtents_dbcs_2fonts
,
730 X11DRV_GetTextMetricsW_normal
, /* FIXME */
733 X11DRV_enum_subfont_charset_cp950
,
734 X11DRV_unicode_to_char2b_cp950
,
735 X11DRV_DrawString_dbcs
,
736 X11DRV_TextWidth_dbcs_2fonts
,
737 X11DRV_DrawText_dbcs_2fonts
,
738 X11DRV_TextExtents_dbcs_2fonts
,
739 X11DRV_GetTextMetricsW_cp932
,
742 X11DRV_enum_subfont_charset_normal
,
743 X11DRV_unicode_to_char2b_symbol
,
744 X11DRV_DrawString_normal
,
745 X11DRV_TextWidth_normal
,
746 X11DRV_DrawText_normal
,
747 X11DRV_TextExtents_normal
,
748 X11DRV_GetTextMetricsW_normal
,