void TkBezierScreenPoints( Tk_Canvas canvas, /* Canvas in which curve is to be drawn. */ double control[], /* Array of coordinates for four control * points: x0, y0, x1, y1, ... x3 y3. */ int numSteps, /* Number of curve points to generate. */ register XPoint *xPointPtr) /* Where to put new points. */ { int i; double u, u2, u3, t, t2, t3; for (i = 1; i <= numSteps; i++, xPointPtr++) { t = ((double) i)/((double) numSteps); t2 = t*t; t3 = t2*t; u = 1.0 - t; u2 = u*u; u3 = u2*u; Tk_CanvasDrawableCoords(canvas, (control[0]*u3 + 3.0 * (control[2]*t*u2 + control[4]*t2*u) + control[6]*t3), (control[1]*u3 + 3.0 * (control[3]*t*u2 + control[5]*t2*u) + control[7]*t3), &xPointPtr->x, &xPointPtr->y); } }
static void DisplayBLine(Tk_Canvas canvas, Tk_Item *itemPtr, Display *display, Drawable drawable, int x, int y, int width, int height) { register BLineItem *linePtr = (BLineItem *) itemPtr; XPoint staticPoints[MAX_STATIC_POINTS]; XPoint *pointPtr; register XPoint *pPtr; register double *coordPtr; int i, numPoints; /* * Build up an array of points in screen coordinates. Use a * static array unless the line has an enormous number of points; * in this case, dynamically allocate an array. For smoothed lines, * generate the curve points on each redisplay. */ numPoints = linePtr->numPoints; if (numPoints <= MAX_STATIC_POINTS) { pointPtr = staticPoints; } else { pointPtr = (XPoint *) ckalloc((unsigned) (numPoints * sizeof(XPoint))); } for (i = 0, coordPtr = linePtr->coordPtr, pPtr = pointPtr; i < linePtr->numPoints; i += 1, coordPtr += 2, pPtr++) { Tk_CanvasDrawableCoords(canvas, coordPtr[0], coordPtr[1], &pPtr->x, &pPtr->y); } Tk_DrawBeveledLine(display, drawable, linePtr->border, pointPtr, numPoints, linePtr->width, linePtr->borderWidth, linePtr->relief); if (pointPtr != staticPoints) { ckfree((char *) pointPtr); } }
static void DisplayImage( Tk_Canvas canvas, /* Canvas that contains item. */ Tk_Item *itemPtr, /* Item to be displayed. */ Display *display, /* Display on which to draw item. */ Drawable drawable, /* Pixmap or window in which to draw item. */ int x, int y, int width, int height) /* Describes region of canvas that must be * redisplayed (not used). */ { ImageItem *imgPtr = (ImageItem *) itemPtr; short drawableX, drawableY; Tk_Image image; Tk_State state = itemPtr->state; if (state == TK_STATE_NULL) { state = Canvas(canvas)->canvas_state; } image = imgPtr->image; if (Canvas(canvas)->currentItemPtr == itemPtr) { if (imgPtr->activeImage != NULL) { image = imgPtr->activeImage; } } else if (state == TK_STATE_DISABLED) { if (imgPtr->disabledImage != NULL) { image = imgPtr->disabledImage; } } if (image == NULL) { return; } /* * Translate the coordinates to those of the image, then redisplay it. */ Tk_CanvasDrawableCoords(canvas, (double) x, (double) y, &drawableX, &drawableY); Tk_RedrawImage(image, x - imgPtr->header.x1, y - imgPtr->header.y1, width, height, drawable, drawableX, drawableY); }
static void DisplayRectOval( Tk_Canvas canvas, /* Canvas that contains item. */ Tk_Item *itemPtr, /* Item to be displayed. */ Display *display, /* Display on which to draw item. */ Drawable drawable, /* Pixmap or window in which to draw item. */ int x, int y, int width, int height) /* Describes region of canvas that must be * redisplayed (not used). */ { RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr; short x1, y1, x2, y2; Pixmap fillStipple; Tk_State state = itemPtr->state; /* * Compute the screen coordinates of the bounding box for the item. Make * sure that the bbox is at least one pixel large, since some X servers * will die if it isn't. */ Tk_CanvasDrawableCoords(canvas, rectOvalPtr->bbox[0],rectOvalPtr->bbox[1], &x1, &y1); Tk_CanvasDrawableCoords(canvas, rectOvalPtr->bbox[2],rectOvalPtr->bbox[3], &x2, &y2); if (x2 <= x1) { x2 = x1+1; } if (y2 <= y1) { y2 = y1+1; } /* * Display filled part first (if wanted), then outline. If we're * stippling, then modify the stipple offset in the GC. Be sure to reset * the offset when done, since the GC is supposed to be read-only. */ if (state == TK_STATE_NULL) { state = Canvas(canvas)->canvas_state; } fillStipple = rectOvalPtr->fillStipple; if (Canvas(canvas)->currentItemPtr == (Tk_Item *) rectOvalPtr) { if (rectOvalPtr->activeFillStipple != None) { fillStipple = rectOvalPtr->activeFillStipple; } } else if (state == TK_STATE_DISABLED) { if (rectOvalPtr->disabledFillStipple != None) { fillStipple = rectOvalPtr->disabledFillStipple; } } if (rectOvalPtr->fillGC != None) { if (fillStipple != None) { Tk_TSOffset *tsoffset; int w = 0, h = 0; tsoffset = &rectOvalPtr->tsoffset; if (tsoffset) { int flags = tsoffset->flags; if (flags & (TK_OFFSET_CENTER|TK_OFFSET_MIDDLE)) { Tk_SizeOfBitmap(display, fillStipple, &w, &h); if (flags & TK_OFFSET_CENTER) { w /= 2; } else { w = 0; } if (flags & TK_OFFSET_MIDDLE) { h /= 2; } else { h = 0; } } tsoffset->xoffset -= w; tsoffset->yoffset -= h; } Tk_CanvasSetOffset(canvas, rectOvalPtr->fillGC, tsoffset); if (tsoffset) { tsoffset->xoffset += w; tsoffset->yoffset += h; } } if (rectOvalPtr->header.typePtr == &tkRectangleType) { XFillRectangle(display, drawable, rectOvalPtr->fillGC, x1, y1, (unsigned int) (x2-x1), (unsigned int) (y2-y1)); } else { XFillArc(display, drawable, rectOvalPtr->fillGC, x1, y1, (unsigned) (x2-x1), (unsigned) (y2-y1), 0, 360*64); } if (fillStipple != None) { XSetTSOrigin(display, rectOvalPtr->fillGC, 0, 0); } } if (rectOvalPtr->outline.gc != None) { Tk_ChangeOutlineGC(canvas, itemPtr, &(rectOvalPtr->outline)); if (rectOvalPtr->header.typePtr == &tkRectangleType) { XDrawRectangle(display, drawable, rectOvalPtr->outline.gc, x1, y1, (unsigned) (x2-x1), (unsigned) (y2-y1)); } else { XDrawArc(display, drawable, rectOvalPtr->outline.gc, x1, y1, (unsigned) (x2-x1), (unsigned) (y2-y1), 0, 360*64); } Tk_ResetOutlineGC(canvas, itemPtr, &(rectOvalPtr->outline)); } }
static void DisplayBitmap( Tk_Canvas canvas, /* Canvas that contains item. */ Tk_Item *itemPtr, /* Item to be displayed. */ Display *display, /* Display on which to draw item. */ Drawable drawable, /* Pixmap or window in which to draw item. */ int x, int y, int width, int height) /* Describes region of canvas that must be * redisplayed (not used). */ { BitmapItem *bmapPtr = (BitmapItem *) itemPtr; int bmapX, bmapY, bmapWidth, bmapHeight; short drawableX, drawableY; Pixmap bitmap; Tk_State state = itemPtr->state; /* * If the area being displayed doesn't cover the whole bitmap, then only * redisplay the part of the bitmap that needs redisplay. */ if (state == TK_STATE_NULL) { state = Canvas(canvas)->canvas_state; } bitmap = bmapPtr->bitmap; if (Canvas(canvas)->currentItemPtr == itemPtr) { if (bmapPtr->activeBitmap!=None) { bitmap = bmapPtr->activeBitmap; } } else if (state == TK_STATE_DISABLED) { if (bmapPtr->disabledBitmap!=None) { bitmap = bmapPtr->disabledBitmap; } } if (bitmap != None) { if (x > bmapPtr->header.x1) { bmapX = x - bmapPtr->header.x1; bmapWidth = bmapPtr->header.x2 - x; } else { bmapX = 0; if ((x+width) < bmapPtr->header.x2) { bmapWidth = x + width - bmapPtr->header.x1; } else { bmapWidth = bmapPtr->header.x2 - bmapPtr->header.x1; } } if (y > bmapPtr->header.y1) { bmapY = y - bmapPtr->header.y1; bmapHeight = bmapPtr->header.y2 - y; } else { bmapY = 0; if ((y+height) < bmapPtr->header.y2) { bmapHeight = y + height - bmapPtr->header.y1; } else { bmapHeight = bmapPtr->header.y2 - bmapPtr->header.y1; } } Tk_CanvasDrawableCoords(canvas, (double) (bmapPtr->header.x1 + bmapX), (double) (bmapPtr->header.y1 + bmapY), &drawableX, &drawableY); /* * Must modify the mask origin within the graphics context to line up * with the bitmap's origin (in order to make bitmaps with * "-background {}" work right). */ XSetClipOrigin(display, bmapPtr->gc, drawableX - bmapX, drawableY - bmapY); XCopyPlane(display, bitmap, drawable, bmapPtr->gc, bmapX, bmapY, (unsigned int) bmapWidth, (unsigned int) bmapHeight, drawableX, drawableY, 1); XSetClipOrigin(display, bmapPtr->gc, 0, 0); } }
int TkMakeRawCurve( Tk_Canvas canvas, /* Canvas in which curve is to be drawn. */ double *pointPtr, /* Array of input coordinates: x0, y0, x1, y1, * etc.. */ int numPoints, /* Number of points at pointPtr. */ int numSteps, /* Number of steps to use for each curve * segment (determines smoothness of * curve). */ XPoint xPoints[], /* Array of XPoints to fill in (e.g. for * display). NULL means don't fill in any * XPoints. */ double dblPoints[]) /* Array of points to fill in as doubles, in * the form x0, y0, x1, y1, .... NULL means * don't fill in anything in this form. * Caller must make sure that this array has * enough space. */ { int outputPoints, i; int numSegments = (numPoints+1)/3; double *segPtr; /* * The input describes a curve with s Bezier curve segments if there are * 3s+1, 3s, or 3s-1 input points. In the last two cases, 1 or 2 initial * points from the first curve segment are reused as defining points also * for the last curve segment. In the case of 3s input points, this will * automatically close the curve. */ if (!pointPtr) { /* * If pointPtr == NULL, this function returns an upper limit of the * array size to store the coordinates. This can be used to allocate * storage, before the actual coordinates are calculated. */ return 1 + numSegments * numSteps; } outputPoints = 0; if (xPoints != NULL) { Tk_CanvasDrawableCoords(canvas, pointPtr[0], pointPtr[1], &xPoints->x, &xPoints->y); xPoints += 1; } if (dblPoints != NULL) { dblPoints[0] = pointPtr[0]; dblPoints[1] = pointPtr[1]; dblPoints += 2; } outputPoints += 1; /* * The next loop handles all curve segments except one that overlaps the * end of the list of coordinates. */ for (i=numPoints,segPtr=pointPtr ; i>=4 ; i-=3,segPtr+=6) { if (segPtr[0]==segPtr[2] && segPtr[1]==segPtr[3] && segPtr[4]==segPtr[6] && segPtr[5]==segPtr[7]) { /* * The control points on this segment are equal to their * neighbouring knots, so this segment is just a straight line. A * single point is sufficient. */ if (xPoints != NULL) { Tk_CanvasDrawableCoords(canvas, segPtr[6], segPtr[7], &xPoints->x, &xPoints->y); xPoints += 1; } if (dblPoints != NULL) { dblPoints[0] = segPtr[6]; dblPoints[1] = segPtr[7]; dblPoints += 2; } outputPoints += 1; } else { /* * This is a generic Bezier curve segment. */ if (xPoints != NULL) { TkBezierScreenPoints(canvas, segPtr, numSteps, xPoints); xPoints += numSteps; } if (dblPoints != NULL) { TkBezierPoints(segPtr, numSteps, dblPoints); dblPoints += 2*numSteps; } outputPoints += numSteps; } } /* * If at this point i>1, then there is some point which has not yet been * used. Make another curve segment. */ if (i > 1) { int j; double control[8]; /* * Copy the relevant coordinates to control[], so that it can be * passed as a unit to e.g. TkBezierPoints. */ for (j=0; j<2*i; j++) { control[j] = segPtr[j]; } for (; j<8; j++) { control[j] = pointPtr[j-2*i]; } /* * Then we just do the same things as above. */ if (control[0]==control[2] && control[1]==control[3] && control[4]==control[6] && control[5]==control[7]) { /* * The control points on this segment are equal to their * neighbouring knots, so this segment is just a straight line. A * single point is sufficient. */ if (xPoints != NULL) { Tk_CanvasDrawableCoords(canvas, control[6], control[7], &xPoints->x, &xPoints->y); xPoints += 1; } if (dblPoints != NULL) { dblPoints[0] = control[6]; dblPoints[1] = control[7]; dblPoints += 2; } outputPoints += 1; } else { /* * This is a generic Bezier curve segment. */ if (xPoints != NULL) { TkBezierScreenPoints(canvas, control, numSteps, xPoints); xPoints += numSteps; } if (dblPoints != NULL) { TkBezierPoints(control, numSteps, dblPoints); dblPoints += 2*numSteps; } outputPoints += numSteps; } } return outputPoints; }
int TkMakeBezierCurve( Tk_Canvas canvas, /* Canvas in which curve is to be drawn. */ double *pointPtr, /* Array of input coordinates: x0, y0, x1, y1, * etc.. */ int numPoints, /* Number of points at pointPtr. */ int numSteps, /* Number of steps to use for each spline * segments (determines smoothness of * curve). */ XPoint xPoints[], /* Array of XPoints to fill in (e.g. for * display). NULL means don't fill in any * XPoints. */ double dblPoints[]) /* Array of points to fill in as doubles, in * the form x0, y0, x1, y1, .... NULL means * don't fill in anything in this form. Caller * must make sure that this array has enough * space. */ { int closed, outputPoints, i; int numCoords = numPoints*2; double control[8]; /* * If the curve is a closed one then generate a special spline that spans * the last points and the first ones. Otherwise just put the first point * into the output. */ if (!pointPtr) { /* * Of pointPtr == NULL, this function returns an upper limit of the * array size to store the coordinates. This can be used to allocate * storage, before the actual coordinates are calculated. */ return 1 + numPoints * numSteps; } outputPoints = 0; if ((pointPtr[0] == pointPtr[numCoords-2]) && (pointPtr[1] == pointPtr[numCoords-1])) { closed = 1; control[0] = 0.5*pointPtr[numCoords-4] + 0.5*pointPtr[0]; control[1] = 0.5*pointPtr[numCoords-3] + 0.5*pointPtr[1]; control[2] = 0.167*pointPtr[numCoords-4] + 0.833*pointPtr[0]; control[3] = 0.167*pointPtr[numCoords-3] + 0.833*pointPtr[1]; control[4] = 0.833*pointPtr[0] + 0.167*pointPtr[2]; control[5] = 0.833*pointPtr[1] + 0.167*pointPtr[3]; control[6] = 0.5*pointPtr[0] + 0.5*pointPtr[2]; control[7] = 0.5*pointPtr[1] + 0.5*pointPtr[3]; if (xPoints != NULL) { Tk_CanvasDrawableCoords(canvas, control[0], control[1], &xPoints->x, &xPoints->y); TkBezierScreenPoints(canvas, control, numSteps, xPoints+1); xPoints += numSteps+1; } if (dblPoints != NULL) { dblPoints[0] = control[0]; dblPoints[1] = control[1]; TkBezierPoints(control, numSteps, dblPoints+2); dblPoints += 2*(numSteps+1); } outputPoints += numSteps+1; } else { closed = 0; if (xPoints != NULL) { Tk_CanvasDrawableCoords(canvas, pointPtr[0], pointPtr[1], &xPoints->x, &xPoints->y); xPoints += 1; } if (dblPoints != NULL) { dblPoints[0] = pointPtr[0]; dblPoints[1] = pointPtr[1]; dblPoints += 2; } outputPoints += 1; } for (i = 2; i < numPoints; i++, pointPtr += 2) { /* * Set up the first two control points. This is done differently for * the first spline of an open curve than for other cases. */ if ((i == 2) && !closed) { control[0] = pointPtr[0]; control[1] = pointPtr[1]; control[2] = 0.333*pointPtr[0] + 0.667*pointPtr[2]; control[3] = 0.333*pointPtr[1] + 0.667*pointPtr[3]; } else { control[0] = 0.5*pointPtr[0] + 0.5*pointPtr[2]; control[1] = 0.5*pointPtr[1] + 0.5*pointPtr[3]; control[2] = 0.167*pointPtr[0] + 0.833*pointPtr[2]; control[3] = 0.167*pointPtr[1] + 0.833*pointPtr[3]; } /* * Set up the last two control points. This is done differently for * the last spline of an open curve than for other cases. */ if ((i == (numPoints-1)) && !closed) { control[4] = .667*pointPtr[2] + .333*pointPtr[4]; control[5] = .667*pointPtr[3] + .333*pointPtr[5]; control[6] = pointPtr[4]; control[7] = pointPtr[5]; } else { control[4] = .833*pointPtr[2] + .167*pointPtr[4]; control[5] = .833*pointPtr[3] + .167*pointPtr[5]; control[6] = 0.5*pointPtr[2] + 0.5*pointPtr[4]; control[7] = 0.5*pointPtr[3] + 0.5*pointPtr[5]; } /* * If the first two points coincide, or if the last two points * coincide, then generate a single straight-line segment by * outputting the last control point. */ if (((pointPtr[0] == pointPtr[2]) && (pointPtr[1] == pointPtr[3])) || ((pointPtr[2] == pointPtr[4]) && (pointPtr[3] == pointPtr[5]))) { if (xPoints != NULL) { Tk_CanvasDrawableCoords(canvas, control[6], control[7], &xPoints[0].x, &xPoints[0].y); xPoints++; } if (dblPoints != NULL) { dblPoints[0] = control[6]; dblPoints[1] = control[7]; dblPoints += 2; } outputPoints += 1; continue; } /* * Generate a Bezier spline using the control points. */ if (xPoints != NULL) { TkBezierScreenPoints(canvas, control, numSteps, xPoints); xPoints += numSteps; } if (dblPoints != NULL) { TkBezierPoints(control, numSteps, dblPoints); dblPoints += 2*numSteps; } outputPoints += numSteps; } return outputPoints; }
static void DisplayCanvText( Tk_Canvas canvas, /* Canvas that contains item. */ Tk_Item *itemPtr, /* Item to be displayed. */ Display *display, /* Display on which to draw item. */ Drawable drawable, /* Pixmap or window in which to draw item. */ int x, int y, int width, int height) /* Describes region of canvas that must be * redisplayed (not used). */ { TextItem *textPtr; Tk_CanvasTextInfo *textInfoPtr; int selFirstChar, selLastChar; short drawableX, drawableY; Pixmap stipple; Tk_State state = itemPtr->state; textPtr = (TextItem *) itemPtr; textInfoPtr = textPtr->textInfoPtr; if (state == TK_STATE_NULL) { state = Canvas(canvas)->canvas_state; } stipple = textPtr->stipple; if (Canvas(canvas)->currentItemPtr == itemPtr) { if (textPtr->activeStipple != None) { stipple = textPtr->activeStipple; } } else if (state == TK_STATE_DISABLED) { if (textPtr->disabledStipple != None) { stipple = textPtr->disabledStipple; } } if (textPtr->gc == NULL) { return; } /* * If we're stippling, then modify the stipple offset in the GC. Be sure * to reset the offset when done, since the GC is supposed to be * read-only. */ if (stipple != None) { Tk_CanvasSetOffset(canvas, textPtr->gc, &textPtr->tsoffset); } selFirstChar = -1; selLastChar = 0; /* lint. */ Tk_CanvasDrawableCoords(canvas, textPtr->drawOrigin[0], textPtr->drawOrigin[1], &drawableX, &drawableY); if (textInfoPtr->selItemPtr == itemPtr) { selFirstChar = textInfoPtr->selectFirst; selLastChar = textInfoPtr->selectLast; if (selLastChar > textPtr->numChars) { selLastChar = textPtr->numChars - 1; } if ((selFirstChar >= 0) && (selFirstChar <= selLastChar)) { int xFirst, yFirst, hFirst; int xLast, yLast, wLast; /* * Draw a special background under the selection. */ Tk_CharBbox(textPtr->textLayout, selFirstChar, &xFirst, &yFirst, NULL, &hFirst); Tk_CharBbox(textPtr->textLayout, selLastChar, &xLast, &yLast, &wLast, NULL); /* * If the selection spans the end of this line, then display * selection background all the way to the end of the line. * However, for the last line we only want to display up to the * last character, not the end of the line. */ x = xFirst; height = hFirst; for (y = yFirst ; y <= yLast; y += height) { int dx1, dy1, dx2, dy2; double s = textPtr->sine, c = textPtr->cosine; XPoint points[4]; if (y == yLast) { width = xLast + wLast - x; } else { width = textPtr->actualWidth - x; } dx1 = x - textInfoPtr->selBorderWidth; dy1 = y; dx2 = width + 2 * textInfoPtr->selBorderWidth; dy2 = height; points[0].x = (short)(drawableX + dx1*c + dy1*s); points[0].y = (short)(drawableY + dy1*c - dx1*s); points[1].x = (short)(drawableX + (dx1+dx2)*c + dy1*s); points[1].y = (short)(drawableY + dy1*c - (dx1+dx2)*s); points[2].x = (short)(drawableX + (dx1+dx2)*c + (dy1+dy2)*s); points[2].y = (short)(drawableY + (dy1+dy2)*c - (dx1+dx2)*s); points[3].x = (short)(drawableX + dx1*c + (dy1+dy2)*s); points[3].y = (short)(drawableY + (dy1+dy2)*c - dx1*s); Tk_Fill3DPolygon(Tk_CanvasTkwin(canvas), drawable, textInfoPtr->selBorder, points, 4, textInfoPtr->selBorderWidth, TK_RELIEF_RAISED); x = 0; } } } /* * If the insertion point should be displayed, then draw a special * background for the cursor before drawing the text. Note: if we're the * cursor item but the cursor is turned off, then redraw background over * the area of the cursor. This guarantees that the selection won't make * the cursor invisible on mono displays, where both are drawn in the same * color. */ if ((textInfoPtr->focusItemPtr == itemPtr) && (textInfoPtr->gotFocus)) { if (Tk_CharBbox(textPtr->textLayout, textPtr->insertPos, &x, &y, NULL, &height)) { int dx1, dy1, dx2, dy2; double s = textPtr->sine, c = textPtr->cosine; XPoint points[4]; dx1 = x - (textInfoPtr->insertWidth / 2); dy1 = y; dx2 = textInfoPtr->insertWidth; dy2 = height; points[0].x = (short)(drawableX + dx1*c + dy1*s); points[0].y = (short)(drawableY + dy1*c - dx1*s); points[1].x = (short)(drawableX + (dx1+dx2)*c + dy1*s); points[1].y = (short)(drawableY + dy1*c - (dx1+dx2)*s); points[2].x = (short)(drawableX + (dx1+dx2)*c + (dy1+dy2)*s); points[2].y = (short)(drawableY + (dy1+dy2)*c - (dx1+dx2)*s); points[3].x = (short)(drawableX + dx1*c + (dy1+dy2)*s); points[3].y = (short)(drawableY + (dy1+dy2)*c - dx1*s); Tk_SetCaretPos(Tk_CanvasTkwin(canvas), points[0].x, points[0].y, height); if (textInfoPtr->cursorOn) { Tk_Fill3DPolygon(Tk_CanvasTkwin(canvas), drawable, textInfoPtr->insertBorder, points, 4, textInfoPtr->insertBorderWidth, TK_RELIEF_RAISED); } else if (textPtr->cursorOffGC != NULL) { /* * Redraw the background over the area of the cursor, even * though the cursor is turned off. This guarantees that the * selection won't make the cursor invisible on mono displays, * where both may be drawn in the same color. */ XFillPolygon(display, drawable, textPtr->cursorOffGC, points, 4, Convex, CoordModeOrigin); } } } /* * If there is no selected text or the selected text foreground is the * same as the regular text foreground, then draw one text string. If * there is selected text and the foregrounds differ, draw the regular * text up to the selection, draw the selection, then draw the rest of the * regular text. Drawing the regular text and then the selected text over * it would causes problems with anti-aliased text because the two * anti-aliasing colors would blend together. */ if ((selFirstChar >= 0) && (textPtr->selTextGC != textPtr->gc)) { TkDrawAngledTextLayout(display, drawable, textPtr->gc, textPtr->textLayout, drawableX, drawableY, textPtr->angle, 0, selFirstChar); TkDrawAngledTextLayout(display, drawable, textPtr->selTextGC, textPtr->textLayout, drawableX, drawableY, textPtr->angle, selFirstChar, selLastChar + 1); TkDrawAngledTextLayout(display, drawable, textPtr->gc, textPtr->textLayout, drawableX, drawableY, textPtr->angle, selLastChar + 1, -1); } else { TkDrawAngledTextLayout(display, drawable, textPtr->gc, textPtr->textLayout, drawableX, drawableY, textPtr->angle, 0, -1); } TkUnderlineAngledTextLayout(display, drawable, textPtr->gc, textPtr->textLayout, drawableX, drawableY, textPtr->angle, textPtr->underline); if (stipple != None) { XSetTSOrigin(display, textPtr->gc, 0, 0); } }