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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
31 /***********************************************************************
32 * IsLegalDBCSChar for cp932/936/949/950/euc
35 int IsLegalDBCSChar_cp932( BYTE lead
, BYTE trail
)
37 return ( ( ( lead
>= (BYTE
)0x81 && lead
<= (BYTE
)0x9f ) ||
38 ( lead
>= (BYTE
)0xe0 && lead
<= (BYTE
)0xfc ) ) &&
39 ( ( trail
>= (BYTE
)0x40 && trail
<= (BYTE
)0x7e ) ||
40 ( trail
>= (BYTE
)0x80 && trail
<= (BYTE
)0xfc ) ) );
44 int IsLegalDBCSChar_cp936( BYTE lead
, BYTE trail
)
46 return ( ( lead
>= (BYTE
)0x81 && lead
<= (BYTE
)0xfe ) &&
47 ( trail
>= (BYTE
)0x40 && trail
<= (BYTE
)0xfe ) );
51 int IsLegalDBCSChar_cp949( BYTE lead
, BYTE trail
)
53 return ( ( lead
>= (BYTE
)0x81 && lead
<= (BYTE
)0xfe ) &&
54 ( trail
>= (BYTE
)0x41 && trail
<= (BYTE
)0xfe ) );
58 int IsLegalDBCSChar_cp950( BYTE lead
, BYTE trail
)
60 return ( ( lead
>= (BYTE
)0x81 && lead
<= (BYTE
)0xfe ) &&
61 ( ( trail
>= (BYTE
)0x40 && trail
<= (BYTE
)0x7e ) ||
62 ( trail
>= (BYTE
)0xa1 && trail
<= (BYTE
)0xfe ) ) );
66 /***********************************************************************
67 * DBCSCharToXChar2b for cp932/euc
71 void DBCSCharToXChar2b_cp932( XChar2b
* pch
, BYTE lead
, BYTE trail
)
73 unsigned int high
, low
;
75 high
= (unsigned int)lead
;
76 low
= (unsigned int)trail
;
79 high
= (high
<<1) - 0xe0;
81 high
= (high
<<1) - 0x160;
95 pch
->byte1
= (unsigned char)high
;
96 pch
->byte2
= (unsigned char)low
;
100 static WORD
X11DRV_enum_subfont_charset_normal( UINT index
)
102 return DEFAULT_CHARSET
;
105 static WORD
X11DRV_enum_subfont_charset_cp932( UINT index
)
109 case 0: return X11FONT_JISX0201_CHARSET
;
110 case 1: return X11FONT_JISX0212_CHARSET
;
113 return DEFAULT_CHARSET
;
116 static WORD
X11DRV_enum_subfont_charset_cp936( UINT index
)
120 case 0: return ANSI_CHARSET
;
123 return DEFAULT_CHARSET
;
126 static WORD
X11DRV_enum_subfont_charset_cp949( UINT index
)
130 case 0: return ANSI_CHARSET
;
133 return DEFAULT_CHARSET
;
136 static WORD
X11DRV_enum_subfont_charset_cp950( UINT index
)
140 case 0: return ANSI_CHARSET
;
143 return DEFAULT_CHARSET
;
147 static XChar2b
* X11DRV_unicode_to_char2b_sbcs( fontObject
* pfo
,
148 LPCWSTR lpwstr
, UINT count
)
153 UINT codepage
= pfo
->fi
->codepage
;
154 char ch
= pfo
->fs
->default_char
;
156 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
158 if (!(str
= HeapAlloc( GetProcessHeap(), 0, count
)))
160 HeapFree( GetProcessHeap(), 0, str2b
);
164 WideCharToMultiByte( codepage
, 0, lpwstr
, count
, str
, count
, &ch
, NULL
);
166 for (i
= 0; i
< count
; i
++)
169 str2b
[i
].byte2
= str
[i
];
171 HeapFree( GetProcessHeap(), 0, str
);
176 static XChar2b
* X11DRV_unicode_to_char2b_unicode( fontObject
* pfo
,
177 LPCWSTR lpwstr
, UINT count
)
182 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
185 for (i
= 0; i
< count
; i
++)
187 str2b
[i
].byte1
= lpwstr
[i
] >> 8;
188 str2b
[i
].byte2
= lpwstr
[i
] & 0xff;
194 /* FIXME: handle jisx0212.1990... */
195 static XChar2b
* X11DRV_unicode_to_char2b_cp932( fontObject
* pfo
,
196 LPCWSTR lpwstr
, UINT count
)
203 char ch
= pfo
->fs
->default_char
;
205 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
207 if (!(str
= HeapAlloc( GetProcessHeap(), 0, count
*2 )))
209 HeapFree( GetProcessHeap(), 0, str2b
);
213 /* handle jisx0212.1990... */
214 WideCharToMultiByte( 932, 0, lpwstr
, count
, str
, count
*2, &ch
, NULL
);
216 str_src
= (BYTE
*) str
;
218 for (i
= 0; i
< count
; i
++, str_src
++, str2b_dst
++)
220 if ( IsLegalDBCSChar_cp932( *str_src
, *(str_src
+1) ) )
222 DBCSCharToXChar2b_cp932( str2b_dst
, *str_src
, *(str_src
+1) );
227 str2b_dst
->byte1
= 0;
228 str2b_dst
->byte2
= *str_src
;
232 HeapFree( GetProcessHeap(), 0, str
);
238 static XChar2b
* X11DRV_unicode_to_char2b_cp936( fontObject
* pfo
,
239 LPCWSTR lpwstr
, UINT count
)
246 char ch
= pfo
->fs
->default_char
;
248 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
250 if (!(str
= HeapAlloc( GetProcessHeap(), 0, count
*2 )))
252 HeapFree( GetProcessHeap(), 0, str2b
);
255 WideCharToMultiByte( 936, 0, lpwstr
, count
, str
, count
*2, &ch
, NULL
);
257 str_src
= (BYTE
*) str
;
259 for (i
= 0; i
< count
; i
++, str_src
++, str2b_dst
++)
261 if ( IsLegalDBCSChar_cp936( *str_src
, *(str_src
+1) ) )
263 str2b_dst
->byte1
= *str_src
;
264 str2b_dst
->byte2
= *(str_src
+1);
269 str2b_dst
->byte1
= 0;
270 str2b_dst
->byte2
= *str_src
;
274 HeapFree( GetProcessHeap(), 0, str
);
279 static XChar2b
* X11DRV_unicode_to_char2b_cp949( fontObject
* pfo
,
280 LPCWSTR lpwstr
, UINT count
)
287 char ch
= pfo
->fs
->default_char
;
289 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
291 if (!(str
= HeapAlloc( GetProcessHeap(), 0, count
*2 )))
293 HeapFree( GetProcessHeap(), 0, str2b
);
296 WideCharToMultiByte( 949, 0, lpwstr
, count
, str
, count
*2, &ch
, NULL
);
298 str_src
= (BYTE
*) str
;
300 for (i
= 0; i
< count
; i
++, str_src
++, str2b_dst
++)
302 if ( IsLegalDBCSChar_cp949( *str_src
, *(str_src
+1) ) )
304 str2b_dst
->byte1
= *str_src
;
305 str2b_dst
->byte2
= *(str_src
+1);
310 str2b_dst
->byte1
= 0;
311 str2b_dst
->byte2
= *str_src
;
315 HeapFree( GetProcessHeap(), 0, str
);
321 static XChar2b
* X11DRV_unicode_to_char2b_cp950( fontObject
* pfo
,
322 LPCWSTR lpwstr
, UINT count
)
329 char ch
= pfo
->fs
->default_char
;
331 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
333 if (!(str
= HeapAlloc( GetProcessHeap(), 0, count
*2 )))
335 HeapFree( GetProcessHeap(), 0, str2b
);
338 WideCharToMultiByte( 950, 0, lpwstr
, count
, str
, count
*2, &ch
, NULL
);
340 str_src
= (BYTE
*) str
;
342 for (i
= 0; i
< count
; i
++, str_src
++, str2b_dst
++)
344 if ( IsLegalDBCSChar_cp950( *str_src
, *(str_src
+1) ) )
346 str2b_dst
->byte1
= *str_src
;
347 str2b_dst
->byte2
= *(str_src
+1);
352 str2b_dst
->byte1
= 0;
353 str2b_dst
->byte2
= *str_src
;
357 HeapFree( GetProcessHeap(), 0, str
);
362 static XChar2b
* X11DRV_unicode_to_char2b_symbol( fontObject
* pfo
,
363 LPCWSTR lpwstr
, UINT count
)
367 char ch
= pfo
->fs
->default_char
;
369 if (!(str2b
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(XChar2b
) )))
372 for (i
= 0; i
< count
; i
++)
375 if(lpwstr
[i
] >= 0xf000 && lpwstr
[i
] < 0xf100)
376 str2b
[i
].byte2
= lpwstr
[i
] - 0xf000;
377 else if(lpwstr
[i
] < 0x100)
378 str2b
[i
].byte2
= lpwstr
[i
];
387 static void X11DRV_DrawString_normal( fontObject
* pfo
, Display
* pdisp
,
388 Drawable d
, GC gc
, int x
, int y
,
389 XChar2b
* pstr
, int count
)
392 XDrawString16( pdisp
, d
, gc
, x
, y
, pstr
, count
);
396 static int X11DRV_TextWidth_normal( fontObject
* pfo
, XChar2b
* pstr
, int count
)
400 ret
= XTextWidth16( pfo
->fs
, pstr
, count
);
405 static void X11DRV_DrawText_normal( fontObject
* pfo
, Display
* pdisp
, Drawable d
,
406 GC gc
, int x
, int y
, XTextItem16
* pitems
,
410 XDrawText16( pdisp
, d
, gc
, x
, y
, pitems
, count
);
414 static void X11DRV_TextExtents_normal( fontObject
* pfo
, XChar2b
* pstr
, int count
,
415 int* pdir
, int* pascent
, int* pdescent
,
416 int* pwidth
, int max_extent
, int* pfit
,
417 int* partial_extents
)
420 int ascent
, descent
, width
;
428 for ( i
= 0; i
< count
; i
++ )
430 XTextExtents16( pfo
->fs
, pstr
, 1, pdir
, &ascent
, &descent
, &info
);
431 if ( *pascent
< ascent
) *pascent
= ascent
;
432 if ( *pdescent
< descent
) *pdescent
= descent
;
434 if ( partial_extents
) partial_extents
[i
] = width
;
435 if ( width
< max_extent
) fit
++;
441 if ( pfit
) *pfit
= fit
;
444 static void X11DRV_GetTextMetricsW_normal( fontObject
* pfo
, LPTEXTMETRICW pTM
)
446 LPIFONTINFO16 pdf
= &pfo
->fi
->df
;
448 if( ! pfo
->lpX11Trans
) {
449 pTM
->tmAscent
= pfo
->fs
->ascent
;
450 pTM
->tmDescent
= pfo
->fs
->descent
;
452 pTM
->tmAscent
= pfo
->lpX11Trans
->ascent
;
453 pTM
->tmDescent
= pfo
->lpX11Trans
->descent
;
456 pTM
->tmAscent
*= pfo
->rescale
;
457 pTM
->tmDescent
*= pfo
->rescale
;
459 pTM
->tmHeight
= pTM
->tmAscent
+ pTM
->tmDescent
;
461 pTM
->tmAveCharWidth
= pfo
->foAvgCharWidth
* pfo
->rescale
;
462 pTM
->tmMaxCharWidth
= pfo
->foMaxCharWidth
* pfo
->rescale
;
464 pTM
->tmInternalLeading
= pfo
->foInternalLeading
* pfo
->rescale
;
465 pTM
->tmExternalLeading
= pdf
->dfExternalLeading
* pfo
->rescale
;
467 pTM
->tmStruckOut
= (pfo
->fo_flags
& FO_SYNTH_STRIKEOUT
)
468 ? 1 : pdf
->dfStrikeOut
;
469 pTM
->tmUnderlined
= (pfo
->fo_flags
& FO_SYNTH_UNDERLINE
)
470 ? 1 : pdf
->dfUnderline
;
473 if( pfo
->fo_flags
& FO_SYNTH_ITALIC
)
475 pTM
->tmOverhang
+= pTM
->tmHeight
/3;
478 pTM
->tmItalic
= pdf
->dfItalic
;
480 pTM
->tmWeight
= pdf
->dfWeight
;
481 if( pfo
->fo_flags
& FO_SYNTH_BOLD
)
484 pTM
->tmWeight
+= 100;
487 pTM
->tmFirstChar
= pdf
->dfFirstChar
;
488 pTM
->tmLastChar
= pdf
->dfLastChar
;
489 pTM
->tmDefaultChar
= pdf
->dfDefaultChar
;
490 pTM
->tmBreakChar
= pdf
->dfBreakChar
;
492 pTM
->tmCharSet
= pdf
->dfCharSet
;
493 pTM
->tmPitchAndFamily
= pdf
->dfPitchAndFamily
;
495 pTM
->tmDigitizedAspectX
= pdf
->dfHorizRes
;
496 pTM
->tmDigitizedAspectY
= pdf
->dfVertRes
;
502 void X11DRV_DrawString_dbcs( fontObject
* pfo
, Display
* pdisp
,
503 Drawable d
, GC gc
, int x
, int y
,
504 XChar2b
* pstr
, int count
)
512 X11DRV_cptable
[pfo
->fi
->cptable
].pDrawText(
513 pfo
, pdisp
, d
, gc
, x
, y
, &item
, 1 );
517 int X11DRV_TextWidth_dbcs_2fonts( fontObject
* pfo
, XChar2b
* pstr
, int count
)
522 fontObject
* pfos
[X11FONT_REFOBJS_MAX
+1];
524 pfos
[0] = XFONT_GetFontObject( pfo
->prefobjs
[0] );
526 if ( pfos
[0] == NULL
) pfos
[0] = pfo
;
530 for ( i
= 0; i
< count
; i
++ )
532 curfont
= ( pstr
->byte1
!= 0 ) ? 1 : 0;
533 width
+= XTextWidth16( pfos
[curfont
]->fs
, pstr
, 1 );
541 void X11DRV_DrawText_dbcs_2fonts( fontObject
* pfo
, Display
* pdisp
, Drawable d
,
542 GC gc
, int x
, int y
, XTextItem16
* pitems
,
545 int i
, nitems
, prevfont
= -1, curfont
;
549 fontObject
* pfos
[X11FONT_REFOBJS_MAX
+1];
551 pfos
[0] = XFONT_GetFontObject( pfo
->prefobjs
[0] );
553 if ( pfos
[0] == NULL
) pfos
[0] = pfo
;
556 for ( i
= 0; i
< count
; i
++ )
557 nitems
+= pitems
->nchars
;
558 ptibuf
= HeapAlloc( GetProcessHeap(), 0, sizeof(XTextItem16
) * nitems
);
559 if ( ptibuf
== NULL
)
560 return; /* out of memory */
563 while ( count
-- > 0 )
565 pti
->chars
= pstr
= pitems
->chars
;
566 pti
->delta
= pitems
->delta
;
568 for ( i
= 0; i
< pitems
->nchars
; i
++, pstr
++ )
570 curfont
= ( pstr
->byte1
!= 0 ) ? 1 : 0;
571 if ( curfont
!= prevfont
)
573 if ( pstr
!= pti
->chars
)
575 pti
->nchars
= pstr
- pti
->chars
;
580 pti
->font
= pfos
[curfont
]->fs
->fid
;
584 pti
->nchars
= pstr
- pti
->chars
;
588 XDrawText16( pdisp
, d
, gc
, x
, y
, ptibuf
, pti
- ptibuf
);
590 HeapFree( GetProcessHeap(), 0, ptibuf
);
594 void X11DRV_TextExtents_dbcs_2fonts( fontObject
* pfo
, XChar2b
* pstr
, int count
,
595 int* pdir
, int* pascent
, int* pdescent
,
596 int* pwidth
, int max_extent
, int* pfit
,
597 int* partial_extents
)
600 int ascent
, descent
, width
;
604 fontObject
* pfos
[X11FONT_REFOBJS_MAX
+1];
606 pfos
[0] = XFONT_GetFontObject( pfo
->prefobjs
[0] );
608 if ( pfos
[0] == NULL
) pfos
[0] = pfo
;
615 for ( i
= 0; i
< count
; i
++ )
617 curfont
= ( pstr
->byte1
!= 0 ) ? 1 : 0;
618 XTextExtents16( pfos
[curfont
]->fs
, pstr
, 1, pdir
, &ascent
, &descent
, &info
);
619 if ( *pascent
< ascent
) *pascent
= ascent
;
620 if ( *pdescent
< descent
) *pdescent
= descent
;
622 if ( partial_extents
) partial_extents
[i
] = width
;
623 if ( width
<= max_extent
) fit
++;
629 if ( pfit
) *pfit
= fit
;
632 static void X11DRV_GetTextMetricsW_cp932( fontObject
* pfo
, LPTEXTMETRICW pTM
)
634 fontObject
* pfo_ansi
= XFONT_GetFontObject( pfo
->prefobjs
[0] );
635 LPIFONTINFO16 pdf
= &pfo
->fi
->df
;
636 LPIFONTINFO16 pdf_ansi
;
638 pdf_ansi
= ( pfo_ansi
!= NULL
) ? (&pfo_ansi
->fi
->df
) : pdf
;
640 if( ! pfo
->lpX11Trans
) {
641 pTM
->tmAscent
= pfo
->fs
->ascent
;
642 pTM
->tmDescent
= pfo
->fs
->descent
;
644 pTM
->tmAscent
= pfo
->lpX11Trans
->ascent
;
645 pTM
->tmDescent
= pfo
->lpX11Trans
->descent
;
648 pTM
->tmAscent
*= pfo
->rescale
;
649 pTM
->tmDescent
*= pfo
->rescale
;
651 pTM
->tmHeight
= pTM
->tmAscent
+ pTM
->tmDescent
;
653 if ( pfo_ansi
!= NULL
)
655 pTM
->tmAveCharWidth
= floor((pfo_ansi
->foAvgCharWidth
* 2.0 + pfo
->foAvgCharWidth
) / 3.0 * pfo
->rescale
+ 0.5);
656 pTM
->tmMaxCharWidth
= max(pfo_ansi
->foMaxCharWidth
, pfo
->foMaxCharWidth
) * pfo
->rescale
;
660 pTM
->tmAveCharWidth
= floor((pfo
->foAvgCharWidth
* pfo
->rescale
+ 1.0) / 2.0);
661 pTM
->tmMaxCharWidth
= pfo
->foMaxCharWidth
* pfo
->rescale
;
664 pTM
->tmInternalLeading
= pfo
->foInternalLeading
* pfo
->rescale
;
665 pTM
->tmExternalLeading
= pdf
->dfExternalLeading
* pfo
->rescale
;
667 pTM
->tmStruckOut
= (pfo
->fo_flags
& FO_SYNTH_STRIKEOUT
)
668 ? 1 : pdf
->dfStrikeOut
;
669 pTM
->tmUnderlined
= (pfo
->fo_flags
& FO_SYNTH_UNDERLINE
)
670 ? 1 : pdf
->dfUnderline
;
673 if( pfo
->fo_flags
& FO_SYNTH_ITALIC
)
675 pTM
->tmOverhang
+= pTM
->tmHeight
/3;
678 pTM
->tmItalic
= pdf
->dfItalic
;
680 pTM
->tmWeight
= pdf
->dfWeight
;
681 if( pfo
->fo_flags
& FO_SYNTH_BOLD
)
684 pTM
->tmWeight
+= 100;
687 pTM
->tmFirstChar
= pdf_ansi
->dfFirstChar
;
688 pTM
->tmLastChar
= pdf_ansi
->dfLastChar
;
689 pTM
->tmDefaultChar
= pdf_ansi
->dfDefaultChar
;
690 pTM
->tmBreakChar
= pdf_ansi
->dfBreakChar
;
692 pTM
->tmCharSet
= pdf
->dfCharSet
;
693 pTM
->tmPitchAndFamily
= pdf
->dfPitchAndFamily
;
695 pTM
->tmDigitizedAspectX
= pdf
->dfHorizRes
;
696 pTM
->tmDigitizedAspectY
= pdf
->dfVertRes
;
703 const X11DRV_CP X11DRV_cptable
[X11DRV_CPTABLE_COUNT
] =
706 X11DRV_enum_subfont_charset_normal
,
707 X11DRV_unicode_to_char2b_sbcs
,
708 X11DRV_DrawString_normal
,
709 X11DRV_TextWidth_normal
,
710 X11DRV_DrawText_normal
,
711 X11DRV_TextExtents_normal
,
712 X11DRV_GetTextMetricsW_normal
,
715 X11DRV_enum_subfont_charset_normal
,
716 X11DRV_unicode_to_char2b_unicode
,
717 X11DRV_DrawString_normal
,
718 X11DRV_TextWidth_normal
,
719 X11DRV_DrawText_normal
,
720 X11DRV_TextExtents_normal
,
721 X11DRV_GetTextMetricsW_normal
,
724 X11DRV_enum_subfont_charset_cp932
,
725 X11DRV_unicode_to_char2b_cp932
,
726 X11DRV_DrawString_dbcs
,
727 X11DRV_TextWidth_dbcs_2fonts
,
728 X11DRV_DrawText_dbcs_2fonts
,
729 X11DRV_TextExtents_dbcs_2fonts
,
730 X11DRV_GetTextMetricsW_cp932
,
733 X11DRV_enum_subfont_charset_cp936
,
734 X11DRV_unicode_to_char2b_cp936
,
735 X11DRV_DrawString_dbcs
,
736 X11DRV_TextWidth_dbcs_2fonts
,
737 X11DRV_DrawText_dbcs_2fonts
,
738 X11DRV_TextExtents_dbcs_2fonts
,
739 X11DRV_GetTextMetricsW_normal
, /* FIXME */
742 X11DRV_enum_subfont_charset_cp949
,
743 X11DRV_unicode_to_char2b_cp949
,
744 X11DRV_DrawString_dbcs
,
745 X11DRV_TextWidth_dbcs_2fonts
,
746 X11DRV_DrawText_dbcs_2fonts
,
747 X11DRV_TextExtents_dbcs_2fonts
,
748 X11DRV_GetTextMetricsW_normal
, /* FIXME */
751 X11DRV_enum_subfont_charset_cp950
,
752 X11DRV_unicode_to_char2b_cp950
,
753 X11DRV_DrawString_dbcs
,
754 X11DRV_TextWidth_dbcs_2fonts
,
755 X11DRV_DrawText_dbcs_2fonts
,
756 X11DRV_TextExtents_dbcs_2fonts
,
757 X11DRV_GetTextMetricsW_cp932
,
760 X11DRV_enum_subfont_charset_normal
,
761 X11DRV_unicode_to_char2b_symbol
,
762 X11DRV_DrawString_normal
,
763 X11DRV_TextWidth_normal
,
764 X11DRV_DrawText_normal
,
765 X11DRV_TextExtents_normal
,
766 X11DRV_GetTextMetricsW_normal
,