2 Commits c1b5883433 ... 6df044ab2a

Author SHA1 Message Date
  Niels Nesse 6df044ab2a Use UTF-32 for charset instead of UTF-8 9 years ago
  Niels Nesse aaa65d8a9e Specify number of characters in submit render 9 years ago
5 changed files with 44 additions and 54 deletions
  1. 5 2
      Makefile.am
  2. 0 2
      configure.ac
  3. 21 15
      src/examples/text_render.c
  4. 13 31
      src/text/gltext.c
  5. 5 4
      src/text/gltext.h

+ 5 - 2
Makefile.am

@@ -11,9 +11,11 @@ AM_CPPFLAGS += -I$(top_srcdir)/src/math
 AM_CPPFLAGS += -I$(top_srcdir)/src/text
 #endif
 
+AM_CFLAGS = -std=c11
+
 lib_LTLIBRARIES = libglplatform.la
 libglplatform_la_LIBADD=$(FREETYPE2_LIBS)
-libglplatform_la_CFLAGS=-std=c99 $(FREETYPE2_CFLAGS)
+libglplatform_la_CFLAGS=$(FREETYPE2_CFLAGS) $(AM_CFLAGS)
 libglplatform_la_SOURCES = src/glbindings/glplatform-glcore.c
 
 if WINDOWS
@@ -49,6 +51,7 @@ endif
 
 simple_window_SOURCES = src/examples/simple_window.c
 simple_window_LDADD = libglplatform.la
+simple_window_CFLAGS = $(AM_CFLAGS)
 
 if WINDOWS
 simple_window_LDADD += $(WINDOWS_LDADD)
@@ -56,7 +59,7 @@ endif
 
 
 text_render_SOURCES = src/examples/text_render.c
-text_render_CFLAGS = -DTTF_PATH=\"${abs_srcdir}/src/examples/ttf/\"
+text_render_CFLAGS = -DTTF_PATH=\"${abs_srcdir}/src/examples/ttf/\" $(AM_CFLAGS)
 text_render_LDADD = libglplatform.la
 
 if WINDOWS

+ 0 - 2
configure.ac

@@ -20,8 +20,6 @@ fi
 AS_IF([ test $enable_text = yes ],
 	[PKG_CHECK_MODULES(FREETYPE2,freetype2 >= 2.53, [ enable_text="yes" ], [ enable_text="no" ])])
 
-AC_CHECK_HEADER("iconv.h",,AC_MSG_ERROR([Could not find iconv.h]))
-
 AS_IF([ test $host_os = 'linux-gnu' ],
 	[AC_CHECK_LIB([X11],[XOpenDisplay],,AC_MSG_ERROR([Could not find libX11]))
 	 AC_CHECK_LIB([GL],[glXGetProcAddress],,AC_MSG_ERROR([Could not find libGL]))])

+ 21 - 15
src/examples/text_render.c

@@ -9,6 +9,8 @@
 #include <windows.h>
 #endif
 
+#include <uchar.h>
+
 void on_destroy(struct glplatform_win *win)
 {
 	glplatform_destroy_window(win);
@@ -30,10 +32,10 @@ int main()
 		.on_destroy = on_destroy
 	};
 
-
-	const char *charset = " abcdefghijklmnopqrstuvwxyz"
-		"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-		"'\"0123456789`~!@#$%^&*()_+;/?.>,<={}[]\\";
+	const char32_t *charset = U"abcdefghijklmnopqrstuvwxyz"
+		U"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+		U"0123456789"
+		U" '\"`~!@#$%^&*()_+;/?.>,<={}[]\u2122";
 
 	if (!glplatform_init()) {
 		fprintf(stderr, "Failed to initialize GL window manager\n");
@@ -55,7 +57,7 @@ int main()
 
 	font = gltext_font_create(charset,
 		gltext_get_typeface(TTF_PATH "LiberationSans-Regular.ttf"),
-		20);
+		22);
 
 	if (!font) {
 		fprintf(stderr, "Failed to create font\n");
@@ -71,8 +73,10 @@ int main()
 		glClearColor(0,0,0,1);
 		glClear(GL_COLOR_BUFFER_BIT);
 
-		const char *str = "The quick brown fox jumps over the lazy dog()'\"0123456789`~!@#$%^&*()_+;/?.>,<={}[]\\";
-		struct gltext_glyph_instance *r = gltext_prepare_render(font, (int)strlen(str));
+		const char32_t *str = U"The quick brown fox jumps over the lazy dog()'\"0123456789`~!@#$%^&*()_+;/?.>,<={}[]\u2122\\";
+		int sz = 0;
+		while (str[sz]) sz++;
+		struct gltext_glyph_instance *r = gltext_prepare_render(font, sz);
 
 		const struct gltext_glyph *g_prev = NULL;
 		float x_pos = 0;
@@ -83,14 +87,16 @@ int main()
 			.b = 1,
 			.a = 1
 		};
