https://github.com/libsdl-org/Maelstrom/commit/0a46460971ddaf973c23dac409dfc611dae46b51
From 0a46460971ddaf973c23dac409dfc611dae46b51 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Fri, 28 Oct 2011 19:24:33 -0400
Subject: [PATCH] Moved the label into the core UI elements and it uses the
UIManager text interfaces. Moved the font/text hashing into MaelstromUI.
---
MaelstromUI.cpp | 94 ++++++++++++++++++-
MaelstromUI.h | 8 +-
Makefile.am | 2 -
UIDialogLabel.cpp | 3 +-
UIDialogLabel.h | 2 +-
maclib/Mac_FontServ.cpp | 35 +------
maclib/Mac_FontServ.h | 3 -
netlogic/game.cpp | 15 ++-
netlogic/game.h | 13 ++-
screenlib/Makefile.am | 2 +
.../UIElementLabel.cpp | 69 +++++++-------
.../UIElementLabel.h | 9 +-
screenlib/UIElementLine.h | 2 +-
screenlib/UIElementRect.h | 2 +-
screenlib/UIElementTexture.h | 2 +-
screenlib/UIFontInterface.h | 14 +--
16 files changed, 169 insertions(+), 106 deletions(-)
rename UIElementLabel.cpp => screenlib/UIElementLabel.cpp (62%)
rename UIElementLabel.h => screenlib/UIElementLabel.h (86%)
diff --git a/MaelstromUI.cpp b/MaelstromUI.cpp
index c160fafb..0afbc831 100644
--- a/MaelstromUI.cpp
+++ b/MaelstromUI.cpp
@@ -14,8 +14,26 @@
#include "UIElementTitle.h"
+static void
+hash_nuke_string_font(const void *key, const void *value, void *data)
+{
+ SDL_free((char*)key);
+ fontserv->FreeFont((MFont *)value);
+}
+
+static void
+hash_nuke_string_text(const void *key, const void *value, void *data)
+{
+ SDL_free((char*)key);
+ fontserv->FreeText((SDL_Texture *)value);
+}
+
MaelstromUI::MaelstromUI(FrameBuf *screen) : UIManager(screen)
{
+ /* Create our font hashtables */
+ m_fonts = hash_create(screen, hash_hash_string, hash_keymatch_string, hash_nuke_string_font);
+ m_strings = hash_create(screen, hash_hash_string, hash_keymatch_string, hash_nuke_string_text);
+
/* Load up our UI templates */
SetLoadPath("UI");
LoadTemplates("UITemplates.xml");
@@ -23,17 +41,89 @@ MaelstromUI::MaelstromUI(FrameBuf *screen) : UIManager(screen)
MaelstromUI::~MaelstromUI()
{
+ hash_destroy(m_fonts);
+ hash_destroy(m_strings);
+}
+
+MFont *
+MaelstromUI::GetFont(const char *fontName, int fontSize)
+{
+ char *key, *keycopy;
+ int keysize;
+ MFont *font;
+
+ keysize = strlen(fontName)+1+2+1;
+ key = SDL_stack_alloc(char, keysize);
+ sprintf(key, "%s:%d", fontName, fontSize);
+ if (hash_find(m_fonts, key, (const void**)&font)) {
+ SDL_stack_free(key);
+ return font;
+ }
+
+ font = fontserv->NewFont(fontName, fontSize);
+ if (font) {
+ /* Add it to our cache */
+ hash_insert(m_fonts, SDL_strdup(key), font);
+ }
+ SDL_stack_free(key);
+
+ return font;
}
SDL_Texture *
-MaelstromUI::CreateText(const char *text, const char *fontName, int fontSize, UIFontStyle fontStyle)
+MaelstromUI::CreateText(const char *text, const char *fontName, int fontSize, UIFontStyle fontStyle, Uint32 color)
{
+ MFont *font;
+ Uint8 style;
+ char *key, *keycopy;
+ int keysize;
+ SDL_Texture *texture;
+
+ /* First see if we can find it in our cache */
+ keysize = strlen(fontName)+1+2+1+1+1+8+1+strlen(text)+1;
+ key = SDL_stack_alloc(char, keysize);
+ sprintf(key, "%s:%d:%c:%8.8x:%s", fontName, fontSize, '0'+fontStyle, color, text);
+ if (hash_find(m_strings, key, (const void**)&texture)) {
+ SDL_stack_free(key);
+ return texture;
+ }
+
+ font = GetFont(fontName, fontSize);
+ if (!font) {
+ SetError("Couldn't find font %s size %d", fontName, fontSize);
+ return NULL;
+ }
+
+ switch (fontStyle) {
+ case UIFONT_STYLE_NORMAL:
+ style = STYLE_NORM;
+ break;
+ case UIFONT_STYLE_BOLD:
+ style = STYLE_BOLD;
+ break;
+ case UIFONT_STYLE_UNDERLINE:
+ style = STYLE_ULINE;
+ break;
+ case UIFONT_STYLE_ITALIC:
+ style = STYLE_ITALIC;
+ break;
+ }
+
+ texture = fontserv->TextImage(text, font, style, color);
+ if (texture) {
+ /* Add it to our cache */
+ hash_insert(m_strings, SDL_strdup(key), texture);
+ }
+ SDL_stack_free(key);
+
+ return texture;
}
void
MaelstromUI::FreeText(SDL_Texture *texture)
{
- fontserv->FreeText(texture);
+ /* We'll likely be asked for this again soon, leave it alone */
+ return;
}
void
diff --git a/MaelstromUI.h b/MaelstromUI.h
index b1590fa6..401e6947 100644
--- a/MaelstromUI.h
+++ b/MaelstromUI.h
@@ -1,5 +1,5 @@
-#include "screenlib/UIManager.h"
+#include "Maelstrom_Globals.h"
class HashTable;
@@ -12,7 +12,7 @@ class MaelstromUI : public UIManager
//
// UIFontInterface
//
- virtual SDL_Texture *CreateText(const char *text, const char *fontName, int fontSize, UIFontStyle fontStyle);
+ virtual SDL_Texture *CreateText(const char *text, const char *fontName, int fontSize, UIFontStyle fontStyle, Uint32 color);
virtual void FreeText(SDL_Texture *texture);
//
@@ -29,4 +29,8 @@ class MaelstromUI : public UIManager
protected:
HashTable *m_fonts;
+ HashTable *m_strings;
+
+protected:
+ MFont *GetFont(const char *fontName, int fontSize);
};
diff --git a/Makefile.am b/Makefile.am
index e685d417..af7fafae 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -40,8 +40,6 @@ Maelstrom_SOURCES = \
UIElementIcon.h \
UIElementKeyButton.cpp \
UIElementKeyButton.h \
- UIElementLabel.cpp \
- UIElementLabel.h \
UIElementSprite.cpp \
UIElementSprite.h \
UIElementTitle.cpp \
diff --git a/UIDialogLabel.cpp b/UIDialogLabel.cpp
index 3fdb179c..5e53b14c 100644
--- a/UIDialogLabel.cpp
+++ b/UIDialogLabel.cpp
@@ -8,6 +8,7 @@ UIElementType UIDialogLabel::s_elementType;
UIDialogLabel::UIDialogLabel(UIPanel *panel, const char *name) :
UIElementLabel(panel, name)
{
- m_font = fonts[CHICAGO_12];
+ m_fontName = SDL_strdup("Chicago");
+ m_fontSize = 12;
m_color = m_screen->MapRGB(0x00, 0x00, 0x00);
}
diff --git a/UIDialogLabel.h b/UIDialogLabel.h
index bdfe2d09..3f0ba8dd 100644
--- a/UIDialogLabel.h
+++ b/UIDialogLabel.h
@@ -1,7 +1,7 @@
#ifndef _UIDialogLabel_h
#define _UIDialogLabel_h
-#include "UIElementLabel.h"
+#include "screenlib/UIElementLabel.h"
class UIDialogLabel : public UIElementLabel
{
diff --git a/maclib/Mac_FontServ.cpp b/maclib/Mac_FontServ.cpp
index b236539d..cfd97e77 100644
--- a/maclib/Mac_FontServ.cpp
+++ b/maclib/Mac_FontServ.cpp
@@ -29,7 +29,6 @@
#include "SDL_types.h"
#include "bitesex.h"
-#include "hashtable.h"
#include "Mac_FontServ.h"
#define copy_short(S, D) memcpy(&S, D, 2); D += 2;
@@ -70,20 +69,10 @@ struct FOND {
/* The Kerning Table */
};
-static void
-hash_nuke_string_texture(const void *key, const void *value, void *data)
-{
- FrameBuf *screen = (FrameBuf *)data;
-
- delete[] (char*)key;
- screen->FreeImage((SDL_Texture *)value);
-}
-
FontServ:: FontServ(FrameBuf *_screen, const char *fontfile)
{
screen = _screen;
fontres = new Mac_Resource(fontfile);
- strings = hash_create(screen, hash_hash_string, hash_keymatch_string, hash_nuke_string_texture);
if ( fontres->Error() ) {
SetError("Couldn't load resources from %s", fontfile);
@@ -98,8 +87,6 @@ FontServ:: FontServ(FrameBuf *_screen, const char *fontfile)
FontServ:: ~FontServ()
{
- hash_destroy(strings);
-
delete fontres;
}
@@ -294,14 +281,6 @@ FontServ:: TextImage(const char *text, MFont *font, Uint8 style, SDL_Color fg)
int ascii, i, y;
int bit;
- /* First see if we can find it in our cache */
- keysize = strlen(font->name)+1+2+1+1+1+6+1+strlen(text)+1;
- key = SDL_stack_alloc(char, keysize);
- sprintf(key, "%s:%d:%c:%2.2x%2.2x%2.2x:%s", font->name, font->ptsize, '0'+style, fg.r, fg.g, fg.b, text);
- if (hash_find(strings, key, (const void**)&image)) {
- return image;
- }
-
switch (style) {
case STYLE_NORM: bold_offset = 0;
break;
@@ -391,7 +370,7 @@ FontServ:: TextImage(const char *text, MFont *font, Uint8 style, SDL_Color fg)
y*(font->header)->rowWords;
for ( bit = 0; bit<glyph_width; ++bit ) {
bitmap[dst_offset+bit+boldness] |=
- GETBIT(src_scanline, glyph_line_offset+bit)*color;
+ GETBIT(src_scanline, glyph_line_offset+bit)*0xFFFFFFFF;
}
}
#ifdef WIDE_BOLD
@@ -405,19 +384,14 @@ FontServ:: TextImage(const char *text, MFont *font, Uint8 style, SDL_Color fg)
y = (height-(font->header)->descent+1);
bit_offset = (y*width);
for ( bit=0; bit<width; ++bit )
- bitmap[bit_offset++] = color;
+ bitmap[bit_offset++] = 0xFFFFFFFF;
}
/* Create the image */
image = screen->LoadImage(width, height, bitmap);
delete[] bitmap;
SDL_SetTextureBlendMode(image, SDL_BLENDMODE_BLEND);
-
- /* Add it to our cache */
- keycopy = new char[keysize];
- strcpy(keycopy, key);
- hash_insert(strings, keycopy, image);
- SDL_stack_free(key);
+ SDL_SetTextureColorMod(image, fg.r, fg.g, fg.b);
return(image);
}
@@ -425,6 +399,5 @@ FontServ:: TextImage(const char *text, MFont *font, Uint8 style, SDL_Color fg)
void
FontServ:: FreeText(SDL_Texture *text)
{
- /* We'll likely be asked for this again soon, leave it alone */
- return;
+ screen->FreeImage(text);
}
diff --git a/maclib/Mac_FontServ.h b/maclib/Mac_FontServ.h
index ee8abd05..d0df3fc5 100644
--- a/maclib/Mac_FontServ.h
+++ b/maclib/Mac_FontServ.h
@@ -85,8 +85,6 @@ typedef struct MFont {
Mac_ResData *nfnt;
} MFont;
-struct HashTable;
-
class FontServ {
public:
@@ -137,7 +135,6 @@ class FontServ {
private:
FrameBuf *screen;
Mac_Resource *fontres;
- HashTable *strings;
/* Useful for getting error feedback */
void SetError(const char *fmt, ...) {
diff --git a/netlogic/game.cpp b/netlogic/game.cpp
index af9b818f..6d338dcf 100644
--- a/netlogic/game.cpp
+++ b/netlogic/game.cpp
@@ -6,8 +6,7 @@
#include "make.h"
#include "load.h"
#include "game.h"
-#include "../UIElementIcon.h"
-#include "../UIElementLabel.h"
+#include "../screenlib/UIElementLabel.h"
#include "../screenlib/UIElementRect.h"
@@ -191,14 +190,14 @@ GamePanelDelegate::OnLoad()
for (i = 0; i < SDL_arraysize(m_multiplier); ++i) {
sprintf(name, "multiplier%d", 2+i);
- m_multiplier[i] = m_panel->GetElement<UIElementIcon>(name);
+ m_multiplier[i] = m_panel->GetElement<UIElement>(name);
}
- m_autofire = m_panel->GetElement<UIElementIcon>("autofire");
- m_airbrakes = m_panel->GetElement<UIElementIcon>("airbrakes");
- m_lucky = m_panel->GetElement<UIElementIcon>("lucky");
- m_triplefire = m_panel->GetElement<UIElementIcon>("triplefire");
- m_longfire = m_panel->GetElement<UIElementIcon>("longfire");
+ m_autofire = m_panel->GetElement<UIElement>("autofire");
+ m_airbrakes = m_panel->GetElement<UIElement>("airbrakes");
+ m_lucky = m_panel->GetElement<UIElement>("lucky");
+ m_triplefire = m_panel->GetElement<UIElement>("triplefire");
+ m_longfire = m_panel->GetElement<UIElement>("longfire");
m_multiplayerCaption = m_panel->GetElement<UIElementLabel>("multiplayer_caption");
m_multiplayerColor = m_panel->GetElement<UIElementRect>("multiplayer_color");
diff --git a/netlogic/game.h b/netlogic/game.h
index 3f6a6417..19058d83 100644
--- a/netlogic/game.h
+++ b/netlogic/game.h
@@ -3,7 +3,6 @@
#define _game_h
class UIElement;
-class UIElementIcon;
class UIElementLabel;
class UIElementRect;
@@ -33,12 +32,12 @@ class GamePanelDelegate : public UIPanelDelegate
UIElementLabel *m_lives;
UIElementLabel *m_bonus;
- UIElementIcon *m_multiplier[4];
- UIElementIcon *m_autofire;
- UIElementIcon *m_airbrakes;
- UIElementIcon *m_lucky;
- UIElementIcon *m_triplefire;
- UIElementIcon *m_longfire;
+ UIElement *m_multiplier[4];
+ UIElement *m_autofire;
+ UIElement *m_airbrakes;
+ UIElement *m_lucky;
+ UIElement *m_triplefire;
+ UIElement *m_longfire;
UIElementLabel *m_multiplayerCaption;
UIElementRect *m_multiplayerColor;
diff --git a/screenlib/Makefile.am b/screenlib/Makefile.am
index b2c4b0e2..adb6dfb9 100644
--- a/screenlib/Makefile.am
+++ b/screenlib/Makefile.am
@@ -11,6 +11,8 @@ libSDLscreen_a_SOURCES = \
UIElement.h \
UIElementButton.cpp \
UIElementButton.h \
+ UIElementLabel.cpp \
+ UIElementLabel.h \
UIElementLine.cpp \
UIElementLine.h \
UIElementRect.cpp \
diff --git a/UIElementLabel.cpp b/screenlib/UIElementLabel.cpp
similarity index 62%
rename from UIElementLabel.cpp
rename to screenlib/UIElementLabel.cpp
index 9402b466..1f2726ea 100644
--- a/UIElementLabel.cpp
+++ b/screenlib/UIElementLabel.cpp
@@ -8,8 +8,9 @@ UIElementType UIElementLabel::s_elementType;
UIElementLabel::UIElementLabel(UIPanel *panel, const char *name) :
UIElement(panel, name)
{
- m_font = NULL;
- m_style = STYLE_NORM;
+ m_fontName = NULL;
+ m_fontSize = 0;
+ m_fontStyle = UIFONT_STYLE_NORMAL;
m_color = m_screen->MapRGB(0xFF, 0xFF, 0xFF);
m_text = NULL;
m_texture = NULL;
@@ -17,26 +18,27 @@ UIElementLabel::UIElementLabel(UIPanel *panel, const char *name) :
UIElementLabel::~UIElementLabel()
{
+ if (m_fontName) {
+ SDL_free(m_fontName);
+ }
if (m_text) {
- delete[] m_text;
+ SDL_free(m_text);
}
if (m_texture) {
- fontserv->FreeText(m_texture);
+ m_panel->GetUI()->FreeText(m_texture);
}
}
-static Uint8 ParseStyle(const char *text)
+static UIFontStyle ParseStyle(const char *text)
{
- Uint8 style = STYLE_NORM;
-
if (strcasecmp(text, "BOLD") == 0) {
- style = STYLE_BOLD;
+ return UIFONT_STYLE_BOLD;
} else if (strcasecmp(text, "UNDERLINE") == 0) {
- style = STYLE_ULINE;
+ return UIFONT_STYLE_UNDERLINE;
} else if (strcasecmp(text, "ITALIC") == 0) {
- style = STYLE_ITALIC;
+ return UIFONT_STYLE_UNDERLINE;
}
- return style;
+ return UIFONT_STYLE_NORMAL;
}
bool
@@ -44,8 +46,6 @@ UIElementLabel::Load(rapidxml::xml_node<> *node, const UITemplates *templates)
{
rapidxml::xml_node<> *child;
rapidxml::xml_attribute<> *attr;
- const char *fontName = NULL;
- int fontSize = 0;
if (!UIElement::Load(node, templates)) {
return false;
@@ -53,28 +53,20 @@ UIElementLabel::Load(rapidxml::xml_node<> *node, const UITemplates *templates)
attr = node->first_attribute("fontName", 0, false);
if (attr) {
- fontName = attr->value();
+ if (m_fontName) {
+ SDL_free(m_fontName);
+ }
+ m_fontName = SDL_strdup(attr->value());
}
attr = node->first_attribute("fontSize", 0, false);
if (attr) {
- fontSize = SDL_atoi(attr->value());
- }
-
- if (fontName && fontSize) {
- m_font = fontserv->NewFont(fontName, fontSize);
- if (!m_font) {
- SetError("Element 'Label' couldn't find font %s:%d", fontName, fontSize);
- return false;
- }
- } else if (!m_font) {
- SetError("Element 'Label' missing attribute 'fontName' or 'fontSize'");
- return false;
+ m_fontSize = SDL_atoi(attr->value());
}
attr = node->first_attribute("fontStyle", 0, false);
if (attr) {
- m_style = ParseStyle(attr->value());
+ m_fontStyle = ParseStyle(attr->value());
}
child = node->first_node("color", 0, false);
@@ -93,20 +85,27 @@ UIElementLabel::Load(rapidxml::xml_node<> *node, const UITemplates *templates)
void
UIElementLabel::SetText(const char *text)
{
- if (m_text && strcmp(text, m_text) == 0) {
+ SDL_Texture *texture;
+
+ if (!m_fontName || !m_fontSize) {
+ SetError("You must set a font first");
+ return;
+ }
+
+ if (m_text && SDL_strcmp(text, m_text) == 0) {
return;
}
if (m_text) {
- delete[] m_text;
+ SDL_free(m_text);
}
if (m_texture) {
- fontserv->FreeText(m_texture);
+ m_panel->GetUI()->FreeText(m_texture);
}
- m_text = new char[strlen(text)+1];
- strcpy(m_text, text);
- m_texture = fontserv->TextImage(m_text, m_font, m_style, m_color);
+ m_text = SDL_strdup(text);
+ m_texture = m_panel->GetUI()->CreateText(m_text, m_fontName, m_fontSize, m_fontStyle, m_color);
+
m_rect.w = m_screen->GetImageWidth(m_texture);
m_rect.h = m_screen->GetImageHeight(m_texture);
CalculateAnchor();
@@ -125,9 +124,9 @@ UIElementLabel::SetTextColor(Uint8 R, Uint8 G, Uint8 B)
if (m_text) {
if (m_texture) {
- fontserv->FreeText(m_texture);
+ m_panel->GetUI()->FreeText(m_texture);
}
- m_texture = fontserv->TextImage(m_text, m_font, m_style, m_color);
+ m_texture = m_panel->GetUI()->CreateText(m_text, m_fontName, m_fontSize, m_fontStyle, m_color);
}
}
diff --git a/UIElementLabel.h b/screenlib/UIElementLabel.h
similarity index 86%
rename from UIElementLabel.h
rename to screenlib/UIElementLabel.h
index 523e8b3a..9ddd574d 100644
--- a/UIElementLabel.h
+++ b/screenlib/UIElementLabel.h
@@ -1,9 +1,9 @@
#ifndef _UIElementLabel_h
#define _UIElementLabel_h
-#include "screenlib/UIElement.h"
+#include "UIElement.h"
+#include "UIFontInterface.h"
-class MFont;
class UIElementLabel : public UIElement
{
@@ -23,8 +23,9 @@ class UIElementLabel : public UIElement
virtual void Draw();
protected:
- MFont *m_font;
- Uint8 m_style;
+ char *m_fontName;
+ int m_fontSize;
+ UIFontStyle m_fontStyle;
Uint32 m_color;
char *m_text;
SDL_Texture *m_texture;
diff --git a/screenlib/UIElementLine.h b/screenlib/UIElementLine.h
index 6581e630..1e3dd2c3 100644
--- a/screenlib/UIElementLine.h
+++ b/screenlib/UIElementLine.h
@@ -1,7 +1,7 @@
#ifndef _UIElementLine_h
#define _UIElementLine_h
-#include "screenlib/UIElement.h"
+#include "UIElement.h"
class UIElementLine : public UIElement
diff --git a/screenlib/UIElementRect.h b/screenlib/UIElementRect.h
index 9934de8d..a03c20c0 100644
--- a/screenlib/UIElementRect.h
+++ b/screenlib/UIElementRect.h
@@ -1,7 +1,7 @@
#ifndef _UIElementRect_h
#define _UIElementRect_h
-#include "screenlib/UIElement.h"
+#include "UIElement.h"
class UIElementRect : public UIElement
diff --git a/screenlib/UIElementTexture.h b/screenlib/UIElementTexture.h
index 3de4bbd8..c4d6d87a 100644
--- a/screenlib/UIElementTexture.h
+++ b/screenlib/UIElementTexture.h
@@ -1,7 +1,7 @@
#ifndef _UIElementTexture_h
#define _UIElementTexture_h
-#include "screenlib/UIElement.h"
+#include "UIElement.h"
class UIElementTexture : public UIElement
diff --git a/screenlib/UIFontInterface.h b/screenlib/UIFontInterface.h
index 06e0e91e..75b1929e 100644
--- a/screenlib/UIFontInterface.h
+++ b/screenlib/UIFontInterface.h
@@ -23,19 +23,19 @@
#ifndef _UIFontInterface_h
#define _UIFontInterface_h
+#include "SDL.h"
+
enum UIFontStyle {
- UIFONT_STYLE_NORMAL = 0x00,
- UIFONT_STYLE_BOLD = 0x01,
- UIFONT_STYLE_UNDERLINE = 0x02,
- UIFONT_STYLE_ITALIC = 0x04,
+ UIFONT_STYLE_NORMAL,
+ UIFONT_STYLE_BOLD,
+ UIFONT_STYLE_UNDERLINE,
+ UIFONT_STYLE_ITALIC
};
-struct SDL_Texture;
-
class UIFontInterface
{
public:
- virtual SDL_Texture *CreateText(const char *text, const char *fontName, int fontSize, UIFontStyle fontStyle) = 0;
+ virtual SDL_Texture *CreateText(const char *text, const char *fontName, int fontSize, UIFontStyle fontStyle, Uint32 color) = 0;
virtual void FreeText(SDL_Texture *texture) = 0;
};