2 * X11 codepage handling
4 * Copyright 2000 Hidenori Takeshima <hidenori@a2.ctktv.ne.jp>
17 #include "debugtools.h"
19 DEFAULT_DEBUG_CHANNEL(text
);
21 /***********************************************************************
22 * IsLegalDBCSChar for cp932/936/949/950/euc
25 int IsLegalDBCSChar_cp932( BYTE lead
, BYTE trail
)
27 return ( ( ( lead
>= (BYTE
)0x81 && lead
<= (BYTE
)0x9f ) ||
28 ( lead
>= (BYTE
)0xe0 && lead
<= (BYTE
)0xfc ) ) &&
29 ( ( trail
>= (BYTE
)0x40 && trail
<= (BYTE
)0x7e ) ||
30 ( trail
>= (BYTE
)0x80 && trail
<= (BYTE
)0xfc ) ) );
34 int IsLegalDBCSChar_cp936( BYTE lead
, BYTE trail
)
36 return ( ( lead
>= (BYTE
)0x81 && lead
<= (BYTE
)0xfe ) &&
37 ( trail
>= (BYTE
)0x40 && trail
<= (BYTE
)0xfe ) );
41 int IsLegalDBCSChar_cp949( BYTE lead
, BYTE trail
)
43 return ( ( lead
>= (BYTE
)0x81 && lead
<= (BYTE
)0xfe ) &&
44 ( trail
>= (BYTE
)0x41 && trail
<= (BYTE
)0xfe ) );
48 int IsLegalDBCSChar_cp950( BYTE lead
, BYTE trail
)
50 return ( ( lead
>= (BYTE
)0x81 && lead
<= (BYTE
)0xfe ) &&
51 ( ( trail
>= (BYTE
)0x40 && trail
<= (BYTE
)0x7e ) ||
52 ( trail
>= (BYTE
)0xa1 && trail
<= (BYTE
)0xfe ) ) );
56 int IsLegalDBCSChar_euc( BYTE lead
, BYTE trail
)
58 return ( ( lead
>= (BYTE
)0xa1 && lead
<= (BYTE
)0xfe ) &&
59 ( trail
>= (BYTE
)0xa1 && trail
<= (BYTE
)0xfe ) );
63 /***********************************************************************
64 * DBCSCharToXChar2b for cp932/euc
68 void DBCSCharToXChar2b_cp932( XChar2b
* pch
, BYTE lead
, BYTE trail
)
70 unsigned int high
, low
;
72 high
= (unsigned int)lead
;
73 low
= (unsigned int)trail
;
76 high
= (high
<<1) - 0xe0;
78 high
= (high
<<1) - 0x160;
92 pch
->byte1
= (unsigned char)high
;
93 pch
->byte2
= (unsigned char)low
;
97 void DBCSCharToXChar2b_euc( XChar2b
* pch
, BYTE lead
, BYTE trail
)
99 pch
->byte1
= lead
& (BYTE
)0x7f;
100 pch
->byte2
= trail
& (BYTE
)0x7f;
106 static WORD
X11DRV_enum_subfont_charset_normal( UINT index
)
108 return DEFAULT_CHARSET
;
111 static WORD
X11DRV_enum_subfont_charset_cp932( UINT index
)
115 case 0: return X11FONT_JISX0201_CHARSET
;
116 case 1: return X11FONT_JISX0212_CHARSET
;
119 return DEFAULT_CHARSET
;
122 static WORD
X11DRV_enum_subfont_charset_cp936( UINT index
)
126 case 0: return ANSI_CHARSET
;
129 return DEFAULT_CHARSET
;
132 static WORD
X11DRV_enum_subfont_charset_cp949( UINT index
)
136 case 0: return ANSI_CHARSET
;
139 return DEFAULT_CHARSET
;
142 static WORD
X11DRV_enum_subfont_charset_cp950( UINT index
)
144 FIXME( "please implement X11DRV_enum_subfont_charset_cp950!\n" );
145 return DEFAULT_CHARSET
;
149 static XChar2b
* X11DRV_unicode_to_char2b_sbcs( fontObject
* pfo
,
150 LPCWSTR lpwstr
, UINT count
)
155 UINT codepage
= pfo
->fi
->codepage
;
156 char ch
= pfo
->fs
->default_char
;
158 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
160 if (!(str
= HeapAlloc( GetProcessHeap(), 0, count
)))
162 HeapFree( GetProcessHeap(), 0, str2b
);
166 WideCharToMultiByte( codepage
, 0, lpwstr
, count
, str
, count
, &ch
, NULL
);
168 for (i
= 0; i
< count
; i
++)
171 str2b
[i
].byte2
= str
[i
];
173 HeapFree( GetProcessHeap(), 0, str
);
178 static XChar2b
* X11DRV_unicode_to_char2b_unicode( fontObject
* pfo
,
179 LPCWSTR lpwstr
, UINT count
)
184 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
187 for (i
= 0; i
< count
; i
++)
189 str2b
[i
].byte1
= lpwstr
[i
] >> 8;
190 str2b
[i
].byte2
= lpwstr
[i
] & 0xff;
196 /* FIXME: handle jisx0212.1990... */
197 static XChar2b
* X11DRV_unicode_to_char2b_cp932( fontObject
* pfo
,
198 LPCWSTR lpwstr
, UINT count
)
205 char ch
= pfo
->fs
->default_char
;
207 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
209 if (!(str
= HeapAlloc( GetProcessHeap(), 0, count
*2 )))
211 HeapFree( GetProcessHeap(), 0, str2b
);
215 /* handle jisx0212.1990... */
216 WideCharToMultiByte( 932, 0, lpwstr
, count
, str
, count
*2, &ch
, NULL
);
220 for (i
= 0; i
< count
; i
++, str_src
++, str2b_dst
++)
222 if ( IsLegalDBCSChar_cp932( *str_src
, *(str_src
+1) ) )
224 DBCSCharToXChar2b_cp932( str2b_dst
, *str_src
, *(str_src
+1) );
229 str2b_dst
->byte1
= 0;
230 str2b_dst
->byte2
= *str_src
;
234 HeapFree( GetProcessHeap(), 0, str
);
240 static XChar2b
* X11DRV_unicode_to_char2b_cp936( fontObject
* pfo
,
241 LPCWSTR lpwstr
, UINT count
)
248 char ch
= pfo
->fs
->default_char
;
250 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
252 if (!(str
= HeapAlloc( GetProcessHeap(), 0, count
*2 )))
254 HeapFree( GetProcessHeap(), 0, str2b
);
257 WideCharToMultiByte( 936, 0, lpwstr
, count
, str
, count
*2, &ch
, NULL
);
261 for (i
= 0; i
< count
; i
++, str_src
++, str2b_dst
++)
263 if ( IsLegalDBCSChar_cp936( *str_src
, *(str_src
+1) ) )
265 if ( IsLegalDBCSChar_euc( *str_src
, *(str_src
+1) ) )
267 DBCSCharToXChar2b_euc( str2b_dst
, *str_src
, *(str_src
+1) );
272 str2b_dst
->byte1
= 0;
273 str2b_dst
->byte2
= 0;
279 str2b_dst
->byte1
= 0;
280 str2b_dst
->byte2
= *str_src
;
284 HeapFree( GetProcessHeap(), 0, str
);
289 static XChar2b
* X11DRV_unicode_to_char2b_cp949( fontObject
* pfo
,
290 LPCWSTR lpwstr
, UINT count
)
297 char ch
= pfo
->fs
->default_char
;
299 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
301 if (!(str
= HeapAlloc( GetProcessHeap(), 0, count
*2 )))
303 HeapFree( GetProcessHeap(), 0, str2b
);
306 WideCharToMultiByte( 949, 0, lpwstr
, count
, str
, count
*2, &ch
, NULL
);
310 for (i
= 0; i
< count
; i
++, str_src
++, str2b_dst
++)
312 if ( IsLegalDBCSChar_cp949( *str_src
, *(str_src
+1) ) )
314 if ( IsLegalDBCSChar_euc( *str_src
, *(str_src
+1) ) )
316 DBCSCharToXChar2b_euc( str2b_dst
, *str_src
, *(str_src
+1) );
321 str2b_dst
->byte1
= 0;
322 str2b_dst
->byte2
= 0;
328 str2b_dst
->byte1
= 0;
329 str2b_dst
->byte2
= *str_src
;
333 HeapFree( GetProcessHeap(), 0, str
);
339 static XChar2b
* X11DRV_unicode_to_char2b_cp950( fontObject
* pfo
,
340 LPCWSTR lpwstr
, UINT count
)
342 FIXME( "please implement X11DRV_unicode_to_char2b_cp950!\n" );
347 static void X11DRV_DrawString_normal( fontObject
* pfo
, Display
* pdisp
,
348 Drawable d
, GC gc
, int x
, int y
,
349 XChar2b
* pstr
, int count
)
351 TSXDrawString16( pdisp
, d
, gc
, x
, y
, pstr
, count
);
354 static int X11DRV_TextWidth_normal( fontObject
* pfo
, XChar2b
* pstr
, int count
)
356 return TSXTextWidth16( pfo
->fs
, pstr
, count
);
359 static void X11DRV_DrawText_normal( fontObject
* pfo
, Display
* pdisp
, Drawable d
,
360 GC gc
, int x
, int y
, XTextItem16
* pitems
,
363 TSXDrawText16( pdisp
, d
, gc
, x
, y
, pitems
, count
);
366 static void X11DRV_TextExtents_normal( fontObject
* pfo
, XChar2b
* pstr
, int count
,
367 int* pdir
, int* pascent
, int* pdescent
,
372 TSXTextExtents16( pfo
->fs
, pstr
, count
, pdir
, pascent
, pdescent
, &info
);
373 *pwidth
= info
.width
;
376 static void X11DRV_GetTextMetricsA_normal( fontObject
* pfo
, LPTEXTMETRICA pTM
)
378 LPIFONTINFO16 pdf
= &pfo
->fi
->df
;
380 if( ! pfo
->lpX11Trans
) {
381 pTM
->tmAscent
= pfo
->fs
->ascent
;
382 pTM
->tmDescent
= pfo
->fs
->descent
;
384 pTM
->tmAscent
= pfo
->lpX11Trans
->ascent
;
385 pTM
->tmDescent
= pfo
->lpX11Trans
->descent
;
388 pTM
->tmAscent
*= pfo
->rescale
;
389 pTM
->tmDescent
*= pfo
->rescale
;
391 pTM
->tmHeight
= pTM
->tmAscent
+ pTM
->tmDescent
;
393 pTM
->tmAveCharWidth
= pfo
->foAvgCharWidth
* pfo
->rescale
;
394 pTM
->tmMaxCharWidth
= pfo
->foMaxCharWidth
* pfo
->rescale
;
396 pTM
->tmInternalLeading
= pfo
->foInternalLeading
* pfo
->rescale
;
397 pTM
->tmExternalLeading
= pdf
->dfExternalLeading
* pfo
->rescale
;
399 pTM
->tmStruckOut
= (pfo
->fo_flags
& FO_SYNTH_STRIKEOUT
)
400 ? 1 : pdf
->dfStrikeOut
;
401 pTM
->tmUnderlined
= (pfo
->fo_flags
& FO_SYNTH_UNDERLINE
)
402 ? 1 : pdf
->dfUnderline
;
405 if( pfo
->fo_flags
& FO_SYNTH_ITALIC
)
407 pTM
->tmOverhang
+= pTM
->tmHeight
/3;
410 pTM
->tmItalic
= pdf
->dfItalic
;
412 pTM
->tmWeight
= pdf
->dfWeight
;
413 if( pfo
->fo_flags
& FO_SYNTH_BOLD
)
416 pTM
->tmWeight
+= 100;
419 pTM
->tmFirstChar
= pdf
->dfFirstChar
;
420 pTM
->tmLastChar
= pdf
->dfLastChar
;
421 pTM
->tmDefaultChar
= pdf
->dfDefaultChar
;
422 pTM
->tmBreakChar
= pdf
->dfBreakChar
;
424 pTM
->tmCharSet
= pdf
->dfCharSet
;
425 pTM
->tmPitchAndFamily
= pdf
->dfPitchAndFamily
;
427 pTM
->tmDigitizedAspectX
= pdf
->dfHorizRes
;
428 pTM
->tmDigitizedAspectY
= pdf
->dfVertRes
;
434 void X11DRV_DrawString_dbcs( fontObject
* pfo
, Display
* pdisp
,
435 Drawable d
, GC gc
, int x
, int y
,
436 XChar2b
* pstr
, int count
)
444 X11DRV_cptable
[pfo
->fi
->cptable
].pDrawText(
445 pfo
, pdisp
, d
, gc
, x
, y
, &item
, 1 );
449 int X11DRV_TextWidth_dbcs_2fonts( fontObject
* pfo
, XChar2b
* pstr
, int count
)
454 fontObject
* pfos
[X11FONT_REFOBJS_MAX
+1];
456 pfos
[0] = XFONT_GetFontObject( pfo
->prefobjs
[0] );
458 if ( pfos
[0] == NULL
) pfos
[0] = pfo
;
461 for ( i
= 0; i
< count
; i
++ )
463 curfont
= ( pstr
->byte1
!= 0 ) ? 1 : 0;
464 width
+= TSXTextWidth16( pfos
[curfont
]->fs
, pstr
, 1 );
472 void X11DRV_DrawText_dbcs_2fonts( fontObject
* pfo
, Display
* pdisp
, Drawable d
,
473 GC gc
, int x
, int y
, XTextItem16
* pitems
,
476 int i
, nitems
, prevfont
= -1, curfont
;
480 fontObject
* pfos
[X11FONT_REFOBJS_MAX
+1];
482 pfos
[0] = XFONT_GetFontObject( pfo
->prefobjs
[0] );
484 if ( pfos
[0] == NULL
) pfos
[0] = pfo
;
487 for ( i
= 0; i
< count
; i
++ )
488 nitems
+= pitems
->nchars
;
489 ptibuf
= HeapAlloc( GetProcessHeap(), 0, sizeof(XTextItem16
) * nitems
);
490 if ( ptibuf
== NULL
)
491 return; /* out of memory */
494 while ( count
-- > 0 )
496 pti
->chars
= pstr
= pitems
->chars
;
497 pti
->delta
= pitems
->delta
;
499 for ( i
= 0; i
< pitems
->nchars
; i
++, pstr
++ )
501 curfont
= ( pstr
->byte1
!= 0 ) ? 1 : 0;
502 if ( curfont
!= prevfont
)
504 if ( pstr
!= pti
->chars
)
506 pti
->nchars
= pstr
- pti
->chars
;
511 pti
->font
= pfos
[curfont
]->fs
->fid
;
515 pti
->nchars
= pstr
- pti
->chars
;
518 TSXDrawText16( pdisp
, d
, gc
, x
, y
, ptibuf
, pti
- ptibuf
);
519 HeapFree( GetProcessHeap(), 0, ptibuf
);
523 void X11DRV_TextExtents_dbcs_2fonts( fontObject
* pfo
, XChar2b
* pstr
, int count
,
524 int* pdir
, int* pascent
, int* pdescent
,
528 int ascent
, descent
, width
;
531 fontObject
* pfos
[X11FONT_REFOBJS_MAX
+1];
533 pfos
[0] = XFONT_GetFontObject( pfo
->prefobjs
[0] );
535 if ( pfos
[0] == NULL
) pfos
[0] = pfo
;
540 for ( i
= 0; i
< count
; i
++ )
542 curfont
= ( pstr
->byte1
!= 0 ) ? 1 : 0;
543 TSXTextExtents16( pfos
[curfont
]->fs
, pstr
, 1, pdir
,
544 &ascent
, &descent
, &info
);
545 if ( *pascent
< ascent
) *pascent
= ascent
;
546 if ( *pdescent
< descent
) *pdescent
= descent
;
555 static void X11DRV_GetTextMetricsA_cp932( fontObject
* pfo
, LPTEXTMETRICA pTM
)
557 fontObject
* pfo_ansi
= XFONT_GetFontObject( pfo
->prefobjs
[0] );
558 LPIFONTINFO16 pdf
= &pfo
->fi
->df
;
559 LPIFONTINFO16 pdf_ansi
;
561 pdf_ansi
= ( pfo_ansi
!= NULL
) ? (&pfo_ansi
->fi
->df
) : pdf
;
563 if( ! pfo
->lpX11Trans
) {
564 pTM
->tmAscent
= pfo
->fs
->ascent
;
565 pTM
->tmDescent
= pfo
->fs
->descent
;
567 pTM
->tmAscent
= pfo
->lpX11Trans
->ascent
;
568 pTM
->tmDescent
= pfo
->lpX11Trans
->descent
;
571 pTM
->tmAscent
*= pfo
->rescale
;
572 pTM
->tmDescent
*= pfo
->rescale
;
574 pTM
->tmHeight
= pTM
->tmAscent
+ pTM
->tmDescent
;
576 if ( pfo_ansi
!= NULL
)
578 pTM
->tmAveCharWidth
= floor((pfo_ansi
->foAvgCharWidth
* 2.0 + pfo
->foAvgCharWidth
) / 3.0 * pfo
->rescale
+ 0.5);
579 pTM
->tmMaxCharWidth
= __max(pfo_ansi
->foMaxCharWidth
, pfo
->foMaxCharWidth
) * pfo
->rescale
;
583 pTM
->tmAveCharWidth
= floor((pfo
->foAvgCharWidth
* pfo
->rescale
+ 1.0) / 2.0);
584 pTM
->tmMaxCharWidth
= pfo
->foMaxCharWidth
* pfo
->rescale
;
587 pTM
->tmInternalLeading
= pfo
->foInternalLeading
* pfo
->rescale
;
588 pTM
->tmExternalLeading
= pdf
->dfExternalLeading
* pfo
->rescale
;
590 pTM
->tmStruckOut
= (pfo
->fo_flags
& FO_SYNTH_STRIKEOUT
)
591 ? 1 : pdf
->dfStrikeOut
;
592 pTM
->tmUnderlined
= (pfo
->fo_flags
& FO_SYNTH_UNDERLINE
)
593 ? 1 : pdf
->dfUnderline
;
596 if( pfo
->fo_flags
& FO_SYNTH_ITALIC
)
598 pTM
->tmOverhang
+= pTM
->tmHeight
/3;
601 pTM
->tmItalic
= pdf
->dfItalic
;
603 pTM
->tmWeight
= pdf
->dfWeight
;
604 if( pfo
->fo_flags
& FO_SYNTH_BOLD
)
607 pTM
->tmWeight
+= 100;
610 pTM
->tmFirstChar
= pdf_ansi
->dfFirstChar
;
611 pTM
->tmLastChar
= pdf_ansi
->dfLastChar
;
612 pTM
->tmDefaultChar
= pdf_ansi
->dfDefaultChar
;
613 pTM
->tmBreakChar
= pdf_ansi
->dfBreakChar
;
615 pTM
->tmCharSet
= pdf
->dfCharSet
;
616 pTM
->tmPitchAndFamily
= pdf
->dfPitchAndFamily
;
618 pTM
->tmDigitizedAspectX
= pdf
->dfHorizRes
;
619 pTM
->tmDigitizedAspectY
= pdf
->dfVertRes
;
626 const X11DRV_CP X11DRV_cptable
[X11DRV_CPTABLE_COUNT
] =
629 X11DRV_enum_subfont_charset_normal
,
630 X11DRV_unicode_to_char2b_sbcs
,
631 X11DRV_DrawString_normal
,
632 X11DRV_TextWidth_normal
,
633 X11DRV_DrawText_normal
,
634 X11DRV_TextExtents_normal
,
635 X11DRV_GetTextMetricsA_normal
,
638 X11DRV_enum_subfont_charset_normal
,
639 X11DRV_unicode_to_char2b_unicode
,
640 X11DRV_DrawString_normal
,
641 X11DRV_TextWidth_normal
,
642 X11DRV_DrawText_normal
,
643 X11DRV_TextExtents_normal
,
644 X11DRV_GetTextMetricsA_normal
,
647 X11DRV_enum_subfont_charset_cp932
,
648 X11DRV_unicode_to_char2b_cp932
,
649 X11DRV_DrawString_dbcs
,
650 X11DRV_TextWidth_dbcs_2fonts
,
651 X11DRV_DrawText_dbcs_2fonts
,
652 X11DRV_TextExtents_dbcs_2fonts
,
653 X11DRV_GetTextMetricsA_cp932
,
656 X11DRV_enum_subfont_charset_cp936
,
657 X11DRV_unicode_to_char2b_cp936
,
658 X11DRV_DrawString_dbcs
,
659 X11DRV_TextWidth_dbcs_2fonts
,
660 X11DRV_DrawText_dbcs_2fonts
,
661 X11DRV_TextExtents_dbcs_2fonts
,
662 X11DRV_GetTextMetricsA_normal
, /* FIXME */
665 X11DRV_enum_subfont_charset_cp949
,
666 X11DRV_unicode_to_char2b_cp949
,
667 X11DRV_DrawString_dbcs
,
668 X11DRV_TextWidth_dbcs_2fonts
,
669 X11DRV_DrawText_dbcs_2fonts
,
670 X11DRV_TextExtents_dbcs_2fonts
,
671 X11DRV_GetTextMetricsA_normal
, /* FIXME */
674 X11DRV_enum_subfont_charset_cp950
,
675 X11DRV_unicode_to_char2b_cp950
,
676 X11DRV_DrawString_normal
, /* FIXME */
677 X11DRV_TextWidth_normal
, /* FIXME */
678 X11DRV_DrawText_normal
, /* FIXME */
679 X11DRV_TextExtents_normal
, /* FIXME */
680 X11DRV_GetTextMetricsA_normal
, /* FIXME */