From 3b15f3f1e43c5b4bc03f6d2fa55a3d4ebbcbbada Mon Sep 17 00:00:00 2001 From: Ykkrosh Date: Sat, 4 Sep 2004 20:35:12 +0000 Subject: [PATCH] Text alignment alterations This was SVN commit r1119. --- source/gui/CGUI.cpp | 13 ++++++++--- source/gui/GUItext.cpp | 7 +++++- source/gui/GUItext.h | 2 ++ source/lib/res/unifont.cpp | 46 ++++++++++++++++++++++++++++---------- source/lib/res/unifont.h | 13 ++++++----- 5 files changed, 59 insertions(+), 22 deletions(-) diff --git a/source/gui/CGUI.cpp b/source/gui/CGUI.cpp index 44378334c7..c838d8e2ac 100755 --- a/source/gui/CGUI.cpp +++ b/source/gui/CGUI.cpp @@ -621,6 +621,9 @@ SGUIText CGUI::GenerateText(const CGUIString &string, int from=0; bool done=false; + bool FirstLine = true; // Necessary because text in the first line is shorter + // (it doesn't count the line spacing) + // Images on the left or the right side. vector Images[2]; int pos_last_img=-1; // Position in the string where last img (either left or right) were encountered. @@ -643,7 +646,8 @@ SGUIText CGUI::GenerateText(const CGUIString &string, // Width and height of all text calls generated. string.GenerateTextCall(Feedback, Font, - string.m_Words[i], string.m_Words[i+1]); + string.m_Words[i], string.m_Words[i+1], + FirstLine); // Loop through our images queues, to see if images has been added. @@ -758,7 +762,8 @@ SGUIText CGUI::GenerateText(const CGUIString &string, // we want them to be reported in the final GenerateTextCall() // so that we don't get duplicates. string.GenerateTextCall(Feedback2, Font, - string.m_Words[j], string.m_Words[j+1]); + string.m_Words[j], string.m_Words[j+1], + FirstLine); // Append X value. x += Feedback2.m_Size.cx; @@ -788,7 +793,7 @@ SGUIText CGUI::GenerateText(const CGUIString &string, // Defaults string.GenerateTextCall(Feedback2, Font, string.m_Words[j], string.m_Words[j+1], - pObject); + FirstLine, pObject); // Iterate all and set X/Y values // Since X values are not set, we need to make an internal @@ -856,6 +861,8 @@ SGUIText CGUI::GenerateText(const CGUIString &string, // Update height of all Text.m_Size.cy = MAX(Text.m_Size.cy, y+BufferZone); + FirstLine = false; + // Now if we entered as from = i, then we want // i being one minus that, so that it will become // the same i in the next loop. The difference is that diff --git a/source/gui/GUItext.cpp b/source/gui/GUItext.cpp index b01f339406..870ad4cfc6 100755 --- a/source/gui/GUItext.cpp +++ b/source/gui/GUItext.cpp @@ -33,7 +33,8 @@ void CGUIString::SFeedback::Reset() void CGUIString::GenerateTextCall(SFeedback &Feedback, const CStr& DefaultFont, - const int &from, const int &to, + const int &from, const int &to, + const bool FirstLine, const IGUIObject *pObject) const { // Reset width and height, because they will be determined with incrementation @@ -199,6 +200,10 @@ void CGUIString::GenerateTextCall(SFeedback &Feedback, int cx, cy; CFont font (TextCall.m_Font); font.CalculateStringSize(TextCall.m_String, cx, cy); + // For anything other than the first line, the line spacing + // needs to be considered rather than just the height of the text + if (! FirstLine) + cy = font.GetLineSpacing(); size.cx = (float)cx; size.cy = (float)cy; diff --git a/source/gui/GUItext.h b/source/gui/GUItext.h index 277ac9366d..c31b7e3c73 100755 --- a/source/gui/GUItext.h +++ b/source/gui/GUItext.h @@ -276,6 +276,7 @@ public: * @param DefaultFont Default Font * @param from From character n, * @param to to chacter n. + * @param FirstLine Whether this is the first line of text, to calculate its height correctly * * pObject Only for Error outputting, optional! If NULL * then no Errors will be reported! Useful when you need @@ -285,6 +286,7 @@ public: void GenerateTextCall(SFeedback &Feedback, const CStr& DefaultFont, const int &from, const int &to, + const bool FirstLine, const IGUIObject *pObject=NULL) const; /** diff --git a/source/lib/res/unifont.cpp b/source/lib/res/unifont.cpp index 9b3c2fc1ba..be9d90e228 100755 --- a/source/lib/res/unifont.cpp +++ b/source/lib/res/unifont.cpp @@ -1,5 +1,5 @@ /* -$Id: unifont.cpp,v 1.14 2004/08/27 22:07:34 philip Exp $ +$Id: unifont.cpp,v 1.15 2004/09/04 20:34:57 philip Exp $ Unicode OpenGL texture font @@ -34,11 +34,14 @@ glyphmap_id* BoundGlyphs = NULL; struct UniFont { - Handle ht; // handle to font texture - glyphmap_id* glyphs_id; + Handle ht; // Handle to font texture + + glyphmap_id* glyphs_id; // Stored as pointers to keep the struct's size down. (sizeof(std::map)==12, though that's probably not enough to matter) glyphmap_size* glyphs_size; + uint ListBase; int LineSpacing; + int Height; // of a capital letter, roughly }; H_TYPE_DEFINE(UniFont); @@ -100,6 +103,11 @@ static int UniFont_reload(UniFont* f, const char* fn, Handle UNUSEDPARAM(h)) FNTStream >> f->LineSpacing; + if (Version >= 101) + FNTStream >> f->Height; + else + f->Height = 0; + f->ListBase = glGenLists(NumGlyphs); if (f->ListBase == 0) // My Voodoo2 drivers didn't support display lists (although I'd be surprised if they got this far) { @@ -109,8 +117,8 @@ static int UniFont_reload(UniFont* f, const char* fn, Handle UNUSEDPARAM(h)) for (int i = 0; i < NumGlyphs; ++i) { - int Codepoint, TextureX, TextureY, Width, Height, OffsetX, OffsetY, Advance; - FNTStream >> Codepoint >> TextureX >> TextureY >> Width >> Height >> OffsetX >> OffsetY >> Advance; + int Codepoint, TextureX, TextureY, Width, Height, OffsetX, OffsetY, Advance; + FNTStream >> Codepoint>>TextureX>>TextureY>>Width>>Height>>OffsetX>>OffsetY>>Advance; if (Codepoint > 0xffff) { @@ -118,11 +126,23 @@ static int UniFont_reload(UniFont* f, const char* fn, Handle UNUSEDPARAM(h)) continue; } + if (Version < 101 && Codepoint == 'I') + { + f->Height = Height; + } + GLfloat u = (GLfloat)TextureX / (GLfloat)TextureWidth; GLfloat v = (GLfloat)TextureY / (GLfloat)TextureHeight; GLfloat w = (GLfloat)Width / (GLfloat)TextureWidth; GLfloat h = (GLfloat)Height / (GLfloat)TextureHeight; + /* + + It might be better to use vertex arrays instead of display lists, + but this works well enough for now. + + */ + glNewList(f->ListBase+i, GL_COMPILE); glBegin(GL_QUADS); glTexCoord2f(u, v); glVertex2i(OffsetX, -OffsetY); @@ -137,6 +157,8 @@ static int UniFont_reload(UniFont* f, const char* fn, Handle UNUSEDPARAM(h)) (*f->glyphs_size)[(wchar_t)Codepoint] = Advance; } + assert(f->Height); // Ensure the height has been found (which should always happen if the font includes an 'I') + // Load glyph texture std::string FilenameTex = FilenameBase+".tga"; const char* tex_fn = FilenameTex.c_str(); @@ -184,16 +206,16 @@ int unifont_linespacing(const Handle h) void glwprintf(const wchar_t* fmt, ...) { - va_list args; const int buf_size = 1024; wchar_t buf[buf_size]; + va_list args; va_start(args, fmt); if (vswprintf(buf, buf_size-1, fmt, args) < 0) debug_out("glwprintf failed (buffer size exceeded?)\n"); va_end(args); - // Make sure there's always NULL termination + // Make sure there's always null termination buf[buf_size-1] = 0; assert(BoundGlyphs != NULL); // You always need to bind something first @@ -211,11 +233,11 @@ void glwprintf(const wchar_t* fmt, ...) if (it == BoundGlyphs->end()) // Missing the missing glyph symbol - give up { - debug_out("Missing the missing glyph in a unifont!\n"); + debug_warn("Missing the missing glyph in a unifont!\n"); return; } - buf[i] = (*it).second; // Replace with the display list offset + buf[i] = it->second; // Replace with the display list offset } // 0 glyphs -> nothing to do (avoid BoundsChecker warning) @@ -232,7 +254,7 @@ int unifont_stringsize(const Handle h, const char* text, int& width, int& height H_DEREF(h, UniFont, f); width = 0; - height = f->LineSpacing; + height = f->Height; size_t len = strlen(text); @@ -245,11 +267,11 @@ int unifont_stringsize(const Handle h, const char* text, int& width, int& height if (it == f->glyphs_size->end()) // Missing the missing glyph symbol - give up { - debug_out("Missing the missing glyph in a unifont!\n"); + debug_warn("Missing the missing glyph in a unifont!\n"); return 0; } - width += (*it).second; // Add the character's advance distance + width += it->second; // Add the character's advance distance } return 0; diff --git a/source/lib/res/unifont.h b/source/lib/res/unifont.h index 7bef810d46..eb3077af35 100755 --- a/source/lib/res/unifont.h +++ b/source/lib/res/unifont.h @@ -1,4 +1,4 @@ -// $Id: unifont.h,v 1.4 2004/07/13 22:47:20 philip Exp $ +// $Id: unifont.h,v 1.5 2004/09/04 20:34:57 philip Exp $ #ifndef __UNIFONT_H__ #define __UNIFONT_H__ @@ -9,17 +9,17 @@ // Load and return a handle to the font defined // in fn+".fnt" with texture fn+".tga" -extern Handle unifont_load(const char* fn, int scope = RES_STATIC); +Handle unifont_load(const char* fn, int scope = RES_STATIC); // Release a handle to a previously loaded font int unifont_unload(Handle& h); // Use the font referenced by h for all subsequent glwprintf() calls. // Must be called before any glwprintf(). -extern int unifont_bind(Handle h); +int unifont_bind(Handle h); // Output text at current OpenGL modelview pos. -extern void glwprintf(const wchar_t* fmt, ...); +void glwprintf(const wchar_t* fmt, ...); /* glwprintf assumes an environment roughly like: @@ -34,8 +34,9 @@ extern void glwprintf(const wchar_t* fmt, ...); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); */ -// Intended for the GUI (hence ASCIIness) -extern int unifont_stringsize(const Handle h, const char* text, int& width, int& height); +// Intended for the GUI (hence ASCIIness). 'height' is roughly the height of +// a capital letter, for use when aligning text in an aesthetically pleasing way. +int unifont_stringsize(const Handle h, const char* text, int& width, int& height); // Return spacing in pixels from one line of text to the next int unifont_linespacing(const Handle h);