1 /**
2 * Copyright (c) 2006-2011 LOVE Development Team
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty.  In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 *
8 * Permission is granted to anyone to use this software for any purpose,
9 * including commercial applications, and to alter it and redistribute it
10 * freely, subject to the following restrictions:
11 *
12 * 1. The origin of this software must not be misrepresented; you must not
13 *    claim that you wrote the original software. If you use this software
14 *    in a product, an acknowledgment in the product documentation would be
15 *    appreciated but is not required.
16 * 2. Altered source versions must be plainly marked as such, and must not be
17 *    misrepresented as being the original software.
18 * 3. This notice may not be removed or altered from any source distribution.
19 **/
20 
21 // LOVE
22 #include "TrueTypeRasterizer.h"
23 
24 #include <common/Exception.h>
25 
26 namespace love
27 {
28 namespace font
29 {
30 namespace freetype
31 {
32 	struct la { unsigned char l,a; };
33 
TrueTypeRasterizer(FT_Library library,Data * data,int size)34 	TrueTypeRasterizer::TrueTypeRasterizer(FT_Library library, Data * data, int size)
35 		: data(data)
36 	{
37 		data->retain();
38 
39 		if(FT_New_Memory_Face(	library,
40 								(const FT_Byte *)data->getData(),	/* first byte in memory */
41 								data->getSize(),					/* size in bytes        */
42 								0,									/* face_index           */
43 								&face))
44 			throw love::Exception("TrueTypeFont Loading error: FT_New_Face failed (there is probably a problem with your font file)\n");
45 
46 		FT_Set_Pixel_Sizes(face, size, size);
47 
48 		// Set global metrics
49 		FT_Size_Metrics s = face->size->metrics;
50 		metrics.advance = s.max_advance >> 6;
51 		metrics.ascent = s.ascender >> 6;
52 		metrics.descent = s.descender >> 6;
53 		metrics.height = s.height >> 6;
54 	}
55 
~TrueTypeRasterizer()56 	TrueTypeRasterizer::~TrueTypeRasterizer()
57 	{
58 		FT_Done_Face(face);
59 		data->release();
60 	}
61 
getLineHeight() const62 	int TrueTypeRasterizer::getLineHeight() const
63 	{
64 		return (int)(getHeight() * 1.25);
65 	}
66 
getGlyphData(unsigned short glyph) const67 	GlyphData * TrueTypeRasterizer::getGlyphData(unsigned short glyph) const
68 	{
69 		love::font::GlyphMetrics glyphMetrics;
70 		FT_Glyph ftglyph;
71 
72 		// Initialize
73 		if(FT_Load_Glyph(face, FT_Get_Char_Index(face, glyph), FT_LOAD_DEFAULT))
74 			throw love::Exception("TrueTypeFont Loading vm->error: FT_Load_Glyph failed\n");
75 
76 		if( FT_Get_Glyph(face->glyph, &ftglyph) )
77 			throw love::Exception("TrueTypeFont Loading vm->error: FT_Get_Glyph failed\n");
78 
79 		FT_Glyph_To_Bitmap(&ftglyph, FT_RENDER_MODE_NORMAL, 0, 1);
80 		FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)ftglyph;
81 		FT_Bitmap& bitmap = bitmap_glyph->bitmap; //just to make things easier
82 
83 		// Get metrics
84 		glyphMetrics.bearingX = face->glyph->metrics.horiBearingX >> 6;
85 		glyphMetrics.bearingY = face->glyph->metrics.horiBearingY >> 6;
86 		glyphMetrics.height = bitmap.rows;
87 		glyphMetrics.width = bitmap.width;
88 		glyphMetrics.advance = face->glyph->metrics.horiAdvance >> 6;
89 
90 		GlyphData * glyphData = new GlyphData(glyph, glyphMetrics, GlyphData::FORMAT_LUMINANCE_ALPHA);
91 
92 		{
93 			int size = bitmap.rows*bitmap.width;
94 			unsigned char * dst = (unsigned char *)glyphData->getData();
95 
96 			// Note that bitmap.buffer contains only luminosity. We copy that single value to
97 			// our luminosity-alpha format.
98 			for(int i = 0; i<size; i++)
99 			{
100 				dst[2*i] = 255;
101 				dst[2*i+1] = bitmap.buffer[i];
102 			}
103 		}
104 
105 		// Having copied the data over, we can destroy the glyph
106 		FT_Done_Glyph(ftglyph);
107 
108 		// Pad the GlyphData for graphics cards that don't support npo2 textures
109 		glyphData->pad();
110 
111 		// Return data
112 		return glyphData;
113 	}
114 
getNumGlyphs() const115 	int TrueTypeRasterizer::getNumGlyphs() const
116 	{
117 		return 256;
118 	}
119 
120 } // freetype
121 } // font
122 } // love