OSDN Git Service

Please enter the commit message for your changes. Lines starting
[eos/base.git] / util / src / TclTk / tk8.6.4 / unix / tkUnixRFont.c
diff --git a/util/src/TclTk/tk8.6.4/unix/tkUnixRFont.c b/util/src/TclTk/tk8.6.4/unix/tkUnixRFont.c
deleted file mode 100644 (file)
index ab2ed4a..0000000
+++ /dev/null
@@ -1,1140 +0,0 @@
-/*
- * tkUnixRFont.c --
- *
- *     Alternate implementation of tkUnixFont.c using Xft.
- *
- * Copyright (c) 2002-2003 Keith Packard
- *
- * See the file "license.terms" for information on usage and redistribution of
- * this file, and for a DISCLAIMER OF ALL WARRANTIES.
- */
-
-#include "tkUnixInt.h"
-#include "tkFont.h"
-#include <X11/Xft/Xft.h>
-#include <ctype.h>
-
-typedef struct {
-    XftFont *ftFont;
-    XftFont *ft0Font;
-    FcPattern *source;
-    FcCharSet *charset;
-    double angle;
-} UnixFtFace;
-
-typedef struct {
-    TkFont font;               /* Stuff used by generic font package. Must be
-                                * first in structure. */
-    UnixFtFace *faces;
-    int nfaces;
-    FcFontSet *fontset;
-    FcPattern *pattern;
-
-    Display *display;
-    int screen;
-    XftDraw *ftDraw;
-    XftColor color;
-} UnixFtFont;
-
-/*
- * Used to describe the current clipping box. Can't be passed normally because
- * the information isn't retrievable from the GC.
- */
-
-typedef struct ThreadSpecificData {
-    Region clipRegion;         /* The clipping region, or None. */
-} ThreadSpecificData;
-static Tcl_ThreadDataKey dataKey;
-\f
-/*
- * Package initialization:
- *     Nothing to do here except register the fact that we're using Xft in
- *     the TIP 59 configuration database.
- */
-
-#ifndef TCL_CFGVAL_ENCODING
-#define TCL_CFGVAL_ENCODING "ascii"
-#endif
-
-void
-TkpFontPkgInit(
-    TkMainInfo *mainPtr)       /* The application being created. */
-{
-    static Tcl_Config cfg[] = {
-       { "fontsystem", "xft" },
-       { 0,0 }
-    };
-
-    Tcl_RegisterConfig(mainPtr->interp, "tk", cfg, TCL_CFGVAL_ENCODING);
-}
-\f
-static XftFont *
-GetFont(
-    UnixFtFont *fontPtr,
-    FcChar32 ucs4,
-    double angle)
-{
-    int i;
-
-    if (ucs4) {
-       for (i = 0; i < fontPtr->nfaces; i++) {
-           FcCharSet *charset = fontPtr->faces[i].charset;
-
-           if (charset && FcCharSetHasChar(charset, ucs4)) {
-               break;
-           }
-       }
-       if (i == fontPtr->nfaces) {
-           i = 0;
-       }
-    } else {
-       i = 0;
-    }
-    if ((angle == 0.0 && !fontPtr->faces[i].ft0Font) || (angle != 0.0 &&
-           (!fontPtr->faces[i].ftFont || fontPtr->faces[i].angle != angle))){
-       FcPattern *pat = FcFontRenderPrepare(0, fontPtr->pattern,
-               fontPtr->faces[i].source);
-       double s = sin(angle*PI/180.0), c = cos(angle*PI/180.0);
-       FcMatrix mat;
-       XftFont *ftFont;
-
-       /*
-        * Initialize the matrix manually so this can compile with HP-UX cc
-        * (which does not allow non-constant structure initializers). [Bug
-        * 2978410]
-        */
-
-       mat.xx = mat.yy = c;
-       mat.xy = -(mat.yx = s);
-
-       if (angle != 0.0) {
-           FcPatternAddMatrix(pat, FC_MATRIX, &mat);
-       }
-       ftFont = XftFontOpenPattern(fontPtr->display, pat);
-       if (!ftFont) {
-           /*
-            * The previous call to XftFontOpenPattern() should not fail, but
-            * sometimes does anyway. Usual cause appears to be a
-            * misconfigured fontconfig installation; see [Bug 1090382]. Try a
-            * fallback:
-            */
-
-           ftFont = XftFontOpen(fontPtr->display, fontPtr->screen,
-                   FC_FAMILY, FcTypeString, "sans",
-                   FC_SIZE, FcTypeDouble, 12.0,
-                   FC_MATRIX, FcTypeMatrix, &mat,
-                   NULL);
-       }
-       if (!ftFont) {
-           /*
-            * The previous call should definitely not fail. Impossible to
-            * proceed at this point.
-            */
-
-           Tcl_Panic("Cannot find a usable font");
-       }
-
-       if (angle == 0.0) {
-           fontPtr->faces[i].ft0Font = ftFont;
-       } else {
-           if (fontPtr->faces[i].ftFont) {
-               XftFontClose(fontPtr->display, fontPtr->faces[i].ftFont);
-           }
-           fontPtr->faces[i].ftFont = ftFont;
-           fontPtr->faces[i].angle = angle;
-       }
-    }
-    return (angle==0.0? fontPtr->faces[i].ft0Font : fontPtr->faces[i].ftFont);
-}
-\f
-/*
- *---------------------------------------------------------------------------
- *
- * GetTkFontAttributes --
- *     Fill in TkFontAttributes from an XftFont.
- */
-
-static void
-GetTkFontAttributes(
-    XftFont *ftFont,
-    TkFontAttributes *faPtr)
-{
-    const char *family = "Unknown";
-    const char *const *familyPtr = &family;
-    int weight, slant, size, pxsize;
-    double ptsize;
-
-    (void) XftPatternGetString(ftFont->pattern, XFT_FAMILY, 0, familyPtr);
-    if (XftPatternGetDouble(ftFont->pattern, XFT_SIZE, 0,
-           &ptsize) == XftResultMatch) {
-       size = (int) ptsize;
-    } else if (XftPatternGetInteger(ftFont->pattern, XFT_PIXEL_SIZE, 0,
-           &pxsize) == XftResultMatch) {
-       size = -pxsize;
-    } else {
-       size = 12;
-    }
-    if (XftPatternGetInteger(ftFont->pattern, XFT_WEIGHT, 0,
-           &weight) != XftResultMatch) {
-       weight = XFT_WEIGHT_MEDIUM;
-    }
-    if (XftPatternGetInteger(ftFont->pattern, XFT_SLANT, 0,
-           &slant) != XftResultMatch) {
-       slant = XFT_SLANT_ROMAN;
-    }
-
-#if DEBUG_FONTSEL
-    printf("family %s size %d weight %d slant %d\n",
-           family, size, weight, slant);
-#endif /* DEBUG_FONTSEL */
-
-    faPtr->family = Tk_GetUid(family);
-    faPtr->size = size;
-    faPtr->weight = (weight > XFT_WEIGHT_MEDIUM) ? TK_FW_BOLD : TK_FW_NORMAL;
-    faPtr->slant = (slant > XFT_SLANT_ROMAN) ? TK_FS_ITALIC : TK_FS_ROMAN;
-    faPtr->underline = 0;
-    faPtr->overstrike = 0;
-}
-\f
-/*
- *---------------------------------------------------------------------------
- *
- * GetTkFontMetrics --
- *     Fill in TkFontMetrics from an XftFont.
- */
-
-static void
-GetTkFontMetrics(
-    XftFont *ftFont,
-    TkFontMetrics *fmPtr)
-{
-    int spacing;
-
-    if (XftPatternGetInteger(ftFont->pattern, XFT_SPACING, 0,
-           &spacing) != XftResultMatch) {
-       spacing = XFT_PROPORTIONAL;
-    }
-
-    fmPtr->ascent = ftFont->ascent;
-    fmPtr->descent = ftFont->descent;
-    fmPtr->maxWidth = ftFont->max_advance_width;
-    fmPtr->fixed = spacing != XFT_PROPORTIONAL;
-}
-\f
-/*
- *---------------------------------------------------------------------------
- *
- * InitFont --
- *
- *     Initializes the fields of a UnixFtFont structure. If fontPtr is NULL,
- *     also allocates a new UnixFtFont.
- *
- * Results:
- *     On error, frees fontPtr and returns NULL, otherwise returns fontPtr.
- *
- *---------------------------------------------------------------------------
- */
-
-static UnixFtFont *
-InitFont(
-    Tk_Window tkwin,
-    FcPattern *pattern,
-    UnixFtFont *fontPtr)
-{
-    FcFontSet *set;
-    FcCharSet *charset;
-    FcResult result;
-    XftFont *ftFont;
-    int i, iWidth;
-
-    if (!fontPtr) {
-       fontPtr = ckalloc(sizeof(UnixFtFont));
-    }
-
-    FcConfigSubstitute(0, pattern, FcMatchPattern);
-    XftDefaultSubstitute(Tk_Display(tkwin), Tk_ScreenNumber(tkwin), pattern);
-
-    /*
-     * Generate the list of fonts
-     */
-
-    set = FcFontSort(0, pattern, FcTrue, NULL, &result);
-    if (!set) {
-       ckfree(fontPtr);
-       return NULL;
-    }
-
-    fontPtr->fontset = set;
-    fontPtr->pattern = pattern;
-    fontPtr->faces = ckalloc(set->nfont * sizeof(UnixFtFace));
-    fontPtr->nfaces = set->nfont;
-
-    /*
-     * Fill in information about each returned font
-     */
-
-    for (i = 0; i < set->nfont; i++) {
-       fontPtr->faces[i].ftFont = 0;
-       fontPtr->faces[i].ft0Font = 0;
-       fontPtr->faces[i].source = set->fonts[i];
-       if (FcPatternGetCharSet(set->fonts[i], FC_CHARSET, 0,
-               &charset) == FcResultMatch) {
-           fontPtr->faces[i].charset = FcCharSetCopy(charset);
-       } else {
-           fontPtr->faces[i].charset = 0;
-       }
-       fontPtr->faces[i].angle = 0.0;
-    }
-
-    fontPtr->display = Tk_Display(tkwin);
-    fontPtr->screen = Tk_ScreenNumber(tkwin);
-    fontPtr->ftDraw = 0;
-    fontPtr->color.color.red = 0;
-    fontPtr->color.color.green = 0;
-    fontPtr->color.color.blue = 0;
-    fontPtr->color.color.alpha = 0xffff;
-    fontPtr->color.pixel = 0xffffffff;
-
-    /*
-     * Fill in platform-specific fields of TkFont.
-     */
-
-    ftFont = GetFont(fontPtr, 0, 0.0);
-    fontPtr->font.fid = XLoadFont(Tk_Display(tkwin), "fixed");
-    GetTkFontAttributes(ftFont, &fontPtr->font.fa);
-    GetTkFontMetrics(ftFont, &fontPtr->font.fm);
-
-    /*
-     * Fontconfig can't report any information about the position or thickness
-     * of underlines or overstrikes. Thus, we use some defaults that are
-     * hacked around from backup defaults in tkUnixFont.c, which are in turn
-     * based on recommendations in the X manual. The comments from that file
-     * leading to these computations were:
-     *
-     *     If the XA_UNDERLINE_POSITION property does not exist, the X manual
-     *     recommends using half the descent.
-     *
-     *     If the XA_UNDERLINE_THICKNESS property does not exist, the X
-     *     manual recommends using the width of the stem on a capital letter.
-     *     I don't know of a way to get the stem width of a letter, so guess
-     *     and use 1/3 the width of a capital I.
-     *
-     * Note that nothing corresponding to *either* property is reported by
-     * Fontconfig at all. [Bug 1961455]
-     */
-
-    {
-       TkFont *fPtr = &fontPtr->font;
-
-       fPtr->underlinePos = fPtr->fm.descent / 2;
-       Tk_MeasureChars((Tk_Font) fPtr, "I", 1, -1, 0, &iWidth);
-       fPtr->underlineHeight = iWidth / 3;
-       if (fPtr->underlineHeight == 0) {
-           fPtr->underlineHeight = 1;
-       }
-       if (fPtr->underlineHeight + fPtr->underlinePos > fPtr->fm.descent) {
-           fPtr->underlineHeight = fPtr->fm.descent - fPtr->underlinePos;
-           if (fPtr->underlineHeight == 0) {
-               fPtr->underlinePos--;
-               fPtr->underlineHeight = 1;
-           }
-       }
-    }
-
-    return fontPtr;
-}
-\f
-static void
-FinishedWithFont(
-    UnixFtFont *fontPtr)
-{
-    Display *display = fontPtr->display;
-    int i;
-    Tk_ErrorHandler handler =
-           Tk_CreateErrorHandler(display, -1, -1, -1, NULL, NULL);
-
-    for (i = 0; i < fontPtr->nfaces; i++) {
-       if (fontPtr->faces[i].ftFont) {
-           XftFontClose(fontPtr->display, fontPtr->faces[i].ftFont);
-       }
-       if (fontPtr->faces[i].ft0Font) {
-           XftFontClose(fontPtr->display, fontPtr->faces[i].ft0Font);
-       }
-       if (fontPtr->faces[i].charset) {
-           FcCharSetDestroy(fontPtr->faces[i].charset);
-       }
-    }
-    if (fontPtr->faces) {
-       ckfree(fontPtr->faces);
-    }
-    if (fontPtr->pattern) {
-       FcPatternDestroy(fontPtr->pattern);
-    }
-    if (fontPtr->ftDraw) {
-       XftDrawDestroy(fontPtr->ftDraw);
-    }
-    if (fontPtr->font.fid) {
-       XUnloadFont(fontPtr->display, fontPtr->font.fid);
-    }
-    if (fontPtr->fontset) {
-       FcFontSetDestroy(fontPtr->fontset);
-    }
-    Tk_DeleteErrorHandler(handler);
-}
-\f
-TkFont *
-TkpGetNativeFont(
-    Tk_Window tkwin,           /* For display where font will be used. */
-    const char *name)          /* Platform-specific font name. */
-{
-    UnixFtFont *fontPtr;
-    FcPattern *pattern;
-#if DEBUG_FONTSEL
-    printf("TkpGetNativeFont %s\n", name);
-#endif /* DEBUG_FONTSEL */
-
-    pattern = XftXlfdParse(name, FcFalse, FcFalse);
-    if (!pattern) {
-       return NULL;
-    }
-
-    /*
-     * Should also try: pattern = FcNameParse(name); but generic/tkFont.c
-     * expects TkpGetNativeFont() to only work on XLFD names under Unix.
-     */
-
-    fontPtr = InitFont(tkwin, pattern, NULL);
-    if (!fontPtr) {
-       FcPatternDestroy(pattern);
-       return NULL;
-    }
-    return &fontPtr->font;
-}
-\f
-TkFont *
-TkpGetFontFromAttributes(
-    TkFont *tkFontPtr,         /* If non-NULL, store the information in this
-                                * existing TkFont structure, rather than
-                                * allocating a new structure to hold the
-                                * font; the existing contents of the font
-                                * will be released. If NULL, a new TkFont
-                                * structure is allocated. */
-    Tk_Window tkwin,           /* For display where font will be used. */
-    const TkFontAttributes *faPtr)
-                               /* Set of attributes to match. */
-{
-    XftPattern *pattern;
-    int weight, slant;
-    UnixFtFont *fontPtr;
-
-#if DEBUG_FONTSEL
-    printf("TkpGetFontFromAttributes %s-%d %d %d\n", faPtr->family,
-           faPtr->size, faPtr->weight, faPtr->slant);
-#endif /* DEBUG_FONTSEL */
-    pattern = XftPatternCreate();
-    if (faPtr->family) {
-       XftPatternAddString(pattern, XFT_FAMILY, faPtr->family);
-    }
-    if (faPtr->size > 0) {
-       XftPatternAddDouble(pattern, XFT_SIZE, (double)faPtr->size);
-    } else if (faPtr->size < 0) {
-       XftPatternAddInteger(pattern, XFT_PIXEL_SIZE, -faPtr->size);
-    } else {
-       XftPatternAddDouble(pattern, XFT_SIZE, 12.0);
-    }
-    switch (faPtr->weight) {
-    case TK_FW_NORMAL:
-    default:
-       weight = XFT_WEIGHT_MEDIUM;
-       break;
-    case TK_FW_BOLD:
-       weight = XFT_WEIGHT_BOLD;
-       break;
-    }
-    XftPatternAddInteger(pattern, XFT_WEIGHT, weight);
-    switch (faPtr->slant) {
-    case TK_FS_ROMAN:
-    default:
-       slant = XFT_SLANT_ROMAN;
-       break;
-    case TK_FS_ITALIC:
-       slant = XFT_SLANT_ITALIC;
-       break;
-    case TK_FS_OBLIQUE:
-       slant = XFT_SLANT_OBLIQUE;
-       break;
-    }
-    XftPatternAddInteger(pattern, XFT_SLANT, slant);
-
-    fontPtr = (UnixFtFont *) tkFontPtr;
-    if (fontPtr != NULL) {
-       FinishedWithFont(fontPtr);
-    }
-    fontPtr = InitFont(tkwin, pattern, fontPtr);
-
-    /*
-     * Hack to work around issues with weird issues with Xft/Xrender
-     * connection. For details, see comp.lang.tcl thread starting from
-     * <adcc99ed-c73e-4efc-bb5d-e57a57a051e8@l35g2000pra.googlegroups.com>
-     */
-
-    if (!fontPtr) {
-       XftPatternAddBool(pattern, XFT_RENDER, FcFalse);
-       fontPtr = InitFont(tkwin, pattern, fontPtr);
-    }
-
-    if (!fontPtr) {
-       FcPatternDestroy(pattern);
-       return NULL;
-    }
-
-    fontPtr->font.fa.underline = faPtr->underline;
-    fontPtr->font.fa.overstrike = faPtr->overstrike;
-    return &fontPtr->font;
-}
-\f
-void
-TkpDeleteFont(
-    TkFont *tkFontPtr)         /* Token of font to be deleted. */
-{
-    UnixFtFont *fontPtr = (UnixFtFont *) tkFontPtr;
-
-    FinishedWithFont(fontPtr);
-    /* XXX tkUnixFont.c doesn't free tkFontPtr... */
-}
-\f
-/*
- *---------------------------------------------------------------------------
- *
- * TkpGetFontFamilies --
- *
- *     Return information about the font families that are available on the
- *     display of the given window.
- *
- * Results:
- *     Modifies interp's result object to hold a list of all the available
- *     font families.
- *
- *---------------------------------------------------------------------------
- */
-
-void
-TkpGetFontFamilies(
-    Tcl_Interp *interp,                /* Interp to hold result. */
-    Tk_Window tkwin)           /* For display to query. */
-{
-    Tcl_Obj *resultPtr;
-    XftFontSet *list;
-    int i;
-
-    resultPtr = Tcl_NewListObj(0, NULL);
-
-    list = XftListFonts(Tk_Display(tkwin), Tk_ScreenNumber(tkwin),
-               (char *) 0,             /* pattern elements */
-               XFT_FAMILY, (char*) 0); /* fields */
-    for (i = 0; i < list->nfont; i++) {
-       char *family, **familyPtr = &family;
-
-       if (XftPatternGetString(list->fonts[i], XFT_FAMILY, 0, familyPtr)
-               == XftResultMatch) {
-           Tcl_Obj *strPtr = Tcl_NewStringObj(family, -1);
-
-           Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
-       }
-    }
-    XftFontSetDestroy(list);
-
-    Tcl_SetObjResult(interp, resultPtr);
-}
-\f
-/*
- *-------------------------------------------------------------------------
- *
- * TkpGetSubFonts --
- *
- *     Called by [testfont subfonts] in the Tk testing package.
- *
- * Results:
- *     Sets interp's result to a list of the faces used by tkfont
- *
- *-------------------------------------------------------------------------
- */
-
-void
-TkpGetSubFonts(
-    Tcl_Interp *interp,
-    Tk_Font tkfont)
-{
-    Tcl_Obj *objv[3], *listPtr, *resultPtr;
-    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
-    FcPattern *pattern;
-    const char *family = "Unknown";
-    const char *const *familyPtr = &family;
-    const char *foundry = "Unknown";
-    const char *const *foundryPtr = &foundry;
-    const char *encoding = "Unknown";
-    const char *const *encodingPtr = &encoding;
-    int i;
-
-    resultPtr = Tcl_NewListObj(0, NULL);
-
-    for (i = 0; i < fontPtr->nfaces ; ++i) {
-       pattern = FcFontRenderPrepare(0, fontPtr->pattern,
-               fontPtr->faces[i].source);
-
-       XftPatternGetString(pattern, XFT_FAMILY, 0, familyPtr);
-       XftPatternGetString(pattern, XFT_FOUNDRY, 0, foundryPtr);
-       XftPatternGetString(pattern, XFT_ENCODING, 0, encodingPtr);
-       objv[0] = Tcl_NewStringObj(family, -1);
-       objv[1] = Tcl_NewStringObj(foundry, -1);
-       objv[2] = Tcl_NewStringObj(encoding, -1);
-       listPtr = Tcl_NewListObj(3, objv);
-       Tcl_ListObjAppendElement(NULL, resultPtr, listPtr);
-    }
-    Tcl_SetObjResult(interp, resultPtr);
-}
-\f
-/*
- *----------------------------------------------------------------------
- *
- * TkpGetFontAttrsForChar --
- *
- *     Retrieve the font attributes of the actual font used to render a given
- *     character.
- *
- *----------------------------------------------------------------------
- */
-
-void
-TkpGetFontAttrsForChar(
-    Tk_Window tkwin,           /* Window on the font's display */
-    Tk_Font tkfont,            /* Font to query */
-    Tcl_UniChar c,             /* Character of interest */
-    TkFontAttributes *faPtr)   /* Output: Font attributes */
-{
-    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
-                               /* Structure describing the logical font */
-    FcChar32 ucs4 = (FcChar32) c;
-                               /* UCS-4 character to map */
-    XftFont *ftFont = GetFont(fontPtr, ucs4, 0.0);
-                               /* Actual font used to render the character */
-
-    GetTkFontAttributes(ftFont, faPtr);
-    faPtr->underline = fontPtr->font.fa.underline;
-    faPtr->overstrike = fontPtr->font.fa.overstrike;
-}
-\f
-int
-Tk_MeasureChars(
-    Tk_Font tkfont,            /* Font in which characters will be drawn. */
-    const char *source,                /* UTF-8 string to be displayed. Need not be
-                                * '\0' terminated. */
-    int numBytes,              /* Maximum number of bytes to consider from
-                                * source string. */
-    int maxLength,             /* If >= 0, maxLength specifies the longest
-                                * permissible line length in pixels; don't
-                                * consider any character that would cross
-                                * this x-position. If < 0, then line length
-                                * is unbounded and the flags argument is
-                                * ignored. */
-    int flags,                 /* Various flag bits OR-ed together:
-                                * TK_PARTIAL_OK means include the last char
-                                * which only partially fit on this line.
-                                * TK_WHOLE_WORDS means stop on a word
-                                * boundary, if possible. TK_AT_LEAST_ONE
-                                * means return at least one character even if
-                                * no characters fit. */
-    int *lengthPtr)            /* Filled with x-location just after the
-                                * terminating character. */
-{
-    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
-    XftFont *ftFont;
-    FcChar32 c;
-    XGlyphInfo extents;
-    int clen, curX, newX, curByte, newByte, sawNonSpace;
-    int termByte = 0, termX = 0;
-#if DEBUG_FONTSEL
-    char string[256];
-    int len = 0;
-#endif /* DEBUG_FONTSEL */
-
-    curX = 0;
-    curByte = 0;
-    sawNonSpace = 0;
-    while (numBytes > 0) {
-       Tcl_UniChar unichar;
-
-       clen = Tcl_UtfToUniChar(source, &unichar);
-       c = (FcChar32) unichar;
-
-       if (clen <= 0) {
-           /*
-            * This can't happen (but see #1185640)
-            */
-
-           *lengthPtr = curX;
-           return curByte;
-       }
-
-       source += clen;
-       numBytes -= clen;
-       if (c < 256 && isspace(c)) {            /* I18N: ??? */
-           if (sawNonSpace) {
-               termByte = curByte;
-               termX = curX;
-               sawNonSpace = 0;
-           }
-       } else {
-           sawNonSpace = 1;
-       }
-
-#if DEBUG_FONTSEL
-       string[len++] = (char) c;
-#endif /* DEBUG_FONTSEL */
-       ftFont = GetFont(fontPtr, c, 0.0);
-
-       XftTextExtents32(fontPtr->display, ftFont, &c, 1, &extents);
-
-       newX = curX + extents.xOff;
-       newByte = curByte + clen;
-       if (maxLength >= 0 && newX > maxLength) {
-           if (flags & TK_PARTIAL_OK ||
-                   (flags & TK_AT_LEAST_ONE && curByte == 0)) {
-               curX = newX;
-               curByte = newByte;
-           } else if (flags & TK_WHOLE_WORDS && termX != 0) {
-               curX = termX;
-               curByte = termByte;
-           }
-           break;
-       }
-
-       curX = newX;
-       curByte = newByte;
-    }
-#if DEBUG_FONTSEL
-    string[len] = '\0';
-    printf("MeasureChars %s length %d bytes %d\n", string, curX, curByte);
-#endif /* DEBUG_FONTSEL */
-    *lengthPtr = curX;
-    return curByte;
-}
-\f
-int
-TkpMeasureCharsInContext(
-    Tk_Font tkfont,
-    const char *source,
-    int numBytes,
-    int rangeStart,
-    int rangeLength,
-    int maxLength,
-    int flags,
-    int *lengthPtr)
-{
-    (void) numBytes; /*unused*/
-
-    return Tk_MeasureChars(tkfont, source + rangeStart, rangeLength,
-           maxLength, flags, lengthPtr);
-}
-\f
-#define NUM_SPEC    1024
-
-void
-Tk_DrawChars(
-    Display *display,          /* Display on which to draw. */
-    Drawable drawable,         /* Window or pixmap in which to draw. */
-    GC gc,                     /* Graphics context for drawing characters. */
-    Tk_Font tkfont,            /* Font in which characters will be drawn;
-                                * must be the same as font used in GC. */
-    const char *source,                /* UTF-8 string to be displayed. Need not be
-                                * '\0' terminated. All Tk meta-characters
-                                * (tabs, control characters, and newlines)
-                                * should be stripped out of the string that
-                                * is passed to this function. If they are not
-                                * stripped out, they will be displayed as
-                                * regular printing characters. */
-    int numBytes,              /* Number of bytes in string. */
-    int x, int y)              /* Coordinates at which to place origin of
-                                * string when drawing. */
-{
-    const int maxCoord = 0x7FFF;/* Xft coordinates are 16 bit values */
-    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
-    XGCValues values;
-    XColor xcolor;
-    int clen, nspec, xStart = x;
-    XftGlyphFontSpec specs[NUM_SPEC];
-    XGlyphInfo metrics;
-    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
-            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
-
-    if (fontPtr->ftDraw == 0) {
-#if DEBUG_FONTSEL
-       printf("Switch to drawable 0x%x\n", drawable);
-#endif /* DEBUG_FONTSEL */
-       fontPtr->ftDraw = XftDrawCreate(display, drawable,
-               DefaultVisual(display, fontPtr->screen),
-               DefaultColormap(display, fontPtr->screen));
-    } else {
-       Tk_ErrorHandler handler =
-               Tk_CreateErrorHandler(display, -1, -1, -1, NULL, NULL);
-
-       XftDrawChange(fontPtr->ftDraw, drawable);
-       Tk_DeleteErrorHandler(handler);
-    }
-    XGetGCValues(display, gc, GCForeground, &values);
-    if (values.foreground != fontPtr->color.pixel) {
-       xcolor.pixel = values.foreground;
-       XQueryColor(display, DefaultColormap(display, fontPtr->screen),
-               &xcolor);
-       fontPtr->color.color.red = xcolor.red;
-       fontPtr->color.color.green = xcolor.green;
-       fontPtr->color.color.blue = xcolor.blue;
-       fontPtr->color.color.alpha = 0xffff;
-       fontPtr->color.pixel = values.foreground;
-    }
-    if (tsdPtr->clipRegion != None) {
-       XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion);
-    }
-    nspec = 0;
-    while (numBytes > 0 && x <= maxCoord && y <= maxCoord) {
-       XftFont *ftFont;
-       FcChar32 c;
-
-       clen = FcUtf8ToUcs4((FcChar8 *) source, &c, numBytes);
-       if (clen <= 0) {
-           /*
-            * This should not happen, but it can.
-            */
-
-           goto doUnderlineStrikeout;
-       }
-       source += clen;
-       numBytes -= clen;
-
-       ftFont = GetFont(fontPtr, c, 0.0);
-       if (ftFont) {
-           specs[nspec].font = ftFont;
-           specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c);
-           specs[nspec].x = x;
-           specs[nspec].y = y;
-           XftGlyphExtents(fontPtr->display, ftFont, &specs[nspec].glyph, 1,
-                   &metrics);
-           x += metrics.xOff;
-           y += metrics.yOff;
-           nspec++;
-           if (nspec == NUM_SPEC) {
-               XftDrawGlyphFontSpec(fontPtr->ftDraw, &fontPtr->color,
-                       specs, nspec);
-               nspec = 0;
-           }
-       }
-    }
-    if (nspec) {
-       XftDrawGlyphFontSpec(fontPtr->ftDraw, &fontPtr->color, specs, nspec);
-    }
-
-  doUnderlineStrikeout:
-    if (tsdPtr->clipRegion != None) {
-       XftDrawSetClip(fontPtr->ftDraw, None);
-    }
-    if (fontPtr->font.fa.underline != 0) {
-       XFillRectangle(display, drawable, gc, xStart,
-               y + fontPtr->font.underlinePos, (unsigned) (x - xStart),
-               (unsigned) fontPtr->font.underlineHeight);
-    }
-    if (fontPtr->font.fa.overstrike != 0) {
-       y -= fontPtr->font.fm.descent + (fontPtr->font.fm.ascent) / 10;
-       XFillRectangle(display, drawable, gc, xStart, y,
-               (unsigned) (x - xStart),
-               (unsigned) fontPtr->font.underlineHeight);
-    }
-}
-\f
-/*
- *---------------------------------------------------------------------------
- *
- * TkDrawAngledChars --
- *
- *     Draw some characters at an angle. This would be simple code, except
- *     Xft has bugs with cumulative errors in character positioning which are
- *     caused by trying to perform all calculations internally with integers.
- *     So we have to do the work ourselves with floating-point math.
- *
- * Results:
- *     None.
- *
- * Side effects:
- *     Target drawable is updated.
- *
- *---------------------------------------------------------------------------
- */
-
-void
-TkDrawAngledChars(
-    Display *display,          /* Display on which to draw. */
-    Drawable drawable,         /* Window or pixmap in which to draw. */
-    GC gc,                     /* Graphics context for drawing characters. */
-    Tk_Font tkfont,            /* Font in which characters will be drawn;
-                                * must be the same as font used in GC. */
-    const char *source,                /* UTF-8 string to be displayed. Need not be
-                                * '\0' terminated. All Tk meta-characters
-                                * (tabs, control characters, and newlines)
-                                * should be stripped out of the string that
-                                * is passed to this function. If they are not
-                                * stripped out, they will be displayed as
-                                * regular printing characters. */
-    int numBytes,              /* Number of bytes in string. */
-    double x, double y,                /* Coordinates at which to place origin of
-                                * string when drawing. */
-    double angle)              /* What angle to put text at, in degrees. */
-{
-    const int maxCoord = 0x7FFF;/* Xft coordinates are 16 bit values */
-    const int minCoord = -1000;        /* Should be good enough... */
-    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
-    XGCValues values;
-    XColor xcolor;
-    int xStart = x, yStart = y;
-    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
-            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
-#ifdef XFT_HAS_FIXED_ROTATED_PLACEMENT
-    int clen, nglyph;
-    FT_UInt glyphs[NUM_SPEC];
-    XGlyphInfo metrics;
-    XftFont *currentFtFont;
-    int originX, originY;
-
-    if (fontPtr->ftDraw == 0) {
-#if DEBUG_FONTSEL
-       printf("Switch to drawable 0x%x\n", drawable);
-#endif /* DEBUG_FONTSEL */
-       fontPtr->ftDraw = XftDrawCreate(display, drawable,
-               DefaultVisual(display, fontPtr->screen),
-               DefaultColormap(display, fontPtr->screen));
-    } else {
-       Tk_ErrorHandler handler =
-               Tk_CreateErrorHandler(display, -1, -1, -1, NULL, NULL);
-
-       XftDrawChange(fontPtr->ftDraw, drawable);
-       Tk_DeleteErrorHandler(handler);
-    }
-
-    XGetGCValues(display, gc, GCForeground, &values);
-    if (values.foreground != fontPtr->color.pixel) {
-       xcolor.pixel = values.foreground;
-       XQueryColor(display, DefaultColormap(display, fontPtr->screen),
-               &xcolor);
-       fontPtr->color.color.red = xcolor.red;
-       fontPtr->color.color.green = xcolor.green;
-       fontPtr->color.color.blue = xcolor.blue;
-       fontPtr->color.color.alpha = 0xffff;
-       fontPtr->color.pixel = values.foreground;
-    }
-    if (tsdPtr->clipRegion != None) {
-       XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion);
-    }
-
-    nglyph = 0;
-    currentFtFont = NULL;
-    originX = originY = 0;             /* lint */
-
-    while (numBytes > 0 && x <= maxCoord && x >= minCoord && y <= maxCoord
-           && y >= minCoord) {
-       XftFont *ftFont;
-       FcChar32 c;
-
-       clen = FcUtf8ToUcs4((FcChar8 *) source, &c, numBytes);
-       if (clen <= 0) {
-           /*
-            * This should not happen, but it can.
-            */
-
-           goto doUnderlineStrikeout;
-       }
-       source += clen;
-       numBytes -= clen;
-
-       ftFont = GetFont(fontPtr, c, angle);
-       if (!ftFont) {
-           continue;
-       }
-
-       if (ftFont != currentFtFont || nglyph == NUM_SPEC) {
-           if (nglyph) {
-               /*
-                * We pass multiple glyphs at once to enable the code to
-                * perform better rendering of sub-pixel inter-glyph spacing.
-                * If only the current Xft implementation could make use of
-                * this information... but we'll be ready when it does!
-                */
-
-               XftDrawGlyphs(fontPtr->ftDraw, &fontPtr->color, currentFtFont,
-                       originX, originY, glyphs, nglyph);
-           }
-           originX = ROUND16(x);
-           originY = ROUND16(y);
-           if (nglyph) {
-               XftGlyphExtents(fontPtr->display, currentFtFont, glyphs,
-                       nglyph, &metrics);
-               nglyph = 0;
-               x += metrics.xOff;
-               y += metrics.yOff;
-           }
-           currentFtFont = ftFont;
-       }
-       glyphs[nglyph++] = XftCharIndex(fontPtr->display, ftFont, c);
-    }
-    if (nglyph) {
-       XftDrawGlyphs(fontPtr->ftDraw, &fontPtr->color, currentFtFont,
-               originX, originY, glyphs, nglyph);
-    }
-#else /* !XFT_HAS_FIXED_ROTATED_PLACEMENT */
-    int clen, nspec;
-    XftGlyphFontSpec specs[NUM_SPEC];
-    XGlyphInfo metrics;
-    double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0);
-
-    if (fontPtr->ftDraw == 0) {
-#if DEBUG_FONTSEL
-       printf("Switch to drawable 0x%x\n", drawable);
-#endif /* DEBUG_FONTSEL */
-       fontPtr->ftDraw = XftDrawCreate(display, drawable,
-               DefaultVisual(display, fontPtr->screen),
-               DefaultColormap(display, fontPtr->screen));
-    } else {
-       Tk_ErrorHandler handler =
-               Tk_CreateErrorHandler(display, -1, -1, -1, NULL, NULL);
-
-       XftDrawChange(fontPtr->ftDraw, drawable);
-       Tk_DeleteErrorHandler(handler);
-    }
-    XGetGCValues(display, gc, GCForeground, &values);
-    if (values.foreground != fontPtr->color.pixel) {
-       xcolor.pixel = values.foreground;
-       XQueryColor(display, DefaultColormap(display, fontPtr->screen),
-               &xcolor);
-       fontPtr->color.color.red = xcolor.red;
-       fontPtr->color.color.green = xcolor.green;
-       fontPtr->color.color.blue = xcolor.blue;
-       fontPtr->color.color.alpha = 0xffff;
-       fontPtr->color.pixel = values.foreground;
-    }
-    if (tsdPtr->clipRegion != None) {
-       XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion);
-    }
-    nspec = 0;
-    while (numBytes > 0 && x <= maxCoord && x >= minCoord
-           && y <= maxCoord && y >= minCoord) {
-       XftFont *ftFont, *ft0Font;
-       FcChar32 c;
-
-       clen = FcUtf8ToUcs4((FcChar8 *) source, &c, numBytes);
-       if (clen <= 0) {
-           /*
-            * This should not happen, but it can.
-            */
-
-           goto doUnderlineStrikeout;
-       }
-       source += clen;
-       numBytes -= clen;
-
-       ftFont = GetFont(fontPtr, c, angle);
-       ft0Font = GetFont(fontPtr, c, 0.0);
-       if (ftFont && ft0Font) {
-           specs[nspec].font = ftFont;
-           specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c);
-           specs[nspec].x = ROUND16(x);
-           specs[nspec].y = ROUND16(y);
-           XftGlyphExtents(fontPtr->display, ft0Font, &specs[nspec].glyph, 1,
-                   &metrics);
-           x += metrics.xOff*cosA + metrics.yOff*sinA;
-           y += metrics.yOff*cosA - metrics.xOff*sinA;
-           nspec++;
-           if (nspec == NUM_SPEC) {
-               XftDrawGlyphFontSpec(fontPtr->ftDraw, &fontPtr->color,
-                       specs, nspec);
-               nspec = 0;
-           }
-       }
-    }
-    if (nspec) {
-       XftDrawGlyphFontSpec(fontPtr->ftDraw, &fontPtr->color, specs, nspec);
-    }
-#endif /* XFT_HAS_FIXED_ROTATED_PLACEMENT */
-
-  doUnderlineStrikeout:
-    if (tsdPtr->clipRegion != None) {
-       XftDrawSetClip(fontPtr->ftDraw, None);
-    }
-    if (fontPtr->font.fa.underline || fontPtr->font.fa.overstrike) {
-       XPoint points[5];
-       double width = (x - xStart) * cosA + (yStart - y) * sinA;
-       double barHeight = fontPtr->font.underlineHeight;
-       double dy = fontPtr->font.underlinePos;
-
-       if (fontPtr->font.fa.underline != 0) {
-           if (fontPtr->font.underlineHeight == 1) {
-               dy++;
-           }
-           points[0].x = xStart + ROUND16(dy*sinA);
-           points[0].y = yStart + ROUND16(dy*cosA);
-           points[1].x = xStart + ROUND16(dy*sinA + width*cosA);
-           points[1].y = yStart + ROUND16(dy*cosA - width*sinA);
-           if (fontPtr->font.underlineHeight == 1) {
-               XDrawLines(display, drawable, gc, points, 2, CoordModeOrigin);
-           } else {
-               points[2].x = xStart + ROUND16(dy*sinA + width*cosA
-                       + barHeight*sinA);
-               points[2].y = yStart + ROUND16(dy*cosA - width*sinA
-                       + barHeight*cosA);
-               points[3].x = xStart + ROUND16(dy*sinA + barHeight*sinA);
-               points[3].y = yStart + ROUND16(dy*cosA + barHeight*cosA);
-               points[4].x = points[0].x;
-               points[4].y = points[0].y;
-               XFillPolygon(display, drawable, gc, points, 5, Complex,
-                       CoordModeOrigin);
-               XDrawLines(display, drawable, gc, points, 5, CoordModeOrigin);
-           }
-       }
-       if (fontPtr->font.fa.overstrike != 0) {
-           dy = -fontPtr->font.fm.descent
-                  - (fontPtr->font.fm.ascent) / 10;
-           points[0].x = xStart + ROUND16(dy*sinA);
-           points[0].y = yStart + ROUND16(dy*cosA);
-           points[1].x = xStart + ROUND16(dy*sinA + width*cosA);
-           points[1].y = yStart + ROUND16(dy*cosA - width*sinA);
-           if (fontPtr->font.underlineHeight == 1) {
-               XDrawLines(display, drawable, gc, points, 2, CoordModeOrigin);
-           } else {
-               points[2].x = xStart + ROUND16(dy*sinA + width*cosA
-                       + barHeight*sinA);
-               points[2].y = yStart + ROUND16(dy*cosA - width*sinA
-                       + barHeight*cosA);
-               points[3].x = xStart + ROUND16(dy*sinA + barHeight*sinA);
-               points[3].y = yStart + ROUND16(dy*cosA + barHeight*cosA);
-               points[4].x = points[0].x;
-               points[4].y = points[0].y;
-               XFillPolygon(display, drawable, gc, points, 5, Complex,
-                       CoordModeOrigin);
-               XDrawLines(display, drawable, gc, points, 5, CoordModeOrigin);
-           }
-       }
-    }
-}
-\f
-void
-TkUnixSetXftClipRegion(
-    TkRegion clipRegion)       /* The clipping region to install. */
-{
-    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
-            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
-
-    tsdPtr->clipRegion = (Region) clipRegion;
-}
-\f
-/*
- * Local Variables:
- * c-basic-offset: 4
- * fill-column: 78
- * End:
- */