diff options
author | Luo Jinghua <sunmoon1997@gmail.com> | 2011-06-12 16:48:49 +0800 |
---|---|---|
committer | Luo Jinghua <sunmoon1997@gmail.com> | 2011-06-12 16:48:49 +0800 |
commit | 618d9d3062aa2e9be38490dcc4fefb6e2da6419f (patch) | |
tree | 978309349708aa514b06bd25297afb5767633115 | |
parent | 585303c5727ba65fd41896ae6b22346595ae36bd (diff) |
test: add another test program
-rw-r--r-- | src/Makefile.am | 7 | ||||
-rw-r--r-- | src/wrap-test.cpp | 315 |
2 files changed, 321 insertions, 1 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 2a43f7d..78fb735 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,5 @@ AM_CFLAGS = -I$(srcdir) $(FONTCONFIG_CFLAGS) $(FREETYPE_CFLAGS) $(SDL_CFLAGS) $(WARN_CFLAGS) $(CFLAGS) +AM_CXXFLAGS = $(AM_CFLAGS) if HAVE_FONTCONFIG libsdl_ft = libsdl-ft.la @@ -68,6 +69,7 @@ if HAVE_SDL sdl_test = sdl-test if HAVE_OPENGL sdl_opengl_test = sdl-opengl-test +wrap_test = wrap-test endif endif @@ -75,7 +77,7 @@ if HAVE_OPENGLES gles_test = gles-test endif -noinst_PROGRAMS = hash-test cache-test font-test $(sdl_test) $(sdl_opengl_test) $(gles_test) +noinst_PROGRAMS = hash-test cache-test font-test $(sdl_test) $(sdl_opengl_test) $(gles_test) $(wrap_test) hash_test_SOURCES = hash-test.c hash_test_LDADD = libsdl-freetype.la @@ -94,6 +96,9 @@ sdl_opengl_test_LDADD = libsdl-freetype-opengl.la libsdl-ft.la gles_test_SOURCES = gles-test.c gles_test_LDADD = libsdl-freetype-opengles.la libsdl-ft.la $(EGL_LIBS) +wrap_test_SOURCES = wrap-test.cpp +wrap_test_LDADD = libsdl-freetype-opengl.la libsdl-ft.la + lib_LTLIBRARIES = \ libsdl-freetype.la \ $(libsdl_ft) \ diff --git a/src/wrap-test.cpp b/src/wrap-test.cpp new file mode 100644 index 0000000..f2d22a0 --- /dev/null +++ b/src/wrap-test.cpp @@ -0,0 +1,315 @@ +#include <SDL.h> + +#include <GL/gl.h> + +#include <sdl-freetype.h> +#include <sdl-freetype-opengl.h> +#include <sdl-ft.h> + +#include <stdio.h> + +#include <vector> + +enum TextFormat { + TF_NONE = 0, + TF_CALCRECT = 1 << 0, + TF_CENTER = 1 << 1, + TF_LEFT = 1 << 2, + TF_RIGHT = 1 << 3, + TF_SINGLELINE = 1 << 4 +}; + +struct TextRect { + int x; + int y; + int width; + int height; +}; + +struct TextColor { + unsigned char r; + unsigned char g; + unsigned char b; + unsigned char a; +}; + +typedef std::vector<sdl_freetype_glyph_t> GlyphVector; +struct TextLine { + GlyphVector glyphs; + sdl_freetype_text_fixed_extents_t exts; +}; +typedef std::vector<TextLine> TextLineVector; + +static int +DrawText(sdl_freetype_font_t * font, + FT_Int32 *text, int len, + TextRect *rect, + TextFormat format, + TextColor color) +{ + if (!font || !text) + return 0; + + TextLineVector lines; + + if (len < 0) { + FT_Int32 *s = text; + + len = 0; + while (*s++) + len++; + } + + sdl_freetype_font_fixed_extents_t exts; + sdl_freetype_font_fixed_extents(font, &exts); + + sdl_freetype_fixed_t x = 0; + sdl_freetype_fixed_t y = 0; + sdl_freetype_fixed_t adv_x = 0; + sdl_freetype_fixed_t adv_y = 0; + sdl_freetype_fixed_t width = format & TF_SINGLELINE ? 0 : rect->width << 16; + sdl_freetype_fixed_t maxwidth = 0; + + lines.push_back(TextLine()); + TextLine *line = &lines.back(); + memset(&line->exts, 0, sizeof(line->exts)); + + for (int i = 0; i < len; i++) { + sdl_freetype_glyph_t g; + sdl_freetype_text_fixed_extents_t metrics; + + if (text[i] == '\r') + continue; + + if (text[i] == '\n') { + if (format & TF_SINGLELINE) + continue; + y += exts.height; + + sdl_freetype_font_glyphs_fixed_extents(font, &line->exts, + &line->glyphs[0], line->glyphs.size()); + if (line->exts.width > maxwidth) + maxwidth = line->exts.width; + + lines.push_back(TextLine()); + line = &lines.back(); + memset(&line->exts, 0, sizeof(line->exts)); + adv_x = 0; + adv_y = 0; + x = 0; + } + + x += adv_x; + y += adv_y; + g.x = x; + g.y = y; + g.index = sdl_freetype_font_glyph_index(font, text[i]); + if (!g.index || sdl_freetype_font_glyph_fixed_metrics(font, g.index, &metrics)) { + adv_x = 0; + adv_y = 0; + continue; + } else { + adv_x = metrics.x_advance; + adv_y = metrics.y_advance; + } + if (format & TF_SINGLELINE) { + line->glyphs.push_back(g); + } else { + if (x + metrics.width > width) { + sdl_freetype_font_glyphs_fixed_extents(font, &line->exts, + &line->glyphs[0], line->glyphs.size()); + if (line->exts.width > maxwidth) + maxwidth = line->exts.width; + + lines.push_back(TextLine()); + line = &lines.back(); + memset(&line->exts, 0, sizeof(line->exts)); + + x = 0; + y += exts.height; + g.y = y; + g.x = x; + } + line->glyphs.push_back(g); + } + } + if (line->glyphs.size() && !line->exts.width) + sdl_freetype_font_glyphs_fixed_extents(font, &line->exts, + &line->glyphs[0], line->glyphs.size()); + if (!(format & TF_CALCRECT)) { + int xoffset; + int yoffset; + + if (lines.size()) + yoffset = exts.ascent >> 16; + for (size_t i = 0; i < lines.size(); i++) { + TextLine &line = lines[i]; + + xoffset = line.exts.x_bearing >> 16; + if (format & TF_RIGHT) + xoffset += rect->width - (line.exts.width >> 16); + else if (format & TF_CENTER) + xoffset += (rect->width - (line.exts.width >> 16)) / 2; + + sdl_freetype_font_show_glyphs(font, 0, + color.r, color.g, color.b, color.a, + rect->x + xoffset, rect->y + yoffset, + &line.glyphs[0], line.glyphs.size()); + } + } + + rect->width = maxwidth / 65536.0f; + return (lines.size() * exts.height) / 65536.0f; +} + +static void DrawLine(float x0, float y0, float x1, float y1) +{ + GLfloat verts[4]; + + verts[0] = x0; + verts[1] = y0; + verts[2] = x1; + verts[3] = y1; + + glEnableClientState (GL_VERTEX_ARRAY); + + glVertexPointer (2, GL_FLOAT, 0, verts); + glDrawArrays (GL_LINES, 0, 2); + + glDisableClientState (GL_VERTEX_ARRAY); +} + +static void DrawRect(float x, float y, float w, float h) +{ + DrawLine(x, y, x + w, y); + DrawLine(x + w, y, x + w, y + h); + DrawLine(x + w, y + h, x, y + h); + DrawLine(x, y + h, x, y); +} + +int +main(int argc, char *argv[]) +{ + SDL_Surface * screen; + Uint8 video_bpp; + Uint32 videoflags; + int done; + SDL_Event event; + float alpha, step; + sdl_freetype_font_t * font; + sdl_freetype_glyph_render_t * render; + FT_Int32 text[] = { 'h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '.', ' ', + 0x4f60, 0x597d, ',', ' ', 0x5927, 0x4e16, 0x754c, 0xff01, 0x0000 }; + + /* Initialize SDL */ + if (SDL_Init (SDL_INIT_VIDEO) < 0) + goto errquit0; + + videoflags = SDL_HWSURFACE; + videoflags |= SDL_OPENGL; + video_bpp = 32; + + /* Set 640x480 video mode */ + screen = SDL_SetVideoMode (640, 480, video_bpp, videoflags); + if (!screen) + goto errquit0; + + font = sdl_ft_create_font ("sans", 18, + SDL_FT_WEIGHT_NORMAL, SDL_FT_SLANT_NORMAL, 96); + if (!font) + goto errquit0; + + render = sdl_freetype_opengl_render_create (); + if (!render) + goto errquit1; + sdl_freetype_font_set_render (font, render); + + glMatrixMode (GL_PROJECTION) ; + glLoadIdentity (); + glOrtho (0, 640, 480, 0, -1.0, 1.0); + + glMatrixMode (GL_MODELVIEW); + glLoadIdentity (); + + glEnable (GL_TEXTURE_2D); + glClearColor (0.8f, 0.8f, 0.8f, 0.0f); + + alpha = 1.0f; + step = -0.01; + /* Wait for a keystroke */ + done = 0; + while (!done) { + /* Check for events */ + while (SDL_PollEvent (&event)) { + switch (event.type) { + case SDL_MOUSEBUTTONDOWN: + break; + case SDL_KEYDOWN: + case SDL_QUIT: + done = 1; + break; + default: + break; + } + } + + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode (GL_MODELVIEW); + glLoadIdentity (); + + TextColor color; + color.r = 255; + color.g = 0; + color.b = 0; + color.a = alpha * 255; + + TextRect rect; + rect.x = 100; + rect.y = 100; + rect.width = 100; + rect.height = 100; + + int h; + + h = DrawText(font, text, -1, &rect, TF_LEFT, color); + DrawRect(100, 100, 200, 100); + DrawLine(100, 100 + h, 100 + 200, 100 + h); + + rect.x = 100; + rect.y = 200; + rect.width = 200; + rect.height = 100; + h = DrawText(font, text, -1, &rect, TF_RIGHT, color); + DrawRect(100, 200, 200, 100); + DrawLine(100, 200 + h, 100 + 200, 200 + h); + + rect.x = 100; + rect.y = 300; + rect.width = 200; + rect.height = 100; + h = DrawText(font, text, -1, &rect, TF_CENTER, color); + DrawRect(100, 300, 200, 100); + DrawLine(100, 300 + h, 100 + 200, 300 + h); + + SDL_GL_SwapBuffers(); + + alpha += step; + if (alpha < 0.0f) { + alpha = 0.0f; + step = -step; + } else if (alpha > 1.0f) { + alpha = 1.0f; + step = -step; + } + + SDL_Delay(20); + } + + errquit1: + sdl_freetype_font_destroy (font); + sdl_freetype_fini (); + + errquit0: + SDL_Quit(); + return 0; +} |