diff options
author | hobbs <hobbs> | 2001-06-04 03:07:54 (GMT) |
---|---|---|
committer | hobbs <hobbs> | 2001-06-04 03:07:54 (GMT) |
commit | 5165963ea7e6851e73d580e8e762af57814cfa98 (patch) | |
tree | e92d8d254e94d90c1f9bcb107f299b5c3bb78066 /unix/tkUnixFont.c | |
parent | ac5f60c9f60c0027e827f34bb7725791923496e2 (diff) | |
download | tk-5165963ea7e6851e73d580e8e762af57814cfa98.zip tk-5165963ea7e6851e73d580e8e762af57814cfa98.tar.gz tk-5165963ea7e6851e73d580e8e762af57814cfa98.tar.bz2 |
* unix/tkUnixFont.c: Corrected support for iso10646 (X11 Unicode)
fonts on Unix. This adds a ucs-2be (UCS-2 Big Endian) encoding in
Tk on Unix that is used for those fonts (X11 requires
big-endianness). (welch) [Patch #406411; Bug #220890 #220899]
This differs from the 8.3.3 patch by not adding ucs-2be in the
preferred encodingList (seems works fine without).
Added alias for jisx0201* fonts to jis0201 encoding. [Bug #414033]
Diffstat (limited to 'unix/tkUnixFont.c')
-rw-r--r-- | unix/tkUnixFont.c | 222 |
1 files changed, 214 insertions, 8 deletions
diff --git a/unix/tkUnixFont.c b/unix/tkUnixFont.c index 59826c2..4d711e8 100644 --- a/unix/tkUnixFont.c +++ b/unix/tkUnixFont.c @@ -9,11 +9,12 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkUnixFont.c,v 1.8 1999/12/21 23:56:34 hobbs Exp $ + * RCS: @(#) $Id: tkUnixFont.c,v 1.9 2001/06/04 03:07:54 hobbs Exp $ */ #include "tkUnixInt.h" #include "tkFont.h" +#include <netinet/in.h> /* for htons() prototype */ /* * The preferred font encodings. @@ -180,6 +181,7 @@ static EncodingAlias encodingAliases[] = { {"cns11643-1", "cns11643*.1-0"}, {"cns11643-2", "cns11643*-2"}, {"cns11643-2", "cns11643*.2-0"}, + {"jis0201", "jisx0201*"}, {"jis0201", "jisx0202*"}, {"jis0208", "jisc6226*"}, {"jis0208", "jisx0208*"}, @@ -187,6 +189,7 @@ static EncodingAlias encodingAliases[] = { {"tis620", "tis620*"}, {"ksc5601", "ksc5601*"}, {"dingbats", "*dingbats"}, + {"ucs-2be", "iso10646-1"}, {NULL, NULL} }; @@ -243,6 +246,16 @@ static void ReleaseSubFont _ANSI_ARGS_((Display *display, SubFont *subFontPtr)); static int SeenName _ANSI_ARGS_((CONST char *name, Tcl_DString *dsPtr)); +static int Ucs2beToUtfProc _ANSI_ARGS_((ClientData clientData, + CONST char *src, int srcLen, int flags, + Tcl_EncodingState *statePtr, char *dst, int dstLen, + int *srcReadPtr, int *dstWrotePtr, + int *dstCharsPtr)); +static int UtfToUcs2beProc _ANSI_ARGS_((ClientData clientData, + CONST char *src, int srcLen, int flags, + Tcl_EncodingState *statePtr, char *dst, int dstLen, + int *srcReadPtr, int *dstWrotePtr, + int *dstCharsPtr)); /* @@ -274,12 +287,12 @@ TkpFontPkgInit(mainPtr) int i; if (tsdPtr->controlFamily.encoding == NULL) { - type.encodingName = "X11ControlChars"; - type.toUtfProc = ControlUtfProc; - type.fromUtfProc = ControlUtfProc; - type.freeProc = NULL; - type.clientData = NULL; - type.nullSize = 0; + type.encodingName = "X11ControlChars"; + type.toUtfProc = ControlUtfProc; + type.fromUtfProc = ControlUtfProc; + type.freeProc = NULL; + type.clientData = NULL; + type.nullSize = 0; tsdPtr->controlFamily.refCount = 2; tsdPtr->controlFamily.encoding = Tcl_CreateEncoding(&type); @@ -291,6 +304,19 @@ TkpFontPkgInit(mainPtr) FontMapInsert(&dummy, i); FontMapInsert(&dummy, i + 0x80); } + + /* + * UCS-2BE is unicode in big-endian format. + * It is used in iso10646 fonts. + */ + + type.encodingName = "ucs-2be"; + type.toUtfProc = Ucs2beToUtfProc; + type.fromUtfProc = UtfToUcs2beProc; + type.freeProc = NULL; + type.clientData = NULL; + type.nullSize = 2; + Tcl_CreateEncoding(&type); } } @@ -387,6 +413,176 @@ ControlUtfProc(clientData, src, srcLen, flags, statePtr, dst, dstLen, } /* + *------------------------------------------------------------------------- + * + * Ucs2beToUtfProc -- + * + * Convert from UCS-2BE (big-endian 16-bit Unicode) to UTF-8. + * + * Results: + * Returns TCL_OK if conversion was successful. + * + * Side effects: + * None. + * + *------------------------------------------------------------------------- + */ + +static int +Ucs2beToUtfProc(clientData, src, srcLen, flags, statePtr, dst, dstLen, + srcReadPtr, dstWrotePtr, dstCharsPtr) + ClientData clientData; /* Not used. */ + CONST char *src; /* Source string in Unicode. */ + int srcLen; /* Source string length in bytes. */ + int flags; /* Conversion control flags. */ + Tcl_EncodingState *statePtr;/* Place for conversion routine to store + * state information used during a piecewise + * conversion. Contents of statePtr are + * initialized and/or reset by conversion + * routine under control of flags argument. */ + char *dst; /* Output buffer in which converted string + * is stored. */ + int dstLen; /* The maximum length of output buffer in + * bytes. */ + int *srcReadPtr; /* Filled with the number of bytes from the + * source string that were converted. This + * may be less than the original source length + * if there was a problem converting some + * source characters. */ + int *dstWrotePtr; /* Filled with the number of bytes that were + * stored in the output buffer as a result of + * the conversion. */ + int *dstCharsPtr; /* Filled with the number of characters that + * correspond to the bytes stored in the + * output buffer. */ +{ + CONST Tcl_UniChar *wSrc, *wSrcStart, *wSrcEnd; + char *dstEnd, *dstStart; + int result, numChars; + + result = TCL_OK; + if ((srcLen % sizeof(Tcl_UniChar)) != 0) { + result = TCL_CONVERT_MULTIBYTE; + srcLen /= sizeof(Tcl_UniChar); + srcLen *= sizeof(Tcl_UniChar); + } + + wSrc = (Tcl_UniChar *) src; + + wSrcStart = (Tcl_UniChar *) src; + wSrcEnd = (Tcl_UniChar *) (src + srcLen); + + dstStart = dst; + dstEnd = dst + dstLen - TCL_UTF_MAX; + + for (numChars = 0; wSrc < wSrcEnd; numChars++) { + if (dst > dstEnd) { + result = TCL_CONVERT_NOSPACE; + break; + } + /* + * On a little-endian machine (Intel) the UCS-2BE is in the + * wrong byte-order in comparison to "unicode", which is + * in native host order. + */ + dst += Tcl_UniCharToUtf(htons(*wSrc), dst); + wSrc++; + } + + *srcReadPtr = (char *) wSrc - (char *) wSrcStart; + *dstWrotePtr = dst - dstStart; + *dstCharsPtr = numChars; + return result; +} + +/* + *------------------------------------------------------------------------- + * + * UtfToUcs2beProc -- + * + * Convert from UTF-8 to UCS-2BE. + * + * Results: + * Returns TCL_OK if conversion was successful. + * + * Side effects: + * None. + * + *------------------------------------------------------------------------- + */ + +static int +UtfToUcs2beProc(clientData, src, srcLen, flags, statePtr, dst, dstLen, + srcReadPtr, dstWrotePtr, dstCharsPtr) + ClientData clientData; /* TableEncodingData that specifies encoding. */ + CONST char *src; /* Source string in UTF-8. */ + int srcLen; /* Source string length in bytes. */ + int flags; /* Conversion control flags. */ + Tcl_EncodingState *statePtr;/* Place for conversion routine to store + * state information used during a piecewise + * conversion. Contents of statePtr are + * initialized and/or reset by conversion + * routine under control of flags argument. */ + char *dst; /* Output buffer in which converted string + * is stored. */ + int dstLen; /* The maximum length of output buffer in + * bytes. */ + int *srcReadPtr; /* Filled with the number of bytes from the + * source string that were converted. This + * may be less than the original source length + * if there was a problem converting some + * source characters. */ + int *dstWrotePtr; /* Filled with the number of bytes that were + * stored in the output buffer as a result of + * the conversion. */ + int *dstCharsPtr; /* Filled with the number of characters that + * correspond to the bytes stored in the + * output buffer. */ +{ + CONST char *srcStart, *srcEnd, *srcClose; + Tcl_UniChar *wDst, *wDstStart, *wDstEnd; + int result, numChars; + + srcStart = src; + srcEnd = src + srcLen; + srcClose = srcEnd; + if ((flags & TCL_ENCODING_END) == 0) { + srcClose -= TCL_UTF_MAX; + } + + wDst = (Tcl_UniChar *) dst; + wDstStart = (Tcl_UniChar *) dst; + wDstEnd = (Tcl_UniChar *) (dst + dstLen - sizeof(Tcl_UniChar)); + + result = TCL_OK; + for (numChars = 0; src < srcEnd; numChars++) { + if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) { + /* + * If there is more string to follow, this will ensure that the + * last UTF-8 character in the source buffer hasn't been cut off. + */ + + result = TCL_CONVERT_MULTIBYTE; + break; + } + if (wDst > wDstEnd) { + result = TCL_CONVERT_NOSPACE; + break; + } + src += Tcl_UtfToUniChar(src, wDst); + /* + * Byte swap for little-endian machines. + */ + *wDst = htons(*wDst); + wDst++; + } + *srcReadPtr = src - srcStart; + *dstWrotePtr = (char *) wDst - (char *) wDstStart; + *dstCharsPtr = numChars; + return result; +} + +/* *--------------------------------------------------------------------------- * * TkpGetNativeFont -- @@ -1460,7 +1656,17 @@ AllocFontFamily(display, fontStructPtr, base) */ familyPtr->refCount = 2; - familyPtr->isTwoByteFont = (fontStructPtr->min_byte1 > 0); + + /* + * One byte/character fonts have both min_byte1 and max_byte1 0, + * and max_char_or_byte2 <= 255. + * Anything else specifies a two byte/character font. + */ + + familyPtr->isTwoByteFont = !( + (fontStructPtr->min_byte1 == 0) && + (fontStructPtr->max_byte1 == 0) && + (fontStructPtr->max_char_or_byte2 < 256)); return familyPtr; } |