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

📄 fl_text_display.cxx

📁 SRI international 发布的OAA框架软件
💻 CXX
📖 第 1 页 / 共 5 页
字号:
//
// "$Id: Fl_Text_Display.cxx,v 1.1.1.1 2003/06/03 22:25:44 agno Exp $"
//
// Copyright 2001-2003 by Bill Spitzak and others.
// Original code Copyright Mark Edel.  Permission to distribute under
// the LGPL for the FLTK library granted by Mark Edel.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// Please report all bugs and problems to "fltk-bugs@fltk.org".
//

#include <stdio.h>
#include <stdlib.h>
#include "flstring.h"
#include <limits.h>
#include <ctype.h>
#include <FL/Fl.H>
#include <FL/Fl_Text_Buffer.H>
#include <FL/Fl_Text_Display.H>
#include <FL/Fl_Window.H>

#undef min
#undef max

// Text area margins.  Left & right margins should be at least 3 so that
// there is some room for the overhanging parts of the cursor!
#define TOP_MARGIN 1
#define BOTTOM_MARGIN 1
#define LEFT_MARGIN 3
#define RIGHT_MARGIN 3

#define NO_HINT -1

/* Masks for text drawing methods.  These are or'd together to form an
   integer which describes what drawing calls to use to draw a string */
#define FILL_MASK 0x100
#define SECONDARY_MASK 0x200
#define PRIMARY_MASK 0x400
#define HIGHLIGHT_MASK 0x800
#define STYLE_LOOKUP_MASK 0xff

/* Maximum displayable line length (how many characters will fit across the
   widest window).  This amount of memory is temporarily allocated from the
   stack in the draw_vline() method for drawing strings */
#define MAX_DISP_LINE_LEN 1000

static int max( int i1, int i2 );
static int min( int i1, int i2 );
static int countlines( const char *string );

// CET - FIXME
#define TMPFONTWIDTH 6

Fl_Text_Display::Fl_Text_Display(int X, int Y, int W, int H,  const char* l)
    : Fl_Group(X, Y, W, H, l) {
  int i;

  mMaxsize = 0;
  damage_range1_start = damage_range1_end = -1;
  damage_range2_start = damage_range2_end = -1;
  dragPos = dragType = dragging = 0;
  display_insert_position_hint = 0;

  color(FL_BACKGROUND2_COLOR, FL_SELECTION_COLOR);
  box(FL_DOWN_FRAME);
  textsize((uchar)FL_NORMAL_SIZE);
  textcolor(FL_FOREGROUND_COLOR);
  textfont(FL_HELVETICA);

  text_area.x = 0;
  text_area.y = 0;
  text_area.w = 0;
  text_area.h = 0;

  mVScrollBar = new Fl_Scrollbar(0,0,1,1);
  mVScrollBar->callback((Fl_Callback*)v_scrollbar_cb, this);
  mHScrollBar = new Fl_Scrollbar(0,0,1,1);
  mHScrollBar->callback((Fl_Callback*)h_scrollbar_cb, this);
  mHScrollBar->type(FL_HORIZONTAL);

  end();

  scrollbar_width(16);
  scrollbar_align(FL_ALIGN_BOTTOM_RIGHT);

  mCursorOn = 0;
  mCursorPos = 0;
  mCursorOldY = -100;
  mCursorToHint = NO_HINT;
  mCursorStyle = NORMAL_CURSOR;
  mCursorPreferredCol = -1;
  mBuffer = 0;
  mFirstChar = 0;
  mLastChar = 0;
  mNBufferLines = 0;
  mTopLineNum = mTopLineNumHint = 1;
  mAbsTopLineNum = 1;
  mNeedAbsTopLineNum = 0;
  mHorizOffset = mHorizOffsetHint = 0;

  mCursor_color = FL_BLACK;

  mFixedFontWidth = TMPFONTWIDTH;// CET - FIXME
  mStyleBuffer = 0;
  mStyleTable = 0;
  mNStyles = 0;
  mNVisibleLines = 1;
  mLineStarts = new int[mNVisibleLines];
  mLineStarts[0] = 0;
  for (i=1; i<mNVisibleLines; i++)
    mLineStarts[i] = -1;
  mSuppressResync = 0;
  mNLinesDeleted = 0;
  mModifyingTabDistance = 0;

  mUnfinishedStyle = 0;
  mUnfinishedHighlightCB = 0;
  mHighlightCBArg = 0;

  mLineNumLeft = mLineNumWidth = 0;
  mContinuousWrap = 0;
  mWrapMargin = 0;
  mSuppressResync = mNLinesDeleted = mModifyingTabDistance = 0;
}

