From 78c783bb578f348c1e96fbc516bb3c4cdde4bfa0 Mon Sep 17 00:00:00 2001 From: rude Date: Wed, 3 Mar 2010 20:38:21 +0100 Subject: [PATCH] Fixed ImageFont. --- changes.txt | 2 + src/modules/graphics/opengl/ImageFont.cpp | 140 +++++++++------------- src/modules/graphics/opengl/ImageFont.h | 9 +- src/modules/image/ImageData.h | 3 +- 4 files changed, 68 insertions(+), 86 deletions(-) diff --git a/changes.txt b/changes.txt index 7f7a50981..bea50cf22 100644 --- a/changes.txt +++ b/changes.txt @@ -1,6 +1,8 @@ LOVE 0.6.2 ---------- + * Fixed a bug causing ImageFonts to cut off some pixels. + * Fixed a bug where filled rectangles were too small. * Fixed a bug in Image:setFilter where it would switch the parameters. * Fixed a bug in ImageRasterizer where it wasn't using the data. * Image filter and wrap modes now use string constants as well. diff --git a/src/modules/graphics/opengl/ImageFont.cpp b/src/modules/graphics/opengl/ImageFont.cpp index c74ec8015..d99fb8d55 100644 --- a/src/modules/graphics/opengl/ImageFont.cpp +++ b/src/modules/graphics/opengl/ImageFont.cpp @@ -20,17 +20,16 @@ #include "ImageFont.h" +#include #include -using std::string; - namespace love { namespace graphics { namespace opengl { - ImageFont::ImageFont(Image * image, std::string glyphs) + ImageFont::ImageFont(Image * image, const std::string& glyphs) : Font(0), image(image), glyphs(glyphs) { @@ -43,7 +42,7 @@ namespace opengl image->release(); } - void ImageFont::print(string text, float x, float y) const + void ImageFont::print(std::string text, float x, float y) const { glPushMatrix(); glTranslatef(x, y, 0.0f); @@ -58,7 +57,7 @@ namespace opengl glPushMatrix(); glTranslatef(x, y, 0.0f); - glRotatef(angle * 57.29578f, 0, 0, 1.0f); + glRotatef(LOVE_TORAD(angle), 0, 0, 1.0f); glScalef(sx, sy, 1.0f); GLuint OpenGLFont = list; @@ -92,73 +91,57 @@ namespace opengl { love::image::pixel * pixels = (love::image::pixel *)(image->getData()->getData()); - // Reading texture data begins - size = (int)image->getHeight(); + unsigned imgw = (unsigned)image->getWidth(); + unsigned imgh = (unsigned)image->getHeight(); + unsigned imgs = imgw*imgh; - for(unsigned int i = 0; i < MAX_CHARS; i++) positions[i] = -1; + // Reading texture data begins + size = imgh; + + for(unsigned int i = 0; i < MAX_CHARS; i++) + positions[i] = -1; love::image::pixel spacer = pixels[0]; - unsigned int current = 0; - int width = 0; - int space = 0; + + unsigned num = glyphs.size(); + + unsigned start = 0; + unsigned end = 0; + unsigned space = 0; - // Finds out where the first character starts - int firstchar = 0; - for(int i = 0; i != (int)image->getWidth(); i++) + for(unsigned i = 0; i < num; ++i) { - if(spacer.r == pixels[i].r && spacer.g == pixels[i].g && spacer.b == pixels[i].b && spacer.a == pixels[i].a) - continue; - else - { - firstchar = i; + if(i >= MAX_CHARS) break; - } + + start = end; + + // Finds out where the first character starts + while(start < imgw && equal(pixels[start], spacer)) + ++start; + + if(i > 0) + spacing[glyphs[i - 1]] = (start > end) ? (start - end) : 0; + + end = start; + + // Find where glyph ends. + while(end < imgw && !equal(pixels[end], spacer)) + ++end; + + if(start >= end) + break; + + unsigned c = glyphs[i]; + + positions[c] = start; + widths[c] = (end - start); } - for(int i = firstchar; i != (int)image->getWidth(); i++) - { - if(spacer.r == pixels[i].r && spacer.g == pixels[i].g && spacer.b == pixels[i].b && spacer.a == pixels[i].a) - { - if(width != 0) // this means we have found the end of our current character - { - if((unsigned int)glyphs[current] > MAX_CHARS) - printf("Error reading texture font: Character '%c' is out of range.", glyphs[current]); - else - { - widths[(int)glyphs[current]] = width - 1; - positions[(int)glyphs[current]] = i - width; - } - - width = 0; - //space++; // start counting the spacing - } - space++; - } - else - { - if(space != 0) // this means we have found the end of our spacing - { - if((unsigned int)spacing[current] > MAX_CHARS) - printf("Error reading image font: Character '%c' is out of range.", glyphs[current]); - else - spacing[(int)glyphs[current]] = space; - - current++; - if(current == glyphs.size()) - i = (int)image->getWidth() - 1; // just to end it when the last character is found - - space = 0; - //width++; // start counting the width - } - width++; - } - } - // Reading image data ends - // Replace spacer color with an empty pixel - for(int i = 0; i < (int)(image->getWidth() * image->getHeight()); i++) + for(unsigned int i = 0; i < imgs; ++i) { - if(spacer.r == pixels[i].r && spacer.g == pixels[i].g && spacer.b == pixels[i].b && spacer.a == pixels[i].a) + if(equal(pixels[i], spacer)) { pixels[i].r = 0; pixels[i].g = 0; @@ -176,26 +159,14 @@ namespace opengl if(positions[i] != -1) { + Quad::Viewport v; + v.x = positions[i]; + v.y = 0; + v.w = widths[i]; + v.h = imgh; + Quad q(v, imgw, imgh); - float x = (float)positions[i] + 1; - float y = 1.0; - float w = (float)widths[i]; - float h = (float)size+1; - - image->bind(); - - float xTex = x/(float)image->getWidth(); - float yTex = y/(float)image->getHeight(); - - float wTex = w/(float)image->getWidth(); - float hTex = h/(float)image->getHeight(); - - glBegin(GL_QUADS); - glTexCoord2f(xTex,yTex); glVertex2f(0,0); - glTexCoord2f(xTex,yTex+hTex); glVertex2f(0,h); - glTexCoord2f(xTex+wTex,yTex+hTex); glVertex2f(w,h); - glTexCoord2f(xTex+wTex,yTex); glVertex2f(w,0); - glEnd(); + image->drawq(&q, 0, 0, 0, 1, 1, 0, 0); glTranslatef((float)widths[i] + ((float)spacing[i] * mSpacing), 0, 0); } @@ -213,7 +184,12 @@ namespace opengl glDeleteLists(list, MAX_CHARS); } - inline int ImageFont::next_p2(int num) + bool ImageFont::equal(const love::image::pixel& a, const love::image::pixel& b) + { + return (a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a); + } + + int ImageFont::next_p2(int num) { int powered = 2; while(powered < num) powered <<= 1; diff --git a/src/modules/graphics/opengl/ImageFont.h b/src/modules/graphics/opengl/ImageFont.h index ecc68de23..76282c631 100644 --- a/src/modules/graphics/opengl/ImageFont.h +++ b/src/modules/graphics/opengl/ImageFont.h @@ -64,7 +64,7 @@ namespace opengl * @param file The image file. * @param glyphs A list of the characters as they appear in the image. **/ - ImageFont(Image * image, std::string glyphs); + ImageFont(Image * image, const std::string& glyphs); /** * Calls unload(). @@ -87,12 +87,17 @@ namespace opengl protected: + /** + * Checks whether two pixels are equal. + **/ + bool equal(const love::image::pixel& a, const love::image::pixel& b); + /** * Returns the closest number to num which is a power of two. * * @param num The number to be 2powered. **/ - inline int next_p2(int num); + int next_p2(int num); }; // ImageFont diff --git a/src/modules/image/ImageData.h b/src/modules/image/ImageData.h index 0d7ead502..3a24decd2 100644 --- a/src/modules/image/ImageData.h +++ b/src/modules/image/ImageData.h @@ -32,7 +32,7 @@ namespace image struct pixel { // Red, green, blue, alpha. - unsigned char r, g, b, a; + unsigned char r, g, b, a; }; /** @@ -95,7 +95,6 @@ namespace image **/ virtual pixel getPixel(int x, int y) const = 0; - }; // ImageData } // image