Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix text clipping when working with the Xft-based renderer. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | core-8-5-branch |
Files: | files | file ages | folders |
SHA1: |
2c72a41785ba1d51d99aca17a0977205 |
User & Date: | dkf 2012-06-12 08:29:27 |
Context
2012-06-15
| ||
05:43 | Backport of [Bug 3532186] fix check-in: 15e3ff22 user: jan.nijtmans tags: core-8-5-branch | |
2012-06-12
| ||
08:34 | Fix text clipping when working with the Xft-based renderer. check-in: 66c1f59a user: dkf tags: trunk | |
08:29 | Fix text clipping when working with the Xft-based renderer. check-in: 2c72a417 user: dkf tags: core-8-5-branch | |
2012-06-11
| ||
13:06 | fix test failure check-in: 10319218 user: dkf tags: core-8-5-branch | |
Changes
Changes to ChangeLog.
1 2 3 4 5 6 7 | 2012-06-11 Donal K. Fellows <[email protected]> * generic/ttk/ttkLabel.c (TextDraw): [Bug 3294450]: Get the clipping * generic/ttk/ttkEntry.c (EntryDisplay): of text in Ttk various text elements (e.g., buttons, entries, etc.) correct. Stops a whole range of visual problems, including loss of the second and subsequent lines of a label when the first line doesn't entirely fit, and failing to | > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 2012-06-12 Donal K. Fellows <[email protected]> * unix/tkUnixRFont.c (Tk_DrawChars, TkUnixSetXftClipRegion): Add some * generic/ttk/ttkEntry.c (EntryDisplay): special magic to make the * generic/ttk/ttkLabel.c (TextDraw): text clipping work right with the Xft-based renderer (which doesn't use the standard Tk GC except to supply the color). 2012-06-11 Donal K. Fellows <[email protected]> * generic/ttk/ttkLabel.c (TextDraw): [Bug 3294450]: Get the clipping * generic/ttk/ttkEntry.c (EntryDisplay): of text in Ttk various text elements (e.g., buttons, entries, etc.) correct. Stops a whole range of visual problems, including loss of the second and subsequent lines of a label when the first line doesn't entirely fit, and failing to |
︙ | ︙ |
Changes to generic/tkInt.h.
︙ | ︙ | |||
1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 | #ifdef __WIN32__ #define TkParseColor XParseColor #else MODULE_SCOPE Status TkParseColor (Display * display, Colormap map, CONST char* spec, XColor * colorPtr); #endif /* * Unsupported commands. */ MODULE_SCOPE int TkUnsupported1ObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, | > > > | 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 | #ifdef __WIN32__ #define TkParseColor XParseColor #else MODULE_SCOPE Status TkParseColor (Display * display, Colormap map, CONST char* spec, XColor * colorPtr); #endif #ifdef HAVE_XFT MODULE_SCOPE void TkUnixSetXftClipRegion(Region clipRegion); #endif /* * Unsupported commands. */ MODULE_SCOPE int TkUnsupported1ObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, |
︙ | ︙ |
Changes to generic/ttk/ttkEntry.c.
︙ | ︙ | |||
1217 1218 1219 1220 1221 1222 1223 | selStartX - borderWidth, entryPtr->entry.layoutY - borderWidth, selEndX - selStartX + 2*borderWidth, entryPtr->entry.layoutHeight + 2*borderWidth, borderWidth, TK_RELIEF_RAISED); } } | | > > > > | 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 | selStartX - borderWidth, entryPtr->entry.layoutY - borderWidth, selEndX - selStartX + 2*borderWidth, entryPtr->entry.layoutHeight + 2*borderWidth, borderWidth, TK_RELIEF_RAISED); } } /* Initialize the clip region. Note that Xft does _not_ derive its * clipping area from the GC, so we have to supply that by other means. */ rect.x = textarea.x; rect.y = textarea.y; rect.width = textarea.width; rect.height = textarea.height; clipRegion = TkCreateRegion(); TkUnionRectWithRegion(&rect, clipRegion, clipRegion); #ifdef HAVE_XFT TkUnixSetXftClipRegion(clipRegion); #endif /* Draw cursor: */ if (showCursor) { int cursorX = EntryCharPosition(entryPtr, entryPtr->entry.insertPos), cursorY = entryPtr->entry.layoutY, cursorHeight = entryPtr->entry.layoutHeight, |
︙ | ︙ | |||
1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 | gc = EntryGetGC(entryPtr, es.selForegroundObj, clipRegion); Tk_DrawTextLayout( Tk_Display(tkwin), d, gc, entryPtr->entry.textLayout, entryPtr->entry.layoutX, entryPtr->entry.layoutY, selFirst, selLast); Tk_FreeGC(Tk_Display(tkwin), gc); } TkDestroyRegion(clipRegion); } /*------------------------------------------------------------------------ * +++ Widget commands. */ | > > > > > > > | 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 | gc = EntryGetGC(entryPtr, es.selForegroundObj, clipRegion); Tk_DrawTextLayout( Tk_Display(tkwin), d, gc, entryPtr->entry.textLayout, entryPtr->entry.layoutX, entryPtr->entry.layoutY, selFirst, selLast); Tk_FreeGC(Tk_Display(tkwin), gc); } /* Drop the region. Note that we have to manually remove the reference to * it from the Xft guts (if they're being used). */ #ifdef HAVE_XFT TkUnixSetXftClipRegion(None); #endif TkDestroyRegion(clipRegion); } /*------------------------------------------------------------------------ * +++ Widget commands. */ |
︙ | ︙ |
Changes to generic/ttk/ttkLabel.c.
︙ | ︙ | |||
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | static void TextDraw(TextElement *text, Tk_Window tkwin, Drawable d, Ttk_Box b) { XColor *color = Tk_GetColorFromObj(tkwin, text->foregroundObj); int underline = -1; XGCValues gcValues; GC gc1, gc2; Tk_Anchor anchor = TK_ANCHOR_CENTER; gcValues.font = Tk_FontId(text->tkfont); gcValues.foreground = color->pixel; gc1 = Tk_GetGC(tkwin, GCFont | GCForeground, &gcValues); gcValues.foreground = WhitePixelOfScreen(Tk_Screen(tkwin)); gc2 = Tk_GetGC(tkwin, GCFont | GCForeground, &gcValues); /* * Place text according to -anchor: */ Tk_GetAnchorFromObj(NULL, text->anchorObj, &anchor); b = Ttk_AnchorBox(b, text->width, text->height, anchor); /* * Clip text if it's too wide: */ if (b.width < text->width) { | > < > > > > > | 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | static void TextDraw(TextElement *text, Tk_Window tkwin, Drawable d, Ttk_Box b) { XColor *color = Tk_GetColorFromObj(tkwin, text->foregroundObj); int underline = -1; XGCValues gcValues; GC gc1, gc2; Tk_Anchor anchor = TK_ANCHOR_CENTER; TkRegion clipRegion = NULL; gcValues.font = Tk_FontId(text->tkfont); gcValues.foreground = color->pixel; gc1 = Tk_GetGC(tkwin, GCFont | GCForeground, &gcValues); gcValues.foreground = WhitePixelOfScreen(Tk_Screen(tkwin)); gc2 = Tk_GetGC(tkwin, GCFont | GCForeground, &gcValues); /* * Place text according to -anchor: */ Tk_GetAnchorFromObj(NULL, text->anchorObj, &anchor); b = Ttk_AnchorBox(b, text->width, text->height, anchor); /* * Clip text if it's too wide: */ if (b.width < text->width) { XRectangle rect; clipRegion = TkCreateRegion(); rect.x = b.x; rect.y = b.y; rect.width = b.width + (text->embossed ? 1 : 0); rect.height = b.height + (text->embossed ? 1 : 0); TkUnionRectWithRegion(&rect, clipRegion, clipRegion); TkSetRegion(Tk_Display(tkwin), gc1, clipRegion); TkSetRegion(Tk_Display(tkwin), gc2, clipRegion); #ifdef HAVE_XFT TkUnixSetXftClipRegion(clipRegion); #else TkDestroyRegion(clipRegion); #endif } if (text->embossed) { Tk_DrawTextLayout(Tk_Display(tkwin), d, gc2, text->textLayout, b.x+1, b.y+1, 0/*firstChar*/, -1/*lastChar*/); } Tk_DrawTextLayout(Tk_Display(tkwin), d, gc1, |
︙ | ︙ | |||
176 177 178 179 180 181 182 183 184 185 186 187 188 189 | } Tk_UnderlineTextLayout(Tk_Display(tkwin), d, gc1, text->textLayout, b.x, b.y, underline); } Tk_FreeGC(Tk_Display(tkwin), gc1); Tk_FreeGC(Tk_Display(tkwin), gc2); } static void TextElementSize( void *clientData, void *elementRecord, Tk_Window tkwin, int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) { TextElement *text = elementRecord; | > > > > > > | 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | } Tk_UnderlineTextLayout(Tk_Display(tkwin), d, gc1, text->textLayout, b.x, b.y, underline); } Tk_FreeGC(Tk_Display(tkwin), gc1); Tk_FreeGC(Tk_Display(tkwin), gc2); #ifdef HAVE_XFT if (clipRegion != NULL) { TkUnixSetXftClipRegion(None); TkDestroyRegion(clipRegion); } #endif } static void TextElementSize( void *clientData, void *elementRecord, Tk_Window tkwin, int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr) { TextElement *text = elementRecord; |
︙ | ︙ |
Changes to unix/tkUnixRFont.c.
︙ | ︙ | |||
29 30 31 32 33 34 35 36 37 38 39 40 41 42 | FcPattern *pattern; Display *display; int screen; XftDraw *ftDraw; XftColor color; } UnixFtFont; /* * Package initialization: * Nothing to do here except register the fact that we're using Xft in * the TIP 59 configuration database. */ | > > > > > > > > > > | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | 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; /* * Package initialization: * Nothing to do here except register the fact that we're using Xft in * the TIP 59 configuration database. */ |
︙ | ︙ | |||
708 709 710 711 712 713 714 715 716 717 718 719 720 721 | 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; 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), | > > | 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 | 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), |
︙ | ︙ | |||
734 735 736 737 738 739 740 741 742 743 744 745 746 747 | &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; } nspec = 0; while (numBytes > 0 && x <= maxCoord && y <= maxCoord) { XftFont *ftFont; FcChar32 c; clen = FcUtf8ToUcs4((FcChar8 *) source, &c, numBytes); if (clen <= 0) { | > > > | 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 | &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) { |
︙ | ︙ | |||
771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 | nspec = 0; } } } if (nspec) { XftDrawGlyphFontSpec(fontPtr->ftDraw, &fontPtr->color, specs, nspec); } doUnderlineStrikeout: 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); } } | > > > > > > > > > > > > > | 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 | nspec = 0; } } } if (nspec) { XftDrawGlyphFontSpec(fontPtr->ftDraw, &fontPtr->color, specs, nspec); } if (tsdPtr->clipRegion != None) { XftDrawSetClip(fontPtr->ftDraw, None); } doUnderlineStrikeout: 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); } } void TkUnixSetXftClipRegion( Region clipRegion) /* The clipping region to install. */ { ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); tsdPtr->clipRegion = clipRegion; } |