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

📄 scrolltext.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
	    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))	      {		  thisLine->lineFlags |= WRAPFLAG;		  /* Handle the spacing problem the same way as a newline */		  HandleNewLine(display, textInfo, NONEWLINE);		  thisLine = textInfo->txtBuffer[textInfo->curLine];	      }	    /* 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, 0);	} else if (*str == NEWFONT) {	    /* Go into waiting for font number mode */	    textInfo->flagWord |= FONTNUMWAIT;	} else if (*str == BACKSPACE) {	    HandleBackspace(display, textInfo, 0);	} else {	    /* Ignore all others */	}    }    textInfo->flagWord |= SCREENWRONG;    return 1;}int TxtRepaint(display,w)Display *display;Window w;/* * Repaints the given scrollable text window.  The routine repaints * the entire window.  For handling exposure events,  the TxtFilter  * routine should be used. */{    struct txtWin *textInfo;    int index, ypos;    if ((textInfo = (struct txtWin *) XLookUpAssoc(display, textWindows, (XID) w)	 ) == 0)      return 0;    /* Check to see if the screen is up to date */    if (textInfo->flagWord & SCREENWRONG) {	textInfo->endLine = FindEndLine(textInfo, &(textInfo->bottomSpace));	textInfo->flagWord &= (~SCREENWRONG);    }    ypos = YPADDING;    index = textInfo->startLine;    for (;;) {	DrawLine(display, textInfo, index, ypos);	if (index >= textInfo->endLine) break;	ypos += (textInfo->txtBuffer[index]->lineHeight + INTERLINE);	index++;    }    /* Draw the cursor (if on screen) */    if (textInfo->endLine == textInfo->curLine) {	XFillRectangle(display, w, textInfo->CursorGC,		       textInfo->txtBuffer[index]->lineWidth + CUROFFSET,		       ypos /* + textInfo->txtBuffer[index]->lineHeight */,		       CURSORWIDTH, textInfo->txtBuffer[index]->lineHeight);    }    /* Update the scroll bar */    UpdateScroll(display, textInfo);    return 1;}static int InsertIndex(textInfo, thisIndex, ypos)struct txtWin *textInfo;	/* Text Window Information    */int thisIndex;			/* Line index of exposed line */int ypos;			/* Drawing position of line   *//* * This routine inserts the supplied line index into the copy * exposure array for 'textInfo'.  The array is kept sorted * from lowest to highest using insertion sort.  The array * is dynamically expanded if needed. */{    struct expEvent *newItem;    int newSize, index, downIndex;    /* Check to see if we need to expand it */    if ((textInfo->exposeSize + 3) >= textInfo->exposeAlloc) {	newSize = textInfo->exposeAlloc +	  (textInfo->exposeAlloc * EXPANDPERCENT / 100);	textInfo->exposeAry = (struct expEvent **)	  realloc((char *) textInfo->exposeAry,		  (unsigned) (newSize * sizeof(struct expEvent *)));	for (index = textInfo->exposeAlloc;  index < newSize;  index++)	  textInfo->exposeAry[index] = alloc(struct expEvent);	textInfo->exposeAlloc = newSize;    }    /* Find spot for insertion.  NOTE: last spot has big number */    for (index = 0;  index <= textInfo->exposeSize;  index++) {	if (textInfo->exposeAry[index]->lineIndex >= thisIndex) {	    if (textInfo->exposeAry[index]->lineIndex > thisIndex) {		/* Insert before this entry */		newItem = textInfo->exposeAry[textInfo->exposeSize+1];		for (downIndex = textInfo->exposeSize;		     downIndex >= index;		     downIndex--)		  {		      textInfo->exposeAry[downIndex+1] =			textInfo->exposeAry[downIndex];		  }		/* Put a free structure at this spot */		textInfo->exposeAry[index] = newItem;		/* Fill it in */		textInfo->exposeAry[index]->lineIndex = thisIndex;		textInfo->exposeAry[index]->ypos = ypos;		/* Break out of loop */		textInfo->exposeSize += 1;	    }	    break;	}    }    return 1;}static int ScrollUp(display, textInfo)Display *display;struct txtWin *textInfo;	/* Text window information   *//* * This routine scrolls the indicated text window up by one * line.  The line above the current line must exist.  The * window is scrolled so that the line above the start line * is displayed at the top of the screen.  This may cause * many lines to scroll off the bottom.  The scrolling is * done using XCopyArea.  The exposure events should be caught * by ExposeCopy. */{    int targetSpace;    /* Make sure all exposures have been handled by now */    if (textInfo->startLine == 0) return 0;    targetSpace = textInfo->txtBuffer[textInfo->startLine-1]->lineHeight +      INTERLINE;    /* Move the area downward by the target amount */    XCopyArea(display, textInfo->mainWindow, textInfo->mainWindow,	      DEFAULT_GC,	      0, YPADDING, textInfo->w - BARSIZE,	      textInfo->h, 0, targetSpace);    textInfo->flagWord |= COPYEXPOSE;    /* Update the text window parameters */    textInfo->startLine -= 1;    textInfo->endLine = FindEndLine(textInfo, &(textInfo->bottomSpace));    /* Clear out bottom space region */    XClearArea(display, textInfo->mainWindow,	       0, textInfo->h - textInfo->bottomSpace,	       textInfo->w, textInfo->bottomSpace);        UpdateExposures(display, textInfo);    UpdateScroll(display, textInfo);    return 1;}static int ScrollToSpot(display, textInfo, ySpot)Display *display;struct txtWin *textInfo;	/* Text window information          */int ySpot;			/* Button position in scroll window *//* * This routine scrolls the specified text window relative to the * position of the mouse in the scroll bar.  The center of the screen * will be positioned to correspond to the mouse position. */{    int targetLine, aboveLines;    targetLine = textInfo->numLines * ySpot / textInfo->h;    textInfo->startLine = targetLine;    textInfo->endLine = FindEndLine(textInfo, &(textInfo->bottomSpace));    aboveLines = 0;    /* Make the target line the *center* of the window */    while ((textInfo->startLine > 0) &&	   (aboveLines < textInfo->endLine - targetLine))      {	  textInfo->startLine -= 1;	  textInfo->endLine = FindEndLine(textInfo, &(textInfo->bottomSpace));	  aboveLines++;      }    if (textInfo->endLine == textInfo->numLines-1) {	WarpToBottom(display, textInfo);    } else {	XClearWindow(display, textInfo->mainWindow);	TxtRepaint(display, textInfo->mainWindow);    }    return 1;}static int LineToTop(display, textInfo, pos)Display *display;struct txtWin *textInfo;	/* Text window information */int pos;			/* Y position of mouse     *//* * This routine scrolls the screen down until the line at the * mouse position is at the top of the screen.  It stops * if it can't scroll the buffer down that far.  If the * global 'ScrollOption' is NORMSCROLL,  a smooth scroll * is used.  Otherwise,  it jumps to the right position * and repaints the screen. */{    int index, sum;    /* First,  we find the current line */    sum = 0;    for (index = textInfo->startLine;  index <= textInfo->endLine;  index++) {	if (sum + textInfo->txtBuffer[index]->lineHeight + INTERLINE> pos) break;	sum += textInfo->txtBuffer[index]->lineHeight + INTERLINE;    }    /* We always want to scroll down at least one line */    if (index == textInfo->startLine) index++;    if (ScrollOption == NORMSCROLL) {	/* Scroll down until 'index' is the starting line */	while ((textInfo->startLine < index) && ScrollDown(display, textInfo))	{	    /* Empty Loop Body */	}    } else {	/* Immediately jump to correct spot */	textInfo->startLine = index;	textInfo->endLine = FindEndLine(textInfo, &(textInfo->bottomSpace));	if (textInfo->endLine == textInfo->numLines-1) {	    WarpToBottom(display, textInfo);	} else {	    XClearWindow(display, textInfo->mainWindow);	    TxtRepaint(display, textInfo->mainWindow);	}    }    /* Check to see if at end of buffer */    if (textInfo->endLine >= textInfo->numLines-1) {	textInfo->flagWord &= (~NOTATBOTTOM);    }    return 1;}static int TopToHere(display, textInfo, pos)Display *display;struct txtWin *textInfo;	/* Text window information */int pos;			/* Y position of mouse     *//* * This routine scrolls the screen up until the top line of * the screen is at the current Y position of the mouse.  Again, * it will stop if it can't scroll that far.  If the global * 'ScrollOption' is NORMSCROLL,  a smooth scroll is used. * If it's not,  it will simply redraw the screen at the * correct spot. */{    int sum, target, linesup, index;    target = pos - textInfo->txtBuffer[textInfo->startLine]->lineHeight;    /* We always want to scroll up at least one line */    if (target <= 0) target = 1;    sum = 0;    linesup = 0;    /* Check to see if we are at the top anyway */    if (textInfo->startLine == 0) return 0;    if (ScrollOption == NORMSCROLL) {	/* Scroll up until sum of new top lines greater than target */	while ((sum < target) && ScrollUp(display, textInfo)) {	    sum += textInfo->txtBuffer[textInfo->startLine]->lineHeight;	    linesup++;	}    } else {	/* Search backward to find index */	index = textInfo->startLine - 1;	while ((index > 0) && (sum < target)) {	    sum += textInfo->txtBuffer[index]->lineHeight;	    linesup++;	    index--;	}	/* Go directly to the index */	textInfo->startLine = index;	textInfo->endLine = FindEndLine(textInfo, &(textInfo->bottomSpace));	XClearWindow(display, textInfo->mainWindow);	TxtRepaint(display, textInfo->mainWindow);    }    /* If we scrolled,  assert we are not at bottom of buffer */    if (linesup > 0) {	textInfo->flagWord |= NOTATBOTTOM;    }    return 1;}int TxtFilter(display, evt)Display *display;XEvent *evt;/* * This routine handles events associated with scrollable text windows. * It will handle all exposure events and any button released events * in the scroll bar of a text window.  It does NOT handle any other * events.  If it cannot handle the event,  it will return 0. */{    XExposeEvent *expose = &evt->xexpose;    XButtonEvent *btEvt = &evt->xbutton;    XGraphicsExposeEvent *gexpose = &evt->xgraphicsexpose;    XNoExposeEvent *noexpose = &evt->xnoexpose;    struct txtWin *textInfo;    int index, ypos;    Window w, sw;    if (textWindows == (XAssocTable *) 0) {	textWindows = XCreateAssocTable(32);	if (textWindows == (XAssocTable *) 0) return(0);    }    if (evt->type == Expose) {	w = expose->window;	sw = 0;    }    else if (evt->type == GraphicsExpose) {	w = gexpose->drawable;	sw = 0;    }    else if (evt->type == NoExpose) {	w = noexpose->drawable;	sw = 0;    }    else if (evt->type == ButtonRelease) {	w = btEvt->window;	sw = btEvt->subwindow;    }    else	return 0;    if ((textInfo = (struct txtWin *)	 XLookUpAssoc(display, textWindows, (XID) w)) == 0)		return 0;    /* Determine whether it's main window or not */    if ((w == textInfo->mainWindow) && (sw == 0)) {	/* Main Window - handle exposures */	switch (evt->type) {	case Expose:	    ypos = 0 /*YPADDING*/;	    for (index = textInfo->startLine;		 index <= textInfo->endLine;		 index++)	      {		  int lh = textInfo->txtBuffer[index]->lineHeight;		  if (((ypos + lh) >= expose->y) &&		      (ypos <= (expose->y + expose->height)))		    {			/* Intersection region */			/* Draw line immediately */			DrawLine(display, textInfo, index, ypos);			/* And possibly draw cursor */			if (textInfo->curLine == index) {			    XFillRectangle(display, w, textInfo->CursorGC,				       textInfo->txtBuffer[index]->lineWidth +					   CUROFFSET,					   ypos,					   CURSORWIDTH,					   lh);			}		    }		  ypos += lh + INTERLINE;	      }	    break;	case GraphicsExpose:	    ypos = 0 /*YPADDING*/;	    for (index = textInfo->startLine;		 index <= textInfo->endLine;		 index++)	      {		  int lh = textInfo->txtBuffer[index]->lineHeight;		  if (((ypos + lh) >= gexpose->y) &&		      (ypos <= (gexpose->y + gexpose->height)))		    {			/* Intersection region */			/* Draw line immediately */			DrawLine(display, textInfo, index, ypos);			/* And possibly draw cursor */			if (textInfo->curLine == index) {			    XFillRectangle(display, w, textInfo->CursorGC,				    textInfo->txtBuffer[index]->lineWidth +				    CUROFFSET,				    ypos,				    CURSORWIDTH,				    lh);			}		    }		  ypos += lh + INTERLINE;	      }	    break;	case NoExpose:	    break;	default:	    /* Not one of our events */	    return 0;	}    } else {	switch (evt->type) {	case Expose:	    UpdateScroll(display, textInfo);	    break;	case ButtonRelease:	    /* Find out which button */	    switch (btEvt->button) {	    case Button1:		/* Scroll up until top line is at mouse position */		TopToHere(display, textInfo, btEvt->y);		break;	    case Button2:		/* Scroll to spot relative to position */		ScrollToSpot(display, textInfo, btEvt->y);		if (textInfo->endLine >= textInfo->numLines-1) {		    textInfo->flagWord &= (~NOTATBOTTOM);		} else {		    textInfo->flagWord |= NOTATBOTTOM;		}		break;	    case Button3:		/* Scroll down until pointed line is at top */		LineToTop(display, textInfo, btEvt->y);		break;	    }	    break;	default:	    /* Not one of our events */	    return 0;	}    }    return 1;}

⌨️ 快捷键说明

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