From 51cd2f5ced8d37f767ec179851c787e6fc0592ab Mon Sep 17 00:00:00 2001 From: Rodrigo Braz Monteiro Date: Fri, 13 Apr 2007 14:38:27 +0000 Subject: [PATCH] Completed (although it could still use some new features) OpenGL Text drawing code, and fully re-implemented video mouse coordinates. Originally committed to SVN as r1072. --- aegisub/gl_text.cpp | 120 +++++++++++++++++++++++++------ aegisub/gl_text.h | 13 ++-- aegisub/video_display.cpp | 7 +- aegisub/video_display_visual.cpp | 40 ++++------- 4 files changed, 128 insertions(+), 52 deletions(-) diff --git a/aegisub/gl_text.cpp b/aegisub/gl_text.cpp index ec38f22b3..eeee4cd15 100644 --- a/aegisub/gl_text.cpp +++ b/aegisub/gl_text.cpp @@ -79,15 +79,18 @@ OpenGLText* OpenGLText::GetInstance() { //////////// // Set font -void OpenGLText::DoSetFont(wxString face,int size) { +void OpenGLText::DoSetFont(wxString face,int size,bool bold,bool italics) { // No change required - if (size == fontSize && face == fontFace) return; + if (size == fontSize && face == fontFace && bold == fontBold && italics == fontItalics) return; // Set font fontFace = face; fontSize = size; + fontBold = bold; + fontItalics = italics; font.SetFaceName(fontFace); font.SetPointSize(size); + font.SetWeight(bold ? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL); // Delete all old data Reset(); @@ -107,14 +110,35 @@ void OpenGLText::DoSetColour(wxColour col,float alpha) { ///////// // Print void OpenGLText::DoPrint(wxString text,int x,int y) { + // Set OpenGL + glEnable(GL_BLEND); + glEnable(GL_TEXTURE_2D); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + // Draw border + glColor4f(0.0f,0.0f,0.0f,1.0f); + DrawString(text,x-1,y); + DrawString(text,x+1,y); + DrawString(text,x,y-1); + DrawString(text,x,y+1); + + // Draw primary string + glColor4f(r,g,b,a); + DrawString(text,x,y); + + // Disable blend + glDisable(GL_BLEND); +} + + +///////////////// +// Draw a string +void OpenGLText::DrawString(wxString text,int x,int y) { // Variables - int dx=x,dy=y; size_t len = text.Length(); OpenGLTextGlyph glyph; - lineHeight = 16; // FIXME - - // Set OpenGL - // TODO + lineHeight = 0; + int dx=x,dy=y; // Draw string for (size_t i=0;i lineHeight) lineHeight = glyph.h; } } } +///////////////////////// +// Calculate text extent +void OpenGLText::DoGetExtent(wxString text,int &w,int &h) { + // Variables + size_t len = text.Length(); + OpenGLTextGlyph glyph; + lineHeight = 0; + int dx=0,dy=0; + w = 0; + h = 0; + + // Simulate drawing of string + for (size_t i=0;i w) w = dx; + dx = 0; + dy += lineHeight; + lineHeight = 0; + } + + // Handle normal glyphs + else { + glyph = GetGlyph(curChar); + dx += glyph.w; + if (glyph.h > lineHeight) lineHeight = glyph.h; + } + } + + // Return results + if (dx > w) w = dx; + h = dy+lineHeight; +} + + /////////////// // Get a glyph OpenGLTextGlyph OpenGLText::GetGlyph(int i) { @@ -216,7 +279,7 @@ OpenGLTextTexture::~OpenGLTextTexture() { ////////////////////////// // Can fit a glyph in it? -bool OpenGLTextTexture::TryToInsert(OpenGLTextGlyph glyph) { +bool OpenGLTextTexture::TryToInsert(OpenGLTextGlyph &glyph) { // Get size int w = glyph.w; int h = glyph.h; @@ -225,18 +288,18 @@ bool OpenGLTextTexture::TryToInsert(OpenGLTextGlyph glyph) { // Can fit in this row? if (x + w < width) { + Insert(glyph); x += w; if (y+h > nextY) nextY = y+h; - Insert(glyph); return true; } // Can fit the next row? else { - y = nextY; - if (y+h > height) return false; - nextY = y+h; + if (nextY+h > height) return false; x = 0; + y = nextY; + nextY = y+h; Insert(glyph); return true; } @@ -245,7 +308,7 @@ bool OpenGLTextTexture::TryToInsert(OpenGLTextGlyph glyph) { ////////// // Insert -void OpenGLTextTexture::Insert(OpenGLTextGlyph glyph) { +void OpenGLTextTexture::Insert(OpenGLTextGlyph &glyph) { // Glyph data wxString str = wxChar(glyph.value); int w = glyph.w; @@ -259,17 +322,34 @@ void OpenGLTextTexture::Insert(OpenGLTextGlyph glyph) { glyph.tex = tex; // Create bitmap and bind it to a DC - wxBitmap bmp(w,h,24); + wxBitmap bmp(((w+1)/2)*2,((h+1)/2)*2,24); wxMemoryDC dc(bmp); // Draw text and convert to image dc.SetFont(OpenGLText::GetFont()); + dc.SetTextForeground(wxColour(255,255,255)); dc.DrawText(str,0,0); + //bmp.SaveFile(wxString::Format(_T("glyph%i.bmp"),glyph.value),wxBITMAP_TYPE_BMP); wxImage img = bmp.ConvertToImage(); + // Convert to alpha + int imgw = img.GetWidth(); + int imgh = img.GetHeight(); + size_t len = imgw*imgh; + const unsigned char *src = img.GetData(); + const unsigned char *read = src; + unsigned char *alpha = new unsigned char[len*2]; + unsigned char *write = alpha; + for (size_t i=0;ifont; } - static void SetFont(wxString face,int size) { GetInstance()->DoSetFont(face,size); } + static void SetFont(wxString face=_T("Verdana"),int size=10,bool bold=true,bool italics=false) { GetInstance()->DoSetFont(face,size,bold,italics); } static void SetColour(wxColour col,float alpha=1.0f) { GetInstance()->DoSetColour(col,alpha); } static void Print(wxString text,int x,int y) { GetInstance()->DoPrint(text,x,y); } + static void GetExtent(wxString text,int &w,int &h) { GetInstance()->DoGetExtent(text,w,h); } }; diff --git a/aegisub/video_display.cpp b/aegisub/video_display.cpp index 6054a53f8..cc69e9b57 100644 --- a/aegisub/video_display.cpp +++ b/aegisub/video_display.cpp @@ -345,9 +345,12 @@ void VideoDisplay::OnMouseEvent(wxMouseEvent& event) { // Disable when playing if (VideoContext::Get()->IsPlaying()) return; + // Set mode, for whatever reason this is needed + visual->SetMode(visual->mode); + + // OnMouseLeave isn't called as long as we have an OnMouseEvent + // Just check for it and call it manually instead if (event.Leaving()) { - // OnMouseLeave isn't called as long as we have an OnMouseEvent - // Just check for it and call it manually instead OnMouseLeave(event); event.Skip(true); return; diff --git a/aegisub/video_display_visual.cpp b/aegisub/video_display_visual.cpp index 72c34aeb0..fad40fac2 100644 --- a/aegisub/video_display_visual.cpp +++ b/aegisub/video_display_visual.cpp @@ -501,34 +501,24 @@ void VideoDisplayVisual::DrawOverlay() { glDisable(GL_COLOR_LOGIC_OP); // Setup text - OpenGLText::SetFont(_T("Verdana"),10); - OpenGLText::Print(mouseText,x,y); + int tw,th; + OpenGLText::SetFont(_T("Verdana"),12,true); + OpenGLText::SetColour(wxColour(255,255,255)); + OpenGLText::GetExtent(mouseText,tw,th); - //// Setup text - //wxFont font(10,wxFONTFAMILY_DEFAULT,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_BOLD,false,_T("Verdana")); - //dc.SetFont(font); - //int tw,th; - //parent->GetTextExtent(mouseText,&tw,&th,NULL,NULL,&font); + // Calculate draw position + bool left = x > w/2; + bool bottom = y < h/2; - //// Inversion - //bool left = x > w/2; - //bool bottom = y < h/2; + // Text draw coords + int dx = x,dy = y; + if (left) dx -= tw + 4; + else dx += 4; + if (bottom) dy += 3; + else dy -= th + 3; - //// Text draw coords - //int dx = x,dy = y; - //if (left) dx -= tw + 4; - //else dx += 4; - //if (bottom) dy += 3; - //else dy -= th + 3; - - //// Draw text - //dc.SetTextForeground(wxColour(64,64,64)); - //dc.DrawText(mouseText,dx+1,dy-1); - //dc.DrawText(mouseText,dx+1,dy+1); - //dc.DrawText(mouseText,dx-1,dy-1); - //dc.DrawText(mouseText,dx-1,dy+1); - //dc.SetTextForeground(colour[2]); - //dc.DrawText(mouseText,dx,dy); + // Draw text + OpenGLText::Print(mouseText,dx,dy); } }