Some work on rendering glyphs.
This commit is contained in:
parent
6ff4bdcc11
commit
2ab09b47bf
@ -11,10 +11,10 @@ static bool Initialized;
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
FT_Face face;
|
|
||||||
int32_t advance;
|
int32_t advance;
|
||||||
int32_t line_height;
|
int32_t line_height;
|
||||||
int32_t baseline_offset;
|
int32_t baseline_offset;
|
||||||
|
FT_Face face;
|
||||||
} Font;
|
} Font;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -1,7 +1,15 @@
|
|||||||
module jes.gui.font;
|
module jes.gui.font;
|
||||||
import std.string;
|
import std.string;
|
||||||
|
import derelict.opengl;
|
||||||
|
import gltk;
|
||||||
|
import core.stdc.string;
|
||||||
|
|
||||||
struct CFont;
|
struct CFont
|
||||||
|
{
|
||||||
|
int advance;
|
||||||
|
int line_height;
|
||||||
|
int baseline_offset;
|
||||||
|
}
|
||||||
|
|
||||||
struct CGlyph
|
struct CGlyph
|
||||||
{
|
{
|
||||||
@ -20,20 +28,72 @@ private extern(C) void Font_Free(CFont * font);
|
|||||||
|
|
||||||
class Font
|
class Font
|
||||||
{
|
{
|
||||||
|
private static __gshared Glyph[uint] glyphs;
|
||||||
|
|
||||||
class Glyph
|
class Glyph
|
||||||
{
|
{
|
||||||
int advance;
|
int advance;
|
||||||
|
gltk.Texture m_texture;
|
||||||
|
gltk.Buffer m_buffer;
|
||||||
|
gltk.Array m_array;
|
||||||
|
|
||||||
|
this(const(CGlyph) * cglyph)
|
||||||
|
{
|
||||||
|
advance = cglyph.advance;
|
||||||
|
m_texture = new gltk.Texture();
|
||||||
|
m_texture.bind(GL_TEXTURE_2D);
|
||||||
|
int rounded_width = gltk.Texture.next_power_of_2(cglyph.width);
|
||||||
|
int rounded_height = gltk.Texture.next_power_of_2(cglyph.height);
|
||||||
|
ubyte[] texture = new ubyte[rounded_width * rounded_height];
|
||||||
|
memset(texture.ptr, 0, rounded_width * rounded_height);
|
||||||
|
for (int i = 0; i < cglyph.height; i++)
|
||||||
|
{
|
||||||
|
memcpy(&texture[rounded_width * i],
|
||||||
|
&cglyph.bitmap[cglyph.width * (cglyph.height - i - 1)],
|
||||||
|
cglyph.width);
|
||||||
|
}
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, rounded_width, rounded_height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, texture.ptr);
|
||||||
|
|
||||||
|
m_array = new gltk.Array();
|
||||||
|
m_array.bind();
|
||||||
|
|
||||||
|
int left = cglyph.left;
|
||||||
|
int top = cglyph.top;
|
||||||
|
float s_max = cglyph.width / cast(float)rounded_width;
|
||||||
|
float t_max = cglyph.height / cast(float)rounded_height;
|
||||||
|
m_buffer = new gltk.Buffer();
|
||||||
|
GLfloat[] data = [
|
||||||
|
cast(GLfloat)left, cast(GLfloat)(top - cglyph.height), 0.0, 0.0,
|
||||||
|
cast(GLfloat)(left + cglyph.width), cast(GLfloat)(top - cglyph.height), s_max, 0.0,
|
||||||
|
cast(GLfloat)left, cast(GLfloat)top, 0.0, t_max,
|
||||||
|
cast(GLfloat)(left + cglyph.width), cast(GLfloat)top, s_max, t_max,
|
||||||
|
];
|
||||||
|
m_buffer.set_buffer_data(GL_ARRAY_BUFFER, GL_STATIC_DRAW, data.ptr, data.length);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, null);
|
||||||
|
}
|
||||||
|
|
||||||
void render()
|
void render()
|
||||||
{
|
{
|
||||||
|
m_array.bind();
|
||||||
|
m_texture.bind(GL_TEXTURE_2D);
|
||||||
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CFont * font;
|
CFont * m_font;
|
||||||
|
|
||||||
this(const char * fname, int size)
|
this(const char * fname, int size)
|
||||||
{
|
{
|
||||||
font = Font_Load(fname, size);
|
m_font = Font_Load(fname, size);
|
||||||
if (font == null)
|
if (m_font == null)
|
||||||
{
|
{
|
||||||
throw new Exception("Could not load font");
|
throw new Exception("Could not load font");
|
||||||
}
|
}
|
||||||
@ -46,6 +106,38 @@ class Font
|
|||||||
|
|
||||||
~this()
|
~this()
|
||||||
{
|
{
|
||||||
Font_Free(font);
|
Font_Free(m_font);
|
||||||
|
}
|
||||||
|
|
||||||
|
@property int advance()
|
||||||
|
{
|
||||||
|
return m_font.advance;
|
||||||
|
}
|
||||||
|
|
||||||
|
@property int line_height()
|
||||||
|
{
|
||||||
|
return m_font.line_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
@property int baseline_offset()
|
||||||
|
{
|
||||||
|
return m_font.baseline_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
Glyph get_glyph(uint char_code)
|
||||||
|
{
|
||||||
|
if (char_code in glyphs)
|
||||||
|
{
|
||||||
|
return glyphs[char_code];
|
||||||
|
}
|
||||||
|
Glyph glyph;
|
||||||
|
CGlyph * cglyph = Font_LoadGlyph(m_font, char_code);
|
||||||
|
if (cglyph != null)
|
||||||
|
{
|
||||||
|
glyph = new Glyph(cglyph);
|
||||||
|
Font_FreeGlyph(cglyph);
|
||||||
|
}
|
||||||
|
glyphs[char_code] = glyph;
|
||||||
|
return glyph;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user