📄 tktextdisp.c
字号:
* Display the chunk at a coordinate that can be clearly * identified by the displayProc as being off-screen to * the left (the displayProc may not be able to tell if * something is off to the right). */ (*chunkPtr->displayProc)(chunkPtr, -chunkPtr->width, dlPtr->spaceAbove, dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow, dlPtr->baseline - dlPtr->spaceAbove, display, pixmap, dlPtr->y + dlPtr->spaceAbove); } else { (*chunkPtr->displayProc)(chunkPtr, x, dlPtr->spaceAbove, dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow, dlPtr->baseline - dlPtr->spaceAbove, display, pixmap, dlPtr->y + dlPtr->spaceAbove); } if (dInfoPtr->dLinesInvalidated) { return; } } /* * Copy the pixmap onto the screen. If this is the last line on * the screen then copy a piece of the line, so that it doesn't * overflow into the border area. Another special trick: copy the * padding area to the left of the line; this is because the * insertion cursor sometimes overflows onto that area and we want * to get as much of the cursor as possible. */ height = dlPtr->height; if ((height + dlPtr->y) > dInfoPtr->maxY) { height = dInfoPtr->maxY - dlPtr->y; } XCopyArea(display, pixmap, Tk_WindowId(textPtr->tkwin), dInfoPtr->copyGC, dInfoPtr->x, 0, (unsigned) (dInfoPtr->maxX - dInfoPtr->x), (unsigned) height, dInfoPtr->x, dlPtr->y); linesRedrawn++;}/* *-------------------------------------------------------------- * * DisplayLineBackground -- * * This procedure is called to fill in the background for * a display line. It draws 3D borders cleverly so that * adjacent chunks with the same style (whether on the same * line or different lines) have a single 3D border around * the whole region. * * Results: * There is no return value. Pixmap is filled in with background * information for dlPtr. * * Side effects: * None. * *-------------------------------------------------------------- */static voidDisplayLineBackground(textPtr, dlPtr, prevPtr, pixmap) TkText *textPtr; /* Text widget containing line. */ register DLine *dlPtr; /* Information about line to draw. */ DLine *prevPtr; /* Line just above dlPtr, or NULL if dlPtr * is the top-most line in the window. */ Pixmap pixmap; /* Pixmap to use for double-buffering. * Caller must make sure it's large enough * to hold line. Caller must also have * filled it with the background color for * the widget. */{ TextDInfo *dInfoPtr = textPtr->dInfoPtr; TkTextDispChunk *chunkPtr; /* Pointer to chunk in the current line. */ TkTextDispChunk *chunkPtr2; /* Pointer to chunk in the line above or * below the current one. NULL if we're to * the left of or to the right of the chunks * in the line. */ TkTextDispChunk *nextPtr2; /* Next chunk after chunkPtr2 (it's not the * same as chunkPtr2->nextPtr in the case * where chunkPtr2 is NULL because the line * is indented). */ int leftX; /* The left edge of the region we're * currently working on. */ int leftXIn; /* 1 means beveled edge at leftX slopes right * as it goes down, 0 means it slopes left * as it goes down. */ int rightX; /* Right edge of chunkPtr. */ int rightX2; /* Right edge of chunkPtr2. */ int matchLeft; /* Does the style of this line match that * of its neighbor just to the left of * the current x coordinate? */ int matchRight; /* Does line's style match its neighbor * just to the right of the current x-coord? */ int minX, maxX, xOffset; StyleValues *sValuePtr; Display *display; /* * Pass 1: scan through dlPtr from left to right. For each range of * chunks with the same style, draw the main background for the style * plus the vertical parts of the 3D borders (the left and right * edges). */ display = Tk_Display(textPtr->tkwin); minX = dInfoPtr->curPixelOffset; xOffset = dInfoPtr->x - minX; maxX = minX + dInfoPtr->maxX - dInfoPtr->x; chunkPtr = dlPtr->chunkPtr; /* * Note A: in the following statement, and a few others later in * this file marked with "See Note A above", the right side of the * assignment was replaced with 0 on 6/18/97. This has the effect * of highlighting the empty space to the left of a line whenever * the leftmost character of the line is highlighted. This way, * multi-line highlights always line up along their left edges. * However, this may look funny in the case where a single word is * highlighted. To undo the change, replace "leftX = 0" with "leftX * = chunkPtr->x" and "rightX2 = 0" with "rightX2 = nextPtr2->x" * here and at all the marked points below. This restores the old * behavior where empty space to the left of a line is not * highlighted, leaving a ragged left edge for multi-line * highlights. */ leftX = 0; for (; leftX < maxX; chunkPtr = chunkPtr->nextPtr) { if ((chunkPtr->nextPtr != NULL) && SAME_BACKGROUND(chunkPtr->nextPtr->stylePtr, chunkPtr->stylePtr)) { continue; } sValuePtr = chunkPtr->stylePtr->sValuePtr; rightX = chunkPtr->x + chunkPtr->width; if ((chunkPtr->nextPtr == NULL) && (rightX < maxX)) { rightX = maxX; } if (chunkPtr->stylePtr->bgGC != None) { XFillRectangle(display, pixmap, chunkPtr->stylePtr->bgGC, leftX + xOffset, 0, (unsigned int) (rightX - leftX), (unsigned int) dlPtr->height); if (sValuePtr->relief != TK_RELIEF_FLAT) { Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border, leftX + xOffset, 0, sValuePtr->borderWidth, dlPtr->height, 1, sValuePtr->relief); Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border, rightX - sValuePtr->borderWidth + xOffset, 0, sValuePtr->borderWidth, dlPtr->height, 0, sValuePtr->relief); } } leftX = rightX; } /* * Pass 2: draw the horizontal bevels along the top of the line. To * do this, scan through dlPtr from left to right while simultaneously * scanning through the line just above dlPtr. ChunkPtr2 and nextPtr2 * refer to two adjacent chunks in the line above. */ chunkPtr = dlPtr->chunkPtr; leftX = 0; /* See Note A above. */ leftXIn = 1; rightX = chunkPtr->x + chunkPtr->width; if ((chunkPtr->nextPtr == NULL) && (rightX < maxX)) { rightX = maxX; } chunkPtr2 = NULL; if (prevPtr != NULL) { /* * Find the chunk in the previous line that covers leftX. */ nextPtr2 = prevPtr->chunkPtr; rightX2 = 0; /* See Note A above. */ while (rightX2 <= leftX) { chunkPtr2 = nextPtr2; if (chunkPtr2 == NULL) { break; } nextPtr2 = chunkPtr2->nextPtr; rightX2 = chunkPtr2->x + chunkPtr2->width; if (nextPtr2 == NULL) { rightX2 = INT_MAX; } } } else { nextPtr2 = NULL; rightX2 = INT_MAX; } while (leftX < maxX) { matchLeft = (chunkPtr2 != NULL) && SAME_BACKGROUND(chunkPtr2->stylePtr, chunkPtr->stylePtr); sValuePtr = chunkPtr->stylePtr->sValuePtr; if (rightX <= rightX2) { /* * The chunk in our line is about to end. If its style * changes then draw the bevel for the current style. */ if ((chunkPtr->nextPtr == NULL) || !SAME_BACKGROUND(chunkPtr->stylePtr, chunkPtr->nextPtr->stylePtr)) { if (!matchLeft && (sValuePtr->relief != TK_RELIEF_FLAT)) { Tk_3DHorizontalBevel(textPtr->tkwin, pixmap, sValuePtr->border, leftX + xOffset, 0, rightX - leftX, sValuePtr->borderWidth, leftXIn, 1, 1, sValuePtr->relief); } leftX = rightX; leftXIn = 1; /* * If the chunk in the line above is also ending at * the same point then advance to the next chunk in * that line. */ if ((rightX == rightX2) && (chunkPtr2 != NULL)) { goto nextChunk2; } } chunkPtr = chunkPtr->nextPtr; if (chunkPtr == NULL) { break; } rightX = chunkPtr->x + chunkPtr->width; if ((chunkPtr->nextPtr == NULL) && (rightX < maxX)) { rightX = maxX; } continue; } /* * The chunk in the line above is ending at an x-position where * there is no change in the style of the current line. If the * style above matches the current line on one side of the change * but not on the other, we have to draw an L-shaped piece of * bevel. */ matchRight = (nextPtr2 != NULL) && SAME_BACKGROUND(nextPtr2->stylePtr, chunkPtr->stylePtr); if (matchLeft && !matchRight) { if (sValuePtr->relief != TK_RELIEF_FLAT) { Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border, rightX2 - sValuePtr->borderWidth + xOffset, 0, sValuePtr->borderWidth, sValuePtr->borderWidth, 0, sValuePtr->relief); } leftX = rightX2 - sValuePtr->borderWidth; leftXIn = 0; } else if (!matchLeft && matchRight && (sValuePtr->relief != TK_RELIEF_FLAT)) { Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border, rightX2 + xOffset, 0, sValuePtr->borderWidth, sValuePtr->borderWidth, 1, sValuePtr->relief); Tk_3DHorizontalBevel(textPtr->tkwin, pixmap, sValuePtr->border, leftX + xOffset, 0, rightX2 + sValuePtr->borderWidth -leftX, sValuePtr->borderWidth, leftXIn, 0, 1, sValuePtr->relief); } nextChunk2: chunkPtr2 = nextPtr2; if (chunkPtr2 == NULL) { rightX2 = INT_MAX; } else { nextPtr2 = chunkPtr2->nextPtr; rightX2 = chunkPtr2->x + chunkPtr2->width; if (nextPtr2 == NULL) { rightX2 = INT_MAX; } } } /* * Pass 3: draw the horizontal bevels along the bottom of the line. * This uses the same approach as pass 2. */ chunkPtr = dlPtr->chunkPtr; leftX = 0; /* See Note A above. */ leftXIn = 0; rightX = chunkPtr->x + chunkPtr->width; if ((chunkPtr->nextPtr == NULL) && (rightX < maxX)) { rightX = maxX; } chunkPtr2 = NULL; if (dlPtr->nextPtr != NULL) { /* * Find the chunk in the previous line that covers leftX. */ nextPtr2 = dlPtr->nextPtr->chunkPtr; rightX2 = 0; /* See Note A above. */ while (rightX2 <= leftX) { chunkPtr2 = nextPtr2; if (chunkPtr2 == NULL) { break; } nextPtr2 = chunkPtr2->nextPtr; rightX2 = chunkPtr2->x + chunkPtr2->width; if (nextPtr2 == NULL) { rightX2 = INT_MAX; } } } else { nextPtr2 = NULL; rightX2 = INT_MAX; } while (leftX < maxX) { matchLeft = (chunkPtr2 != NULL) && SAME_BACKGROUND(chunkPtr2->stylePtr, chunkPtr->stylePtr); sValuePtr = chunkPtr->stylePtr->sValuePtr; if (rightX <= rightX2) { if ((chunkPtr->nextPtr == NULL) || !SAME_BACKGROUND(chunkPtr->stylePtr, chunkPtr->nextPtr->stylePtr)) { if (!matchLeft && (sValuePtr->relief != TK_RELIEF_FLAT)) { Tk_3DHorizontalBevel(textPtr->tkwin, pixmap, sValuePtr->border, leftX + xOffset, dlPtr->height - sValuePtr->borderWidth, rightX - leftX, sValuePtr->borderWidth, leftXIn, 0, 0, sValuePtr->relief); } leftX = rightX; leftXIn = 0; if ((rightX == rightX2) && (chunkPtr2 != NULL)) { goto nextChunk2b; } } chunkPtr = chunkPtr->nextPtr; if (chunkPtr == NULL) { break; } rightX = chunkPtr->x + chunkPtr->width; if ((chunkPtr->nextPtr == NULL) && (rightX < maxX)) { rightX = maxX; } continue; } matchRight = (nextPtr2 != NULL) && SAME_BACKGROUND(nextPtr2->stylePtr, chunkPtr->stylePtr); if (matchLeft && !matchRight) { if (sValuePtr->relief != TK_RELIEF_FLAT) { Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border, rightX2 - sValuePtr->borderWidth + xOffset, dlPtr->height - sValuePtr->borderWidth, sValuePtr->borderWidth, sValuePtr->borderWidth, 0, sValuePtr->relief); } leftX = rightX2 - sValuePtr->borderWidth; leftXIn = 1; } else if (!matchLeft && matchRight && (sValuePtr->relief != TK_RELIEF_FLAT)) { Tk_3DVerticalBevel(textPtr->tkwin, pixmap, sValuePtr->border, rightX2 + xOffset, dlPtr->height - sValuePtr->borderWidth, sValuePtr->borderWidth, sValuePtr->borderWidth, 1, sValuePtr->relief); Tk_3DHorizontalBevel(textPtr->tkwin, pixmap, sValuePtr->border, leftX + xOffset, dlPtr->height - sValuePtr->borderWidth, rightX2 + sValuePtr->borderWidth - leftX, sValuePtr->borderWidth, leftXIn, 1, 0, sValuePtr->relief); } nextChunk2b: chunkPtr2 = nextPtr2; if (chunkPtr2 == NULL) { rightX2 = INT_MAX; } else { nextPtr2 = chunkPtr2->nextPtr; rightX2 = chunkPtr2->x + chunkPtr2->width; if (nextPtr2 == NULL) { rightX2 = INT_MAX; } } }}/* *---------------------------------------------------------------------- * * DisplayText -- * * This procedure is invoked as a when-idle handler to update the * display. It only redisplays the parts of the text widget that * are out of date. * * Results: * None. * * Side effects: * Information is redrawn on the screen. * *-------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -