Commits

Anonymous committed db7cd06

Fixed ImageFont.

Comments (0)

Files changed (4)

 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.

src/modules/graphics/opengl/ImageFont.cpp

 
 #include "ImageFont.h"
 
+#include <common/math.h>
 #include <SDL_opengl.h>
 
-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)
 
 	{
 		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);
 		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;
 	{
 		love::image::pixel * pixels = (love::image::pixel *)(image->getData()->getData());
 
+		unsigned imgw = (unsigned)image->getWidth();
+		unsigned imgh = (unsigned)image->getHeight();
+		unsigned imgs = imgw*imgh;
+
 		// Reading texture data begins
-		size = (int)image->getHeight();
+		size = imgh;
 
-		for(unsigned int i = 0; i < MAX_CHARS; i++) positions[i] = -1;
+		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++)
+		// Replace spacer color with an empty pixel
+		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(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++)
-		{
-			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;
 
 			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);
 			}
 		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;

src/modules/graphics/opengl/ImageFont.h

 		* @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().
 	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
 

src/modules/image/ImageData.h

 	struct pixel 
 	{
 		// Red, green, blue, alpha.
-		unsigned char r, g, b, a; 
+		unsigned char r, g, b, a;
 	};
 
 	/**
 		**/
 		virtual pixel getPixel(int x, int y) const = 0;
 
-
 	}; // ImageData
 
 } // image
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.