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

📄 tktextdisp.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 5 页
字号:
    lastCharChunkPtr = NULL;    /*     * Find the first segment to consider for the line.  Can't call     * TkTextIndexToSeg for this because it won't return a segment     * with zero size (such as the insertion cursor's mark).     */    for (offset = curIndex.charIndex, segPtr = curIndex.linePtr->segPtr;	    (offset > 0) && (offset >= segPtr->size);	    offset -= segPtr->size, segPtr = segPtr->nextPtr) {	/* Empty loop body. */    }    while (segPtr != NULL) {	if (segPtr->typePtr->layoutProc == NULL) {	    segPtr = segPtr->nextPtr;	    offset = 0;	    continue;	}	if (chunkPtr == NULL) {	    chunkPtr = (TkTextDispChunk *) ckalloc(sizeof(TkTextDispChunk));	    chunkPtr->nextPtr = NULL;	}	chunkPtr->stylePtr = GetStyle(textPtr, &curIndex);	/*	 * Save style information such as justification and indentation,	 * up until the first character is encountered, then retain that	 * information for the rest of the line.	 */	if (noCharsYet) {	    tabArrayPtr = chunkPtr->stylePtr->sValuePtr->tabArrayPtr;	    justify = chunkPtr->stylePtr->sValuePtr->justify;	    rMargin = chunkPtr->stylePtr->sValuePtr->rMargin;	    wrapMode = chunkPtr->stylePtr->sValuePtr->wrapMode;	    x = ((curIndex.charIndex == 0)		    ? chunkPtr->stylePtr->sValuePtr->lMargin1		    : chunkPtr->stylePtr->sValuePtr->lMargin2);	    if (wrapMode == tkTextNoneUid) {		maxX = INT_MAX;	    } else {		maxX = textPtr->dInfoPtr->maxX - textPtr->dInfoPtr->x			- rMargin;		if (maxX < x) {		    maxX = x;		}	    }	}	/*	 * See if there is a tab in the current chunk; if so, only	 * layout characters up to (and including) the tab.	 */	gotTab = 0;	maxChars = segPtr->size - offset;	if (justify == TK_JUSTIFY_LEFT) {	    if (segPtr->typePtr == &tkTextCharType) {		char *p;		for (p = segPtr->body.chars  + offset; *p != 0; p++) {		    if (*p == '\t') {			maxChars = (p + 1 - segPtr->body.chars) - offset;			gotTab = 1;			break;		    }		}	    }	}	chunkPtr->x = x;	code = (*segPtr->typePtr->layoutProc)(textPtr, &curIndex, segPtr,		offset, maxX-tabSize, maxChars, noCharsYet, wrapMode,		chunkPtr);	if (code <= 0) {	    FreeStyle(textPtr, chunkPtr->stylePtr);	    if (code < 0) {		/*		 * This segment doesn't wish to display itself (e.g. most		 * marks).		 */		segPtr = segPtr->nextPtr;		offset = 0;		continue;	    }	    /*	     * No characters from this segment fit in the window: this	     * means we're at the end of the display line.	     */	    if (chunkPtr != NULL) {		ckfree((char *) chunkPtr);	    }	    break;	}	if (chunkPtr->numChars > 0) {	    noCharsYet = 0;	    lastCharChunkPtr = chunkPtr;	}	if (lastChunkPtr == NULL) {	    dlPtr->chunkPtr = chunkPtr;	} else {	    lastChunkPtr->nextPtr = chunkPtr;	}	lastChunkPtr = chunkPtr;	x += chunkPtr->width;	if (chunkPtr->breakIndex > 0) {	    breakCharOffset = chunkPtr->breakIndex;	    breakIndex = curIndex;	    breakChunkPtr = chunkPtr;	}	if (chunkPtr->numChars != maxChars) {	    break;	}	/*	 * If we're at a new tab, adjust the layout for all the chunks	 * pertaining to the previous tab.  Also adjust the amount of	 * space left in the line to account for space that will be eaten	 * up by the tab.	 */	if (gotTab) {	    if (tabIndex >= 0) {		AdjustForTab(textPtr, tabArrayPtr, tabIndex, tabChunkPtr);		x = chunkPtr->x + chunkPtr->width;	    }	    tabIndex++;	    tabChunkPtr = chunkPtr;	    tabSize = SizeOfTab(textPtr, tabArrayPtr, tabIndex, x, maxX);	    if (tabSize >= (maxX - x)) {		break;	    }	}	curIndex.charIndex += chunkPtr->numChars;	offset += chunkPtr->numChars;	if (offset >= segPtr->size) {	    offset = 0;	    segPtr = segPtr->nextPtr;	}	chunkPtr = NULL;    }    if (noCharsYet) {	panic("LayoutDLine couldn't place any characters on a line");    }    wholeLine = (segPtr == NULL);    /*     * We're at the end of the display line.  Throw away everything     * after the most recent word break, if there is one;  this may     * potentially require the last chunk to be layed out again.     */    if (breakChunkPtr == NULL) {	/*	 * This code makes sure that we don't accidentally display	 * chunks with no characters at the end of the line (such as	 * the insertion cursor).  These chunks belong on the next	 * line.  So, throw away everything after the last chunk that	 * has characters in it.	 */	breakChunkPtr = lastCharChunkPtr;	breakCharOffset = breakChunkPtr->numChars;    }    if ((breakChunkPtr != NULL) && ((lastChunkPtr != breakChunkPtr)	    || (breakCharOffset != lastChunkPtr->numChars))) {	while (1) {	    chunkPtr = breakChunkPtr->nextPtr;	    if (chunkPtr == NULL) {		break;	    }	    FreeStyle(textPtr, chunkPtr->stylePtr);	    breakChunkPtr->nextPtr = chunkPtr->nextPtr;	    (*chunkPtr->undisplayProc)(textPtr, chunkPtr);	    ckfree((char *) chunkPtr);	}	if (breakCharOffset != breakChunkPtr->numChars) {	    (*breakChunkPtr->undisplayProc)(textPtr, breakChunkPtr);	    segPtr = TkTextIndexToSeg(&breakIndex, &offset);	    (*segPtr->typePtr->layoutProc)(textPtr, &breakIndex,		    segPtr, offset, maxX, breakCharOffset, 0, 		    wrapMode, breakChunkPtr);	}	lastChunkPtr = breakChunkPtr;	wholeLine = 0;    }    /*     * Make tab adjustments for the last tab stop, if there is one.     */    if ((tabIndex >= 0) && (tabChunkPtr != NULL)) {	AdjustForTab(textPtr, tabArrayPtr, tabIndex, tabChunkPtr);    }    /*     * Make one more pass over the line to recompute various things     * like its height, length, and total number of characters.  Also     * modify the x-locations of chunks to reflect justification.     * If we're not wrapping, I'm not sure what is the best way to     * handle left and center justification:  should the total length,     * for purposes of justification, be (a) the window width, (b)     * the length of the longest line in the window, or (c) the length     * of the longest line in the text?  (c) isn't available, (b) seems     * weird, since it can change with vertical scrolling, so (a) is     * what is implemented below.     */    if (wrapMode == tkTextNoneUid) {	maxX = textPtr->dInfoPtr->maxX - textPtr->dInfoPtr->x - rMargin;    }    dlPtr->length = lastChunkPtr->x + lastChunkPtr->width;    if (justify == TK_JUSTIFY_LEFT) {	jIndent = 0;    } else if (justify == TK_JUSTIFY_RIGHT) {	jIndent = maxX - dlPtr->length;    } else {	jIndent = (maxX - dlPtr->length)/2;    }    ascent = descent = 0;    for (chunkPtr = dlPtr->chunkPtr; chunkPtr != NULL;	    chunkPtr = chunkPtr->nextPtr) {	chunkPtr->x += jIndent;	dlPtr->count += chunkPtr->numChars;	if (chunkPtr->minAscent > ascent) {	    ascent = chunkPtr->minAscent;	}	if (chunkPtr->minDescent > descent) {	    descent = chunkPtr->minDescent;	}	if (chunkPtr->minHeight > dlPtr->height) {	    dlPtr->height = chunkPtr->minHeight;	}	sValuePtr = chunkPtr->stylePtr->sValuePtr;	if ((sValuePtr->borderWidth > 0)		&& (sValuePtr->relief != TK_RELIEF_FLAT)) {	    dlPtr->flags |= HAS_3D_BORDER;	}    }    if (dlPtr->height < (ascent + descent)) {	dlPtr->height = ascent + descent;	dlPtr->baseline = ascent;    } else {	dlPtr->baseline = ascent + (dlPtr->height - ascent - descent)/2;    }    sValuePtr = dlPtr->chunkPtr->stylePtr->sValuePtr;    if (dlPtr->index.charIndex == 0) {	dlPtr->spaceAbove = sValuePtr->spacing1;    } else {	dlPtr->spaceAbove = sValuePtr->spacing2 - sValuePtr->spacing2/2;    }    if (wholeLine) {	dlPtr->spaceBelow = sValuePtr->spacing3;    } else {	dlPtr->spaceBelow = sValuePtr->spacing2/2;    }    dlPtr->height += dlPtr->spaceAbove + dlPtr->spaceBelow;    dlPtr->baseline += dlPtr->spaceAbove;    /*     * Recompute line length:  may have changed because of justification.     */    dlPtr->length = lastChunkPtr->x + lastChunkPtr->width;    return dlPtr;}/* *---------------------------------------------------------------------- * * UpdateDisplayInfo -- * *	This procedure is invoked to recompute some or all of the *	DLine structures for a text widget.  At the time it is called *	the DLine structures still left in the widget are guaranteed *	to be correct except that (a) the y-coordinates aren't *	necessarily correct, (b) there may be missing structures *	(the DLine structures get removed as soon as they are potentially *	out-of-date), and (c) DLine structures that don't start at the *	beginning of a line may be incorrect if previous information in *	the same line changed size in a way that moved a line boundary *	(DLines for any info that changed will have been deleted, but *	not DLines for unchanged info in the same text line). * * Results: *	None. * * Side effects: *	Upon return, the DLine information for textPtr correctly reflects *	the positions where characters will be displayed.  However, this *	procedure doesn't actually bring the display up-to-date. * *---------------------------------------------------------------------- */static voidUpdateDisplayInfo(textPtr)    TkText *textPtr;			/* Text widget to update. */{    register TextDInfo *dInfoPtr = textPtr->dInfoPtr;    register DLine *dlPtr, *prevPtr;    TkTextIndex index;    TkTextLine *lastLinePtr;    int y, maxY, pixelOffset, maxOffset;    if (!(dInfoPtr->flags & DINFO_OUT_OF_DATE)) {	return;    }    dInfoPtr->flags &= ~DINFO_OUT_OF_DATE;    /*     * Delete any DLines that are now above the top of the window.     */    index = textPtr->topIndex;    dlPtr = FindDLine(dInfoPtr->dLinePtr, &index);    if ((dlPtr != NULL) && (dlPtr != dInfoPtr->dLinePtr)) {	FreeDLines(textPtr, dInfoPtr->dLinePtr, dlPtr, 1);    }    /*     *--------------------------------------------------------------     * Scan through the contents of the window from top to bottom,     * recomputing information for lines that are missing.     *--------------------------------------------------------------     */    lastLinePtr = TkBTreeFindLine(textPtr->tree,	    TkBTreeNumLines(textPtr->tree));    dlPtr = dInfoPtr->dLinePtr;    prevPtr = NULL;    y = dInfoPtr->y;    maxY = dInfoPtr->maxY;    while (1) {	register DLine *newPtr;	if (index.linePtr == lastLinePtr) {	    break;	}	/*	 * There are three possibilities right now:	 * (a) the next DLine (dlPtr) corresponds exactly to the next	 *     information we want to display: just use it as-is.	 * (b) the next DLine corresponds to a different line, or to	 *     a segment that will be coming later in the same line:	 *     leave this DLine alone in the hopes that we'll be able	 *     to use it later, then create a new DLine in front of	 *     it.	 * (c) the next DLine corresponds to a segment in the line we	 *     want, but it's a segment that has already been processed	 *     or will never be processed.  Delete the DLine and try	 *     again.	 *	 * One other twist on all this.  It's possible for 3D borders	 * to interact between lines (see DisplayLineBackground) so if	 * a line is relayed out and has styles with 3D borders, its	 * neighbors have to be redrawn if they have 3D borders too,	 * since the interactions could have changed (the neighbors	 * don't have to be relayed out, just redrawn).	 */	if ((dlPtr == NULL) || (dlPtr->index.linePtr != index.linePtr)) {	    /*	     * Case (b) -- must make new DLine.	     */	    makeNewDLine:	    if (tkTextDebug) {		char string[TK_POS_CHARS];		/*		 * Debugging is enabled, so keep a log of all the lines		 * that were re-layed out.  The test suite uses this		 * information.		 */		TkTextPrintIndex(&index, string);		Tcl_SetVar2(textPtr->interp, "tk_textRelayout", (char *) NULL,			string,			TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);	    }	    newPtr = LayoutDLine(textPtr, &index);	    if (prevPtr == NULL) {		dInfoPtr->dLinePtr = newPtr;	    } else {		prevPtr->nextPtr = newPtr;		if (prevPtr->flags & HAS_3D_BORDER) {		    prevPtr->oldY = -1;		}	    }	    newPtr->nextPtr = dlPtr;	    dlPtr = newPtr;	} else {	    /*	     * DlPtr refers to the line we want.  Next check the	     * index within the line.	     */

⌨️ 快捷键说明

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