From e3a5aacd5a97cfbcfbb84e386bf1a43595066ebb Mon Sep 17 00:00:00 2001 From: Bill Meltsner Date: Wed, 14 Apr 2010 21:51:35 -0400 Subject: [PATCH] Overhauled ImageRasterizer, fixed a bunch of other crap, getting ready to poke around in love.graphics --- .../macosx/love.xcodeproj/project.pbxproj | 8 +- src/modules/font/FontData.cpp | 6 +- src/modules/font/FontData.h | 2 +- src/modules/font/GlyphData.cpp | 50 +++++----- src/modules/font/ImageRasterizer.cpp | 93 ++++++++++++++++++- src/modules/font/ImageRasterizer.h | 57 +++++++----- src/modules/font/Rasterizer.h | 54 +++++------ src/modules/font/freetype/Font.cpp | 52 ++++++----- src/modules/font/freetype/Font.h | 7 +- .../font/freetype/TrueTypeRasterizer.cpp | 6 +- src/modules/font/wrap_Rasterizer.cpp | 3 - src/modules/graphics/opengl/Font.h | 42 ++++----- src/modules/graphics/opengl/Glyph.cpp | 2 +- src/modules/graphics/opengl/TrueTypeFont.h | 4 + src/modules/image/Image.h | 1 - 15 files changed, 249 insertions(+), 138 deletions(-) diff --git a/platform/macosx/love.xcodeproj/project.pbxproj b/platform/macosx/love.xcodeproj/project.pbxproj index 7390b956b..615ee9acb 100644 --- a/platform/macosx/love.xcodeproj/project.pbxproj +++ b/platform/macosx/love.xcodeproj/project.pbxproj @@ -28,6 +28,8 @@ A946CE821172BCD7005E1462 /* wrap_EncodedImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A946CE811172BCD7005E1462 /* wrap_EncodedImageData.cpp */; }; A946D3BB117681BD005E1462 /* FontData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A946D3BA117681BC005E1462 /* FontData.cpp */; }; A946D3C611768D69005E1462 /* wrap_FontData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A946D3C511768D69005E1462 /* wrap_FontData.cpp */; }; + A946D4061176A711005E1462 /* ImageFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6A9110420AC2007D418B /* ImageFont.cpp */; }; + A946D4071176A716005E1462 /* TrueTypeFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6A9710420AC2007D418B /* TrueTypeFont.cpp */; }; A946D67F104248DA002BF36C /* Reference.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E69EA10420ABF007D418B /* Reference.cpp */; }; A946D680104248DA002BF36C /* Matrix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E69E310420ABF007D418B /* Matrix.cpp */; }; A946D681104248DA002BF36C /* Object.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E69E810420ABF007D418B /* Object.cpp */; }; @@ -86,12 +88,10 @@ A946D704104249A4002BF36C /* SpriteBatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6A9510420AC2007D418B /* SpriteBatch.cpp */; }; A946D705104249A4002BF36C /* wrap_Glyph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6A9B10420AC2007D418B /* wrap_Glyph.cpp */; }; A946D706104249A4002BF36C /* Glyph.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6A8B10420AC2007D418B /* Glyph.cpp */; }; - A946D707104249A4002BF36C /* ImageFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6A9110420AC2007D418B /* ImageFont.cpp */; }; A946D708104249A4002BF36C /* Drawable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6A8210420AC2007D418B /* Drawable.cpp */; }; A946D709104249A4002BF36C /* wrap_Graphics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6A9D10420AC3007D418B /* wrap_Graphics.cpp */; }; A946D70A104249A4002BF36C /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6A8F10420AC2007D418B /* Image.cpp */; }; A946D70B104249A4002BF36C /* wrap_Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6A9F10420AC3007D418B /* wrap_Image.cpp */; }; - A946D70C104249A4002BF36C /* TrueTypeFont.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6A9710420AC2007D418B /* TrueTypeFont.cpp */; }; A946D72210424A58002BF36C /* wrap_Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6AB010420AC3007D418B /* wrap_Image.cpp */; }; A946D72310424A58002BF36C /* Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6AA910420AC3007D418B /* Image.cpp */; }; A946D72410424A58002BF36C /* ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6AAB10420AC3007D418B /* ImageData.cpp */; }; @@ -1559,12 +1559,10 @@ A946D704104249A4002BF36C /* SpriteBatch.cpp in Sources */, A946D705104249A4002BF36C /* wrap_Glyph.cpp in Sources */, A946D706104249A4002BF36C /* Glyph.cpp in Sources */, - A946D707104249A4002BF36C /* ImageFont.cpp in Sources */, A946D708104249A4002BF36C /* Drawable.cpp in Sources */, A946D709104249A4002BF36C /* wrap_Graphics.cpp in Sources */, A946D70A104249A4002BF36C /* Image.cpp in Sources */, A946D70B104249A4002BF36C /* wrap_Image.cpp in Sources */, - A946D70C104249A4002BF36C /* TrueTypeFont.cpp in Sources */, A946D72210424A58002BF36C /* wrap_Image.cpp in Sources */, A946D72310424A58002BF36C /* Image.cpp in Sources */, A946D72410424A58002BF36C /* ImageData.cpp in Sources */, @@ -1668,6 +1666,8 @@ A946CE821172BCD7005E1462 /* wrap_EncodedImageData.cpp in Sources */, A946D3BB117681BD005E1462 /* FontData.cpp in Sources */, A946D3C611768D69005E1462 /* wrap_FontData.cpp in Sources */, + A946D4061176A711005E1462 /* ImageFont.cpp in Sources */, + A946D4071176A716005E1462 /* TrueTypeFont.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/src/modules/font/FontData.cpp b/src/modules/font/FontData.cpp index 8b80881f4..af740e32e 100644 --- a/src/modules/font/FontData.cpp +++ b/src/modules/font/FontData.cpp @@ -27,13 +27,11 @@ namespace font { FontData::FontData(Rasterizer * raster) - : height(0) + : raster(raster) { data = new GlyphData *[MAX_CHARS]; for (unsigned int i = 0; i < MAX_CHARS; i++) { data[i] = raster->getGlyphData(i); - int h = data[i]->getHeight(); - if (h > height) height = h; } } @@ -59,7 +57,7 @@ namespace font int FontData::getHeight() const { - return height; + return raster->getHeight(); } } // font diff --git a/src/modules/font/FontData.h b/src/modules/font/FontData.h index 2f864cfee..0be063b2d 100644 --- a/src/modules/font/FontData.h +++ b/src/modules/font/FontData.h @@ -48,7 +48,7 @@ namespace font private: GlyphData ** data; - int height; + Rasterizer * raster; }; } // font } // love diff --git a/src/modules/font/GlyphData.cpp b/src/modules/font/GlyphData.cpp index fedba6945..bf816074f 100644 --- a/src/modules/font/GlyphData.cpp +++ b/src/modules/font/GlyphData.cpp @@ -1,21 +1,21 @@ -/** -* Copyright (c) 2006-2010 LOVE Development Team -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. +/** +* Copyright (c) 2006-2010 LOVE Development Team +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. **/ #include "GlyphData.h" @@ -28,7 +28,7 @@ namespace font GlyphData::GlyphData(unsigned short glyph, GlyphMetrics glyphMetrics) : glyph(glyph), metrics(glyphMetrics) { - data = new unsigned char[getWidth() * getHeight() * 2]; + data = new unsigned char[getWidth() * getHeight() * 4]; } GlyphData::~GlyphData() @@ -36,14 +36,14 @@ namespace font delete[] data; } - void * GlyphData::getData() const - { - return (void *) data; - } - + void * GlyphData::getData() const + { + return (void *) data; + } + int GlyphData::getSize() const { - return getWidth() * getHeight() * 2; + return getWidth() * getHeight() * 4; } int GlyphData::getHeight() const diff --git a/src/modules/font/ImageRasterizer.cpp b/src/modules/font/ImageRasterizer.cpp index 6a3a4821a..db35b4e49 100644 --- a/src/modules/font/ImageRasterizer.cpp +++ b/src/modules/font/ImageRasterizer.cpp @@ -27,15 +27,28 @@ namespace love { namespace font { - ImageRasterizer::ImageRasterizer(love::image::ImageData * data, unsigned short *) - : imageData(data) + + inline bool 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); + } + + ImageRasterizer::ImageRasterizer(love::image::ImageData * data, unsigned short * glyphs, int length) + : imageData(data), glyphs(glyphs), length(length) { imageData->retain(); + positions = new unsigned int[MAX_CHARS]; + widths = new unsigned int[MAX_CHARS]; + spacing = new unsigned int[MAX_CHARS]; + load(); } ImageRasterizer::~ImageRasterizer() { imageData->release(); + delete[] positions; + delete[] widths; + delete[] spacing; } int ImageRasterizer::getLineHeight() const @@ -43,9 +56,81 @@ namespace font return getHeight(); } - GlyphData * ImageRasterizer::getGlyphData(unsigned short) const + GlyphData * ImageRasterizer::getGlyphData(unsigned short glyph) const { - return 0; + GlyphMetrics gm; + gm.height = metrics.height; + gm.width = widths[glyph]; + GlyphData * g = new GlyphData(glyph, gm); + unsigned char * gd = (unsigned char*)g->getData(); + love::image::pixel * pixels = (love::image::pixel *)(imageData->getData()); + for (unsigned int i = positions[glyph]; i < positions[glyph] + widths[glyph]; i++) { + love::image::pixel p = pixels[i]; + gd[i*4] = p.r; + gd[i*4+1] = p.g; + gd[i*4+2] = p.b; + gd[i*4+3] = p.a; + } + return g; + } + + void ImageRasterizer::load() + { + love::image::pixel * pixels = (love::image::pixel *)(imageData->getData()); + + unsigned imgw = (unsigned)imageData->getWidth(); + unsigned imgh = (unsigned)imageData->getHeight(); + unsigned imgs = imgw*imgh; + + // Set the only metric that matters + metrics.height = imgh; + + // Reading texture data begins + love::image::pixel spacer = pixels[0]; + + unsigned int start = 0; + unsigned int end = 0; + + for(unsigned int i = 0; i < length; ++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); + } + + // Replace spacer color with an empty pixel + for(unsigned int i = 0; i < imgs; ++i) + { + if(equal(pixels[i], spacer)) + { + pixels[i].r = 0; + pixels[i].g = 0; + pixels[i].b = 0; + pixels[i].a = 0; + } + } } } // font diff --git a/src/modules/font/ImageRasterizer.h b/src/modules/font/ImageRasterizer.h index 0b2ba7ec1..c5ea3d132 100644 --- a/src/modules/font/ImageRasterizer.h +++ b/src/modules/font/ImageRasterizer.h @@ -1,21 +1,21 @@ -/** -* Copyright (c) 2006-2010 LOVE Development Team -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. +/** +* Copyright (c) 2006-2010 LOVE Development Team +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. **/ #ifndef LOVE_FONT_IMAGE_RASTERIZER_H @@ -36,17 +36,32 @@ namespace font class ImageRasterizer : public Rasterizer { private: + // Load all the glyph positions into memory + void load(); + // The image data love::image::ImageData * imageData; + // The glyphs in the font + unsigned short * glyphs; + // The length of the glyph array + unsigned int length; + // The positions of each glyph + unsigned int * positions; + // The widths of each glyph + unsigned int * widths; + // The spacing of each glyph + unsigned int * spacing; public: - ImageRasterizer(love::image::ImageData * imageData, unsigned short * glyphs); + ImageRasterizer(love::image::ImageData * imageData, unsigned short * glyphs, int length); virtual ~ImageRasterizer(); - // Implement FontData + // Implement Rasterizer virtual int getLineHeight() const; virtual GlyphData * getGlyphData(unsigned short glyph) const; - + + static const unsigned int MAX_CHARS = 256; + }; // ImageRasterizer } // font diff --git a/src/modules/font/Rasterizer.h b/src/modules/font/Rasterizer.h index df7753606..b0134d0d0 100644 --- a/src/modules/font/Rasterizer.h +++ b/src/modules/font/Rasterizer.h @@ -1,21 +1,21 @@ -/** -* Copyright (c) 2006-2010 LOVE Development Team -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. +/** +* Copyright (c) 2006-2010 LOVE Development Team +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. **/ #ifndef LOVE_FONT_RASTERIZER_H @@ -29,15 +29,15 @@ namespace love { namespace font { - /** - * Holds the specific font metrics. - **/ - struct FontMetrics - { - int advance ; - int ascent; - int descent; - int height; + /** + * Holds the specific font metrics. + **/ + struct FontMetrics + { + int advance; + int ascent; + int descent; + int height; }; /** diff --git a/src/modules/font/freetype/Font.cpp b/src/modules/font/freetype/Font.cpp index 8b5a088c8..3b6b92d14 100644 --- a/src/modules/font/freetype/Font.cpp +++ b/src/modules/font/freetype/Font.cpp @@ -1,21 +1,21 @@ -/** -* Copyright (c) 2006-2010 LOVE Development Team -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would be -* appreciated but is not required. -* 2. Altered source versions must be plainly marked as such, and must not be -* misrepresented as being the original software. -* 3. This notice may not be removed or altered from any source distribution. +/** +* Copyright (c) 2006-2010 LOVE Development Team +* +* This software is provided 'as-is', without any express or implied +* warranty. In no event will the authors be held liable for any damages +* arising from the use of this software. +* +* Permission is granted to anyone to use this software for any purpose, +* including commercial applications, and to alter it and redistribute it +* freely, subject to the following restrictions: +* +* 1. The origin of this software must not be misrepresented; you must not +* claim that you wrote the original software. If you use this software +* in a product, an acknowledgment in the product documentation would be +* appreciated but is not required. +* 2. Altered source versions must be plainly marked as such, and must not be +* misrepresented as being the original software. +* 3. This notice may not be removed or altered from any source distribution. **/ #include "Font.h" @@ -44,10 +44,20 @@ namespace freetype { return new TrueTypeRasterizer(library, data, size); } - - Rasterizer * Font::newRasterizer(love::image::ImageData * data, unsigned short * glyphs) + + Rasterizer * Font::newRasterizer(love::image::ImageData * data, std::string glyphs) { - return new ImageRasterizer(data, glyphs); + int length = glyphs.size(); + unsigned short g[length]; + for (int i = 0; i < length; i++) { + g[i] = glyphs[i]; + } + return newRasterizer(data, g, length); + } + + Rasterizer * Font::newRasterizer(love::image::ImageData * data, unsigned short * glyphs, int length) + { + return new ImageRasterizer(data, glyphs, length); } GlyphData * Font::newGlyphData(Rasterizer * r, unsigned short glyph) diff --git a/src/modules/font/freetype/Font.h b/src/modules/font/freetype/Font.h index 7ab056dec..5b236eef8 100644 --- a/src/modules/font/freetype/Font.h +++ b/src/modules/font/freetype/Font.h @@ -22,7 +22,6 @@ #define LOVE_FONT_FREETYPE_FONT_H // LOVE -#include #include #include #include @@ -38,6 +37,9 @@ #include #include +// STD +#include + namespace love { namespace font @@ -62,7 +64,8 @@ namespace freetype virtual ~Font(); Rasterizer * newRasterizer(Data * data, int size); - Rasterizer * newRasterizer(love::image::ImageData * data, unsigned short * glyphs); + Rasterizer * newRasterizer(love::image::ImageData * data, std::string glyphs); + Rasterizer * newRasterizer(love::image::ImageData * data, unsigned short * glyphs, int length); GlyphData * newGlyphData(Rasterizer * r, unsigned short glyph); // Implement Module diff --git a/src/modules/font/freetype/TrueTypeRasterizer.cpp b/src/modules/font/freetype/TrueTypeRasterizer.cpp index 43163cd63..2bb31cb90 100644 --- a/src/modules/font/freetype/TrueTypeRasterizer.cpp +++ b/src/modules/font/freetype/TrueTypeRasterizer.cpp @@ -92,11 +92,11 @@ namespace freetype int size = bitmap.rows*bitmap.width; unsigned char * dst = (unsigned char *)glyphData->getData(); - // Note that bitmap.buffer contains only luminocity. We copy that single value to - // our luminocity-alpha format. + // Note that bitmap.buffer contains only luminosity. We copy that single value to + // our rgba format. for(int i = 0; i + // LOVE #include #include -#include namespace love { @@ -36,8 +38,6 @@ namespace opengl { protected: - love::filesystem::File * file; - int size; float lineHeight; float mSpacing; // modifies the spacing by multiplying it with this value diff --git a/src/modules/graphics/opengl/Glyph.cpp b/src/modules/graphics/opengl/Glyph.cpp index 390b471bb..ee43a6652 100644 --- a/src/modules/graphics/opengl/Glyph.cpp +++ b/src/modules/graphics/opengl/Glyph.cpp @@ -108,7 +108,7 @@ namespace opengl (GLsizei)width, (GLsizei)height, 0, - GL_LUMINANCE_ALPHA, + GL_RGBA, GL_UNSIGNED_BYTE, data->getData()); diff --git a/src/modules/graphics/opengl/TrueTypeFont.h b/src/modules/graphics/opengl/TrueTypeFont.h index b7aeae24a..6df8d1293 100644 --- a/src/modules/graphics/opengl/TrueTypeFont.h +++ b/src/modules/graphics/opengl/TrueTypeFont.h @@ -24,6 +24,10 @@ // Module #include "Font.h" +// LOVE +#include +#include + // FreeType2 #ifdef LOVE_MACOSX #include diff --git a/src/modules/image/Image.h b/src/modules/image/Image.h index d1224f459..57bf94335 100644 --- a/src/modules/image/Image.h +++ b/src/modules/image/Image.h @@ -25,7 +25,6 @@ #include #include #include -#include #include "ImageData.h" namespace love