-		while (*str) {
-			const struct gltext_glyph *g_cur = gltext_get_glyph(font, *str);
+		int num_chars = 0;
+		for (int i = 0; i < sz; i++) {
+			const struct gltext_glyph *g_cur = gltext_get_glyph(font, str[i]);
+			if (!g_cur)
+				continue;
 			x_pos += gltext_get_advance(g_prev, g_cur);
-			r->pos[0] = x_pos;
-			r->pos[1] = y_pos;
-			r->w = g_cur->w;
-			r++;
-			str++;
+			r[num_chars].pos[0] = x_pos;
+			r[num_chars].pos[1] = y_pos;
+			r[num_chars].w = g_cur->w;
+			num_chars++;
 			g_prev = g_cur;
 		}
 		x_pos += gltext_get_advance(g_prev, NULL);
@@ -99,7 +105,7 @@ int main()
 			0,-2.0f/height,0,0,
 			0,0,1,0,
 			-1 + ((width - x_pos)/2)*(2.0f/width),1 + (height/2)*(-2.0f/height),0,1};
-		gltext_submit_render(&color, mvp);
+		gltext_submit_render(&color, num_chars, mvp);
 		glplatform_swap_buffers(win);
 
 		if (glplatform_get_events(true) < 0)

+ 13 - 31
src/text/gltext.c

@@ -10,7 +10,6 @@
 #include <ft2build.h>
 #include FT_FREETYPE_H
 
-#include <iconv.h>
 #include <string.h>
 
 enum vertex_attrib_locations {
@@ -35,9 +34,8 @@ struct gltext_font {
 	int max_char;
 };
 
-const struct gltext_glyph *gltext_get_glyph(gltext_font_t font_, uint32_t c)
+const struct gltext_glyph *gltext_get_glyph(gltext_font_t font, char32_t c)
 {
-	struct gltext_font *font = (struct gltext_font *)(font_);
 	struct gltext_glyph *g;
 	if (c > font->max_char) {
 		return NULL;
@@ -73,7 +71,6 @@ struct gltext_renderer
 	int glyph_metric_sampler_loc;
 	int mvp_loc;
 	int num_chars;
-	iconv_t utf8_to_utf32;
 };
 
 static bool init_renderer(struct gltext_renderer *inst);
@@ -145,7 +142,7 @@ struct gltext_glyph_instance *gltext_prepare_render(gltext_font_t font, int num_
 	return ret;
 }
 
-void gltext_submit_render(const struct gltext_color *color, const float *mvp)
+void gltext_submit_render(const struct gltext_color *color, int num_chars, const float *mvp)
 {
 	struct gltext_renderer *inst = get_renderer();
 	if (!inst)
@@ -157,7 +154,7 @@ void gltext_submit_render(const struct gltext_color *color, const float *mvp)
 	glBindVertexArray(inst->gl_vertex_array);
 	glUniformMatrix4fv(inst->mvp_loc, 1, GL_FALSE, mvp);
 	glUniform4fv(inst->color_loc, 1, (GLfloat *)color);
-	glDrawArrays(GL_POINTS, 0, inst->num_chars);
+	glDrawArrays(GL_POINTS, 0, num_chars);
 }
 
 void deinit_renderer(struct gltext_renderer *inst)
@@ -167,7 +164,6 @@ void deinit_renderer(struct gltext_renderer *inst)
 	glDeleteShader(inst->vertex_shader);
 	glDeleteProgram(inst->glsl_program);
 	FT_Done_FreeType(inst->ft_library);
-	iconv_close(inst->utf8_to_utf32);
 }
 
 gltext_typeface_t gltext_get_typeface(const char *path)
@@ -186,9 +182,6 @@ gltext_typeface_t gltext_get_typeface(const char *path)
 
 static bool init_renderer(struct gltext_renderer *inst)
 {
-	inst->utf8_to_utf32 = iconv_open("UTF-32", "UTF-8");
-	if (inst->utf8_to_utf32 == (iconv_t)-1)
-		return false;
 	FT_Init_FreeType(&inst->ft_library);
 	if (!inst->ft_library)
 		goto error0;
@@ -348,7 +341,6 @@ error1:
 	inst->gl_vertex_array = 0;
 	FT_Done_FreeType(inst->ft_library);
 error0:
-	iconv_close(inst->utf8_to_utf32);
 	return false;
 }
 
@@ -397,7 +389,7 @@ void gltext_font_destroy_texture(gltext_font_t font)
 	}
 }
 
