citrun

watch C/C++ source code execute
Log | Files | Refs | LICENSE

commit a430c7f0c762c9f0bcd3cac2b2e8e1946b1b3b08
parent df82a2b27ef0349e64096e64fec7b88bbe0b696f
Author: Kyle Milz <kyle@0x30.net>
Date:   Sun, 11 Dec 2016 17:34:26 -0700

src: move demo-font -> gl_font

Diffstat:
Msrc/Jamfile | 2+-
Dsrc/demo-font.cc | 252-------------------------------------------------------------------------------
Dsrc/demo-font.h | 69---------------------------------------------------------------------
Msrc/demo-shader.h | 2+-
Msrc/gl_buffer.h | 2+-
Asrc/gl_font.cc | 268+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/gl_font.h | 68++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/gl_main.cc | 22++--------------------
8 files changed, 341 insertions(+), 344 deletions(-)

diff --git a/src/Jamfile b/src/Jamfile @@ -31,7 +31,7 @@ GL_SRCS = gl_view.cc demo-atlas.cc gl_buffer.cc - demo-font.cc + gl_font.cc demo-glstate.cc demo-shader.cc matrix4x4.c diff --git a/src/demo-font.cc b/src/demo-font.cc @@ -1,252 +0,0 @@ -/* - * Copyright 2012 Google, Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Google Author(s): Behdad Esfahbod - */ - -#include <err.h> - -#include "demo-font.h" -#include "glyphy/glyphy-freetype.h" - -#include <unordered_map> - - -typedef std::unordered_map<unsigned int, glyph_info_t> glyph_cache_t; - -struct demo_font_t { - unsigned int refcount; - - FT_Face face; - glyph_cache_t *glyph_cache; - demo_atlas_t *atlas; - glyphy_arc_accumulator_t *acc; - - /* stats */ - unsigned int num_glyphs; - double sum_error; - unsigned int sum_endpoints; - double sum_fetch; - unsigned int sum_bytes; -}; - -demo_font_t * -demo_font_create (FT_Face face, - demo_atlas_t *atlas) -{ - demo_font_t *font = (demo_font_t *) calloc (1, sizeof (demo_font_t)); - font->refcount = 1; - - font->face = face; - font->glyph_cache = new glyph_cache_t (); - font->atlas = demo_atlas_reference (atlas); - font->acc = glyphy_arc_accumulator_create (); - - font->num_glyphs = 0; - font->sum_error = 0; - font->sum_endpoints = 0; - font->sum_fetch = 0; - font->sum_bytes = 0; - - return font; -} - -demo_font_t * -demo_font_reference (demo_font_t *font) -{ - if (font) font->refcount++; - return font; -} - -void -demo_font_destroy (demo_font_t *font) -{ - if (!font || --font->refcount) - return; - - glyphy_arc_accumulator_destroy (font->acc); - demo_atlas_destroy (font->atlas); - delete font->glyph_cache; - free (font); -} - - -FT_Face -demo_font_get_face (demo_font_t *font) -{ - return font->face; -} - -demo_atlas_t * -demo_font_get_atlas (demo_font_t *font) -{ - return font->atlas; -} - - -static glyphy_bool_t -accumulate_endpoint (glyphy_arc_endpoint_t *endpoint, - std::vector<glyphy_arc_endpoint_t> *endpoints) -{ - endpoints->push_back (*endpoint); - return true; -} - -static void -encode_ft_glyph (demo_font_t *font, - unsigned int glyph_index, - double tolerance_per_em, - glyphy_rgba_t *buffer, - unsigned int buffer_len, - unsigned int *output_len, - unsigned int *nominal_width, - unsigned int *nominal_height, - glyphy_extents_t *extents, - double *advance) -{ -/* Used for testing only */ -#define SCALE (1. * (1 << 0)) - - FT_Face face = font->face; - if (FT_Err_Ok != FT_Load_Glyph (face, - glyph_index, - FT_LOAD_NO_BITMAP | - FT_LOAD_NO_HINTING | - FT_LOAD_NO_AUTOHINT | - FT_LOAD_NO_SCALE | - FT_LOAD_LINEAR_DESIGN | - FT_LOAD_IGNORE_TRANSFORM)) - errx(1, "Failed loading FreeType glyph"); - - if (face->glyph->format != FT_GLYPH_FORMAT_OUTLINE) - errx(1, "FreeType loaded glyph format is not outline"); - - unsigned int upem = face->units_per_EM; - double tolerance = upem * tolerance_per_em; /* in font design units */ - double faraway = double (upem) / (MIN_FONT_SIZE * M_SQRT2); - std::vector<glyphy_arc_endpoint_t> endpoints; - - glyphy_arc_accumulator_reset (font->acc); - glyphy_arc_accumulator_set_tolerance (font->acc, tolerance); - glyphy_arc_accumulator_set_callback (font->acc, - (glyphy_arc_endpoint_accumulator_callback_t) accumulate_endpoint, - &endpoints); - - if (FT_Err_Ok != glyphy_freetype(outline_decompose) (&face->glyph->outline, font->acc)) - errx(1, "Failed converting glyph outline to arcs"); - - assert (glyphy_arc_accumulator_get_error (font->acc) <= tolerance); - - if (endpoints.size ()) - { -#if 0 - /* Technically speaking, we want the following code, - * however, crappy fonts have crappy flags. So we just - * fixup unconditionally... */ - if (face->glyph->outline.flags & FT_OUTLINE_EVEN_ODD_FILL) - glyphy_outline_winding_from_even_odd (&endpoints[0], endpoints.size (), false); - else if (face->glyph->outline.flags & FT_OUTLINE_REVERSE_FILL) - glyphy_outline_reverse (&endpoints[0], endpoints.size ()); -#else - glyphy_outline_winding_from_even_odd (&endpoints[0], endpoints.size (), false); -#endif - } - - if (SCALE != 1.) - for (unsigned int i = 0; i < endpoints.size (); i++) - { - endpoints[i].p.x /= SCALE; - endpoints[i].p.y /= SCALE; - } - - double avg_fetch_achieved; - if (!glyphy_arc_list_encode_blob (endpoints.size () ? &endpoints[0] : NULL, endpoints.size (), - buffer, - buffer_len, - faraway / SCALE, - 4, /* UNUSED */ - &avg_fetch_achieved, - output_len, - nominal_width, - nominal_height, - extents)) - errx(1, "Failed encoding arcs"); - - glyphy_extents_scale (extents, 1. / upem, 1. / upem); - glyphy_extents_scale (extents, SCALE, SCALE); - - *advance = face->glyph->metrics.horiAdvance / (double) upem; - - if (0) - LOGI ("gid%3u: endpoints%3d; err%3g%%; tex fetch%4.1f; mem%4.1fkb\n", - glyph_index, - (unsigned int) glyphy_arc_accumulator_get_num_endpoints (font->acc), - round (100 * glyphy_arc_accumulator_get_error (font->acc) / tolerance), - avg_fetch_achieved, - (*output_len * sizeof (glyphy_rgba_t)) / 1024.); - - font->num_glyphs++; - font->sum_error += glyphy_arc_accumulator_get_error (font->acc) / tolerance; - font->sum_endpoints += glyphy_arc_accumulator_get_num_endpoints (font->acc); - font->sum_fetch += avg_fetch_achieved; - font->sum_bytes += (*output_len * sizeof (glyphy_rgba_t)); -} - -static void -_demo_font_upload_glyph (demo_font_t *font, - unsigned int glyph_index, - glyph_info_t *glyph_info) -{ - glyphy_rgba_t buffer[4096 * 16]; - unsigned int output_len; - - encode_ft_glyph (font, - glyph_index, - TOLERANCE, - buffer, ARRAY_LEN (buffer), - &output_len, - &glyph_info->nominal_w, - &glyph_info->nominal_h, - &glyph_info->extents, - &glyph_info->advance); - - glyph_info->is_empty = glyphy_extents_is_empty (&glyph_info->extents); - if (!glyph_info->is_empty) - demo_atlas_alloc (font->atlas, buffer, output_len, - &glyph_info->atlas_x, &glyph_info->atlas_y); -} - -void -demo_font_lookup_glyph (demo_font_t *font, - unsigned int glyph_index, - glyph_info_t *glyph_info) -{ - if (font->glyph_cache->find (glyph_index) == font->glyph_cache->end ()) { - _demo_font_upload_glyph (font, glyph_index, glyph_info); - (*font->glyph_cache)[glyph_index] = *glyph_info; - } else - *glyph_info = (*font->glyph_cache)[glyph_index]; -} - -void -demo_font_print_stats (demo_font_t *font) -{ - LOGI ("%3d glyphs; avg num endpoints%6.2f; avg error%5.1f%%; avg tex fetch%5.2f; avg %5.2fkb per glyph\n", - font->num_glyphs, - (double) font->sum_endpoints / font->num_glyphs, - 100. * font->sum_error / font->num_glyphs, - font->sum_fetch / font->num_glyphs, - font->sum_bytes / 1024. / font->num_glyphs); -} diff --git a/src/demo-font.h b/src/demo-font.h @@ -1,69 +0,0 @@ -/* - * Copyright 2012 Google, Inc. All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Google Author(s): Behdad Esfahbod - */ - -#ifndef DEMO_FONT_H -#define DEMO_FONT_H - -#include "demo-common.h" -#include "demo-atlas.h" - -#include <ft2build.h> -#include FT_FREETYPE_H - - -typedef struct { - glyphy_extents_t extents; - double advance; - glyphy_bool_t is_empty; /* has no outline; eg. space; don't draw it */ - unsigned int nominal_w; - unsigned int nominal_h; - unsigned int atlas_x; - unsigned int atlas_y; -} glyph_info_t; - - -typedef struct demo_font_t demo_font_t; - -demo_font_t * -demo_font_create (FT_Face face, - demo_atlas_t *atlas); - -demo_font_t * -demo_font_reference (demo_font_t *font); - -void -demo_font_destroy (demo_font_t *font); - - -FT_Face -demo_font_get_face (demo_font_t *font); - -demo_atlas_t * -demo_font_get_atlas (demo_font_t *font); - - -void -demo_font_lookup_glyph (demo_font_t *font, - unsigned int glyph_index, - glyph_info_t *glyph_info); - -void -demo_font_print_stats (demo_font_t *font); - - -#endif /* DEMO_FONT_H */ diff --git a/src/demo-shader.h b/src/demo-shader.h @@ -20,7 +20,7 @@ #define DEMO_SHADERS_H #include "demo-common.h" -#include "demo-font.h" +#include "gl_font.h" struct glyph_vertex_t { diff --git a/src/gl_buffer.h b/src/gl_buffer.h @@ -20,7 +20,7 @@ #define DEMO_BUFFER_H #include "demo-common.h" -#include "demo-font.h" +#include "gl_font.h" #include "demo-shader.h" typedef struct demo_buffer_t demo_buffer_t; diff --git a/src/gl_font.cc b/src/gl_font.cc @@ -0,0 +1,268 @@ +/* + * Copyright 2012 Google, Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Google Author(s): Behdad Esfahbod + */ + +#include <err.h> + +#include "gl_font.h" +#include "glyphy/glyphy-freetype.h" + +#include <unordered_map> + +#if defined(__OpenBSD__) +#define FONT_PATH "/usr/X11R6/lib/X11/fonts/TTF/DejaVuSansMono.ttf" +#elif defined(__APPLE__) +#define FONT_PATH "/Library/Fonts/Andale Mono.ttf" +#elif defined(__gnu_linux__) +#define FONT_PATH "/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf" +#else +#error "Font path not configured for this platform!" +#endif + + +typedef std::unordered_map<unsigned int, glyph_info_t> glyph_cache_t; +FT_Library ft_library; +FT_Face ft_face; + +struct demo_font_t { + unsigned int refcount; + + FT_Face face; + glyph_cache_t *glyph_cache; + demo_atlas_t *atlas; + glyphy_arc_accumulator_t *acc; + + /* stats */ + unsigned int num_glyphs; + double sum_error; + unsigned int sum_endpoints; + double sum_fetch; + unsigned int sum_bytes; +}; + +demo_font_t * +demo_font_create (demo_atlas_t *atlas) +{ + FT_Init_FreeType(&ft_library); + + ft_face = NULL; + FT_New_Face(ft_library, FONT_PATH, /* face_index */ 0, &ft_face); + + demo_font_t *font = (demo_font_t *) calloc (1, sizeof (demo_font_t)); + font->refcount = 1; + + font->face = ft_face; + font->glyph_cache = new glyph_cache_t (); + font->atlas = demo_atlas_reference (atlas); + font->acc = glyphy_arc_accumulator_create (); + + font->num_glyphs = 0; + font->sum_error = 0; + font->sum_endpoints = 0; + font->sum_fetch = 0; + font->sum_bytes = 0; + + return font; +} + +demo_font_t * +demo_font_reference (demo_font_t *font) +{ + if (font) font->refcount++; + return font; +} + +void +demo_font_destroy (demo_font_t *font) +{ + if (!font || --font->refcount) + return; + + glyphy_arc_accumulator_destroy (font->acc); + demo_atlas_destroy (font->atlas); + delete font->glyph_cache; + free (font); +} + + +FT_Face +demo_font_get_face (demo_font_t *font) +{ + return font->face; +} + +demo_atlas_t * +demo_font_get_atlas (demo_font_t *font) +{ + return font->atlas; +} + + +static glyphy_bool_t +accumulate_endpoint (glyphy_arc_endpoint_t *endpoint, + std::vector<glyphy_arc_endpoint_t> *endpoints) +{ + endpoints->push_back (*endpoint); + return true; +} + +static void +encode_ft_glyph (demo_font_t *font, + unsigned int glyph_index, + double tolerance_per_em, + glyphy_rgba_t *buffer, + unsigned int buffer_len, + unsigned int *output_len, + unsigned int *nominal_width, + unsigned int *nominal_height, + glyphy_extents_t *extents, + double *advance) +{ +/* Used for testing only */ +#define SCALE (1. * (1 << 0)) + + FT_Face face = font->face; + if (FT_Err_Ok != FT_Load_Glyph (face, + glyph_index, + FT_LOAD_NO_BITMAP | + FT_LOAD_NO_HINTING | + FT_LOAD_NO_AUTOHINT | + FT_LOAD_NO_SCALE | + FT_LOAD_LINEAR_DESIGN | + FT_LOAD_IGNORE_TRANSFORM)) + errx(1, "Failed loading FreeType glyph"); + + if (face->glyph->format != FT_GLYPH_FORMAT_OUTLINE) + errx(1, "FreeType loaded glyph format is not outline"); + + unsigned int upem = face->units_per_EM; + double tolerance = upem * tolerance_per_em; /* in font design units */ + double faraway = double (upem) / (MIN_FONT_SIZE * M_SQRT2); + std::vector<glyphy_arc_endpoint_t> endpoints; + + glyphy_arc_accumulator_reset (font->acc); + glyphy_arc_accumulator_set_tolerance (font->acc, tolerance); + glyphy_arc_accumulator_set_callback (font->acc, + (glyphy_arc_endpoint_accumulator_callback_t) accumulate_endpoint, + &endpoints); + + if (FT_Err_Ok != glyphy_freetype(outline_decompose) (&face->glyph->outline, font->acc)) + errx(1, "Failed converting glyph outline to arcs"); + + assert (glyphy_arc_accumulator_get_error (font->acc) <= tolerance); + + if (endpoints.size ()) + { +#if 0 + /* Technically speaking, we want the following code, + * however, crappy fonts have crappy flags. So we just + * fixup unconditionally... */ + if (face->glyph->outline.flags & FT_OUTLINE_EVEN_ODD_FILL) + glyphy_outline_winding_from_even_odd (&endpoints[0], endpoints.size (), false); + else if (face->glyph->outline.flags & FT_OUTLINE_REVERSE_FILL) + glyphy_outline_reverse (&endpoints[0], endpoints.size ()); +#else + glyphy_outline_winding_from_even_odd (&endpoints[0], endpoints.size (), false); +#endif + } + + if (SCALE != 1.) + for (unsigned int i = 0; i < endpoints.size (); i++) + { + endpoints[i].p.x /= SCALE; + endpoints[i].p.y /= SCALE; + } + + double avg_fetch_achieved; + if (!glyphy_arc_list_encode_blob (endpoints.size () ? &endpoints[0] : NULL, endpoints.size (), + buffer, + buffer_len, + faraway / SCALE, + 4, /* UNUSED */ + &avg_fetch_achieved, + output_len, + nominal_width, + nominal_height, + extents)) + errx(1, "Failed encoding arcs"); + + glyphy_extents_scale (extents, 1. / upem, 1. / upem); + glyphy_extents_scale (extents, SCALE, SCALE); + + *advance = face->glyph->metrics.horiAdvance / (double) upem; + + if (0) + LOGI ("gid%3u: endpoints%3d; err%3g%%; tex fetch%4.1f; mem%4.1fkb\n", + glyph_index, + (unsigned int) glyphy_arc_accumulator_get_num_endpoints (font->acc), + round (100 * glyphy_arc_accumulator_get_error (font->acc) / tolerance), + avg_fetch_achieved, + (*output_len * sizeof (glyphy_rgba_t)) / 1024.); + + font->num_glyphs++; + font->sum_error += glyphy_arc_accumulator_get_error (font->acc) / tolerance; + font->sum_endpoints += glyphy_arc_accumulator_get_num_endpoints (font->acc); + font->sum_fetch += avg_fetch_achieved; + font->sum_bytes += (*output_len * sizeof (glyphy_rgba_t)); +} + +static void +_demo_font_upload_glyph (demo_font_t *font, + unsigned int glyph_index, + glyph_info_t *glyph_info) +{ + glyphy_rgba_t buffer[4096 * 16]; + unsigned int output_len; + + encode_ft_glyph (font, + glyph_index, + TOLERANCE, + buffer, ARRAY_LEN (buffer), + &output_len, + &glyph_info->nominal_w, + &glyph_info->nominal_h, + &glyph_info->extents, + &glyph_info->advance); + + glyph_info->is_empty = glyphy_extents_is_empty (&glyph_info->extents); + if (!glyph_info->is_empty) + demo_atlas_alloc (font->atlas, buffer, output_len, + &glyph_info->atlas_x, &glyph_info->atlas_y); +} + +void +demo_font_lookup_glyph (demo_font_t *font, + unsigned int glyph_index, + glyph_info_t *glyph_info) +{ + if (font->glyph_cache->find (glyph_index) == font->glyph_cache->end ()) { + _demo_font_upload_glyph (font, glyph_index, glyph_info); + (*font->glyph_cache)[glyph_index] = *glyph_info; + } else + *glyph_info = (*font->glyph_cache)[glyph_index]; +} + +void +demo_font_print_stats (demo_font_t *font) +{ + LOGI ("%3d glyphs; avg num endpoints%6.2f; avg error%5.1f%%; avg tex fetch%5.2f; avg %5.2fkb per glyph\n", + font->num_glyphs, + (double) font->sum_endpoints / font->num_glyphs, + 100. * font->sum_error / font->num_glyphs, + font->sum_fetch / font->num_glyphs, + font->sum_bytes / 1024. / font->num_glyphs); +} diff --git a/src/gl_font.h b/src/gl_font.h @@ -0,0 +1,68 @@ +/* + * Copyright 2012 Google, Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef GL_FONT_H +#define GL_FONT_H + +#include "demo-common.h" +#include "demo-atlas.h" + +#include <ft2build.h> +#include FT_FREETYPE_H + + +typedef struct { + glyphy_extents_t extents; + double advance; + glyphy_bool_t is_empty; /* has no outline; eg. space; don't draw it */ + unsigned int nominal_w; + unsigned int nominal_h; + unsigned int atlas_x; + unsigned int atlas_y; +} glyph_info_t; + + +typedef struct demo_font_t demo_font_t; + +demo_font_t * +demo_font_create (demo_atlas_t *atlas); + +demo_font_t * +demo_font_reference (demo_font_t *font); + +void +demo_font_destroy (demo_font_t *font); + + +FT_Face +demo_font_get_face (demo_font_t *font); + +demo_atlas_t * +demo_font_get_atlas (demo_font_t *font); + + +void +demo_font_lookup_glyph (demo_font_t *font, + unsigned int glyph_index, + glyph_info_t *glyph_info); + +void +demo_font_print_stats (demo_font_t *font); + + +#endif /* GL_FONT_H */ diff --git a/src/gl_main.cc b/src/gl_main.cc @@ -4,33 +4,20 @@ #include <sstream> #include <vector> -#include "demo-font.h" #include "gl_buffer.h" +#include "gl_font.h" #include "gl_view.h" #include "process_dir.h" #include "process_file.h" #include <GLFW/glfw3.h> -#if defined(__OpenBSD__) -#define FONT_PATH "/usr/X11R6/lib/X11/fonts/TTF/DejaVuSansMono.ttf" -#elif defined(__APPLE__) -#define FONT_PATH "/Library/Fonts/Andale Mono.ttf" -#elif defined(__gnu_linux__) -#define FONT_PATH "/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf" -#else -#error "Font path not configured for this platform!" -#endif - demo_glstate_t *st; std::vector<ProcessFile> drawables; ProcessDir m_pdir; View *static_vu; -FT_Library ft_library; -FT_Face ft_face; - demo_buffer_t *buffer; void @@ -161,12 +148,7 @@ main(int argc, char *argv[]) static_vu = new View(st, buffer); - FT_Init_FreeType(&ft_library); - - ft_face = NULL; - FT_New_Face(ft_library, FONT_PATH, /* face_index */ 0, &ft_face); - - demo_font_t *font = demo_font_create(ft_face, demo_glstate_get_atlas(st)); + demo_font_t *font = demo_font_create(demo_glstate_get_atlas(st)); static_vu->setup();