⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tktextdisp.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 5 页
字号:
	    if (index.charIndex == dlPtr->index.charIndex) {		/*		 * Case (a) -- can use existing display line as-is.		 */		if ((dlPtr->flags & HAS_3D_BORDER) && (prevPtr != NULL)			&& (prevPtr->flags & (NEW_LAYOUT))) {		    dlPtr->oldY = -1;		}		goto lineOK;	    }	    if (index.charIndex < dlPtr->index.charIndex) {		goto makeNewDLine;	    }	    /*	     * Case (c) -- dlPtr is useless.  Discard it and start	     * again with the next display line.	     */	    newPtr = dlPtr->nextPtr;	    FreeDLines(textPtr, dlPtr, newPtr, 0);	    dlPtr = newPtr;	    if (prevPtr != NULL) {		prevPtr->nextPtr = newPtr;	    } else {		dInfoPtr->dLinePtr = newPtr;	    }	    continue;	}	/*	 * Advance to the start of the next line.	 */	lineOK:	dlPtr->y = y;	y += dlPtr->height;	TkTextIndexForwChars(&index, dlPtr->count, &index);	prevPtr = dlPtr;	dlPtr = dlPtr->nextPtr;	/*	 * If we switched text lines, delete any DLines left for the	 * old text line.	 */	if (index.linePtr != prevPtr->index.linePtr) {	    register DLine *nextPtr;	    nextPtr = dlPtr;	    while ((nextPtr != NULL)		    && (nextPtr->index.linePtr == prevPtr->index.linePtr)) {		nextPtr = nextPtr->nextPtr;	    }	    if (nextPtr != dlPtr) {		FreeDLines(textPtr, dlPtr, nextPtr, 0);		prevPtr->nextPtr = nextPtr;		dlPtr = nextPtr;	    }	}	/*	 * It's important to have the following check here rather than in	 * the while statement for the loop, so that there's always at least	 * one DLine generated, regardless of how small the window is.  This	 * keeps a lot of other code from breaking.	 */	if (y >= maxY) {	    break;	}    }    /*     * Delete any DLine structures that don't fit on the screen.     */    FreeDLines(textPtr, dlPtr, (DLine *) NULL, 1);    /*     *--------------------------------------------------------------     * If there is extra space at the bottom of the window (because     * we've hit the end of the text), then bring in more lines at     * the top of the window, if there are any, to fill in the view.     *--------------------------------------------------------------     */    if (y < maxY) {	int lineNum, spaceLeft, charsToCount;	DLine *lowestPtr;	/*	 * Layout an entire text line (potentially > 1 display line),	 * then link in as many display lines as fit without moving	 * the bottom line out of the window.  Repeat this until	 * all the extra space has been used up or we've reached the	 * beginning of the text.	 */	spaceLeft = maxY - y;	lineNum = TkBTreeLineIndex(dInfoPtr->dLinePtr->index.linePtr);	charsToCount = dInfoPtr->dLinePtr->index.charIndex;	if (charsToCount == 0) {	    charsToCount = INT_MAX;	    lineNum--;	}	for ( ; (lineNum >= 0) && (spaceLeft > 0); lineNum--) {	    index.linePtr = TkBTreeFindLine(textPtr->tree, lineNum);	    index.charIndex = 0;	    lowestPtr = NULL;	    do {		dlPtr = LayoutDLine(textPtr, &index);		dlPtr->nextPtr = lowestPtr;		lowestPtr = dlPtr;		TkTextIndexForwChars(&index, dlPtr->count, &index);		charsToCount -= dlPtr->count;	    } while ((charsToCount > 0)		    && (index.linePtr == lowestPtr->index.linePtr));	    /*	     * Scan through the display lines from the bottom one up to	     * the top one.	     */	    while (lowestPtr != NULL) {		dlPtr = lowestPtr;		spaceLeft -= dlPtr->height;		if (spaceLeft < 0) {		    break;		}		lowestPtr = dlPtr->nextPtr;		dlPtr->nextPtr = dInfoPtr->dLinePtr;		dInfoPtr->dLinePtr = dlPtr;		if (tkTextDebug) {		    char string[TK_POS_CHARS];		    TkTextPrintIndex(&dlPtr->index, string);		    Tcl_SetVar2(textPtr->interp, "tk_textRelayout",			    (char *) NULL, string,			    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);		}	    }	    FreeDLines(textPtr, lowestPtr, (DLine *) NULL, 0);	    charsToCount = INT_MAX;	}	/*	 * Now we're all done except that the y-coordinates in all the	 * DLines are wrong and the top index for the text is wrong.	 * Update them.	 */	textPtr->topIndex = dInfoPtr->dLinePtr->index;	y = dInfoPtr->y;	for (dlPtr = dInfoPtr->dLinePtr; dlPtr != NULL;		dlPtr = dlPtr->nextPtr) {	    if (y > dInfoPtr->maxY) {		panic("Added too many new lines in UpdateDisplayInfo");	    }	    dlPtr->y = y;	    y += dlPtr->height; 	}    }    /*     *--------------------------------------------------------------     * If the old top or bottom line has scrolled elsewhere on the     * screen, we may not be able to re-use its old contents by     * copying bits (e.g., a beveled edge that was drawn when it was     * at the top or bottom won't be drawn when the line is in the     * middle and its neighbor has a matching background).  Similarly,     * if the new top or bottom line came from somewhere else on the     * screen, we may not be able to copy the old bits.     *--------------------------------------------------------------     */    dlPtr = dInfoPtr->dLinePtr;    if ((dlPtr->flags & HAS_3D_BORDER) && !(dlPtr->flags & TOP_LINE)) {	dlPtr->oldY = -1;    }    while (1) {	if ((dlPtr->flags & TOP_LINE) && (dlPtr != dInfoPtr->dLinePtr)		&& (dlPtr->flags & HAS_3D_BORDER)) {	    dlPtr->oldY = -1;	}	if ((dlPtr->flags & BOTTOM_LINE) && (dlPtr->nextPtr != NULL)		&& (dlPtr->flags & HAS_3D_BORDER)) {	    dlPtr->oldY = -1;	}	if (dlPtr->nextPtr == NULL) {	    if ((dlPtr->flags & HAS_3D_BORDER)		    && !(dlPtr->flags & BOTTOM_LINE)) {		dlPtr->oldY = -1;	    }	    dlPtr->flags &= ~TOP_LINE;	    dlPtr->flags |= BOTTOM_LINE;	    break;	}	dlPtr->flags &= ~(TOP_LINE|BOTTOM_LINE);	dlPtr = dlPtr->nextPtr;    }    dInfoPtr->dLinePtr->flags |= TOP_LINE;    /*     * Arrange for scrollbars to be updated.     */    textPtr->flags |= UPDATE_SCROLLBARS;    /*     *--------------------------------------------------------------     * Deal with horizontal scrolling:     * 1. If there's empty space to the right of the longest line,     *    shift the screen to the right to fill in the empty space.     * 2. If the desired horizontal scroll position has changed,     *    force a full redisplay of all the lines in the widget.     * 3. If the wrap mode isn't "none" then re-scroll to the base     *    position.     *--------------------------------------------------------------     */    dInfoPtr->maxLength = 0;    for (dlPtr = dInfoPtr->dLinePtr; dlPtr != NULL;	    dlPtr = dlPtr->nextPtr) {	if (dlPtr->length > dInfoPtr->maxLength) {	    dInfoPtr->maxLength = dlPtr->length;	}    }    maxOffset = (dInfoPtr->maxLength - (dInfoPtr->maxX - dInfoPtr->x)	    + textPtr->charWidth - 1)/textPtr->charWidth;    if (dInfoPtr->newCharOffset > maxOffset) {	dInfoPtr->newCharOffset = maxOffset;    }    if (dInfoPtr->newCharOffset < 0) {	dInfoPtr->newCharOffset = 0;    }    pixelOffset = dInfoPtr->newCharOffset * textPtr->charWidth;    if (pixelOffset != dInfoPtr->curPixelOffset) {	dInfoPtr->curPixelOffset = pixelOffset;	for (dlPtr = dInfoPtr->dLinePtr; dlPtr != NULL;		dlPtr = dlPtr->nextPtr) {	    dlPtr->oldY = -1;	}    }}/* *---------------------------------------------------------------------- * * FreeDLines -- * *	This procedure is called to free up all of the resources *	associated with one or more DLine structures. * * Results: *	None. * * Side effects: *	Memory gets freed and various other resources are released. * *---------------------------------------------------------------------- */static voidFreeDLines(textPtr, firstPtr, lastPtr, unlink)    TkText *textPtr;			/* Information about overall text					 * widget. */    register DLine *firstPtr;		/* Pointer to first DLine to free up. */    DLine *lastPtr;			/* Pointer to DLine just after last					 * one to free (NULL means everything					 * starting with firstPtr). */    int unlink;				/* 1 means DLines are currently linked					 * into the list rooted at					 * textPtr->dInfoPtr->dLinePtr and					 * they have to be unlinked.  0 means					 * just free without unlinking. */{    register TkTextDispChunk *chunkPtr, *nextChunkPtr;    register DLine *nextDLinePtr;    if (unlink) {	if (textPtr->dInfoPtr->dLinePtr == firstPtr) {	    textPtr->dInfoPtr->dLinePtr = lastPtr;	} else {	    register DLine *prevPtr;	    for (prevPtr = textPtr->dInfoPtr->dLinePtr;		    prevPtr->nextPtr != firstPtr; prevPtr = prevPtr->nextPtr) {		/* Empty loop body. */	    }	    prevPtr->nextPtr = lastPtr;	}    }    while (firstPtr != lastPtr) {	nextDLinePtr = firstPtr->nextPtr;	for (chunkPtr = firstPtr->chunkPtr; chunkPtr != NULL;		chunkPtr = nextChunkPtr) {	    if (chunkPtr->undisplayProc != NULL) {		(*chunkPtr->undisplayProc)(textPtr, chunkPtr);	    }	    FreeStyle(textPtr, chunkPtr->stylePtr);	    nextChunkPtr = chunkPtr->nextPtr;	    ckfree((char *) chunkPtr);	}	ckfree((char *) firstPtr);	firstPtr = nextDLinePtr;    }    textPtr->dInfoPtr->dLinesInvalidated = 1;}/* *---------------------------------------------------------------------- * * DisplayDLine -- * *	This procedure is invoked to draw a single line on the *	screen. * * Results: *	None. * * Side effects: *	The line given by dlPtr is drawn at its correct position in *	textPtr's window.  Note that this is one *display* line, not *	one *text* line. * *---------------------------------------------------------------------- */static voidDisplayDLine(textPtr, dlPtr, prevPtr, pixmap)    TkText *textPtr;		/* Text widget in which to draw line. */    register DLine *dlPtr;	/* Information about line to draw. */    DLine *prevPtr;		/* Line just before one to draw, or NULL				 * if dlPtr is the top line. */    Pixmap pixmap;		/* Pixmap to use for double-buffering.				 * Caller must make sure it's large enough				 * to hold line. */{    register TkTextDispChunk *chunkPtr;    TextDInfo *dInfoPtr = textPtr->dInfoPtr;    Display *display;    int height, x;    /*     * First, clear the area of the line to the background color for the     * text widget.     */    display = Tk_Display(textPtr->tkwin);    Tk_Fill3DRectangle(textPtr->tkwin, pixmap, textPtr->border, 0, 0,	    Tk_Width(textPtr->tkwin), dlPtr->height, 0, TK_RELIEF_FLAT);    /*     * Next, draw background information for the whole line.     */    DisplayLineBackground(textPtr, dlPtr, prevPtr, pixmap);    /*     * Make another pass through all of the chunks to redraw the     * insertion cursor, if it is visible on this line.  Must do     * it here rather than in the foreground pass below because     * otherwise a wide insertion cursor will obscure the character     * to its left.     */    if (textPtr->state == tkNormalUid) {	for (chunkPtr = dlPtr->chunkPtr; (chunkPtr != NULL);		chunkPtr = chunkPtr->nextPtr) {	    x = chunkPtr->x + dInfoPtr->x - dInfoPtr->curPixelOffset;	    if (chunkPtr->displayProc == TkTextInsertDisplayProc) {		(*chunkPtr->displayProc)(chunkPtr, x, dlPtr->spaceAbove,			dlPtr->height - dlPtr->spaceAbove - dlPtr->spaceBelow,			dlPtr->baseline - dlPtr->spaceAbove, display, pixmap,			dlPtr->y + dlPtr->spaceAbove);	    }	}    }    /*     * Make yet another pass through all of the chunks to redraw all of     * foreground information.  Note:  we have to call the displayProc     * even for chunks that are off-screen.  This is needed, for     * example, so that embedded windows can be unmapped in this case.     * Conve     */    for (chunkPtr = dlPtr->chunkPtr; (chunkPtr != NULL);	    chunkPtr = chunkPtr->nextPtr) {	if (chunkPtr->displayProc == TkTextInsertDisplayProc) {	    /*	     * Already displayed the insertion cursor above.  Don't	     * do it again here.	     */	    continue;	}	x = chunkPtr->x + dInfoPtr->x - dInfoPtr->curPixelOffset;	if ((x + chunkPtr->width <= 0) || (x >= dInfoPtr->maxX)) {	    /*	     * Note:  we have to call the displayProc even for chunks	     * that are off-screen.  This is needed, for example, so	     * that embedded windows can be unmapped in this case.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -