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
)
411 XDrawString16( pdisp
, d
, gc
, x
, y
, pstr
, count
);
415 static int X11DRV_TextWidth_normal( fontObject
* pfo
, XChar2b
* pstr
, int count
)
419 ret
= XTextWidth16( pfo
->fs
, pstr
, count
);
424 static void X11DRV_DrawText_normal( fontObject
* pfo
, Display
* pdisp
, Drawable d
,
425 GC gc
, int x
, int y
, XTextItem16
* pitems
,
429 XDrawText16( pdisp
, d
, gc
, x
, y
, pitems
, count
);
433 static void X11DRV_TextExtents_normal( fontObject
* pfo
, XChar2b
* pstr
, int count
,
434 int* pdir
, int* pascent
, int* pdescent
,
440 XTextExtents16( pfo
->fs
, pstr
, count
, pdir
, pascent
, pdescent
, &info
);
442 *pwidth
= info
.width
;
445 static void X11DRV_GetTextMetricsW_normal( fontObject
* pfo
, LPTEXTMETRICW pTM
)
447 LPIFONTINFO16 pdf
= &pfo
->fi
->df
;
449 if( ! pfo
->lpX11Trans
) {
450 pTM
->tmAscent
= pfo
->fs
->ascent
;
451 pTM
->tmDescent
= pfo
->fs
->descent
;
453 pTM
->tmAscent
= pfo
->lpX11Trans
->ascent
;
454 pTM
->tmDescent
= pfo
->lpX11Trans
->descent
;
457 pTM
->tmAscent
*= pfo
->rescale
;
458 pTM
->tmDescent
*= pfo
->rescale
;
460 pTM
->tmHeight
= pTM
->tmAscent
+ pTM
->tmDescent
;
462 pTM
->tmAveCharWidth
= pfo
->foAvgCharWidth
* pfo
->rescale
;
463 pTM
->tmMaxCharWidth
= pfo
->foMaxCharWidth
* pfo
->rescale
;
465 pTM
->tmInternalLeading
= pfo
->foInternalLeading
* pfo
->rescale
;
466 pTM
->tmExternalLeading
= pdf
->dfExternalLeading
* pfo
->rescale
;
468 pTM
->tmStruckOut
= (pfo
->fo_flags
& FO_SYNTH_STRIKEOUT
)
469 ? 1 : pdf
->dfStrikeOut
;
470 pTM
->tmUnderlined
= (pfo
->fo_flags
& FO_SYNTH_UNDERLINE
)
471 ? 1 : pdf
->dfUnderline
;
474 if( pfo
->fo_flags
& FO_SYNTH_ITALIC
)
476 pTM
->tmOverhang
+= pTM
->tmHeight
/3;
479 pTM
->tmItalic
= pdf
->dfItalic
;
481 pTM
->tmWeight
= pdf
->dfWeight
;
482 if( pfo
->fo_flags
& FO_SYNTH_BOLD
)
485 pTM
->tmWeight
+= 100;
488 pTM
->tmFirstChar
= pdf
->dfFirstChar
;
489 pTM
->tmLastChar
= pdf
->dfLastChar
;
490 pTM
->tmDefaultChar
= pdf
->dfDefaultChar
;
491 pTM
->tmBreakChar
= pdf
->dfBreakChar
;
493 pTM
->tmCharSet
= pdf
->dfCharSet
;
494 pTM
->tmPitchAndFamily
= pdf
->dfPitchAndFamily
;
496 pTM
->tmDigitizedAspectX
= pdf
->dfHorizRes
;
497 pTM
->tmDigitizedAspectY
= pdf
->dfVertRes
;
503 void X11DRV_DrawString_dbcs( fontObject
* pfo
, Display
* pdisp
,
504 Drawable d
, GC gc
, int x
, int y
,
505 XChar2b
* pstr
, int count
)
513 X11DRV_cptable
[pfo
->fi
->cptable
].pDrawText(
514 pfo
, pdisp
, d
, gc
, x
, y
, &item
, 1 );
518 int X11DRV_TextWidth_dbcs_2fonts( fontObject
* pfo
, XChar2b
* pstr
, int count
)
523 fontObject
* pfos
[X11FONT_REFOBJS_MAX
+1];
525 pfos
[0] = XFONT_GetFontObject( pfo
->prefobjs
[0] );
527 if ( pfos
[0] == NULL
) pfos
[0] = pfo
;
531 for ( i
= 0; i
< count
; i
++ )
533 curfont
= ( pstr
->byte1
!= 0 ) ? 1 : 0;
534 width
+= XTextWidth16( pfos
[curfont
]->fs
, pstr
, 1 );
542 void X11DRV_DrawText_dbcs_2fonts( fontObject
* pfo
, Display
* pdisp
, Drawable d
,
543 GC gc
, int x
, int y
, XTextItem16
* pitems
,
546 int i
, nitems
, prevfont
= -1, curfont
;
550 fontObject
* pfos
[X11FONT_REFOBJS_MAX
+1];
552 pfos
[0] = XFONT_GetFontObject( pfo
->prefobjs
[0] );
554 if ( pfos
[0] == NULL
) pfos
[0] = pfo
;
557 for ( i
= 0; i
< count
; i
++ )
558 nitems
+= pitems
->nchars
;
559 ptibuf
= HeapAlloc( GetProcessHeap(), 0, sizeof(XTextItem16
) * nitems
);
560 if ( ptibuf
== NULL
)
561 return; /* out of memory */
564 while ( count
-- > 0 )
566 pti
->chars
= pstr
= pitems
->chars
;
567 pti
->delta
= pitems
->delta
;
569 for ( i
= 0; i
< pitems
->nchars
; i
++, pstr
++ )
571 curfont
= ( pstr
->byte1
!= 0 ) ? 1 : 0;
572 if ( curfont
!= prevfont
)
574 if ( pstr
!= pti
->chars
)
576 pti
->nchars
= pstr
- pti
->chars
;
581 pti
->font
= pfos
[curfont
]->fs
->fid
;
585 pti
->nchars
= pstr
- pti
->chars
;
589 XDrawText16( pdisp
, d
, gc
, x
, y
, ptibuf
, pti
- ptibuf
);
591 HeapFree( GetProcessHeap(), 0, ptibuf
);
595 void X11DRV_TextExtents_dbcs_2fonts( fontObject
* pfo
, XChar2b
* pstr
, int count
,
596 int* pdir
, int* pascent
, int* pdescent
,
600 int ascent
, descent
, width
;
603 fontObject
* pfos
[X11FONT_REFOBJS_MAX
+1];
605 pfos
[0] = XFONT_GetFontObject( pfo
->prefobjs
[0] );
607 if ( pfos
[0] == NULL
) pfos
[0] = pfo
;
613 for ( i
= 0; i
< count
; i
++ )
615 curfont
= ( pstr
->byte1
!= 0 ) ? 1 : 0;
616 XTextExtents16( pfos
[curfont
]->fs
, pstr
, 1, pdir
, &ascent
, &descent
, &info
);
617 if ( *pascent
< ascent
) *pascent
= ascent
;
618 if ( *pdescent
< descent
) *pdescent
= descent
;
627 static void X11DRV_GetTextMetricsW_cp932( fontObject
* pfo
, LPTEXTMETRICW pTM
)
629 fontObject
* pfo_ansi
= XFONT_GetFontObject( pfo
->prefobjs
[0] );
630 LPIFONTINFO16 pdf
= &pfo
->fi
->df
;
631 LPIFONTINFO16 pdf_ansi
;
633 pdf_ansi
= ( pfo_ansi
!= NULL
) ? (&pfo_ansi
->fi
->df
) : pdf
;
635 if( ! pfo
->lpX11Trans
) {
636 pTM
->tmAscent
= pfo
->fs
->ascent
;
637 pTM
->tmDescent
= pfo
->fs
->descent
;
639 pTM
->tmAscent
= pfo
->lpX11Trans
->ascent
;
640 pTM
->tmDescent
= pfo
->lpX11Trans
->descent
;
643 pTM
->tmAscent
*= pfo
->rescale
;
644 pTM
->tmDescent
*= pfo
->rescale
;
646 pTM
->tmHeight
= pTM
->tmAscent
+ pTM
->tmDescent
;
648 if ( pfo_ansi
!= NULL
)
650 pTM
->tmAveCharWidth
= floor((pfo_ansi
->foAvgCharWidth
* 2.0 + pfo
->foAvgCharWidth
) / 3.0 * pfo
->rescale
+ 0.5);
651 pTM
->tmMaxCharWidth
= max(pfo_ansi
->foMaxCharWidth
, pfo
->foMaxCharWidth
) * pfo
->rescale
;
655 pTM
->tmAveCharWidth
= floor((pfo
->foAvgCharWidth
* pfo
->rescale
+ 1.0) / 2.0);
656 pTM
->tmMaxCharWidth
= pfo
->foMaxCharWidth
* pfo
->rescale
;
659 pTM
->tmInternalLeading
= pfo
->foInternalLeading
* pfo
->rescale
;
660 pTM
->tmExternalLeading
= pdf
->dfExternalLeading
* pfo
->rescale
;
662 pTM
->tmStruckOut
= (pfo
->fo_flags
& FO_SYNTH_STRIKEOUT
)
663 ? 1 : pdf
->dfStrikeOut
;
664 pTM
->tmUnderlined
= (pfo
->fo_flags
& FO_SYNTH_UNDERLINE
)
665 ? 1 : pdf
->dfUnderline
;
668 if( pfo
->fo_flags
& FO_SYNTH_ITALIC
)
670 pTM
->tmOverhang
+= pTM
->tmHeight
/3;
673 pTM
->tmItalic
= pdf
->dfItalic
;
675 pTM
->tmWeight
= pdf
->dfWeight
;
676 if( pfo
->fo_flags
& FO_SYNTH_BOLD
)
679 pTM
->tmWeight
+= 100;
682 pTM
->tmFirstChar
= pdf_ansi
->dfFirstChar
;
683 pTM
->tmLastChar
= pdf_ansi
->dfLastChar
;
684 pTM
->tmDefaultChar
= pdf_ansi
->dfDefaultChar
;
685 pTM
->tmBreakChar
= pdf_ansi
->dfBreakChar
;
687 pTM
->tmCharSet
= pdf
->dfCharSet
;
688 pTM
->tmPitchAndFamily
= pdf
->dfPitchAndFamily
;
690 pTM
->tmDigitizedAspectX
= pdf
->dfHorizRes
;
691 pTM
->tmDigitizedAspectY
= pdf
->dfVertRes
;
698 const X11DRV_CP X11DRV_cptable
[X11DRV_CPTABLE_COUNT
] =
701 X11DRV_enum_subfont_charset_normal
,
702 X11DRV_unicode_to_char2b_sbcs
,
703 X11DRV_DrawString_normal
,
704 X11DRV_TextWidth_normal
,
705 X11DRV_DrawText_normal
,
706 X11DRV_TextExtents_normal
,
707 X11DRV_GetTextMetricsW_normal
,
710 X11DRV_enum_subfont_charset_normal
,
711 X11DRV_unicode_to_char2b_unicode
,
712 X11DRV_DrawString_normal
,
713 X11DRV_TextWidth_normal
,
714 X11DRV_DrawText_normal
,
715 X11DRV_TextExtents_normal
,
716 X11DRV_GetTextMetricsW_normal
,
719 X11DRV_enum_subfont_charset_cp932
,
720 X11DRV_unicode_to_char2b_cp932
,
721 X11DRV_DrawString_dbcs
,
722 X11DRV_TextWidth_dbcs_2fonts
,
723 X11DRV_DrawText_dbcs_2fonts
,
724 X11DRV_TextExtents_dbcs_2fonts
,
725 X11DRV_GetTextMetricsW_cp932
,
728 X11DRV_enum_subfont_charset_cp936
,
729 X11DRV_unicode_to_char2b_cp936
,
730 X11DRV_DrawString_dbcs
,
731 X11DRV_TextWidth_dbcs_2fonts
,
732 X11DRV_DrawText_dbcs_2fonts
,
733 X11DRV_TextExtents_dbcs_2fonts
,
734 X11DRV_GetTextMetricsW_normal
, /* FIXME */
737 X11DRV_enum_subfont_charset_cp949
,
738 X11DRV_unicode_to_char2b_cp949
,
739 X11DRV_DrawString_dbcs
,
740 X11DRV_TextWidth_dbcs_2fonts
,
741 X11DRV_DrawText_dbcs_2fonts
,
742 X11DRV_TextExtents_dbcs_2fonts
,
743 X11DRV_GetTextMetricsW_normal
, /* FIXME */
746 X11DRV_enum_subfont_charset_cp950
,
747 X11DRV_unicode_to_char2b_cp950
,
748 X11DRV_DrawString_dbcs
,
749 X11DRV_TextWidth_dbcs_2fonts
,
750 X11DRV_DrawText_dbcs_2fonts
,
751 X11DRV_TextExtents_dbcs_2fonts
,
752 X11DRV_GetTextMetricsW_cp932
,
755 X11DRV_enum_subfont_charset_normal
,
756 X11DRV_unicode_to_char2b_symbol
,
757 X11DRV_DrawString_normal
,
758 X11DRV_TextWidth_normal
,
759 X11DRV_DrawText_normal
,
760 X11DRV_TextExtents_normal
,
761 X11DRV_GetTextMetricsW_normal
,