/*
** Free a text display and release its associated memory.  Note, the text
** BUFFER that the text display displays is a separate entity and is not
** freed, nor are the style buffer or style table.
*/
Fl_Text_Display::~Fl_Text_Display() {
  if (mBuffer) mBuffer->remove_modify_callback(buffer_modified_cb, this);
  if (mLineStarts) delete[] mLineStarts;
}

/*
** Attach a text buffer to display, replacing the current buffer (if any)
*/
void Fl_Text_Display::buffer( Fl_Text_Buffer *buf ) {
  /* If the text display is already displaying a buffer, clear it off
     of the display and remove our callback from it */
  if ( mBuffer != 0 ) {
    buffer_modified_cb( 0, 0, mBuffer->length(), 0, 0, this );
    mBuffer->remove_modify_callback( buffer_modified_cb, this );
    mBuffer->remove_predelete_callback( buffer_predelete_cb, this );
  }

  /* Add the buffer to the display, and attach a callback to the buffer for
     receiving modification information when the buffer contents change */
  mBuffer = buf;
  mBuffer->add_modify_callback( buffer_modified_cb, this );
  mBuffer->add_predelete_callback( buffer_predelete_cb, this );

  /* Update the display */
  buffer_modified_cb( 0, buf->length(), 0, 0, 0, this );

  /* Resize the widget to update the screen... */
  resize(x(), y(), w(), h());
}

/*
** Attach (or remove) highlight information in text display and redisplay.
** Highlighting information consists of a style buffer which parallels the
** normal text buffer, but codes font and color information for the display;
** a style table which translates style buffer codes (indexed by buffer
** character - 'A') into fonts and colors; and a callback mechanism for
** as-needed highlighting, triggered by a style buffer entry of
** "unfinishedStyle".  Style buffer can trigger additional redisplay during
** a normal buffer modification if the buffer contains a primary Fl_Text_Selection
** (see extendRangeForStyleMods for more information on this protocol).
**
** Style buffers, tables and their associated memory are managed by the caller.
*/
void
Fl_Text_Display::highlight_data(Fl_Text_Buffer *styleBuffer,
                                const Style_Table_Entry *styleTable,
                                int nStyles, char unfinishedStyle,
                                Unfinished_Style_Cb unfinishedHighlightCB,
                                void *cbArg ) {
  mStyleBuffer = styleBuffer;
  mStyleTable = styleTable;
  mNStyles = nStyles;
  mUnfinishedStyle = unfinishedStyle;
  mUnfinishedHighlightCB = unfinishedHighlightCB;
  mHighlightCBArg = cbArg;

  mStyleBuffer->canUndo(0);
#if 0
  // FIXME: this is in nedit code -- is it needed?	
    /* Call TextDSetFont to combine font information from style table and
       primary font, adjust font-related parameters, and then redisplay */
    TextDSetFont(textD, textD->fontStruct);
#endif
  damage(FL_DAMAGE_EXPOSE);
}

#if 0
  // FIXME: this is in nedit code -- is it needed?	
