diff --git a/aegisub/gl_text.cpp b/aegisub/gl_text.cpp index 57329747c..ec38f22b3 100644 --- a/aegisub/gl_text.cpp +++ b/aegisub/gl_text.cpp @@ -37,6 +37,7 @@ /////////// // Headers #include "gl_text.h" +#include "utils.h" /////////////////// @@ -79,6 +80,17 @@ OpenGLText* OpenGLText::GetInstance() { //////////// // Set font void OpenGLText::DoSetFont(wxString face,int size) { + // No change required + if (size == fontSize && face == fontFace) return; + + // Set font + fontFace = face; + fontSize = size; + font.SetFaceName(fontFace); + font.SetPointSize(size); + + // Delete all old data + Reset(); } @@ -95,6 +107,33 @@ void OpenGLText::DoSetColour(wxColour col,float alpha) { ///////// // Print void OpenGLText::DoPrint(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 + + // Draw string + for (size_t i=0;i width) return false; + if (y+h > height) return false; // Can fit in this row? if (x + w < width) { @@ -178,21 +233,95 @@ bool OpenGLTextTexture::TryToInsert(OpenGLTextGlyph glyph) { // Can fit the next row? else { - if (w < width) { - y = nextY; - nextY = y+h; - x = 0; - Insert(glyph); - return true; - } + y = nextY; + if (y+h > height) return false; + nextY = y+h; + x = 0; + Insert(glyph); + return true; } - - // Can't fit - return false; } ////////// // Insert void OpenGLTextTexture::Insert(OpenGLTextGlyph glyph) { + // Glyph data + wxString str = wxChar(glyph.value); + int w = glyph.w; + int h = glyph.h; + + // Fill glyph structure + glyph.x1 = float(x)/width; + glyph.y1 = float(y)/height; + glyph.x2 = float(x+w)/width; + glyph.y2 = float(y+h)/height; + glyph.tex = tex; + + // Create bitmap and bind it to a DC + wxBitmap bmp(w,h,24); + wxMemoryDC dc(bmp); + + // Draw text and convert to image + dc.SetFont(OpenGLText::GetFont()); + dc.DrawText(str,0,0); + wxImage img = bmp.ConvertToImage(); + + // Upload image to video memory + const unsigned char* src = img.GetData(); + glTexSubImage2D(GL_TEXTURE_2D,0,x,y,w,h,GL_ALPHA,GL_UNSIGNED_BYTE,src); + if (glGetError()) throw _T("Error uploading glyph data to video memory."); +} + + +//////////////// +// Draw a glyph +void OpenGLTextGlyph::Draw(int x,int y) { + // Store matrix and translate + glPushMatrix(); + glTranslatef((float)x,(float)y,0.0f); + + // Set blend + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + + // Draw quad + glBegin(GL_QUADS); + // Top-left + glTexCoord2f(x1,y1); + glVertex2f(0,0); + // Bottom-left + glTexCoord2f(x1,y2); + glVertex2f(0,h); + // Bottom-right + glTexCoord2f(x2,y2); + glVertex2f(w,h); + // Top-right + glTexCoord2f(x2,y1); + glVertex2f(w,0); + glEnd(); + + // Restore GL state + glDisable(GL_BLEND); + glPopMatrix(); +} + + +///////////////////// +// Get glyph metrics +wxBitmap *OpenGLTextGlyph::tempBmp = NULL; +void OpenGLTextGlyph::GetMetrics() { + // Glyph data + wxCoord desc,lead; + wxString str = wxChar(value); + + // Create bitmap, if needed + if (!tempBmp) tempBmp = new wxBitmap(16,16,24); + + // Get text extents + { + wxMemoryDC dc(*tempBmp); + dc.SetFont(OpenGLText::GetFont()); + dc.GetTextExtent(str,&w,&h,&desc,&lead); + } } diff --git a/aegisub/gl_text.h b/aegisub/gl_text.h index acf9e0a0c..828d08fae 100644 --- a/aegisub/gl_text.h +++ b/aegisub/gl_text.h @@ -46,10 +46,17 @@ ///////////////////// // Glyph information class OpenGLTextGlyph { +private: + static wxBitmap *tempBmp; + public: + int value; int tex; - float x,y; + float x1,y1,x2,y2; int w,h; + + void GetMetrics(); + void Draw(int x,int y); }; typedef std::map glyphMap; @@ -79,6 +86,11 @@ public: class OpenGLText { private: float r,g,b,a; + int lineHeight; + int fontSize; + wxString fontFace; + wxFont font; + static OpenGLText* instance; glyphMap glyphs; @@ -97,6 +109,7 @@ private: void DoPrint(wxString text,int x,int y); public: + static wxFont GetFont() { return GetInstance()->font; } static void SetFont(wxString face,int size) { GetInstance()->DoSetFont(face,size); } 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); } diff --git a/aegisub/video_context.cpp b/aegisub/video_context.cpp index ad9edc8d9..005ff229d 100644 --- a/aegisub/video_context.cpp +++ b/aegisub/video_context.cpp @@ -517,7 +517,7 @@ GLuint VideoContext::GetFrameAsTexture(int n) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); if (glGetError() != 0) throw _T("Error setting wrap_t texture parameter."); - // Load image data into texture + // Allocate texture int height = frame.h; if (frame.format == FORMAT_YV12) height = height * 3 / 2; int tw = SmallestPowerOf2(MAX(frame.pitch[0]/frame.GetBpp(0),frame.pitch[1]+frame.pitch[2])); diff --git a/aegisub/video_display_visual.cpp b/aegisub/video_display_visual.cpp index e7296ee1a..72c34aeb0 100644 --- a/aegisub/video_display_visual.cpp +++ b/aegisub/video_display_visual.cpp @@ -54,6 +54,7 @@ #include "subs_edit_box.h" #include "export_visible_lines.h" #include "utils.h" +#include "gl_text.h" /////////////// @@ -499,6 +500,10 @@ void VideoDisplayVisual::DrawOverlay() { glEnd(); glDisable(GL_COLOR_LOGIC_OP); + // Setup text + OpenGLText::SetFont(_T("Verdana"),10); + OpenGLText::Print(mouseText,x,y); + //// Setup text //wxFont font(10,wxFONTFAMILY_DEFAULT,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_BOLD,false,_T("Verdana")); //dc.SetFont(font);