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

📄 mimerichtextdraw.c

📁 linux下的E_MAIL客户端源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* *  $Id: MimeRichTextDraw.C,v 1.2 2000/05/07 12:26:10 fnevgeny Exp $ *   *  Copyright (c) 1994 HAL Computer Systems International, Ltd. *  *          HAL COMPUTER SYSTEMS INTERNATIONAL, LTD. *                  1315 Dell Avenue *                  Campbell, CA  95008 * * Author: Greg Hilton * Contributors: Tom Lang, Frank Bieser, and others * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 General Public License for more details. * * http://www.gnu.org/copyleft/gpl.html * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */#include <config.h>#include "MimeRichTextC.h"#include "MimeRichTextP.h"#include "HalAppC.h"#include "WArgList.h"#include "gray.xbm"#include <Xm/ScrollBar.h>extern int	debuglev;/*---------------------------------------------------------------------- * Expose Callback */voidMimeRichTextP::HandleExpose(Widget, MimeRichTextP *This,			    XmDrawingAreaCallbackStruct *da){   if ( !This->realized ) {      This->textWin = XtWindow(This->textDA);//// Create stipple pixmap//      This->stipplePm = XCreateBitmapFromData(halApp->display, This->textWin,					      gray_bits, gray_width,					      gray_height);      Window    root;      int       x, y;      unsigned	w, h;      unsigned  bw;      unsigned	dep;      XGetGeometry(halApp->display, This->stipplePm, &root, &x, &y, &w, &h,		   &bw, &dep);//// Create graphics contexts for drawing//      XtGCMask	fixMask = GCGraphicsExposures | GCBackground | GCLineStyle      			| GCLineWidth | GCPlaneMask | GCStipple;      XtGCMask	modMask = GCClipMask | GCFont | GCFunction | GCForeground      			| GCFillStyle;      XtGCMask	naMask	= GCArcMode | GCCapStyle | GCClipXOrigin			| GCClipYOrigin | GCDashList | GCDashOffset			| GCFillRule | GCJoinStyle | GCSubwindowMode | GCTile			| GCTileStipXOrigin | GCTileStipYOrigin;      XGCValues fixVals;      fixVals.clip_mask		 = None;      fixVals.fill_style	 = FillSolid;      fixVals.stipple            = This->stipplePm;      fixVals.font               = This->plainFont.fid;      fixVals.foreground	 = This->fgColor;      fixVals.background	 = This->bgColor;      fixVals.function	 	 = GXcopy;      fixVals.graphics_exposures = TRUE;      fixVals.line_style	 = LineSolid;      fixVals.line_width	 = 0;      fixVals.plane_mask	 = AllPlanes;      This->textGC = XtAllocateGC(This->textDA, 0, fixMask, &fixVals, modMask,				  naMask);      This->cursorPos.Set(This->topTextLine, 0, 0);      ScreenPosC	spos = This->cursorPos;      This->desiredCursorX = spos.x;      This->cursorOn = False;//// Get scrollbars if necessary//      if ( This->textSW ) {	 XtVaGetValues(This->textSW, XmNverticalScrollBar,   &This->textVSB,	 			     XmNhorizontalScrollBar, &This->textHSB,				     XmNclipWindow,          &This->textClip,				     NULL);	 XtVaGetValues(This->textClip, XmNwidth,  &This->clipWd,	 			       XmNheight, &This->clipHt, NULL);	 if ( This->drawWd == 0 )	    XtVaGetValues(This->textDA, XmNwidth, &This->drawWd, NULL);	 if ( This->drawHt == 0 )	    XtVaGetValues(This->textDA, XmNwidth, &This->drawHt, NULL);	 This->maxWd = This->drawWd;	 This->maxHt = This->drawHt;//// If resize is not allowed, keep the text the same width as the scrolled//    window//	 if ( !This->resizeWidth )	    XtAddEventHandler(This->textSW, StructureNotifyMask, False,			      (XtEventHandler)HandleSWResize, (XtPointer)This);      } // End if we're in a scrolled window      else {	 if ( (int)This->drawWd <= (int)(This->marginWd*2) )	    XtVaGetValues(This->textDA, XmNwidth, &This->drawWd, NULL);	 if ( (int)This->drawHt <= (int)(This->marginHt*2) )	    XtVaGetValues(This->textDA, XmNheight, &This->drawHt, NULL);	 This->maxWd = This->drawWd;	 This->maxHt = This->drawHt;//// Set scrollbar values//	 WArgList	args;	 args.Minimum(0);	 args.Value(0);	 int	lh = This->pub->LineHeight();	 args.Increment(lh);	 if ( (int)This->drawHt > lh ) {	    args.Maximum(This->drawHt);	    args.SliderSize(This->drawHt);	    args.PageIncrement(This->drawHt - lh);	 }	 XtSetValues(This->textVSB, ARGS);	 int	cw = This->pub->CharWidth();	 args.Increment(cw);	 if ( (int)This->drawWd > cw ) {	    args.Maximum(This->drawWd);	    args.SliderSize(This->drawWd);	    args.PageIncrement(This->drawWd - cw);	 }	 XtSetValues(This->textHSB, ARGS);	 This->hsbVal = This->vsbVal = 0;	 This->hsbMax = This->drawWd;	 This->vsbMax = This->drawHt;//// Create a pixmap for off-screen drawing//	 unsigned depth = DefaultDepth(halApp->display,				       DefaultScreen(halApp->display));	 This->textPmWd = This->drawWd;	 This->textPmHt = This->drawHt;	 This->textPm = XCreatePixmap(halApp->display, This->textWin,	 			      This->textPmWd, This->textPmHt, depth);	 XtAddEventHandler(This->scrollForm, StructureNotifyMask, False,			   (XtEventHandler)HandleFormResize, (XtPointer)This);      } // End if we're doing our own scrolling      This->realized = True;      This->FormatScreen();//// Initialize the input method//      if ( This->editable ) {	 XmImRegister(This->textDA, 0);	 XPoint		spot;	 spot.x = 0;	 spot.y = 0;	 Pixmap		bgPixmap;	 XtVaGetValues(This->textDA, XmNbackgroundPixmap, &bgPixmap, NULL);	 XmFontList	fontList = XmFontListCreate(This->plainFont.xfont,						       XmSTRING_DEFAULT_CHARSET);	 WArgList		args;	 args.Background(This->bgColor);	 args.Foreground(This->fgColor);	 args.BackgroundPixmap(bgPixmap);	 args.FontList(fontList);	 args.Add("XmNlineSpacing",   This->lineSpacing);	 args.Add("XmNspotLocation", &spot);	 XmImSetValues(This->textDA, ARGS);      } // End if input method needed//// Start the cursor blinking if the focus is here//      if ( This->hasFocus )	 CursorBlink(This, NULL);   } // End if not realized//// Redraw//   XExposeEvent *ev = (XExposeEvent*)da->event;   RectC        area(ev->x, ev->y, ev->width, ev->height);   This->DrawScreen(area);} // End HandleExpose/*---------------------------------------------------------------------- * Resize callback for scrollForm */voidMimeRichTextP::HandleFormResize(Widget, MimeRichTextP *This, XEvent*, Boolean*){   if ( debuglev > 1 )      cout <<"MimeRichTextC(" <<XtName(This->pub->MainWidget())	   <<")::HandleFormResize" <<endl;   Dimension	wd, ht;   XtVaGetValues(This->textDA, XmNwidth, &wd, XmNheight, &ht, NULL);   if ( wd == This->drawWd && ht == This->drawHt ) return;   halApp->BusyCursor(True);//// See how much the size changed.  Change the max size by these same amounts.//   Dimension	dwd = wd - This->drawWd;   Dimension	dht = ht - This->drawHt;   This->drawWd = wd;   This->drawHt = ht;   This->maxWd += dwd;   This->maxHt += dht;   This->CheckPixmapSize();//// Update drawing area//   This->changed = True;   This->FormatScreen();   if ( This->realized ) {      RectC	area(0, 0, wd, ht);      This->DrawScreen(area);      ScreenPosC	spos = This->cursorPos;      This->desiredCursorX = spos.x;   }   halApp->BusyCursor(False);} // End HandleResize/*----------------------------------------------------------------------- *  Event handler for scrolled window resize */voidMimeRichTextP::HandleSWResize(Widget, MimeRichTextP *This, XEvent*, Boolean*){//// Get the size of the clip window//   XtVaGetValues(This->textClip, XmNwidth,  &This->clipWd,   				 XmNheight, &This->clipHt, NULL);//// If we're not allowed to resize ourself, follow the size of the scrolled//    window.//   if ( !This->resizeWidth ) {      halApp->BusyCursor(True);      Dimension	wd = This->clipWd - 1;      XtVaSetValues(This->textDA, XmNwidth, wd, NULL);      This->drawWd  = wd;      This->changed = True;      This->FormatScreen();      if ( This->realized ) {	 RectC	area(0, 0, This->drawWd, This->drawHt);	 This->DrawScreen(area);	 ScreenPosC	spos = This->cursorPos;	 This->desiredCursorX = spos.x;      }      halApp->BusyCursor(False);   } // End if we're not allowed to set our own size} // End HandleSWResize/*---------------------------------------------------------------------- * Adjust the reference widget so the specified amount of the drawing *    area size is displayed. */voidMimeRichTextP::SetVisibleSize(Dimension newWd, Dimension newHt, Widget ref){//// If we're in a scrolled window, resize that//   if ( textSW ) {      if ( !ref ) ref = textSW;//// Get the current size//      Dimension	swd, sht;      XtVaGetValues(ref, XmNwidth, &swd, XmNheight, &sht, NULL);//// Determine the size difference//      Dimension	dwd = swd - clipWd;      Dimension	dht = sht - clipHt;//// Calculate the new size needed for the scrolled window//      clipWd = newWd + marginWd2 + 1;      clipHt = newHt + marginHt2 + 1;      swd = clipWd + dwd;      sht = clipHt + dht;      XtVaSetValues(ref, XmNwidth, swd, XmNheight, sht, NULL);      //// Calculate the new size needed for the text form//      Dimension	fwd = newWd + marginWd2;      Dimension	fht = newHt + marginHt2;      if ( resizeWidth || (int)fwd < (int)(clipWd - 1) ) fwd = clipWd - 1;      if ( (int)fht < (int)(clipHt - 1) ) fht = clipHt - 1;      XtVaSetValues(textDA, XmNwidth, fwd, XmNheight, fht, NULL);//// Remove any resize events from the queue.  We don't need them.//      XSync(halApp->display, FALSE);      XEvent	event;      while ( XCheckTypedWindowEvent(halApp->display, XtWindow(textSW),				     ConfigureNotify, &event) )	 ;   } // End if we're in a scrolled window//// If we're doing our own scrolling, resize the scrollForm//   else {//// Get the current size//      Dimension	swd = 0, sht = 0;      if ( ref )	 XtVaGetValues(ref, XmNwidth, &swd, XmNheight, &sht, NULL);      if ( swd > 0 && sht > 0 ) {//// Determine the size difference//	 Dimension	dwd = swd - drawWd;	 Dimension	dht = sht - drawHt;//// Set the new size//	 swd = newWd + dwd;	 sht = newHt + dht;	 XtVaSetValues(ref, XmNwidth, swd, XmNheight, sht, NULL);      } // End if reference widget is specified//// Compute the size of the scrollForm required to give us the requested//    drawing area size//      else {	 Dimension	shad;	 XtVaGetValues(textFrame, XmNshadowThickness, &shad, NULL);	 swd = newWd	     + shad		// textFrame	     + (hlThick*2)	// hlForm	     + 2;		// for grins	 if ( vsbOn ) swd += scrollRoff;	 else	      swd += noScrollRoff;	 sht = newHt	     + shad		// textFrame	     + (hlThick*2) 	// hlForm	     + 2;		// for grins	 if ( hsbOn ) sht += scrollBoff;	 else	      sht += noScrollBoff;	 XtVaSetValues(scrollForm, XmNwidth, swd, XmNheight, sht, NULL);      } // End if no reference widget is specified#if 0//// Remove any resize events from the queue.  We don't need them.//      XSync(halApp->display, FALSE);      XEvent	event;      while ( XCheckTypedWindowEvent(halApp->display, XtWindow(scrollForm),				     ConfigureNotify, &event) )	 ;#endif   } // End if we're doing our own scrolling   maxWd = drawWd = newWd;   maxHt = drawHt = newHt;//// Reallocate pixmap//   CheckPixmapSize();//// Update drawing area//   changed = True;   if ( !defer ) {      FormatScreen();      if ( realized ) {	 RectC	area(0, 0, maxWd, maxHt);	 DrawScreen(area);	 ScreenPosC	spos = cursorPos;	 desiredCursorX = spos.x;      }   }} // End SetVisibleSize/*----------------------------------------------------------------------- *  Resize the off-screen pixmap if the visible area has increased */voidMimeRichTextP::CheckPixmapSize(){//// Re-create pixmap if size has increased//   if ( !textPm || (drawWd <= textPmWd && drawHt <= textPmHt) ) return;   XFreePixmap(halApp->display, textPm);   u_int depth = DefaultDepth(halApp->display, DefaultScreen(halApp->display));   textPmWd    = MAX(drawWd, textPmWd);   textPmHt    = MAX(drawHt, textPmHt);   textPm      = XCreatePixmap(halApp->display, textWin, textPmWd, textPmHt,			       depth);} // End CheckPixmapSize/*----------------------------------------------------------------------- *  Format the specified line and redraw all affected lines */voidMimeRichTextP::LineChanged(TextLineC *tline, Boolean forcePlace){   LinesChanged(tline, tline, forcePlace);}/*----------------------------------------------------------------------- *  Format the specified lines and redraw all affected lines */voidMimeRichTextP::LinesChanged(TextLineC *begLine, TextLineC *endLine,			    Boolean forcePlace){//// Re-format the text lines//   Boolean	placeNeeded  = False;   Boolean	widthNeeded  = False;   Boolean	widthChanged = False;   TextLineC	*tline = begLine;   SoftLineC	*sprev = begLine->prev ? begLine->prev->LastSoft()				       : (SoftLineC*)NULL;   while ( tline != endLine->next ) {      int	oldHt = tline->bounds.ht;      int	oldWd = tline->bounds.wd;      FormatLine(tline);      if ( !placeNeeded ) placeNeeded = (oldHt != tline->bounds.ht);//// If the line shrunk, we'll have to recalculate the max line width for all//    lines.//      if ( tline->bounds.wd < oldWd ) widthNeeded = True;//// If the line grew, see if the text width is affected.  If it is, we'll have//    to re-justify all lines.//      else if ( tline->bounds.wd > textWd ) {	 textWd = tline->bounds.wd;	 widthChanged = True;      }//// Update the soft line links//      SoftLineC	*first = tline->FirstSoft();      if ( sprev ) {	 sprev->next = first;	 first->prev = sprev;      }      else	 topSoftLine = first;      sprev = tline->LastSoft();      tline = tline->next;   } // End for each changed line//// Update last soft link//   SoftLineC	*snext = endLine->next ? endLine->next->FirstSoft()				       : (SoftLineC*)NULL;   SoftLineC	*last = endLine->LastSoft();   if ( snext ) {      last->next  = snext;      snext->prev = last;   }   else      botSoftLine = last;//// See if we need to recalculate the maximum line width.//   if ( widthNeeded ) {      int	newWd = MaxLineWidth();      if ( newWd != textWd ) {	 textWd = newWd;	 widthChanged = True;      }   }//// If the max width has changed, we'll need to re-justify all lines.// If not, we'll justify only the lines that changed//   if ( widthChanged )      JustifyLines();   else /*if ( resizeWidth )*/ {      tline = begLine;      while ( tline != endLine->next ) {	 SoftLineC	*sline = tline->softLine;	 while ( sline && sline->textLine == tline ) {	    Justify(sline);	    sline = sline->next;	 }

⌨️ 快捷键说明

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