示例#1
0
void nuiTextLayout::Print(nuiDrawContext* pContext, float X, float Y, bool AlignGlyphPixels) const
{
  bool blendsaved = pContext->GetState().mBlending;
  bool texturesaved = pContext->GetState().mTexturing;
  
  pContext->EnableBlending(true);
  pContext->EnableTexturing(true);
  
  nuiColor SavedColor = pContext->GetFillColor();
  nuiColor oldcolor(pContext->GetStrokeColor());
  pContext->SetStrokeColor(pContext->GetTextColor());
  pContext->SetFillColor(pContext->GetTextColor());
  pContext->SetBlendFunc(nuiBlendTransp);
  
  std::map<nuiTexture*, std::vector<nuiTextGlyph*> > Glyphs;
  
  float x = X;
  float y = Y;
  
  // Iterate runs:
  for (int32 p = 0; p < GetParagraphCount(); p++)
  {
    for (int32 l = 0; l < GetLineCount(p); l++)
    {
      x = X;
      nuiTextLine* pLine = GetLine(p, l);
      for (int32 r = 0; r < pLine->GetRunCount(); r++)
      {
        nuiTextRun* pRun = pLine->GetRun(r);
        std::vector<nuiTextGlyph>& rGlyphs(pRun->GetGlyphs());
        nuiFontBase* pFont = pRun->GetFont();
        
        for (int32 g = 0; g < rGlyphs.size(); g++)
        {
          nuiTextGlyph& rGlyph(rGlyphs.at(g));
          Glyphs[rGlyph.mpTexture].push_back(&rGlyph);
        }
        
        // Draw underlines and strike through if needed
        if (pRun->GetUnderline() || pRun->GetStrikeThrough())
        {
          nuiFontInfo info;
          pFont->GetInfo(info);
          float thickness = ToNearest(info.UnderlineThick);
          pContext->SetLineWidth(thickness);
          
          const float x1 = x;
          const float x2 = x + pRun->GetAdvanceX();
          
          if (pRun->GetUnderline())
          {
            const float pos = -info.UnderlinePos;
            const float _y = ToNearest(y + pos);
            if (x1 != x2)
              pContext->DrawLine(x1, _y, x2, _y);
          }
          
          if (pRun->GetStrikeThrough())
          {
            const float pos = -info.Ascender * .4f;
            const float _y = ToNearest(y + pos);
            if (x1 != x2)
              pContext->DrawLine(x1, _y, x2, _y);
          }
        }
        
        //x += pRun->GetAdvanceX();
      }
      //y += pLine->GetAdvanceY();
    }
  }
  
  PrintGlyphs(pContext, X, Y, Glyphs, AlignGlyphPixels);
  
  
  pContext->EnableBlending(blendsaved);
  pContext->EnableTexturing(texturesaved);
  
  pContext->SetFillColor(SavedColor);
  pContext->SetStrokeColor(oldcolor);
}
示例#2
0
void ChatPanel::OutputLine( const ChatLine& line )
{
  int pos = m_chatlog_text->GetScrollPos(wxVERTICAL);
  int end = m_chatlog_text->GetScrollRange(wxVERTICAL);
  int thumb = m_chatlog_text->GetScrollThumb(wxVERTICAL);
#ifndef __WXMSW__
  float original_pos = (float)(pos+thumb) / (float)end;
#else
  int size = m_chatlog_text->GetSize().GetHeight();
  float original_pos = (float)(pos+size) / (float)end; // wxmsw is retarded and reports thumb size as 0 always
#endif
  if ( original_pos < 0.0f ) original_pos = 0.0f;
  if ( original_pos > 1.0f ) original_pos = 1.0f; // this is necessary because the code in windows isn't 100% right because thumb always returns 0
  long original_line = 0;
#ifndef __WXMSW__
  if (original_pos < 1.0f )
  {
	  original_line = (long)(original_pos *(float)m_chatlog_text->GetNumberOfLines()); // GetNumberOfLines is expensive, only call when necessary
	  m_chatlog_text->Freeze();
  }
#else
	 wxWindowUpdateLocker noUpdates(m_chatlog_text); // use the automatic one in windows
#endif

  m_chatlog_text->SetDefaultStyle( line.timestyle );
  m_chatlog_text->AppendText( line.time );

  m_chatlog_text->SetDefaultStyle( line.chatstyle );

#ifndef __WXOSX_COCOA__
	if ( sett().GetUseIrcColors() )
	{
		wxString m1;
		wxString m2;
		wxString m3;
		wxTextAttr at;
		int oldweight;
		char c;
		int color;
		m1 = line.chat;
		bool _2chars = false;
		bool bold = false;
		wxFont font;
		wxColor curcolor(0,0,0);
		wxColor oldcolor(0,0,0);
		curcolor = line.chatstyle.GetTextColour();
                at = m_chatlog_text->GetDefaultStyle();
		font = at.GetFont();
		oldweight = font.GetWeight();
		oldcolor = line.chatstyle.GetTextColour();
		while ( m1.Len() > 0 )
		{
			c = m1.GetChar(0);
			if (c == 3 && m1.Len() > 1 && (m1.GetChar(1) >= 48 && m1.GetChar(1) <= 58)) // Color
			{
				if (m1.Len() > 2 && (m1.GetChar(2) >= 48 && m1.GetChar(2) <= 58))
				{
					color = (int(m1.GetChar(1)) - 48)*10+(int(m1.GetChar(2)) - 48);
					_2chars = true;
					m1 = m1.Mid(3);
					}
				else
				{
					color = int(m1.GetChar(1)) -48;
					_2chars = false;
					m1 = m1.Mid(2);
					}

				wxColor dummy(0,0,0);
				if ( ( color > -1 ) && ( color < long(( sizeof( m_irc_colors ) / sizeof( dummy ) )) ) )
				{

					curcolor = m_irc_colors[color];
				}

			}else if(c == 2)//Bold
			{
				bold = !bold;
				m1 = m1.Mid(1);
			}else if(c == 0x0F) //Reset formatting
			{
			  bold = false;
			  curcolor = oldcolor;
			  m1 = m1.Mid(1);
			}else{

				at = m_chatlog_text->GetDefaultStyle();
				at.SetFlags(wxTEXT_ATTR_TEXT_COLOUR | wxTEXT_ATTR_FONT_WEIGHT);
				font = at.GetFont();
				if (bold)
					font.SetWeight(wxFONTWEIGHT_BOLD);
				else
					font.SetWeight(oldweight);
				at.SetFont(font);
				at.SetTextColour(curcolor);

				m_chatlog_text->SetDefaultStyle(at);
				m_chatlog_text->AppendText( m1.Mid(0,1) );
				m1 = m1.Mid(1);
			}
		}
		if (bold)
		{
			font = at.GetFont();
			font.SetWeight(oldweight);
			at.SetFont(font);
			m_chatlog_text->SetDefaultStyle(at);
		}

	}
	else
#endif
	{
		m_chatlog_text->AppendText( line.chat );
	}

  m_chatlog_text->AppendText( _T( "\n" ) );

  // crop lines from history that exceeds limit
  int maxlenght = sett().GetChatHistoryLenght();
  if ( ( maxlenght > 0 ) && ( m_chatlog_text->GetNumberOfLines() > sett().GetChatHistoryLenght() ) )
  {
		int end_line = 0;
		for ( int i = 0; i < 20; i++ ) end_line += m_chatlog_text->GetLineLength( i ) + 1;
		m_chatlog_text->Remove( 0, end_line );
  }

  if (original_pos < 1.0f)
  {
#ifndef __WXMSW__
	  wxString linetext = m_chatlog_text->GetLineText(original_line);
	  long zoomto = m_chatlog_text->GetValue().Find(linetext);
	  m_chatlog_text->ShowPosition( zoomto ); // wxgtk is retarded and always autoscrolls
#endif
  }
  else
  {
	m_chatlog_text->ScrollLines(10); // wx is retarded, necessary to show the latest line
#ifdef __WXMSW__
	m_chatlog_text->ShowPosition( m_chatlog_text->GetLastPosition() );
#endif
  }
  this->Refresh();
#ifndef __WXMSW__
 if (original_pos < 1.0f)
  {
	m_chatlog_text->Thaw();
  }
#endif
}