-gltext_font_t gltext_font_create(const char *charset_utf8,
+gltext_font_t gltext_font_create(const char32_t *charset,
 	gltext_typeface_t typeface_,
 	int size)
 {
@@ -418,23 +410,14 @@ gltext_font_t gltext_font_create(const char *charset_utf8,
 
 	f->size = size;
 
-	int charset_utf8_len = (int)strlen(charset_utf8);
-
-	uint32_t *charset_utf32 = (uint32_t *)calloc(charset_utf8_len, sizeof(uint32_t));
-
-	char *inbuf = (char *)charset_utf8;
-	char *outbuf = (char *)charset_utf32;
-	size_t inbytesleft = charset_utf8_len;
-	size_t outbytesleft = (charset_utf8_len + 1) * sizeof(uint32_t);
-	size_t rc = iconv(inst->utf8_to_utf32, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
-	if (rc == -1)
-		return 0;
-
-	f->total_glyphs = ((uint32_t *)outbuf) - charset_utf32;
+	int charset_len = 0;
+        while (charset[charset_len])
+		charset_len++;
+	f->total_glyphs = charset_len;
 
 	int max_char = 0;
 	for (int i = 0; i < f->total_glyphs; i++) {
-		uint32_t c = charset_utf32[i];
+		uint32_t c = charset[i];
 		if (c > max_char)
 			max_char = c;
 	}
@@ -449,7 +432,7 @@ gltext_font_t gltext_font_create(const char *charset_utf8,
 	int w = 0;
 
 	for (int i = 0; i < f->total_glyphs; i++) {
-		uint32_t c = charset_utf32[i];
+		uint32_t c = charset[i];
 		struct gltext_glyph *g = f->glyph_array + c;
 		g->w = w++;
 		int index = FT_Get_Char_Index(typeface, c);
@@ -474,13 +457,13 @@ gltext_font_t gltext_font_create(const char *charset_utf8,
 	}
 
 	for (int i = 0; i < f->total_glyphs; i++) {
-		uint32_t cprev = charset_utf32[i];
+		uint32_t cprev = charset[i];
 		struct gltext_glyph *prev = f->glyph_array + cprev;
 		int index_prev = FT_Get_Char_Index(typeface, cprev);
 		if (!index_prev)
 			continue;
 		for (int j = 0; j < f->total_glyphs; j++) {
-			uint32_t cnext = charset_utf32[j];
+			uint32_t cnext = charset[j];
 			struct gltext_glyph *next = f->glyph_array + cprev;
 			int index_next = FT_Get_Char_Index(typeface, cnext);
 			if (!index_next)
@@ -524,7 +507,7 @@ gltext_font_t gltext_font_create(const char *charset_utf8,
 
 	uint8_t *layer_ptr = atlas_buffer;
 	for (int i = 0; i < f->total_glyphs; i++) {
-		uint32_t c = charset_utf32[i];
+		uint32_t c = charset[i];
 		struct gltext_glyph *g = f->glyph_array + c;
 		int gindex = FT_Get_Char_Index(typeface, c);
 		if (gindex) {
@@ -573,7 +556,6 @@ gltext_font_t gltext_font_create(const char *charset_utf8,
 	free(gx);
 	free(gy);
 	free(dist);
-	free(charset_utf32);
 	f->glyph_metric_array = glyph_metric_array;
 	f->atlas_buffer = atlas_buffer;
 

+ 5 - 4
src/text/gltext.h

@@ -3,6 +3,7 @@
 
 #include <stdint.h>
 #include <stdbool.h>
+#include <uchar.h>
 
 struct gltext_font;
 
@@ -82,10 +83,10 @@ gltext_typeface_t gltext_get_typeface(const char *path);
  *
  * gltext_font_create()
  *
- * Create a font for a specific typeface and charset (UTF-8).
+ * Create a font for a specific typeface and charset (UTF-32).
  *
  */
-gltext_font_t gltext_font_create(const char *charset_utf8, gltext_typeface_t typeface, int font_size);
+gltext_font_t gltext_font_create(const char32_t *charset_utf32, gltext_typeface_t typeface, int font_size);
 
 
 /*
@@ -127,7 +128,7 @@ bool gltext_font_free(gltext_font_t font);
  * the renderer's charset the return value will be NULL.
  *
  */
-const struct gltext_glyph *gltext_get_glyph(gltext_font_t font_, uint32_t c);
+const struct gltext_glyph *gltext_get_glyph(gltext_font_t font_, char32_t c);
 
 /*
  * gltext_prepare_render()
@@ -163,6 +164,6 @@ const struct gltext_glyph *gltext_get_glyph(gltext_font_t font_, uint32_t c);
   * Small font sizes display best when aligned to exact window coordinates
   * with integral glyph positions.
   */
- void gltext_submit_render(const struct gltext_color *color, const float *mvp);
+ void gltext_submit_render(const struct gltext_color *color, int num_chars, const float *mvp);
 
 #endif