convert Font to Ruby class
This commit is contained in:
parent
8d8c9adcb3
commit
b7ad236b7b
98
src/Font.cc
98
src/Font.cc
@ -1,13 +1,44 @@
|
|||||||
#include "Font.h"
|
#include "Font.h"
|
||||||
#include "ruby.h"
|
#include "ruby.h"
|
||||||
|
#include "GLTexture.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <ft2build.h>
|
#include <ft2build.h>
|
||||||
#include FT_FREETYPE_H
|
#include FT_FREETYPE_H
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#define round_up_26_6(val) (((val) + 63) >> 6u)
|
#define round_up_26_6(val) (((val) + 63) >> 6u)
|
||||||
|
|
||||||
|
class Glyph
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Glyph();
|
||||||
|
bool load(FT_Face face, FT_ULong char_code);
|
||||||
|
int get_advance() { return m_advance; }
|
||||||
|
void render()
|
||||||
|
{
|
||||||
|
m_texture->bind();
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id);
|
||||||
|
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
|
||||||
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
}
|
||||||
|
protected:
|
||||||
|
bool m_loaded;
|
||||||
|
int m_advance;
|
||||||
|
GLTextureRef m_texture;
|
||||||
|
GLuint m_vbo_id;
|
||||||
|
};
|
||||||
|
typedef Ref<Glyph> GlyphRef;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
FT_Face face;
|
||||||
|
std::unordered_map<FT_ULong, GlyphRef> glyphs;
|
||||||
|
} Font;
|
||||||
|
|
||||||
static FT_Library ft;
|
static FT_Library ft;
|
||||||
|
static VALUE ruby_class;
|
||||||
|
|
||||||
static void Init_FreeType()
|
static void Init_FreeType()
|
||||||
{
|
{
|
||||||
@ -24,62 +55,87 @@ static void Init_FreeType()
|
|||||||
initialized = true;
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Font::Font()
|
void Font_free(void * ptr)
|
||||||
{
|
{
|
||||||
m_loaded = false;
|
Font * font = (Font *)ptr;
|
||||||
|
|
||||||
|
FT_Done_Face(font->face);
|
||||||
|
|
||||||
|
delete font;
|
||||||
}
|
}
|
||||||
|
|
||||||
Font::~Font()
|
static VALUE Font_new(VALUE klass, VALUE fname, VALUE size)
|
||||||
{
|
{
|
||||||
if (m_loaded)
|
Init_FreeType();
|
||||||
{
|
|
||||||
FT_Done_Face(m_face);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Font::load(FT_Library ft, const char * fname, size_t size)
|
Font * font = new Font();
|
||||||
{
|
|
||||||
if (FT_New_Face(ft, fname, 0, &m_face) != 0)
|
fname = rb_funcall(fname, rb_intern("to_s"), 0);
|
||||||
|
const char * fname_cstr = StringValueCStr(fname);
|
||||||
|
|
||||||
|
if (FT_New_Face(ft, fname_cstr, 0, &font->face) != 0)
|
||||||
{
|
{
|
||||||
std::cerr << "Could not load font " << fname << std::endl;
|
delete font;
|
||||||
return false;
|
rb_raise(rb_eRuntimeError,
|
||||||
|
"Could not load font %s",
|
||||||
|
fname_cstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
FT_Set_Pixel_Sizes(m_face, 0, size);
|
FT_Set_Pixel_Sizes(font->face, 0, NUM2INT(size));
|
||||||
|
|
||||||
|
#if 0
|
||||||
GlyphRef glyph = load_glyph('g');
|
GlyphRef glyph = load_glyph('g');
|
||||||
if (glyph == NULL)
|
if (glyph == NULL)
|
||||||
{
|
{
|
||||||
std::cerr << "Could not load 'g' glyph from font" << fname << std::endl;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
m_glyphs['g'] = glyph;
|
m_glyphs['g'] = glyph;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
m_advance = glyph->get_advance();
|
m_advance = glyph->get_advance();
|
||||||
m_line_height = round_up_26_6(m_face->size->metrics.height);
|
m_line_height = round_up_26_6(m_face->size->metrics.height);
|
||||||
|
#endif
|
||||||
#if 0
|
#if 0
|
||||||
m_baseline_offset = round_up_26_6((m_face->size->metrics.height - (m_face->size->metrics.ascender - m_face->size->metrics.descender)) / 2 - m_face->size->metrics.descender);
|
m_baseline_offset = round_up_26_6((m_face->size->metrics.height - (m_face->size->metrics.ascender - m_face->size->metrics.descender)) / 2 - m_face->size->metrics.descender);
|
||||||
#endif
|
#endif
|
||||||
|
#if 0
|
||||||
m_baseline_offset = 1 - m_face->glyph->bitmap_top + m_face->glyph->bitmap.rows;
|
m_baseline_offset = 1 - m_face->glyph->bitmap_top + m_face->glyph->bitmap.rows;
|
||||||
|
#endif
|
||||||
|
|
||||||
m_loaded = true;
|
return Data_Wrap_Struct(klass, NULL, Font_free, font);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Font::GlyphRef Font::load_glyph(FT_ULong char_code)
|
void Font_Init()
|
||||||
|
{
|
||||||
|
ruby_class = rb_define_class("Font", rb_cObject);
|
||||||
|
rb_define_singleton_method(ruby_class, "new", (VALUE(*)(...))Font_new, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GlyphRef load_glyph(Font * font, FT_ULong char_code)
|
||||||
{
|
{
|
||||||
GlyphRef glyph = new Glyph();
|
GlyphRef glyph = new Glyph();
|
||||||
if (glyph->load(m_face, char_code))
|
if (glyph->load(font->face, char_code))
|
||||||
return glyph;
|
return glyph;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Font::Glyph::Glyph()
|
static GlyphRef get_glyph(Font * font, FT_ULong char_code)
|
||||||
|
{
|
||||||
|
auto it = font->glyphs.find(char_code);
|
||||||
|
if (it != font->glyphs.end())
|
||||||
|
return it->second;
|
||||||
|
GlyphRef g = load_glyph(font, char_code);
|
||||||
|
font->glyphs[char_code] = g;
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
|
||||||
|
Glyph::Glyph()
|
||||||
{
|
{
|
||||||
m_loaded = false;
|
m_loaded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Font::Glyph::load(FT_Face face, FT_ULong char_code)
|
bool Glyph::load(FT_Face face, FT_ULong char_code)
|
||||||
{
|
{
|
||||||
if (FT_Load_Char(face, char_code, FT_LOAD_RENDER) != 0)
|
if (FT_Load_Char(face, char_code, FT_LOAD_RENDER) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
60
src/Font.h
60
src/Font.h
@ -1,64 +1,6 @@
|
|||||||
#ifndef JES_FONT_H
|
#ifndef JES_FONT_H
|
||||||
#define JES_FONT_H
|
#define JES_FONT_H
|
||||||
|
|
||||||
#include "Ref.h"
|
void Font_Init();
|
||||||
#include <ft2build.h>
|
|
||||||
#include FT_FREETYPE_H
|
|
||||||
#include "gl3w.h"
|
|
||||||
#include <unordered_map>
|
|
||||||
#include "GLTexture.h"
|
|
||||||
|
|
||||||
class Font
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
class Glyph
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Glyph();
|
|
||||||
bool load(FT_Face face, FT_ULong char_code);
|
|
||||||
int get_advance() { return m_advance; }
|
|
||||||
void render()
|
|
||||||
{
|
|
||||||
m_texture->bind();
|
|
||||||
glEnableVertexAttribArray(0);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id);
|
|
||||||
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
|
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
|
||||||
}
|
|
||||||
protected:
|
|
||||||
bool m_loaded;
|
|
||||||
int m_advance;
|
|
||||||
GLTextureRef m_texture;
|
|
||||||
GLuint m_vbo_id;
|
|
||||||
};
|
|
||||||
typedef Ref<Glyph> GlyphRef;
|
|
||||||
|
|
||||||
Font();
|
|
||||||
~Font();
|
|
||||||
bool load(FT_Library ft, const char * fname, size_t size);
|
|
||||||
int get_line_height() { return m_line_height; }
|
|
||||||
int get_advance() { return m_advance; }
|
|
||||||
int get_baseline_offset() { return m_baseline_offset; }
|
|
||||||
GlyphRef get_glyph(FT_ULong char_code)
|
|
||||||
{
|
|
||||||
auto it = m_glyphs.find(char_code);
|
|
||||||
if (it != m_glyphs.end())
|
|
||||||
return it->second;
|
|
||||||
GlyphRef g = load_glyph(char_code);
|
|
||||||
m_glyphs[char_code] = g;
|
|
||||||
return g;
|
|
||||||
}
|
|
||||||
protected:
|
|
||||||
GlyphRef load_glyph(FT_ULong char_code);
|
|
||||||
|
|
||||||
FT_Face m_face;
|
|
||||||
int m_line_height;
|
|
||||||
int m_advance;
|
|
||||||
int m_baseline_offset;
|
|
||||||
bool m_loaded;
|
|
||||||
std::unordered_map<FT_ULong, GlyphRef> m_glyphs;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef Ref<Font> FontRef;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
11
src/main.cc
11
src/main.cc
@ -1,8 +1,10 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "ruby.h"
|
#include "ruby.h"
|
||||||
#include "Window.h"
|
|
||||||
#include "GLShader.h"
|
#include "Font.h"
|
||||||
#include "GLProgram.h"
|
#include "GLProgram.h"
|
||||||
|
#include "GLShader.h"
|
||||||
|
#include "Window.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@ -50,9 +52,10 @@ static int bootstrap()
|
|||||||
int rv = 0;
|
int rv = 0;
|
||||||
int err_state = 0;
|
int err_state = 0;
|
||||||
|
|
||||||
Window_Init();
|
Font_Init();
|
||||||
GLShader_Init();
|
|
||||||
GLProgram_Init();
|
GLProgram_Init();
|
||||||
|
GLShader_Init();
|
||||||
|
Window_Init();
|
||||||
|
|
||||||
rb_eval_string_protect(
|
rb_eval_string_protect(
|
||||||
"load File.expand_path('../../runtime/main.rb', $0)",
|
"load File.expand_path('../../runtime/main.rb', $0)",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user