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

📄 scrolltext.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
    textInfo->numLines = linenum+1;    if (startPos == 0) {	textInfo->startLine = 0;    }    textInfo->endLine = FindEndLine(textInfo, &(textInfo->bottomSpace));    textInfo->curLine = linenum;    /* Check to see if we are at the bottom */    if (textInfo->endLine >= textInfo->numLines-1) {	textInfo->curY = textInfo->h - textInfo->bottomSpace -	  lineptr->lineHeight;	textInfo->flagWord &= (~NOTATBOTTOM);    } else {	textInfo->flagWord |= NOTATBOTTOM;    }    return 1;}int TxtAddFont(display, textWin, fontNumber, newFont, newColor)Display *display;Window textWin;			/* Scrollable text window  */int fontNumber;			/* Place to add font (0-7) */XFontStruct *newFont;		/* Font to add             */int newColor;			/* Color of font           *//* * This routine loads a new font so that it can be used in a previously * created text window.  There are eight font slots numbered 0 through 7. * If there is already a font in the specified slot,  it will be replaced * and an automatic redraw of the window will take place.  See TxtWriteStr * for details on using alternate fonts.  The color specifies the foreground * color of the text.  The default foreground color is used if this * parameter is TXT_NO_COLOR.  Returns a non-zero value if * everything went well. */{    struct txtWin *textInfo;    int redrawFlag;    XGCValues gc_val;        if ((fontNumber < 0) || (fontNumber >= MAXFONTS)) return 0;    if ((textInfo = (struct txtWin *)	 XLookUpAssoc(display, textWindows, (XID) textWin)) == 0)      return 0;    if (newColor == TXT_NO_COLOR) {	newColor = textInfo->fgPix;    }    gc_val.font = newFont->fid;    gc_val.foreground = newColor;    gc_val.background = textInfo->bgPix;    gc_val.plane_mask = AllPlanes;    gc_val.graphics_exposures = 1;    gc_val.function = GXcopy;        if (textInfo->fontGC[fontNumber] != 0)    {	XChangeGC(display, textInfo->fontGC[fontNumber],		  GCFont | GCForeground, &gc_val);    }    else	textInfo->fontGC[fontNumber] = XCreateGC(display, textWin,						 GCFont |						 GCForeground |						 GCBackground |						 GCFunction |						 GCPlaneMask |						 GCGraphicsExposures,						 &gc_val);     redrawFlag = (textInfo->theFonts[fontNumber].fid != 0) &&      (((newFont) && (newFont->fid != textInfo->theFonts[fontNumber].fid)) ||       (newColor != textInfo->theColors[fontNumber]));    if (newFont) {	textInfo->theFonts[fontNumber] = *newFont;    }    textInfo->theColors[fontNumber] = newColor;    if (redrawFlag) {	RecompBuffer(textInfo);	XClearWindow(display, textWin);	TxtRepaint(display, textWin);    }    return 1;}int TxtWinP(display, w)Display *display;Window w;/* * Returns a non-zero value if the window has been previously grabbed * using TxtGrab and 0 if it has not. */{    if (XLookUpAssoc(display, textWindows, (XID) w))      return(1);    else return(0);}static int FindEndLine(textInfo, botSpace)struct txtWin *textInfo;int *botSpace;/* * Given the starting line in 'textInfo->startLine',  this routine * determines the index of the last line that can be drawn given the * current size of the screen.  If there are not enough lines to * fill the screen,  the index of the last line will be returned. * The amount of empty bottom space is returned in 'botSpace'. */{    int index, height, lineHeight;    height = YPADDING;    index = textInfo->startLine;    while (index < textInfo->numLines) {	lineHeight = textInfo->txtBuffer[index]->lineHeight + INTERLINE;	if (height + lineHeight > textInfo->h) break;	height += lineHeight;	index++;    }    if (botSpace) {	*botSpace = textInfo->h - height;    }    return index - 1;}static int UpdateScroll(display, textInfo)Display *display;struct txtWin *textInfo;	/* Text window information *//* * This routine computes the current extent of the scroll bar * indicator and repaints the bar with the correct information. */{    int top, bottom;    if (textInfo->numLines > 1) {	top = textInfo->startLine * (textInfo->h - 2*BARBORDER) /	  (textInfo->numLines - 1);	bottom = textInfo->endLine * (textInfo->h - 2*BARBORDER) /	  (textInfo->numLines - 1);    } else {	top = 0;	bottom = textInfo->h - (2*BARBORDER);    }    /* Draw it - make sure there is a little padding */    if (top == 0) top++;    if (bottom == textInfo->h-(2*BARBORDER)) bottom--;    XFillRectangle(display, textInfo->scrollBar,		   textInfo->bgGC, 		   0, 0, BARSIZE, top-1);    XFillRectangle(display, textInfo->scrollBar,		   DEFAULT_GC, top, BARSIZE - (2*BARBORDER) - 2,		   bottom - top);    XFillRectangle(display, textInfo->scrollBar, DEFAULT_GC,		   0, bottom+1, BARSIZE,		   textInfo->h - (2 * BARBORDER) - bottom);    return 1;}int TxtClear(display, w)Display *display;Window w;/* * This routine clears a scrollable text window.  It resets the current * writing position to the upper left hand corner of the screen.  * NOTE:  THIS ALSO CLEARS THE CONTENTS OF THE TEXT WINDOW BUFFER AND * RESETS THE SCROLL BAR.  Returns 0 if the window is not a text window. * This should be used *instead* of XClear. */{    struct txtWin *textInfo;    int index;    if ((textInfo = (struct txtWin *) XLookUpAssoc(display, textWindows, (XID) w)) == 0)      return 0;    /* Zero out the arrays */    textInfo->bufSpot = 0;    for (index = 0;  index < textInfo->numLines;  index++) {	InitLine(textInfo->txtBuffer[index]);    }    textInfo->txtBuffer[0]->lineHeight =      textInfo->theFonts[textInfo->curFont].ascent +	  textInfo->theFonts[textInfo->curFont].descent;    textInfo->numLines = 1;    textInfo->startLine = 0;    textInfo->endLine = 0;    textInfo->curLine = 0;    textInfo->curX = 0;    textInfo->curY = YPADDING + textInfo->theFonts[textInfo->curFont].ascent 	+ textInfo->theFonts[textInfo->curFont].descent;    textInfo->bottomSpace = textInfo->h - YPADDING -      textInfo->theFonts[textInfo->curFont].ascent - INTERLINE -	  textInfo->theFonts[textInfo->curFont].descent;    /* Actually clear the window */    XClearWindow(display, w);    /* Draw the current cursor */    XFillRectangle(display, w, textInfo->CursorGC,		   XPADDING + CUROFFSET, textInfo->curY,		   CURSORWIDTH,		   textInfo->theFonts[textInfo->curFont].ascent +		   textInfo->theFonts[textInfo->curFont].descent);    /* Update the scroll bar */    UpdateScroll(display, textInfo);    return 1;}static int WarpToBottom(display, textInfo)Display *display;struct txtWin *textInfo;	/* Text Information *//* * This routine causes the specified text window to display its * last screen of information.   It updates the scroll bar * to the appropriate spot.  The implementation scans backward * through the buffer to find an appropriate starting spot for * the window. */{    int index, height, lineHeight;    index = textInfo->numLines-1;    height = 0;    while (index >= 0) {	lineHeight = textInfo->txtBuffer[index]->lineHeight + INTERLINE;	if (height + lineHeight > textInfo->h) break;	height += lineHeight;	index--;    }    textInfo->startLine = index + 1;    textInfo->endLine = FindEndLine(textInfo, &(textInfo->bottomSpace));    textInfo->curY = textInfo->h - textInfo->bottomSpace -      textInfo->txtBuffer[textInfo->endLine]->lineHeight;    XClearWindow(display, textInfo->mainWindow);    TxtRepaint(display, textInfo->mainWindow);    return 1;}static int UpdateExposures(display, textInfo)Display *display;struct txtWin *textInfo;	/* Text window information *//* * Before a new scrolling action occurs,  the text window package * must handle all COPYEXPOSE events generated by the last scrolling * action.  This routine is called to do this.  Foreign events (those * not handled by TxtFilter) are queued up and replaced on the queue * after the processing of the exposure events is complete. */{#if 0    XEvent foreignQueue[MAXFOREIGN];    int index, lastItem = 0;    while (textInfo->flagWord & COPYEXPOSE) {	XNextEvent(display, &(foreignQueue[lastItem]));	if (!TxtFilter(display, &(foreignQueue[lastItem])))	  lastItem++;	if (lastItem >= MAXFOREIGN) {	    printf("Too many foreign events to queue!\n");	    textInfo->flagWord &= (~COPYEXPOSE);	}    }    for (index = 0;  index < lastItem;  index++) {	XPutBackEvent(display, &(foreignQueue[index]));    }#endif    return 1;}static int ScrollDown(display,textInfo)Display *display;struct txtWin *textInfo;	/* Text window information *//* * This routine scrolls the indicated text window down by one * line.  The line below the current line must exist.  The window * is scrolled so that the line below the last line is fully * displayed.  This may cause many lines to scroll off the top. * Scrolling is done using XCopyArea.  The exposure events should * be caught using ExposeCopy. */{    int lineSum, index, targetSpace, freeSpace, updateFlag;    lineSum = 0;    if (textInfo->endLine + 1 >= textInfo->numLines) return 0;    targetSpace = textInfo->txtBuffer[textInfo->endLine+1]->lineHeight +      INTERLINE;    if (textInfo->bottomSpace < targetSpace) {	index = textInfo->startLine;	while (index < textInfo->endLine) {	    lineSum += (textInfo->txtBuffer[index]->lineHeight + INTERLINE);	    if (textInfo->bottomSpace + lineSum >= targetSpace) break;	    index++;	}	/* Must move upward by 'lineSum' pixels */	XCopyArea(display, textInfo->mainWindow, textInfo->mainWindow,		  DEFAULT_GC, 0, lineSum,		  textInfo->w - BARSIZE, textInfo->h,		  0, 0);	textInfo->flagWord |= COPYEXPOSE;	/* Repair the damage to the structures */	textInfo->startLine = index + 1;	updateFlag = 1;    } else {	updateFlag = 0;    }    /* More lines might be able to fit.  Let's check. */    freeSpace = textInfo->bottomSpace + lineSum - targetSpace;    index = textInfo->endLine + 1;    while (index < textInfo->numLines-1) {	if (freeSpace - textInfo->txtBuffer[index+1]->lineHeight - INTERLINE < 0)	  break;	freeSpace -= (textInfo->txtBuffer[index+1]->lineHeight + INTERLINE);	index++;    }    textInfo->endLine = index;    textInfo->bottomSpace = freeSpace;    if (updateFlag) {	UpdateExposures(display, textInfo);    }    UpdateScroll(display, textInfo);    return 1;}static int ExpandLines(textInfo)struct txtWin *textInfo;	/* Text Information *//* * This routine allocates and initializes additional space in * the line start array (txtBuffer).  The new space * is allocated using realloc.  The expansion factor is a percentage * given by EXPANDPERCENT. */{    int newSize, index;    newSize = textInfo->allocLines;    newSize += (newSize * EXPANDPERCENT) / 100;    textInfo->txtBuffer = (struct txtLine **)      realloc((char *) textInfo->txtBuffer,	      (unsigned) (newSize * sizeof(struct txtLine *)));    for (index = textInfo->allocLines;  index < newSize;  index++) {	textInfo->txtBuffer[index] = alloc(struct txtLine);	InitLine(textInfo->txtBuffer[index]);    }    textInfo->allocLines = newSize;    return 1;}static int ExpandBuffer(textInfo)struct txtWin *textInfo;	/* Text information *//* * Expands the basic character buffer using realloc.  The expansion * factor is a percentage given by EXPANDPERCENT. */{    int newSize;    newSize = textInfo->bufAlloc + (textInfo->bufAlloc * EXPANDPERCENT) / 100;    textInfo->mainBuffer = (short *)      realloc((char *) textInfo->mainBuffer, (unsigned) newSize * sizeof(short));    textInfo->bufAlloc = newSize;    return 1;}static int HandleNewLine(display, textInfo, flagWord)Display *display;struct txtWin *textInfo;	/* Text Information            */int flagWord;			/* DODISP or NONEWLINE or both *//* * This routine initializes the next line for drawing by setting * its height to the current font height,  scrolls the screen down * one line,  and updates the current drawing position to the * left edge of the newly cleared line.  If DODISP is specified, * the screen will be updated (otherwise not).  If NONEWLINE is * specified,  no newline character will be added to the text buffer * (this is for line wrap). */{    struct txtLine *curLine, *nextLine;    /* Check to see if a new line must be allocated */    if (textInfo->curLine >= textInfo->allocLines-1)      /* Expand the number of lines */      ExpandLines(textInfo);    textInfo->numLines += 1;    /* Then we initialize the next line */    nextLine = textInfo->txtBuffer[textInfo->numLines-1];    nextLine->lineHeight =	textInfo->theFonts[textInfo->curFont].ascent +	    textInfo->theFonts[textInfo->curFont].descent;    curLine = textInfo->txtBuffer[textInfo->curLine];    if (flagWord & DODISP) {	/* Scroll down a line if required */	if ((textInfo->curY + curLine->lineHeight +	     nextLine->lineHeight + (INTERLINE * 2)) > textInfo->h)	  {	      ScrollDown(display, textInfo);	  }	else	  {	      /* Update the bottom space appropriately */	      textInfo->bottomSpace -= (nextLine->lineHeight + INTERLINE);	      textInfo->endLine += 1;	  }	/* Update drawing position */	textInfo->curY = textInfo->h -	  (textInfo->bottomSpace  + nextLine->lineHeight);    }    /* Move down a line */    textInfo->curLine += 1;    if (!(flagWord & NONEWLINE)) {	/* Append end-of-line to text buffer */	if (textInfo->bufSpot >= textInfo->bufAlloc) {	    /* Allocate more space in main text buffer */	    ExpandBuffer(textInfo);	}	textInfo->mainBuffer[(textInfo->bufSpot)++] =	  (textInfo->curFont << FONTSHIFT) | '\n';    }    nextLine->lineText = textInfo->bufSpot;    textInfo->curX = 0;    return 1;}static int CharSize(textInfo, lineNum, charNum)struct txtWin *textInfo;	/* Current Text Information */int lineNum;			/* Line in buffer           */int charNum;			/* Character in line        *//* * This routine determines the size of the specified character.

⌨️ 快捷键说明

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