summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuo Jinghua <sunmoon1997@gmail.com>2011-06-13 11:03:42 +0800
committerLuo Jinghua <sunmoon1997@gmail.com>2011-06-13 11:19:50 +0800
commit2668d45c63d5e17501e5f9ff145d609a87c44945 (patch)
tree9074f061f2a5850f21c45f558a08b3f7a995afc7
parent40555bf99d5ccfa1bebe4e4231ab3d9a86a77cd4 (diff)
test: added a gles variant of wrap-test
-rw-r--r--src/Makefile.am14
-rw-r--r--src/gles-wrap-test.cpp493
-rw-r--r--src/wrap-test.cpp8
3 files changed, 511 insertions, 4 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index a731ad2..53dcf3d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -81,9 +81,11 @@ endif
if HAVE_OPENGLES
gles_test = gles-test
+gles_wrap_test = gles-wrap-test
endif
-noinst_PROGRAMS = hash-test cache-test font-test $(sdl_test) $(sdl_opengl_test) $(gles_test) $(wrap_test)
+noinst_PROGRAMS = hash-test cache-test font-test $(sdl_test) $(sdl_opengl_test) \
+ $(gles_test) $(wrap_test) $(gles_wrap_test)
hash_test_SOURCES = hash-test.c
hash_test_LDADD = libsdl-freetype.la
@@ -129,6 +131,16 @@ endif
endif
endif
+if HAVE_OPENGLES
+gles_wrap_test_SOURCES = gles-wrap-test.cpp
+gles_wrap_test_LDADD = libsdl-freetype-opengles.la $(EGL_LIBS)
+if HAVE_FONTCONFIG
+gles_wrap_test_LDADD += libsdl-ft.la
+else
+gles_wrap_test_LDADD += libsdl-freetype.la
+endif
+endif
+
lib_LTLIBRARIES = \
libsdl-freetype.la \
$(libsdl_ft) \
diff --git a/src/gles-wrap-test.cpp b/src/gles-wrap-test.cpp
new file mode 100644
index 0000000..f1a2001
--- /dev/null
+++ b/src/gles-wrap-test.cpp
@@ -0,0 +1,493 @@
+/* Copyright (C) <2011> Luo Jinghua<sunmoon1997@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <EGL/egl.h>
+#include <GLES/gl.h>
+
+#include <sdl-freetype.h>
+#include <sdl-freetype-opengles.h>
+
+#ifdef HAVE_FONTCONFIG
+#include <sdl-ft.h>
+#endif
+
+#include <stdio.h>
+
+static EGLDisplay eglDisplay = 0;
+static EGLConfig eglConfig = 0;
+static EGLContext eglContext = 0;
+static EGLSurface eglSurface = 0;
+
+#ifdef HAVE_X
+static Display *x11Display = NULL;
+static Window x11Window = None;
+#endif
+
+// consts
+#define COLOURDEPTH_RED_SIZE 8
+#define COLOURDEPTH_GREEN_SIZE 8
+#define COLOURDEPTH_BLUE_SIZE 8
+#define COLOURDEPTH_DEPTH_SIZE 16
+
+static const EGLint configAttribs[] ={
+ EGL_RED_SIZE, COLOURDEPTH_RED_SIZE,
+ EGL_GREEN_SIZE, COLOURDEPTH_GREEN_SIZE,
+ EGL_BLUE_SIZE, COLOURDEPTH_BLUE_SIZE,
+ EGL_DEPTH_SIZE, COLOURDEPTH_DEPTH_SIZE,
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
+ EGL_NONE
+};
+
+static int InitOpenGL(int width, int height)
+{
+ EGLint numConfigsOut = 0;
+ /* EGLint contextParams[] = {EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE}; // Use GLES version 1.x */
+
+#ifdef HAVE_X
+ // use EGL to initialise GLES
+ x11Display = XOpenDisplay(NULL);
+
+ if (!x11Display)
+ {
+ fprintf(stderr, "ERROR: unable to get display!n");
+ return 0;
+ }
+
+ x11Window = XCreateSimpleWindow(x11Display,
+ RootWindow(x11Display, DefaultScreen(x11Display)),
+ 1, 1, width, height, 0,
+ BlackPixel(x11Display, DefaultScreen(x11Display)),
+ BlackPixel(x11Display, DefaultScreen(x11Display)));
+ if (x11Window == None)
+ {
+ fprintf(stderr, "ERROR: unable to create a window!n");
+ return 0;
+ }
+
+ XMapWindow(x11Display, x11Window);
+ XFlush(x11Display);
+
+ eglDisplay = eglGetDisplay((EGLNativeDisplayType)x11Display);
+#else
+ eglDisplay = eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY);
+#endif
+ if (eglDisplay == EGL_NO_DISPLAY)
+ {
+ printf("Unable to initialise EGL display.");
+ return 0;
+ }
+
+ // Initialise egl
+ if (!eglInitialize(eglDisplay, NULL, NULL))
+ {
+ printf("Unable to initialise EGL display.");
+ return 0;
+ }
+
+ // Find a matching config
+ if (eglChooseConfig(eglDisplay, configAttribs, &eglConfig, 1, &numConfigsOut) != EGL_TRUE || numConfigsOut == 0)
+ {
+ fprintf(stderr, "Unable to find appropriate EGL config.");
+ return 0;
+ }
+
+#ifdef HAVE_X
+ eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, (EGLNativeWindowType)x11Window, 0);
+#else
+ eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, (EGLNativeWindowType)0, 0);
+#endif
+ if ( eglSurface == EGL_NO_SURFACE)
+ {
+ printf("Unable to create EGL surface!");
+ return 0;
+ }
+
+ // Bind GLES and create the context
+ eglBindAPI(EGL_OPENGL_ES_API);
+ eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, NULL);
+ if (eglContext == EGL_NO_CONTEXT)
+ {
+ printf("Unable to create GLES context!");
+ return 0;
+ }
+
+ if (eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) == EGL_FALSE)
+ {
+ printf("Unable to make GLES context current");
+ return 0;
+ }
+
+ return 1;
+}
+
+/*======================================================
+ * Kill off any opengl specific details
+ ====================================================*/
+static void TerminateOpenGL(void)
+{
+ eglMakeCurrent(eglDisplay, NULL, NULL, EGL_NO_CONTEXT);
+ eglDestroySurface(eglDisplay, eglSurface);
+ eglDestroyContext(eglDisplay, eglContext);
+ eglSurface = 0;
+ eglContext = 0;
+ eglConfig = 0;
+
+ eglTerminate(eglDisplay);
+ eglDisplay = 0;
+
+#ifdef HAVE_X
+ XDestroyWindow(x11Display, x11Window);
+ XCloseDisplay(x11Display);
+ x11Display = NULL;
+#endif
+}
+
+static int SwapBuffers(void)
+{
+ eglSwapBuffers(eglDisplay, eglSurface);
+ return 0;
+}
+
+#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,
+ TF_NOCLIP = 1 << 5
+};
+
+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,
+ const FT_Int32 *text, int len,
+ TextRect *rect,
+ TextFormat format,
+ TextColor color)
+{
+ if (!font || !text)
+ return 0;
+
+ if (len < 0) {
+ const FT_Int32 *s = text;
+
+ len = 0;
+ while (*s++)
+ len++;
+ }
+
+ TextLineVector lines;
+
+ 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 = rect->width << 16;
+ sdl_freetype_fixed_t maxwidth = 0;
+ bool clip = (format & TF_NOCLIP) == 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 (clip && (y + exts.height) >> 16 > rect->height)
+ break;
+
+ 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) {
+ if (!clip || x + metrics.width <= width)
+ line->glyphs.push_back(g);
+ else
+ break;
+ } else {
+ if (clip && 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.height - exts.descent) >> 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());
+ }
+ }
+
+ if (!lines[0].glyphs.size())
+ return 0;
+
+ rect->width = maxwidth >> 16;
+ return (lines.size() * exts.height) >> 16;
+}
+
+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);
+}
+
+#define WIDTH 640
+#define HEIGHT 480
+int
+main(int argc, char *argv[])
+{
+ int done;
+ sdl_freetype_font_t * font;
+ sdl_freetype_glyph_render_t * render;
+ sdl_freetype_text_extents_t extents;
+ float alpha, step;
+ FT_Int32 text[] = { 'h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '.', ' ',
+ 0x4f60, 0x597d, ',', ' ', 0x5927, 0x4e16, 0x754c, 0xff01, 0x0000 };
+
+#ifdef HAVE_FONTCONFIG
+ font = sdl_ft_create_font ("sans", 16,
+ SDL_FT_WEIGHT_NORMAL, SDL_FT_SLANT_NORMAL, 96);
+#else
+ if (argc < 2) {
+ printf("usage: %s /path/to/font.ttf\n", argv[0]);
+ return -1;
+ }
+ font = sdl_freetype_font_create(argv[1], 16 * 96 / 72.0);
+#endif
+ if (!font)
+ goto errquit0;
+
+ if (!InitOpenGL(WIDTH, HEIGHT))
+ return -1;
+
+ render = sdl_freetype_opengles_render_create ();
+ if (!render)
+ goto errquit1;
+ sdl_freetype_font_set_render (font, render);
+
+ glMatrixMode (GL_PROJECTION) ;
+ glLoadIdentity ();
+ glOrthof (0, WIDTH, HEIGHT, 0, -1.0, 1.0);
+
+ glMatrixMode (GL_MODELVIEW);
+ glLoadIdentity ();
+
+ alpha = 1.0f;
+ step = -0.002;
+ done = 0;
+ while (!done) {
+ float x, y;
+
+#ifdef HAVE_X
+ XEvent xevent;
+
+ while (XPending(x11Display)) {
+ XNextEvent(x11Display, &xevent);
+ if (xevent.type == KeyPress)
+ done = 1;
+ }
+#endif
+
+ glClearColor (0.8f, 0.8f, 0.8f, 1.0f);
+ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glMatrixMode (GL_MODELVIEW);
+ glLoadIdentity ();
+
+ glScalef (alpha + 1.0, alpha + 1.0, 1.0);
+
+ TextColor color;
+ color.r = 255;
+ color.g = 0;
+ color.b = 0;
+ color.a = 64 + alpha * (255 - 64);
+
+ TextRect rect;
+ rect.x = 400;
+ rect.y = 100;
+ rect.width = 200;
+ rect.height = 100;
+
+ int h;
+
+ // draw a single line and left aligned text
+ h = DrawText(font, text, -1, &rect, TextFormat(TF_SINGLELINE | TF_LEFT), color);
+ DrawRect(400, 100, 200, 100);
+ DrawLine(400, 100 + h, 400 + 200, 100 + h);
+
+ // draw a multiple lines and left aligned text
+ rect.x = 100;
+ rect.y = 100;
+ rect.width = 100;
+ rect.height = 100;
+ h = DrawText(font, text, -1, &rect, TF_LEFT, color);
+ DrawRect(100, 100, 200, 100);
+ DrawLine(100, 100 + h, 100 + 200, 100 + h);
+
+ // draw a multiple lines and right aligned text
+ 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);
+
+ // draw a multiple lines and center aligned text
+ 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);
+
+ SwapBuffers();
+
+ alpha += step;
+ if (alpha < 0.0f) {
+ alpha = 0.0f;
+ step = -step;
+ } else if (alpha > 1.0f) {
+ alpha = 1.0f;
+ step = -step;
+ }
+ }
+
+ errquit1:
+ sdl_freetype_font_destroy (font);
+ sdl_freetype_fini ();
+
+ errquit0:
+ TerminateOpenGL();
+ return 0;
+}
diff --git a/src/wrap-test.cpp b/src/wrap-test.cpp
index 7dca6d0..68cec7a 100644
--- a/src/wrap-test.cpp
+++ b/src/wrap-test.cpp
@@ -74,8 +74,6 @@ DrawText(sdl_freetype_font_t * font,
if (!font || !text)
return 0;
- TextLineVector lines;
-
if (len < 0) {
FT_Int32 *s = text;
@@ -84,6 +82,8 @@ DrawText(sdl_freetype_font_t * font,
len++;
}
+ TextLineVector lines;
+
sdl_freetype_font_fixed_extents_t exts;
sdl_freetype_font_fixed_extents(font, &exts);
@@ -176,7 +176,7 @@ DrawText(sdl_freetype_font_t * font,
for (size_t i = 0; i < lines.size(); i++) {
TextLine &line = lines[i];
- xoffset = line.exts.x_bearing >> 16;
+ xoffset = -line.exts.x_bearing >> 16;
if (format & TF_RIGHT)
xoffset += rect->width - (line.exts.width >> 16);
else if (format & TF_CENTER)
@@ -304,6 +304,8 @@ main(int argc, char *argv[])
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
+ glScalef (alpha + 1.0, alpha + 1.0, 1.0);
+
TextColor color;
color.r = 255;
color.g = 0;