From c06d5c3263ee7b328281c87c3116da9bee0b13f1 Mon Sep 17 00:00:00 2001 From: Bill Meltsner Date: Thu, 19 Aug 2010 13:41:19 -0500 Subject: [PATCH] hopefully padded fonts so that people with crappy graphics cards can still see them - this needs testing, though --- src/modules/font/GlyphData.cpp | 69 ++++++++++++++++++- src/modules/font/GlyphData.h | 30 ++++++++ src/modules/font/ImageRasterizer.cpp | 1 + .../font/freetype/TrueTypeRasterizer.cpp | 3 + 4 files changed, 100 insertions(+), 3 deletions(-) diff --git a/src/modules/font/GlyphData.cpp b/src/modules/font/GlyphData.cpp index 249f40cce..91c054521 100644 --- a/src/modules/font/GlyphData.cpp +++ b/src/modules/font/GlyphData.cpp @@ -26,7 +26,7 @@ namespace font { GlyphData::GlyphData(unsigned short glyph, GlyphMetrics glyphMetrics, GlyphData::Format f) - : glyph(glyph), metrics(glyphMetrics), format(f) + : glyph(glyph), metrics(glyphMetrics), format(f), padded(false) { if (getWidth() && getHeight()) { switch (f) { @@ -67,12 +67,12 @@ namespace font int GlyphData::getHeight() const { - return metrics.height; + return (padded ? getPaddedHeight() : metrics.height); } int GlyphData::getWidth() const { - return metrics.width; + return (padded ? getPaddedWidth() : metrics.width); } int GlyphData::getAdvance() const @@ -114,6 +114,69 @@ namespace font { return format; } + + void GlyphData::pad() + { + int w = getWidth(); + int h = getHeight(); + int pw = next_p2(w); + int ph = next_p2(h); + unsigned char * d = new unsigned char[pw * ph * (format == GlyphData::FORMAT_LUMINOSITY_ALPHA ? 2 : 4)]; + for (int i = 0; i < pw; i++) { + for (int j = 0; j < ph; j++) { + int n = i+j*w; + int p = i+j*pw; + if (i < w && j < h) { + if (format == GlyphData::FORMAT_LUMINOSITY_ALPHA) { + p *= 2; + n *= 2; + d[p] = data[n]; + d[p+1] = data[n+1]; + } else { + p *= 4; + n *= 4; + d[p] = data[n]; + d[p+1] = data[n+1]; + d[p+2] = data[n+2]; + d[p+3] = data[n+3]; + } + } else { + if (format == GlyphData::FORMAT_LUMINOSITY_ALPHA) { + p *= 2; + d[p] = d[p+1] = 0; + } else { + p *= 4; + d[p] = d[p+1] = d[p+2] = d[p+3] = 0; + } + } + } + } + delete[] data; + data = d; + padded = true; + } + + bool GlyphData::isPadded() const + { + return padded; + } + + int GlyphData::getPaddedWidth() const + { + return next_p2(metrics.width); + } + + int GlyphData::getPaddedHeight() const + { + return next_p2(metrics.height); + } + + inline int GlyphData::next_p2(int num) const + { + int powered = 2; + while(powered < num) powered <<= 1; + return powered; + } } // font } // love diff --git a/src/modules/font/GlyphData.h b/src/modules/font/GlyphData.h index c92ce1be2..0cf09e818 100644 --- a/src/modules/font/GlyphData.h +++ b/src/modules/font/GlyphData.h @@ -112,6 +112,33 @@ namespace font **/ Format getFormat() const; + /** + * 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) const; + + /** + * Pads the data to fit into a power-of-2 texture. + **/ + void pad(); + + /** + * Returns whether the data has been padded. + **/ + bool isPadded() const; + + /** + * Returns the padded width. + **/ + int getPaddedWidth() const; + + /** + * Returns the padded height. + **/ + int getPaddedHeight() const; + private: // The glyph itself unsigned short glyph; @@ -124,6 +151,9 @@ namespace font // The format the data's in Format format; + + // Padded? + bool padded; }; // GlyphData diff --git a/src/modules/font/ImageRasterizer.cpp b/src/modules/font/ImageRasterizer.cpp index a3c9e2d85..674bf8273 100644 --- a/src/modules/font/ImageRasterizer.cpp +++ b/src/modules/font/ImageRasterizer.cpp @@ -79,6 +79,7 @@ namespace font gd[i*4+2] = p.b; gd[i*4+3] = p.a; } + g->pad(); return g; } diff --git a/src/modules/font/freetype/TrueTypeRasterizer.cpp b/src/modules/font/freetype/TrueTypeRasterizer.cpp index 7f175112e..2d511f5a2 100644 --- a/src/modules/font/freetype/TrueTypeRasterizer.cpp +++ b/src/modules/font/freetype/TrueTypeRasterizer.cpp @@ -104,6 +104,9 @@ namespace freetype // Having copied the data over, we can destroy the glyph FT_Done_Glyph(ftglyph); + + // Pad the GlyphData for graphics cards that don't support npo2 textures + glyphData->pad(); // Return data return glyphData;