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); }
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 }