Mercurial > projects > mde
comparison mde/resource/font.d @ 44:07bd1a09e161
Started implementing text rendering.
Can now position glyphs accurately and render them, in a very basic way.
A basic TextWidget.
committer: Diggory Hardy <diggory.hardy@gmail.com>
author | Diggory Hardy <diggory.hardy@gmail.com> |
---|---|
date | Fri, 16 May 2008 12:22:10 +0100 |
parents | |
children | 0fd51d2c6c8a |
comparison
equal
deleted
inserted
replaced
43:1530d9c04d4d | 44:07bd1a09e161 |
---|---|
1 /* LICENSE BLOCK | |
2 Part of mde: a Modular D game-oriented Engine | |
3 Copyright © 2007-2008 Diggory Hardy | |
4 | |
5 This program is free software: you can redistribute it and/or modify it under the terms | |
6 of the GNU General Public License as published by the Free Software Foundation, either | |
7 version 2 of the License, or (at your option) any later version. | |
8 | |
9 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; | |
10 without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
11 See the GNU General Public License for more details. | |
12 | |
13 You should have received a copy of the GNU General Public License | |
14 along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
15 | |
16 /// Sets up freetype (in a basic way). | |
17 module mde.resource.font; | |
18 | |
19 import mde.resource.exception; | |
20 | |
21 import derelict.freetype.ft; | |
22 import derelict.opengl.gl; | |
23 | |
24 import tango.stdc.stringz; | |
25 import tango.util.log.Log : Log, Logger; | |
26 | |
27 private Logger logger; | |
28 static this () { | |
29 logger = Log.getLogger ("mde.resource.font"); | |
30 } | |
31 | |
32 /** Font class. | |
33 * | |
34 * Particular to a font and size. (Maybe not size?) */ | |
35 class Font | |
36 { | |
37 //BEGIN Static: manager | |
38 static { | |
39 /** Load the freetype library. */ | |
40 void initialize () { | |
41 if (FT_Init_FreeType (&library)) | |
42 throw new fontException ("error initialising the FreeType library"); | |
43 } | |
44 | |
45 //FIXME: don't use GC for Font resources | |
46 /** Cleanup: delete all fonts. */ | |
47 void cleanup () { | |
48 if (font) | |
49 delete font; | |
50 | |
51 FT_Done_FreeType (library); | |
52 } | |
53 | |
54 /** Get a font. | |
55 * | |
56 * Later specify font/size. | |
57 * | |
58 * Throws: | |
59 * fontLoadException when unable to load the font. */ | |
60 Font get(char[] path) { | |
61 if (font is null) font = new Font(path); | |
62 return font; | |
63 } | |
64 | |
65 private: | |
66 FT_Library library; | |
67 Font font; | |
68 } | |
69 //END Static | |
70 | |
71 | |
72 /** Load & cache a new font. */ | |
73 this (char[] path) | |
74 in { | |
75 assert (library !is null, "font: library is null"); | |
76 } body { | |
77 if (FT_New_Face (library, toStringz(path), 0, &face)) | |
78 throw new fontLoadException ("Unable to read font: "~path); | |
79 | |
80 if (FT_Set_Pixel_Sizes (face, 12,12)) | |
81 throw new fontLoadException ("Unable to set pixel size"); | |
82 } | |
83 | |
84 void drawStr (int x, int y, char[] str) { | |
85 FT_Vector pen = { x*64, y*64 }; | |
86 auto g = face.glyph; | |
87 | |
88 FT_Matrix m; | |
89 m.xx = 0x10000; | |
90 m.xy = m.yx = 0; | |
91 m.yy = -0x10000; | |
92 | |
93 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | |
94 | |
95 FT_Pos y_adj = 0; // y adjustment (for height) | |
96 | |
97 foreach (chr; str) { | |
98 FT_Set_Transform(face, &m, &pen); | |
99 if (FT_Load_Char(face, chr, FT_LOAD_RENDER)) | |
100 return; // give up | |
101 | |
102 if (y_adj < g.metrics.height) y_adj = g.metrics.height; | |
103 | |
104 auto b = g.bitmap; | |
105 if (b.pixel_mode != FT_Pixel_Mode.FT_PIXEL_MODE_GRAY || b.num_grays != 256) { | |
106 char[128] tmp; | |
107 logger.warn (logger.format (tmp,"Unsupported freetype bitmap format: {}, {}", b.pixel_mode, b.num_grays)); | |
108 return; | |
109 } | |
110 if (b.pitch != b.width) | |
111 logger.info ("b.pitch != b.width"); | |
112 | |
113 //NOTE: y direction! | |
114 glRasterPos2i (g.bitmap_left,g.bitmap_top + y_adj/64); | |
115 glDrawPixels (b.width, b.rows, GL_LUMINANCE, GL_UNSIGNED_BYTE, cast(void*) b.buffer); | |
116 | |
117 pen.x += g.advance.x; | |
118 pen.y += g.advance.y; | |
119 } | |
120 } | |
121 | |
122 ~this () { | |
123 FT_Done_Face (face); | |
124 } | |
125 | |
126 private: | |
127 FT_Face face; | |
128 } |