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

📄 mimerichtextdraw.c

📁 linux下的E_MAIL客户端源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	 tline = tline->next;      }   }//// See if we need to re-position the lines vertically.  This will update//    both scroll bars.//   int	oldVsbVal = vsbVal;   if ( placeNeeded || forcePlace )      PlaceLines(begLine);//// Update horizontal scroll bar if necessary.  There must be room for at least//   one complete line before we turn the scroll bars on.//   else if ( !textSW ) {      WArgList	args;      int	lineHt = pub->LineHeight();      int	sbSize = scrollBoff - noScrollBoff;      int	drawHtWithSB = drawHt;      if ( !hsbOn ) drawHtWithSB -= sbSize;      if ( (textWd > (int)drawWd) && (drawHtWithSB >= lineHt) ) {	 if ( !hsbOn ) {	    XtVaSetValues(hlForm, XmNbottomOffset, scrollBoff, NULL);	    drawHt -= sbSize;	    hsbOn = True;	 }      } // End if horizontal scroll bar needed      else {	 if ( hsbOn && !hsbAlwaysOn ) {	    XtVaSetValues(hlForm, XmNbottomOffset, noScrollBoff, NULL);	    drawHt += sbSize;	    hsbOn = False;	 }      } // End if horizontal scroll bar not needed      hsbMax = MAX((int)drawWd, textWd);      int	ss = MIN((int)drawWd, hsbMax);      if ( hsbVal + ss > hsbMax ) hsbVal = hsbMax - ss;      int	pi = drawWd - pub->CharWidth();      if ( pi <= 0 ) pi = drawWd;      args.Value(hsbVal);      args.Maximum(hsbMax);      args.MappedWhenManaged(hsbOn);      args.SliderSize(ss);      args.PageIncrement(pi);      XtSetValues(textHSB, ARGS);   } // End if horizontal scroll bar needs to be checked//// Redraw the affected lines.  Draw all lines if the scroll bar moved.//   int	ymin, ht;   if ( vsbVal != oldVsbVal ) {      ymin = 0;      ht   = drawHt;   }   else {      ymin = begLine->bounds.ymin - vsbVal;      if ( ymin < 0 ) ymin = 0;      int	ymax;      if ( placeNeeded || forcePlace ) ymax = drawHt - 1;      else			       ymax = endLine->bounds.ymax - vsbVal;      ht = ymax - ymin + 1;      if ( ht > (int)drawHt ) ht = drawHt;   }   RectC area(0, ymin, drawWd, ht);   DrawScreen(area);//// Call text change callbacks//   CallCallbacks(changeCalls, pub);} // End LinesChanged/*---------------------------------------------------------------------- * Set the position of all lines */voidMimeRichTextP::PlaceLines(TextLineC *startLine){   if ( startLine && startLine->prev )      textY = startLine->prev->bounds.ymax + 1 + lineSpacing;   else {      startLine = topTextLine;      textY = marginHt + 2;	// This will allow the accent characters to be      				// displayed on the top line   }   TextLineC	*line = startLine;   while ( line ) {      SetLinePosition(line, textY);      textY += line->bounds.ht + lineSpacing;      line = line->next;   }   if ( startLine ) textY -= lineSpacing;   textY += marginHt;//// Clear out the bottom part//   if ( realized && textY < (int)textHt ) {      int	y = textY - vsbVal;      if ( y >= 0 && y <= (int)drawHt ) {	 XSetForeground(halApp->display, textGC, bgColor);	 Drawable	drawto = pub->DrawTo();	 XFillRectangle(halApp->display, drawto, textGC, 0, y,			drawWd, drawHt - y + 1);	 if ( drawto != textWin )	    XFillRectangle(halApp->display, textWin, textGC, 0, y,			   drawWd, drawHt - y + 1);	 XSetForeground(halApp->display, textGC, fgColor);      }   }//// If we're in a scrolled window, see if we need to resize ourself.//   if ( textSW ) {      Dimension	newHt = MAX(textY, (int)(clipHt-marginHt2-1));      if ( newHt != textHt ) {	 drawHt = textHt = newHt;	 if ( debuglev > 1 ) cout <<"setting height to " <<textHt NL;	 XtVaSetValues(textDA, XmNheight, textHt+marginHt2, 0);      } // End if height changed   } // End if height can be adjusted//// If we're not in a scrolled window, update the scroll bars//   else {      textHt = textY;//// Update the scroll bars//      static Boolean	formatAgain = False;      if ( !formatAgain ) {	 WArgList	args;//// See if we need a vertical scroll bar//	 args.Reset();	 if ( textHt > (int)maxHt && (int)drawWd >= 2*pub->CharWidth() ) {	    if ( !vsbOn ) {	       XtVaSetValues(hlForm, XmNrightOffset, scrollRoff, NULL);	       drawWd -= (scrollRoff - noScrollRoff);	       formatAgain = True;	       vsbOn = True;	    }	 } // End if vertical scroll bar needed	 else {	    if ( vsbOn && !vsbAlwaysOn ) {	       XtVaSetValues(hlForm, XmNrightOffset, noScrollRoff, NULL);	       drawWd += (scrollRoff - noScrollRoff);	       formatAgain = True;	       vsbOn = False;	    }	 } // End if vertical scroll bar not needed	 if ( formatAgain ) FormatScreen();	 formatAgain = False;	 vsbMax = MAX((int)drawHt, textHt);	 int	ss = MIN((int)drawHt, vsbMax);	 if ( vsbVal + ss > vsbMax ) vsbVal = vsbMax - ss;	 int	pi = drawHt - pub->LineHeight();	 if ( pi <= 0 ) pi = drawHt;	 args.Value(vsbVal);	 args.Maximum(vsbMax);	 args.MappedWhenManaged(vsbOn);	 args.SliderSize(ss);	 args.PageIncrement(pi);	 XtSetValues(textVSB, ARGS);//// See if we need a horizontal scroll bar.  There must be room for at least//   one complete line before we turn the scroll bar on.//	 args.Reset();	 int	lineHt = pub->LineHeight();	 int	sbSize = scrollBoff - noScrollBoff;	 int	drawHtWithSB = drawHt;	 if ( !hsbOn ) drawHtWithSB -= sbSize;	 if ( (textWd > (int)drawWd) && (drawHtWithSB >= lineHt) ) {	    if ( !hsbOn ) {	       XtVaSetValues(hlForm, XmNbottomOffset, scrollBoff, NULL);	       drawHt -= sbSize;	       hsbOn = True;	    }	 } // End if horizontal scroll bar needed	 else {	    if ( hsbOn && !hsbAlwaysOn ) {	       XtVaSetValues(hlForm, XmNbottomOffset, noScrollBoff, NULL);	       drawHt += sbSize;	       hsbOn = False;	    }	 } // End if horizontal scroll bar not needed	 hsbMax = MAX((int)drawWd, textWd);	 ss = MIN((int)drawWd, hsbMax);	 if ( hsbVal + ss > hsbMax ) hsbVal = hsbMax - ss;	 pi = drawWd - pub->CharWidth();	 if ( pi <= 0 ) pi = drawWd;	 args.Value(hsbVal);	 args.Maximum(hsbMax);	 args.MappedWhenManaged(hsbOn);	 args.SliderSize(ss);	 args.PageIncrement(pi);	 XtSetValues(textHSB, ARGS);	 CheckPixmapSize();      } // End if we didn't already do this   } // End if we're doing our own scroll bars} // End PlaceLines/*---------------------------------------------------------------------- * Format the text lines */voidMimeRichTextP::FormatScreen(){   if ( defer || !changed || !realized ) return;   if ( debuglev > 1 )      cout <<"MimeRichTextC(" <<XtName(pub->MainWidget())      	   <<")::FormatScreen" <<endl;   textWd = marginWd2;   textHt = marginHt2;//// Remove all soft lines//   TextLineC	*tline = topTextLine;   while ( tline ) {      SoftLineC	*sline = tline->softLine;      while ( sline && sline->textLine == tline ) {	 SoftLineC	*next = sline->next;	 delete sline;	 sline = next;      }      tline->softLine = NULL;      tline = tline->next;   }   topSoftLine = botSoftLine = NULL;//// Process the lines and link soft lines as we go//   tline = topTextLine;   while ( tline ) {      FormatLine(tline);      if ( !topSoftLine ) {	 topSoftLine = tline->FirstSoft();	 botSoftLine = tline->LastSoft();      }      else {	 SoftLineC	*first = tline->FirstSoft();	 botSoftLine->next = first;	 first->prev = botSoftLine;	 botSoftLine = tline->LastSoft();      }      tline = tline->next;   }//// Set the text width to the maximum line width and justify all lines.//   textWd = MaxLineWidth();   JustifyLines();	// Set horizontal positions//// Set the lines' vertical positions//   PlaceLines();   pub->ResetPartIndex();   changed = False;   if ( debuglev > 1 ) cout <<"Leaving FormatScreen" NL;} // End FormatScreen/*---------------------------------------------------------------------- * Lay out the specified text line */voidMimeRichTextP::FormatLine(TextLineC *textLine){   if ( debuglev > 1 ) cout <<"Formatting line " <<textLine->index <<endl;//// Delete the soft lines for this text//   SoftLineC	*sline = textLine->softLine;   while ( sline && sline->textLine == textLine ) {      SoftLineC	*next = sline->next;      delete sline;      sline = next;   }   textLine->softLine = NULL;// If we do this, we can't change state at the end of some text#if 0//// Make the line as efficient as possible//   CompactLine(textLine);#endif//// Create a new soft line//   SoftLineC	*softLine = new SoftLineC;   softLine->textLine = textLine;   textLine->softLine = softLine;//// Get the initial state and the initial indent conditions//   TextStateC	*state = textLine->State(0);   int		lindent = state->LIndent();   int		rindent = state->RIndent();//// Determine the available width//   int	availWd;   if ( resizeWidth )      availWd = 32768;   else      availWd = drawWd - (indentWd * (lindent + rindent))		       - (excerptWd * state->Excerpt())		       - marginWd2;   int leftX = marginWd + (state->Excerpt() * excerptWd) + (lindent * indentWd);//// Loop through the commands.//   unsigned	ccount = textLine->cmdList.size();   RichCmdC	*cmd;   int i=0; for (i=0; i<ccount; i++) {      cmd = textLine->Cmd(i);      if ( cmd->IsText() )	 softLine = FormatText(textLine, softLine, i, cmd->state, &leftX,			       &availWd, &lindent, &rindent);      else	 softLine = FormatGraphic(textLine, softLine, i, cmd->state, &leftX,				  &availWd, &lindent, &rindent);   } // End for each command//// If there is a blank soft line at the end of the list, remove it.  If it//    is the only one, leave it.//   SoftLineC	*first = textLine->FirstSoft();   SoftLineC	*last  = textLine->LastSoft();   if ( first != last && !last->drawData ) {      last->prev->next = NULL;      delete softLine;   }//// Loop through the soft lines and calculate their sizes//   leftX = marginWd + (state->Excerpt() * excerptWd) + (lindent * indentWd);   int			textLineHt = 0;   int			textLineWd = 0;   RichDrawDataC	*prevData = NULL;   sline = textLine->softLine;   while ( sline && sline->textLine == textLine ) {//// Create an empty draw data for any soft line that has none//      if ( !sline->drawData ) {	 RichDrawDataC	*data = new RichDrawDataC;	 data->softLine = sline;	 if ( prevData ) {	    data->cmdPos    = prevData->cmdPos;	    data->textOff   = prevData->textOff + prevData->string.size();	    data->font      = prevData->font;	    data->underline = prevData->underline;	 }	 else {	    data->cmdPos    = 0;	    data->textOff   = 0;	    data->font      = CurFont(*state);	    data->underline = (state->Underline()>0);	 }	 data->x     = leftX;	 data->width = 0;	 RichDrawDataC	*lastData = softLine->LastData();	 if ( lastData ) {	    lastData->next = data;	    data->prev = lastData;	 }	 else {	    softLine->drawData = data;	 }      } // End if this is an empty line      else {	 prevData = sline->LastData();      }//// Calculate width and height//      GetLineSize(sline);//// Update the bounds of this text line//      textLineHt += sline->bounds.ht;      textLineHt += lineSpacing;      if ( /*resizeWidth &&*/ sline->totalWd > textLineWd )	 textLineWd = sline->totalWd;      sline = sline->next;   } // End for each soft line   textLineHt -= lineSpacing;   if ( textLineHt == 0 ) textLineHt = 1;   textLine->bounds.SetSize(textLineWd, textLineHt);   if ( debuglev > 1 )      cout <<"Text Line bounds are: " <<textLine->bounds.xmin <<" "				      <<textLine->bounds.ymin <<" "				      <<textLine->bounds.wd   <<" "				      <<textLine->bounds.ht   <<endl;//// Position the soft lines vertically//   SetLinePosition(textLine, textLine->bounds.ymin);} // End FormatLine/*---------------------------------------------------------------------- * Try to place the text in the available area.  Wrap if necessary */SoftLineC*MimeRichTextP::FormatText(TextLineC *textLine, SoftLineC *softLine,			  int cmdPos, TextStateC& state, int *leftX,			  int *availWd, int *lindent, int *rindent){//// Grab the text//   StringC	*textStr = textLine->Text(cmdPos);   char		*cs = *textStr;   int		len = textStr->size();   int		remaining = len;   if ( debuglev > 1 ) cout <<"Formatting text ^" <<*textStr <<"^" <<endl;//// If the length is 0, create one draw data and be done with it//   if ( remaining == 0 ) {      RichDrawDataC	*data = new RichDrawDataC;      data->softLine  = softLine;      data->cmdPos    = cmdPos;      data->textOff   = 0;      data->x         = *leftX;      data->width     = 0;      data->font      = CurFont(state);      data->underline = (state.Underline()>0);      data->string    = "";      softLine->AddDrawData(data);   }//// Loop until we're fininshed with this text//   while ( remaining > 0 ) {//// If there are any tabs, split them out//      char	*tp = strchr(cs, '\t');      if ( tp ) {	 if ( tp == cs ) len = 1;	 else		 len = tp - cs;      }//// Get size of text//      int		dir, asc, dsc;      XCharStruct	size;      FontDataC		*curFont = CurFont(state);      if ( *cs == '\t' ) {	 int	charWd  = curFont->CharWidth();	 int	tabSize = tabStop * charWd;	 int	tabX    = (state.Excerpt() * excerptWd) +	 		  (state.LIndent() * indentWd)  + tabSize;	 while ( tabX <= *leftX ) tabX += tabSize;	 size.width = tabX - *leftX;      }      else {	 XTextExtents(curFont->xfont, cs, len, &dir, &asc, &dsc, &size);      }//// If it doesn't fit, find out how much will//      Boolean	addIt = True;      Boolean	lineFull = (size.width > *availWd);      if ( lineFull ) {	 if ( *cs == '\t' ) {	    addIt = (softLine->drawData == NULL);	 }	 else {	    int	fitLen = FitText(cs, curFont->xfont, *availWd);	    if ( fitLen > 0 ) {	       len = fitLen;	       XTextExtents(curFont->xfont, cs, len, &dir, &asc, &dsc, &size);	    }	    else	       addIt = (softLine->drawData == NULL);	 }      }//// Add this section of text if necessary//      if ( addIt ) {//// Create a new draw data//	 RichDrawDataC	*data = new RichDrawDataC;	 data->softLine  = softLine;	 data->cmdPos    = cmdPos;	 data->textOff   = cs - (char*)*textStr;	 data->x         = *leftX;	 data->width     = size.width;	 data->font      = curFont;	 data->underline = (state.Underline()>0);	 data->string.Set(cs, len);	 softLine->AddDrawData(data);

⌨️ 快捷键说明

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