[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Pingus-CVS] r3867 - trunk/pingus/src
From: |
grumbel at BerliOS |
Subject: |
[Pingus-CVS] r3867 - trunk/pingus/src |
Date: |
Fri, 18 Jul 2008 21:06:45 +0200 |
Author: grumbel
Date: 2008-07-18 21:06:44 +0200 (Fri, 18 Jul 2008)
New Revision: 3867
Modified:
trunk/pingus/src/font.cpp
trunk/pingus/src/font.hpp
trunk/pingus/src/font_description.cpp
trunk/pingus/src/font_description.hpp
trunk/pingus/src/fonts.cpp
Log:
Rewrote font system, now utf8 capable, proper fonts still missing, so text will
not be displayed correctly
Modified: trunk/pingus/src/font.cpp
===================================================================
--- trunk/pingus/src/font.cpp 2008-07-18 19:05:39 UTC (rev 3866)
+++ trunk/pingus/src/font.cpp 2008-07-18 19:06:44 UTC (rev 3867)
@@ -16,144 +16,48 @@
#include <iostream>
#include <vector>
+#include <map>
#include "SDL.h"
#include "SDL_image.h"
#include "font.hpp"
#include "surface.hpp"
#include "line_iterator.hpp"
+#include "utf8_iterator.hpp"
#include "font_description.hpp"
#include "display/framebuffer.hpp"
#include "display/display.hpp"
-static bool vline_empty(SDL_Surface* surface, int x, Uint8 threshold)
-{
- if (x >= surface->w)
- return true;
-
- Uint8* pixels = (Uint8*)surface->pixels;
-
- for(int y = 0; y < surface->h; ++y)
- {
- const Uint8& p = pixels[surface->pitch*y +
x*surface->format->BytesPerPixel + 3];
- if (p > threshold)
- {
- return false;
- }
- }
- return true;
-}
-
class FontImpl
{
public:
FramebufferSurface framebuffer_surface;
- Rect chrs[256];
- int space_length;
- float char_spacing;
- float vertical_spacing;
+ typedef std::map<uint32_t, GlyphDescription> Glyphs;
+ Glyphs glyphs; // FIXME: Use a hashmap or something else faster then a map
+ int space_length;
+ float char_spacing;
+ float vertical_spacing;
+ int size;
FontImpl(const FontDescription& desc)
: space_length(desc.space_length),
- char_spacing(desc.char_spacing)
+ char_spacing(desc.char_spacing),
+ size(desc.size)
{
- //std::cout << "desc.image: " << desc.image << std::endl;
- //std::cout << "desc.space: " << desc.space_length << std::endl;
- //std::cout << "Characters: " << desc.characters << std::endl;
+ framebuffer_surface =
Display::get_framebuffer().create_surface(Surface(desc.image));
- Surface software_surface(desc.image);
- SDL_Surface* surface = software_surface.get_surface();
-
- if (!surface)
+ if (!framebuffer_surface)
{
std::cout << "IMG: " << desc.image.str() << std::endl;
- assert(surface);
+ assert(false);
}
- vertical_spacing = (desc.vertical_spacing == -1) ? surface->h :
desc.vertical_spacing;
-
- if (surface->format->BitsPerPixel != 32)
+ vertical_spacing = (desc.vertical_spacing == -1.0f) ? size :
desc.vertical_spacing;
+
+ // Copyh Unicode -> Glyph mapping
+ for(std::vector<GlyphDescription>::const_iterator i = desc.glyphs.begin();
i != desc.glyphs.end(); ++i)
{
- std::cout << "Error: '" << desc.pathname.str() << "' invalid, fonts
need to be RGBA, but is "
- << surface->format->BitsPerPixel << "bpp" << std::endl;
- assert(0);
+ glyphs[i->unicode] = *i;
}
-
- SDL_LockSurface(surface);
-
- if (!desc.monospace)
- {
- int first = -1; // -1 signals no character start found yet
- int idx = 0;
- for(int x = 0; x <= surface->w; ++x) // '<=' so we scan one past
- // the last line, to catch
- // the last character
- {
- if (!vline_empty(surface, x, desc.alpha_threshold))
- { // line contains a character
- if (first == -1)
- { // found the start of a character
- first = x;
- }
- else
- {
- // do nothing and continue to search for an end
- }
- }
- else
- { // line doesn't contain a character
- if (first != -1)
- { // we have a start and a end, so lets construct a char
-
- if (idx < int(desc.characters.size()))
- {
- //std::cout << idx << " '" << desc.characters[idx] <<
"' "
- // << " glyph: " << first << " - " << x <<
std::endl;
-
- chrs[static_cast<unsigned char>(desc.characters[idx])]
- = Rect(Vector2i(first, 0),
- Size(x - first, surface->h));
- }
- else
- {
- std::cout << "Error: Found more desc.characters then
are mapped" << std::endl;
- }
-
- idx += 1;
- first = -1;
- }
- }
- }
-
- if (idx != int(desc.characters.size()))
- {
- std::cout << "Font: " << desc.image << "\n"
- << " Error: glyphs found: " << idx << ", expected " <<
desc.characters.size() << "\n"
- << " Format: bpp: " <<
int(surface->format->BitsPerPixel) << "\n"
- << " Size: " << surface->w << "x" << surface->h
- // << " RMask: " << hex << surface->format->Rmask << "\n"
- // << " GMask: " << hex << surface->format->Gmask << "\n"
- // << " BMask: " << hex << surface->format->Bmask << "\n"
- // << " AMask: " << hex << surface->format->Amask << "\n"
- << std::endl;
- }
- }
- else // monospace
- {
- assert(surface->w % desc.characters.size() == 0);
-
- space_length = surface->w / desc.characters.size();
-
- for(int i = 0; i < int(desc.characters.size()); ++i)
- {
- chrs[static_cast<unsigned char>(desc.characters[i])]
- = Rect(Vector2i(i * space_length, 0),
- Size(space_length, surface->h));
- }
- }
-
- SDL_UnlockSurface(surface);
-
- framebuffer_surface =
Display::get_framebuffer().create_surface(software_surface);
}
~FontImpl()
@@ -162,6 +66,8 @@
void render(Origin origin, int x, int y_, const std::string& text,
Framebuffer& fb)
{
+ y_ += get_height();
+
float y = float(y_);
// FIXME: only origins top_left, top_right and top_center to work right now
LineIterator it(text);
@@ -178,56 +84,58 @@
float dstx = float(x - offset.x);
float dsty = float(y - offset.y);
- for(std::string::size_type i = 0; i < text.size(); ++i)
+ for(UTF8Iterator i(text); !i.done(); ++i)
{
- if (text[i] == ' ')
+ const uint32_t& unicode = *i;
+
+ Glyphs::iterator it = glyphs.find(unicode);
+ if (it != glyphs.end())
{
- dstx += space_length + char_spacing;
+ const GlyphDescription& glyph = it->second;
+ fb.draw_surface(framebuffer_surface, glyph.rect, Vector2i(dstx,
dsty) + glyph.offset);
+ dstx += glyph.advance + char_spacing;
}
else
{
- Rect& srcrect = chrs[static_cast<unsigned char>(text[i])];
- if (srcrect.get_width() != 0 && srcrect.get_height() != 0)
- {
- fb.draw_surface(framebuffer_surface, srcrect, Vector2i(dstx,
dsty));
- dstx += srcrect.get_width() + char_spacing;
- }
- else
- {
- //std::cout << "Font: character " << static_cast<unsigned
char>(text[i]) << " missing in font" << std::endl;
- }
+ // Draw placeholder char and issue a warning
}
}
}
int get_height() const
{
- return framebuffer_surface.get_height();
+ return size;
}
- int get_width(char idx) const
+ int get_width(uint32_t unicode) const
{
- return chrs[static_cast<unsigned char>(idx)].get_width();
+ Glyphs::const_iterator it = glyphs.find(unicode);
+ if (it != glyphs.end())
+ return it->second.advance;
+ else
+ return 0;
}
int get_width(const std::string& text) const
{
float width = 0.0f;
float last_width = 0;
- for(std::string::size_type i = 0; i < text.size(); ++i)
+ for(UTF8Iterator i(text); !i.done(); ++i)
{
- if (text[i] == ' ')
+ const uint32_t& unicode = *i;
+
+ if (unicode == ' ')
{
width += space_length + char_spacing;
}
- else if (text[i] == '\n')
+ else if (unicode == '\n')
{
last_width = std::max(last_width, width);
width = 0;
}
else
{
- width += chrs[static_cast<unsigned char>(text[i])].get_width() +
char_spacing;
+ width += get_width(unicode) + char_spacing;
}
}
return int(std::max(width, last_width));
@@ -277,10 +185,10 @@
}
int
-Font::get_width(char c) const
+Font::get_width(uint32_t unicode) const
{
if (impl)
- return impl->get_width(c);
+ return impl->get_width(unicode);
else
return 0;
}
Modified: trunk/pingus/src/font.hpp
===================================================================
--- trunk/pingus/src/font.hpp 2008-07-18 19:05:39 UTC (rev 3866)
+++ trunk/pingus/src/font.hpp 2008-07-18 19:06:44 UTC (rev 3867)
@@ -38,9 +38,9 @@
void render(Origin origin, int x, int y, const std::string& text,
Framebuffer& fb);
int get_height() const;
- int get_width(char) const;
- int get_width(const std::string& ) const;
- Size get_size(const std::string& str) const;
+ int get_width(uint32_t unicode) const;
+ int get_width(const std::string& text) const;
+ Size get_size(const std::string& text) const;
Rect bounding_rect(int , int, const std::string& str) const;
private:
Modified: trunk/pingus/src/font_description.cpp
===================================================================
--- trunk/pingus/src/font_description.cpp 2008-07-18 19:05:39 UTC (rev
3866)
+++ trunk/pingus/src/font_description.cpp 2008-07-18 19:06:44 UTC (rev
3867)
@@ -18,13 +18,29 @@
#include "file_reader.hpp"
#include "font_description.hpp"
+
+GlyphDescription::GlyphDescription()
+ : unicode(0), advance(0)
+{
+
+}
+
+GlyphDescription::GlyphDescription(FileReader& reader)
+{
+ int lazy = 0; // FIXME: implement read_uint32
+ reader.read_int("unicode", lazy);
+ unicode = lazy;
+ reader.read_vector2i("offset", offset);
+ reader.read_int("advance", advance);
+ reader.read_rect("rect", rect);
+}
+
FontDescription::FontDescription(const Pathname& pathname_)
: pathname(pathname_)
{
name = "<unknown>";
monospace = false;
space_length = 20;
- alpha_threshold = 0;
char_spacing = 1.0f;
vertical_spacing = -1.0f;
@@ -36,15 +52,23 @@
}
else
{
- reader.read_string("name", name);
- reader.read_path("image", image);
- reader.read_string("characters", characters);
- reader.read_bool("monospace", monospace);
+ reader.read_string("name", name);
+ reader.read_path("image", image);
reader.read_float("char-spacing", char_spacing);
reader.read_float("vertical-spacing", vertical_spacing);
- reader.read_int("space-length", space_length);
- reader.read_int("alpha-threshold", alpha_threshold);
+ reader.read_int("space-length", space_length);
+ reader.read_int("size", size);
+
+ FileReader glyph_section;
+ if (reader.read_section("glyphs", glyph_section))
+ {
+ std::vector<FileReader> glyph_reader = glyph_section.get_sections();
+ for(std::vector<FileReader>::iterator i = glyph_reader.begin(); i !=
glyph_reader.end(); ++i)
+ {
+ glyphs.push_back(GlyphDescription(*i));
+ }
+ }
}
}
-
+
/* EOF */
Modified: trunk/pingus/src/font_description.hpp
===================================================================
--- trunk/pingus/src/font_description.hpp 2008-07-18 19:05:39 UTC (rev
3866)
+++ trunk/pingus/src/font_description.hpp 2008-07-18 19:06:44 UTC (rev
3867)
@@ -18,8 +18,24 @@
#define HEADER_FONT_DESCRIPTION_HPP
#include <string>
+#include "math/vector2i.hpp"
+#include "math/rect.hpp"
#include "pathname.hpp"
+class FileReader;
+
+class GlyphDescription
+{
+public:
+ uint32_t unicode;
+ Vector2i offset;
+ int advance;
+ Rect rect;
+
+ GlyphDescription();
+ GlyphDescription(FileReader& reader);
+};
+
/** */
class FontDescription
{
@@ -40,15 +56,14 @@
float vertical_spacing;
- /** Minimum amount of alpha that is handled as character seperator */
- int alpha_threshold;
+ int size;
/** Characters in the font image */
- std::string characters;
+ std::vector<GlyphDescription> glyphs;
FontDescription(const Pathname& filename);
};
-
+
#endif
/* EOF */
Modified: trunk/pingus/src/fonts.cpp
===================================================================
--- trunk/pingus/src/fonts.cpp 2008-07-18 19:05:39 UTC (rev 3866)
+++ trunk/pingus/src/fonts.cpp 2008-07-18 19:06:44 UTC (rev 3867)
@@ -37,8 +37,8 @@
void
init ()
{
- chalk_large = Resource::load_font("fonts/chalk_large" + std::string("-") +
encoding);
- chalk_normal = Resource::load_font("fonts/chalk_normal" + std::string("-") +
encoding);
+ chalk_large = Resource::load_font("fonts/chalk-40px");
+ chalk_normal = Resource::load_font("fonts/chalk-21px");
chalk_small = Resource::load_font("fonts/chalk_small" + std::string("-") +
encoding);
pingus_small = Resource::load_font("fonts/pingus_small" + std::string("-") +
encoding);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Pingus-CVS] r3867 - trunk/pingus/src,
grumbel at BerliOS <=