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

📄 scrolltext.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
 * It takes in account the font of the character and whether its * fixed or variable.  The size includes INTERSPACE spacing between * the characters. */{    register XFontStruct *charFont;    register short *theLine;    register short theChar;    theLine = &(textInfo->mainBuffer[textInfo->txtBuffer[lineNum]->lineText]);    theChar = theLine[charNum] & CHARMASK;    charFont = &(textInfo->theFonts[(theChar & FONTMASK) >> FONTSHIFT]);    if (theChar <= charFont->min_char_or_byte2 ||	theChar >= charFont->max_char_or_byte2 ||	charFont->per_char == 0)	return  charFont->max_bounds.width + 1;    else	return charFont->per_char[theChar].width + 1;}static int HandleBackspace(display, textInfo, flagWord)Display *display;struct txtWin *textInfo;	/* Text Information  */int flagWord;			/* DODISP or nothing *//* * This routine handles a backspace found in the input stream.  The * character before the current writing position will be erased and * the drawing position will move back one character.  If the writing * position is at the left margin,  the drawing position will move * up to the previous line.  If it is a line that has been wrapped, * the character at the end of the previous line will be erased. */{    struct txtLine *thisLine, *prevLine;    int chSize;    thisLine = textInfo->txtBuffer[textInfo->curLine];    /* First,  determine whether we need to go back a line */    if (thisLine->lineLength == 0) {	/* Bleep if at top of buffer */	if (textInfo->curLine == 0) {	    XBell(display, 50);	    return 0;	}	/* See if we have to scroll in the other direction */	if ((flagWord & DODISP) && (textInfo->curY <= YPADDING)) {	    /* This will display the last lines of the buffer */	    WarpToBottom(display, textInfo);	}	/* Set drawing position at end of previous line */	textInfo->curLine -= 1;	prevLine = textInfo->txtBuffer[textInfo->curLine];	textInfo->numLines -= 1;	if (flagWord & DODISP) {	    textInfo->curY -= (prevLine->lineHeight + INTERLINE);	    textInfo->bottomSpace += (thisLine->lineHeight + INTERLINE);	    textInfo->endLine -= 1;	}	/* We are unlinewrapping if the previous line has flag set */	if (prevLine->lineFlags & WRAPFLAG) {	    /* Get rid of line wrap indicator */	    if (flagWord & DODISP) {		XFillRectangle(display, textInfo->mainWindow,			       textInfo->bgGC,			       textInfo->w - BARSIZE - WRAPINDSIZE,			       textInfo->curY,  WRAPINDSIZE,			       prevLine->lineHeight);	    }	    prevLine->lineFlags &= (~WRAPFLAG);	    /* Call recursively to wipe out the ending character */	    HandleBackspace(display, textInfo, flagWord);	} else {	    /* Delete the end-of-line in the primary buffer */	    textInfo->bufSpot -= 1;	}    } else {	/* Normal deletion of character */	chSize =	  CharSize(textInfo, textInfo->curLine,		   textInfo->txtBuffer[textInfo->curLine]->lineLength - 1);	/* Move back appropriate amount and wipe it out */	thisLine->lineWidth -= chSize;	if (flagWord & DODISP) {	    XFillRectangle(display, textInfo->mainWindow,			   textInfo->bgGC,			   thisLine->lineWidth, textInfo->curY,			   chSize, thisLine->lineHeight);	}	/* Delete from buffer */	textInfo->txtBuffer[textInfo->curLine]->lineLength -= 1;	textInfo->bufSpot -= 1;    }    return 1;}static int DrawLineWrap(display, win, x, y, h, col)Display *display;Window win;			/* What window to draw it in     */int x, y;			/* Position of upper left corner */int h;				/* Height of indicator           */int col;			/* Color of indicator            *//* * This routine draws a line wrap indicator at the end of a line. * Visually,  it is an arrow of the specified height directly against * the scroll bar border.  The bitmap used for the arrow is stored * in 'arrowMap' with size 'arrow_width' and 'arrow_height'. */{    struct txtWin *textInfo;    textInfo = (struct txtWin *)XLookUpAssoc(display, textWindows,					     (XID) win);    /* First,  draw the arrow */    XCopyArea(display, textInfo->arrowMap, textInfo->mainWindow,	       textInfo->CursorGC,	       0, 0, arrow_width, arrow_height,	       x, y + h - arrow_height, 1);    /* Then draw the stem */    XDrawLine(display, textInfo->mainWindow, textInfo->CursorGC,	      x + STEMOFFSET, y,	      x + STEMOFFSET, y + h - arrow_height);    return 1;}static int DrawLine(display, textInfo, lineIndex, ypos)Display *display;struct txtWin *textInfo;	/* Text window information   */int lineIndex;			/* Index of line to draw     */int ypos;			/* Y position for line       *//* * This routine destructively draws the indicated line in the * indicated window at the indicated position.  It does not * clear to end of line however.  It draws a line wrap indicator * if needed but does not draw a cursor. */{    int index, startPos, curFont, theColor, curX, saveX, fontIndex;    struct txtLine *someLine;    char lineBuffer[BUFSIZE], *glyph;    short *linePointer;    XFontStruct *theFont;    XGCValues gc;    /* First,  we draw the text */    index = 0;    curX = XPADDING;    someLine = textInfo->txtBuffer[lineIndex];    linePointer = &(textInfo->mainBuffer[someLine->lineText]);    while (index < someLine->lineLength) {	startPos = index;	saveX = curX;	curFont = linePointer[index] & FONTMASK;	fontIndex = curFont >> FONTSHIFT;	theFont = &(textInfo->theFonts[fontIndex]);	theColor = textInfo->theColors[fontIndex];	glyph = &(lineBuffer[0]);	while ((index < someLine->lineLength) &&	       ((linePointer[index] & FONTMASK) == curFont))	{	    *glyph = linePointer[index] & CHARMASK;	    index++;	    curX += CharSize(textInfo, lineIndex, index);	    glyph++;	}		/* Flush out the glyphs */	XFillRectangle(display, textInfo->mainWindow,		       textInfo->bgGC,		       saveX, ypos,		   textInfo->w - BARSIZE,		   someLine->lineHeight + YPADDING + INTERLINE);	XDrawString(display, textInfo->mainWindow,		    textInfo->fontGC[fontIndex],		    saveX, ypos,		    lineBuffer, someLine->lineLength);    }    /* Then the line wrap indicator (if needed) */    if (someLine->lineFlags & WRAPFLAG) {	DrawLineWrap(display, textInfo->mainWindow,		     textInfo->w - BARSIZE - WRAPINDSIZE,		     ypos, someLine->lineHeight,		     textInfo->fgPix);    }    return 1;}static int HandleNewFont(display, fontNum, textInfo, flagWord)Display *display;int fontNum;			/* Font number       */struct txtWin *textInfo;	/* Text information  */int flagWord;			/* DODISP or nothing *//* * This routine handles a new font request.  These requests take * the form "^F<digit>".  The parsing is done in TxtWriteStr. * This routine is called only if the form is valid.  It may return * a failure (0 status) if the requested font is not loaded. * If the new font is larger than any of the current * fonts on the line,  it will change the line height and redisplay * the line. */{    struct txtLine *thisLine;    int heightDiff, baseDiff, redrawFlag;    if (textInfo->theFonts[fontNum].fid == 0) {	return 0;    } else {	thisLine = textInfo->txtBuffer[textInfo->curLine];	textInfo->curFont = fontNum;	redrawFlag = 0;	heightDiff = textInfo->theFonts[fontNum].ascent +	    textInfo->theFonts[fontNum].descent -		thisLine->lineHeight;	if (heightDiff > 0) {	    redrawFlag = 1;	} else {	    heightDiff = 0;	}	if (redrawFlag) {	    if (flagWord & DODISP) {		/* Clear current line */		XFillRectangle(display, textInfo->mainWindow,			       textInfo->bgGC,			       0, textInfo->curY, textInfo->w,			       thisLine->lineHeight);		/* Check to see if it requires scrolling */		if ((textInfo->curY + thisLine->lineHeight + heightDiff +		     INTERLINE) > textInfo->h)		  {		      /* 		       * General approach:  "unscroll" the last line up		       * and then call ScrollDown to do the right thing.		       */		      textInfo->endLine -= 1;		      textInfo->bottomSpace += thisLine->lineHeight +			  INTERLINE;		      XFillRectangle(display, textInfo->mainWindow,				     textInfo->bgGC,				     0, textInfo->h - textInfo->bottomSpace,				     textInfo->w, textInfo->bottomSpace);		      thisLine->lineHeight += heightDiff;		      ScrollDown(display, textInfo);		      textInfo->curY = textInfo->h -			(textInfo->bottomSpace + INTERLINE +			 thisLine->lineHeight);		  }		else 		  {		      /* Just update bottom space */		      textInfo->bottomSpace -= heightDiff;		      thisLine->lineHeight += heightDiff;		  }		/* Redraw the current line */		DrawLine(display, textInfo, textInfo->curLine, textInfo->curY);	    } else {		/* Just update line height */		thisLine->lineHeight += heightDiff;	    }	}	return 1;    }}int TxtWriteStr(display, w, str)Display *display;Window w;			/* Text window            */register char *str;		/* 0 terminated string *//* * This routine writes a string to the specified text window. * The following notes apply: *   - Text is always appended to the end of the text buffer. *   - If the scroll bar is positioned such that the end of the *     text is not visible,  an automatic scroll to the bottom *     will be done before the appending of text. *   - Non-printable ASCII characters are not displayed. *   - The '\n' character causes the current text position to *     advance one line and start at the left. *   - Tabs are not supported. *   - Lines too long for the screen will be wrapped and a line wrap *     indication will be drawn. *   - Backspace clears the previous character.  It will do the right *     thing if asked to backspace past a wrapped line. *   - A new font can be chosen using the sequence '^F<digit>' where *     <digit> is 0-7.  The directive will be ignored if *     there is no font in the specified slot. * Returns 0 if something went wrong.   */{    register int fontIndex;    register struct txtWin *textInfo;    register struct txtLine *thisLine;    if ((textInfo = (struct txtWin *) XLookUpAssoc(display, textWindows, (XID) w)) == 0)      return 0;        /* See if screen needs to be updated */    if (textInfo->flagWord & SCREENWRONG) {	TxtRepaint(display, textInfo->mainWindow);    }    /* See if we have to scroll down to the bottom */    if (textInfo->flagWord & NOTATBOTTOM) {	WarpToBottom(display, textInfo);	textInfo->flagWord &= (~NOTATBOTTOM);    }    /* Undraw the current cursor */    thisLine = textInfo->txtBuffer[textInfo->curLine];    XFillRectangle(display, w, textInfo->bgGC,	    thisLine->lineWidth + CUROFFSET,	    textInfo->curY,	    CURSORWIDTH,	    thisLine->lineHeight);    for ( /* str is ok */ ; (*str != 0) ; str++) {	/* Check to see if we are waiting on a font */	if (textInfo->flagWord & FONTNUMWAIT) {	    textInfo->flagWord &= (~FONTNUMWAIT);	    fontIndex = *str - '0';	    if ((fontIndex >= 0) && (fontIndex < MAXFONTS)) {		/* Handle font -- go get next character */		if (HandleNewFont(display, fontIndex, textInfo, DODISP))		    continue;	    }	}		/* Inline code for handling normal character case */	if ((*str >= LOWCHAR) && (*str <= HIGHCHAR)) {	    register XFontStruct *thisFont;	    register struct txtLine *thisLine;	    register int charWidth;	    int thisColor;	    /* Determine size of character */	    thisFont = &(textInfo->theFonts[textInfo->curFont]);	    thisColor = textInfo->theColors[textInfo->curFont];	    if (*str <= thisFont->min_char_or_byte2 ||		*str >= thisFont->max_char_or_byte2 ||		thisFont->per_char == 0)		charWidth = thisFont->max_bounds.width + 1;	    else		charWidth = thisFont->per_char[*str].width + 1;	    /* Check to see if line wrap is required */	    thisLine = textInfo->txtBuffer[textInfo->curLine];	    if (thisLine->lineWidth + charWidth >		(textInfo->w-BARSIZE-WRAPINDSIZE))	      {		  DrawLineWrap(display, textInfo->mainWindow,			       textInfo->w-BARSIZE-WRAPINDSIZE,			       textInfo->curY, thisLine->lineHeight,			       textInfo->fgPix);		  thisLine->lineFlags |= WRAPFLAG;		  /* Handle the spacing problem the same way as a newline */		  HandleNewLine(display, textInfo, DODISP | NONEWLINE);		  thisLine = textInfo->txtBuffer[textInfo->curLine];	      }	    	    /* Ready to draw character */	    XDrawString(display, textInfo->mainWindow,			DEFAULT_GC, 			textInfo->curX += charWidth,			textInfo->curY + thisLine->lineHeight, 			str, 1);	    	    /* Append character onto main buffer */	    if (textInfo->bufSpot >= textInfo->bufAlloc)	      /* Make room for more characters */	      ExpandBuffer(textInfo);	    textInfo->mainBuffer[(textInfo->bufSpot)++] =	      (textInfo->curFont << FONTSHIFT) | (*str);	    	    /* Update the line start array */	    thisLine->lineLength += 1;	    thisLine->lineWidth += charWidth;	} else if (*str == NEWLINE) {	    HandleNewLine(display, textInfo, DODISP);	} else if (*str == NEWFONT) {	    /* Go into waiting for font number mode */	    textInfo->flagWord |= FONTNUMWAIT;	} else if (*str == BACKSPACE) {	    HandleBackspace(display, textInfo, DODISP);	} else {	    /* Ignore all others */	}    }    /* Draw the cursor in its new position */    thisLine = textInfo->txtBuffer[textInfo->curLine];    XFillRectangle(display, w, textInfo->CursorGC,	    thisLine->lineWidth + CUROFFSET,	    textInfo->curY /* + thisLine->lineHeight */,	    CURSORWIDTH, thisLine->lineHeight);    return 1;}int TxtJamStr(display, w, str)Display *display;Window w;			/* Text window            */register char *str;		/* NULL terminated string *//* * This is the same as TxtWriteStr except the screen is NOT updated. * After a call to this routine,  TxtRepaint should be called to * update the screen.  This routine is meant to be used to load * a text buffer with information and then allow the user to * scroll through it at will. */{    register int fontIndex;    register struct txtWin *textInfo;    if ((textInfo = (struct txtWin *) XLookUpAssoc(display, textWindows, (XID) w)	 ) == 0)      return 0;        for ( /* str is ok */ ; (*str != 0) ; str++) {	/* Check to see if we are waiting on a font */	if (textInfo->flagWord & FONTNUMWAIT) {	    textInfo->flagWord &= (~FONTNUMWAIT);	    fontIndex = *str - '0';	    if ((fontIndex >= 0) && (fontIndex < MAXFONTS)) {		if (HandleNewFont(display, fontIndex, textInfo, 0)) {		    /* Handled font -- go get next character */		    continue;		}	    }	}	/* Inline code for handling normal character case */	if ((*str >= LOWCHAR) && (*str <= HIGHCHAR)) {	    register XFontStruct *thisFont;	    register struct txtLine *thisLine;	    register int charWidth;	    	    /* Determine size of character */	    thisFont = &(textInfo->theFonts[textInfo->curFont]);

⌨️ 快捷键说明

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