/*
** Change the (non highlight) font
*/
void TextDSetFont(textDisp *textD, XFontStruct *fontStruct) {
    Display *display = XtDisplay(textD->w);
    int i, maxAscent = fontStruct->ascent, maxDescent = fontStruct->descent;
    int width, height, fontWidth;
    Pixel bgPixel, fgPixel, selectFGPixel, selectBGPixel;
    Pixel highlightFGPixel, highlightBGPixel;
    XGCValues values;
    XFontStruct *styleFont;
    
    /* If font size changes, cursor will be redrawn in a new position */
    blankCursorProtrusions(textD);
    
    /* If there is a (syntax highlighting) style table in use, find the new
       maximum font height for this text display */
    for (i=0; i<textD->nStyles; i++) {
    	styleFont = textD->styleTable[i].font;
	if (styleFont != NULL && styleFont->ascent > maxAscent)
    	    maxAscent = styleFont->ascent;
    	if (styleFont != NULL && styleFont->descent > maxDescent)
    	    maxDescent = styleFont->descent;
    }
    textD->ascent = maxAscent;
    textD->descent = maxDescent;
    
    /* If all of the current fonts are fixed and match in width, compute */
    fontWidth = fontStruct->max_bounds.width;
    if (fontWidth != fontStruct->min_bounds.width)
	fontWidth = -1;
    else {
	for (i=0; i<textD->nStyles; i++) {
    	    styleFont = textD->styleTable[i].font;
	    if (styleFont != NULL && (styleFont->max_bounds.width != fontWidth ||
		    styleFont->max_bounds.width != styleFont->min_bounds.width))
		fontWidth = -1;
	}
    }
    textD->fixedFontWidth = fontWidth;
    
    /* Don't let the height dip below one line, or bad things can happen */
    if (textD->height < maxAscent + maxDescent)
        textD->height = maxAscent + maxDescent;

    /* Change the font.  In most cases, this means re-allocating the
       affected GCs (they are shared with other widgets, and if the primary
       font changes, must be re-allocated to change it). Unfortunately,
       this requres recovering all of the colors from the existing GCs */
    textD->fontStruct = fontStruct;
    XGetGCValues(display, textD->gc, GCForeground|GCBackground, &values);
    fgPixel = values.foreground;
    bgPixel = values.background;
    XGetGCValues(display, textD->selectGC, GCForeground|GCBackground, &values);
    selectFGPixel = values.foreground;
    selectBGPixel = values.background;
    XGetGCValues(display, textD->highlightGC,GCForeground|GCBackground,&values);
    highlightFGPixel = values.foreground;
    highlightBGPixel = values.background;
    releaseGC(textD->w, textD->gc);
    releaseGC(textD->w, textD->selectGC);
    releaseGC(textD->w, textD->highlightGC);
    releaseGC(textD->w, textD->selectBGGC);
    releaseGC(textD->w, textD->highlightBGGC);
    if (textD->lineNumGC != NULL)
	releaseGC(textD->w, textD->lineNumGC);
    textD->lineNumGC = NULL;
    allocateFixedFontGCs(textD, fontStruct, bgPixel, fgPixel, selectFGPixel,
	    selectBGPixel, highlightFGPixel, highlightBGPixel);
    XSetFont(display, textD->styleGC, fontStruct->fid);
    
    /* Do a full resize to force recalculation of font related parameters */
    width = textD->width;
    height = textD->height;
    textD->width = textD->height = 0;
    TextDResize(textD, width, height);
    
    /* Redisplay */
    TextDRedisplayRect(textD, textD->left, textD->top, textD->width,
    	    textD->height);
    
    /* Clean up line number area in case spacing has changed */
    draw_line_numbers(textD, True);
}

int TextDMinFontWidth(textDisp *textD, Boolean considerStyles) {
    int fontWidth = textD->fontStruct->max_bounds.width;
    int i;

    if (considerStyles) {
        for (i = 0; i < textD->nStyles; ++i) {
            int thisWidth = (textD->styleTable[i].font)->min_bounds.width;
            if (thisWidth < fontWidth) {
                fontWidth = thisWidth;
            }
        }
    }
    return(fontWidth);
}

int TextDMaxFontWidth(textDisp *textD, Boolean considerStyles) {
    int fontWidth = textD->fontStruct->max_bounds.width;
    int i;

    if (considerStyles) {
        for (i = 0; i < textD->nStyles; ++i) {
            int thisWidth = (textD->styleTable[i].font)->max_bounds.width;
            if (thisWidth > fontWidth) {
                fontWidth = thisWidth;
            }
        }
    }
    return(fontWidth);
}
#endif

int Fl_Text_Display::longest_vline() {
  int longest = 0;
  for (int i = 0; i < mNVisibleLines; i++)
    longest = max(longest, measure_vline(i));
  return longest;
}

/*
** Change the size of the displayed text area
*/
void Fl_Text_Display::resize(int X, int Y, int W, int H) {
  const int oldWidth = w();
  Fl_Widget::resize(X,Y,W,H);
  if (!buffer()) return;
  X += Fl::box_dx(box());
  Y += Fl::box_dy(box());
  W -= Fl::box_dw(box());
  H -= Fl::box_dh(box());

⌨️ 快捷键说明

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