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 */