void CglFont::glPrintTable(float x, float y, float s, const int options, const std::string& text) { std::vector<std::string> coltext; coltext.push_back(""); std::vector<SColor> colColor; SColor defaultcolor(0,0,0); defaultcolor[0] = ColorCodeIndicator; for (int i = 0; i < 3; ++i) defaultcolor[i+1] = (unsigned char)(textColor[i] * 255.0f); colColor.push_back(defaultcolor); SColor curcolor(defaultcolor); int col = 0; int row = 0; for (int pos = 0; pos < text.length(); pos++) { const unsigned char& c = text[pos]; switch(c) { // inline colorcodes case ColorCodeIndicator: for (int i = 0; i < 4 && pos < text.length(); ++i, ++pos) { coltext[col] += text[pos]; curcolor[i] = text[pos]; } colColor[col] = curcolor; --pos; break; // column separator is `\t`==`horizontal tab` case '\t': ++col; if (col >= coltext.size()) { coltext.push_back(""); for(int i = 0; i < row; ++i) coltext[col] += 0x0a; colColor.push_back(defaultcolor); } if (colColor[col] != curcolor) { for(int i = 0; i < 4; ++i) coltext[col] += curcolor[i]; colColor[col] = curcolor; } break; // newline case 0x0d: // CR+LF if (pos+1 < text.length() && text[pos + 1] == 0x0a) pos++; case 0x0a: // LF for (int i = 0; i < coltext.size(); ++i) coltext[i] += 0x0a; if (colColor[0] != curcolor) { for(int i = 0; i < 4; ++i) coltext[0] += curcolor[i]; colColor[0] = curcolor; } col = 0; ++row; break; // printable char default: coltext[col] += c; } } float totalWidth = 0.0f; float maxHeight = 0.0f; float minDescender = 0.0f; std::vector<float> colWidths(coltext.size(), 0.0f); for (int i = 0; i < coltext.size(); ++i) { float colwidth = GetTextWidth(coltext[i]); colWidths[i] = colwidth; totalWidth += colwidth; float textDescender; float textHeight = GetTextHeight(coltext[i], &textDescender); if (textHeight > maxHeight) maxHeight = textHeight; if (textDescender < minDescender) minDescender = textDescender; } // s := scale or absolute size? float ss = s; if (options & FONT_SCALE) { ss *= fontSize; } float sizeX = ss, sizeY = ss; // render in normalized coords (0..1) instead of screencoords (0..~1024) if (options & FONT_NORM) { sizeX *= globalRendering->pixelX; sizeY *= globalRendering->pixelY; } // horizontal alignment (FONT_LEFT is default) if (options & FONT_CENTER) { x -= sizeX * 0.5f * totalWidth; } else if (options & FONT_RIGHT) { x -= sizeX * totalWidth; } // vertical alignment if (options & FONT_BASELINE) { // nothing } else if (options & FONT_DESCENDER) { y -= sizeY * GetDescender(); } else if (options & FONT_VCENTER) { y -= sizeY * 0.5f * maxHeight; y -= sizeY * 0.5f * minDescender; } else if (options & FONT_TOP) { y -= sizeY * maxHeight; } else if (options & FONT_ASCENDER) { y -= sizeY * GetDescender(); y -= sizeY; } else if (options & FONT_BOTTOM) { y -= sizeY * minDescender; } for (int i = 0; i < coltext.size(); ++i) { glPrint(x, y, s, (options | FONT_BASELINE) & ~(FONT_RIGHT | FONT_CENTER), coltext[i]); x += sizeX * colWidths[i]; } }
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 }
void ChatPanel::OutputLine(const ChatLine& line) { const int numOfLines = m_chatlog_text->GetNumberOfLines(); const int maxlength = sett().GetChatHistoryLenght(); // crop lines from history that exceeds limit if ((maxlength > 0) && (numOfLines > maxlength)) { int end_line = 0; for (int i = 0; i < numOfLines - maxlength; i++) { end_line += m_chatlog_text->GetLineLength(i) + 1; } if (end_line > 0) { m_chatlog_text->Remove(0, end_line); } } if (!line.time.empty()) { m_chatlog_text->SetDefaultStyle(line.timestyle); m_chatlog_text->AppendText(line.time + _T(" ")); } else { m_chatlog_text->SetDefaultStyle(line.chatstyle); } #ifndef __WXOSX_COCOA__ if (sett().GetUseIrcColors()) { wxString m1(line.chat); wxString m2; wxString m3; wxTextAttr at(line.chatstyle); int color = 0; bool bold = false; wxColor curcolor(line.chatstyle.GetTextColour()); const wxFont oldfont = sett().GetChatFont(); const wxColor oldcolor(line.chatstyle.GetTextColour()); while (m1.Len() > 0) { const size_t firstspec = FirstSpecialChar(m1); if (firstspec > 0) { //unformated text found, add as whole wxFont font = oldfont; //isn't needed any more in wx3.0 at = line.chatstyle; if (bold) font.SetWeight(wxFONTWEIGHT_BOLD); at.SetFont(font); at.SetTextColour(curcolor); m_chatlog_text->SetDefaultStyle(at); m_chatlog_text->AppendText(m1.Mid(0, firstspec)); m1 = m1.Mid(firstspec); if (m1.Len() <= 0) { //no chars left, abort break; } } const unsigned char uc = m1.GetChar(0); switch (uc) { // http://en.wikichip.org/wiki/irc/colors case 0x1f: //underline break; case 0x1d: //italics break; case 0x03: { if (m1.Len() > 2 && (m1.GetChar(2) >= 48 && m1.GetChar(2) <= 58)) { color = (int(m1.GetChar(1)) - 48) * 10 + (int(m1.GetChar(2)) - 48); m1 = m1.Mid(2); //next chars } else { color = int(m1.GetChar(1)) - 48; m1 = m1.Mid(1); //next char } wxColor dummy(0, 0, 0); if ((color > -1) && (color < long((sizeof(m_irc_colors) / sizeof(dummy))))) { curcolor = m_irc_colors[color]; } break; } case 0x02: //bold bold = !bold; break; case 0x16: //reverse; break; case 0x0F: //reset formating bold = false; curcolor = oldcolor; break; } m1 = m1.Mid(1); //next char! } m_chatlog_text->AppendText(_T("\n")); } else #endif { m_chatlog_text->SetDefaultStyle(line.chatstyle); m_chatlog_text->AppendText(line.chat + _T( "\n" )); } m_chatlog_text->ScrollLines(1); m_chatlog_text->ShowPosition(m_chatlog_text->GetLastPosition()); }
void ChatPanel::OutputLine(const ChatLine& line) { const int numOfLines = m_chatlog_text->GetNumberOfLines(); const int maxlength = sett().GetChatHistoryLenght(); // crop lines from history that exceeds limit if ((maxlength > 0) && (numOfLines > maxlength)) { int end_line = 0; for (int i = 0; i < numOfLines - maxlength; i++) { end_line += m_chatlog_text->GetLineLength(i) + 1; } if (end_line > 0) { m_chatlog_text->Remove(0, end_line); } } if (!line.time.empty()) { m_chatlog_text->SetDefaultStyle(line.timestyle); m_chatlog_text->AppendText(line.time); } #ifndef __WXOSX_COCOA__ if (sett().GetUseIrcColors()) { wxString m1(line.chat); wxString m2; wxString m3; wxTextAttr at(line.chatstyle); int color = 0; bool bold = false; wxColor curcolor(line.chatstyle.GetTextColour()); const wxFont oldfont = sett().GetChatFont(); const wxColor oldcolor(line.chatstyle.GetTextColour()); while (m1.Len() > 0) { const wxUniChar 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); m1 = m1.Mid(3); } else { color = int(m1.GetChar(1)) - 48; 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 { wxFont font = oldfont; //isn't needed any more in wx3.0 at = line.chatstyle; if (bold) font.SetWeight(wxFONTWEIGHT_BOLD); at.SetFont(font); at.SetTextColour(curcolor); m_chatlog_text->SetDefaultStyle(at); m_chatlog_text->AppendText(m1.Mid(0, 1)); m1 = m1.Mid(1); } } m_chatlog_text->AppendText(_T("\n")); } else #endif { m_chatlog_text->SetDefaultStyle(line.chatstyle); m_chatlog_text->AppendText(line.chat + _T( "\n" )); } m_chatlog_text->ScrollLines(1); m_chatlog_text->ShowPosition(m_chatlog_text->GetLastPosition()); }