From 1e34c5a67bf0799f6b95e921a6c622bfe7a9f3fa Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Thu, 29 May 2003 00:08:03 +0000 Subject: [PATCH] segs on shutdown, but renders characters, tho the glyph size info is incorrect still. --- glft/font.c | 12 +++---- glft/render.c | 70 +++++++++++++++++++++++++++++++++++++ glft/test.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 169 insertions(+), 8 deletions(-) diff --git a/glft/font.c b/glft/font.c index fcb0512c..db748ba2 100644 --- a/glft/font.c +++ b/glft/font.c @@ -14,11 +14,11 @@ struct GHashTable *glyph_map = NULL; #define TRUNC(x) ((x) >> 6) #define ROUND(x) (((x)+32) & -64) -void dest_glyph_map_value(gpointer data) +void dest_glyph_map_value(gpointer key, gpointer val, gpointer data) { - struct GlftGlyph *g = data; + struct GlftGlyph *g = val; glDeleteLists(g->dlist, 1); - free(data); + free(g); } struct GlftFont *GlftFontOpen(const char *name) @@ -187,9 +187,6 @@ struct GlftFont *GlftFontOpen(const char *name) goto openfail0; } - font->glyph_map = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, - dest_glyph_map_value); - if (font->char_width) font->max_advance_width = font->char_width; else @@ -199,6 +196,8 @@ struct GlftFont *GlftFontOpen(const char *name) if (font->minspace) font->height = font->ascent + font->descent; else font->height = font->face->size->metrics.height >> 6; + font->glyph_map = g_hash_table_new(g_int_hash, g_int_equal); + return font; openfail0: @@ -213,6 +212,7 @@ void GlftFontClose(struct GlftFont *font) FT_Done_Face(font->face); FcPatternDestroy(font->pat); FcCharSetDestroy(font->chars); + g_hash_table_foreach(font->glyph_map, dest_glyph_map_value, NULL); g_hash_table_destroy(font->glyph_map); free(font); } diff --git a/glft/render.c b/glft/render.c index 5eb545ea..2da342c5 100644 --- a/glft/render.c +++ b/glft/render.c @@ -4,9 +4,79 @@ #include #include +#include FT_OUTLINE_H + +struct GlftWalkState { + int drawing; + float x, y; +}; + +static struct GlftWalkState state; + +int GlftMoveToFunc(FT_Vector *to, void *user) +{ + state.x = (to->x >> 6) + (to->x & 63)/64; + state.y = (to->y >> 6) + (to->y & 63)/64; + printf("move to %f:%f\n", state.x, state.y); + if (state.drawing) { + glEnd(); + state.drawing = 0; + } + return 0; +} + +int GlftLineToFunc(FT_Vector *to, void *user) +{ + if (!state.drawing) { + glBegin(GL_LINES); + glVertex2f(state.x, state.y); + } + state.x = (to->x >> 6) + (to->x & 63)/64; + state.y = (to->y >> 6) + (to->y & 63)/64; + printf("line to %f:%f\n", state.x, state.y); + glVertex2f(state.x, state.y); + return 0; +} + +int GlftConicToFunc(FT_Vector *c, FT_Vector *to, void *user) +{ + GlftLineToFunc(to, user); + printf("conic the hedgehog!\n"); + return 0; +} + +int GlftCubicToFunc(FT_Vector *c1, FT_Vector *c2, FT_Vector *to, void +*user) +{ + GlftLineToFunc(to, user); + printf("cubic\n"); + return 0; +} + +FT_Outline_Funcs GlftFuncs = { + GlftMoveToFunc, + GlftLineToFunc, + GlftConicToFunc, + GlftCubicToFunc, + 0, + 0 +}; + void GlftRenderGlyph(FT_Face face, unsigned int dlist) { + int err; FT_GlyphSlot slot = face->glyph; + + state.x = 0; + state.y = 0; + state.drawing = 0; + + glNewList(dlist, GL_COMPILE); + err = FT_Outline_Decompose(&slot->outline, &GlftFuncs, NULL); + g_assert(!err); + if (state.drawing) + glEnd(); + glEndList(); } void GlftRenderString(struct GlftFont *font, const char *str, int bytes, diff --git a/glft/test.c b/glft/test.c index 8b350104..86f986f7 100644 --- a/glft/test.c +++ b/glft/test.c @@ -1,19 +1,110 @@ #include "glft.h" #include + +#include +#include +#include +#include +#include +#include +#include "render.h" +#include +#include + +static int x_error_handler(Display * disp, XErrorEvent * error) +{ + char buf[1024]; + XGetErrorText(disp, error->error_code, buf, 1024); + printf("%s\n", buf); + return 0; +} + +#define X 10 +#define Y 10 +#define W 500 +#define H 500 + int main(int argc, char **argv) { + Display *display; + Window win; + XVisualInfo *vi; + XEvent report, report2; + XClassHint chint; + Atom delete_win, protocols; + GLXContext cont; + int quit; + int config[] = + { GLX_DEPTH_SIZE, 1, GLX_DOUBLEBUFFER, GLX_RGBA, None }; + struct GlftFont *font; if (argc < 2) { - printf("Usage: %s fontname\n", argv[0]); + printf("Usage: %s fontname text\n", argv[0]); return 1; } if (!GlftInit()) return 1; font = GlftFontOpen(argv[1]); + + if (!(display = XOpenDisplay(NULL))) { + fprintf(stderr, "couldn't connect to X server in DISPLAY\n"); + return EXIT_FAILURE; + } + XSetErrorHandler(x_error_handler); + win = XCreateWindow(display, RootWindow(display, DefaultScreen(display)), + X, Y, W, H, 0, + CopyFromParent, /* depth */ + CopyFromParent, /* class */ + CopyFromParent, /* visual */ + 0, /* valuemask */ + 0); /* attributes */ + XSelectInput(display, win, ExposureMask | StructureNotifyMask); + XMapWindow(display, win); + + vi = glXChooseVisual(display, DefaultScreen(display), config); + if (vi == NULL) + printf("no conforming visual\n"); + cont = glXCreateContext(display, vi, NULL, GL_TRUE); + if (cont == NULL) + printf("context creation failed\n"); + glXMakeCurrent(display, win, cont); + + + + chint.res_name = "rendertest"; + chint.res_class = "Rendertest"; + XSetClassHint(display, win, &chint); + + delete_win = XInternAtom(display, "WM_DELETE_WINDOW", False); + protocols = XInternAtom(display, "WM_PROTOCOLS", False); + XSetWMProtocols(display, win, &delete_win, 1); + glClearColor(0.0, 0.0, 1.0, 0.0); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, 30, 0, 40, 0, 10); + glMatrixMode(GL_MODELVIEW); + + quit = 0; + while (!quit) { + XNextEvent(display, &report); + switch (report.type) { + case ClientMessage: + if ((Atom)report.xclient.message_type == protocols) + if ((Atom)report.xclient.data.l[0] == delete_win) + quit = 1; + case Expose: + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + GlftRenderString(font, argv[2], strlen(argv[2]), 0, 0); + glXSwapBuffers(display, win); + case ConfigureNotify: + break; + } + + } GlftFontClose(font); - return 0; + return 1; } -- 2.34.1