Browse Source

hopefully padded fonts so that people with crappy graphics cards can still see them - this needs testing, though

Bill Meltsner 15 years ago
parent
commit
c06d5c3263

+ 66 - 3
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

+ 30 - 0
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
 

+ 1 - 0
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;
 	}
 

+ 3 - 0
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;