commit 21c03b9b80b6ea306ad0946614463d0bc268d546
parent 4b05f3cea583f60f8ad3817cde5a9970c89c7e0c
Author: Kyle Milz <kyle@0x30.net>
Date: Tue, 19 Jul 2016 19:44:19 -0600
src: use raw glsl files
Diffstat:
16 files changed, 537 insertions(+), 510 deletions(-)
diff --git a/Jamrules b/Jamrules
@@ -103,6 +103,19 @@ actions Test {
Test test : ;
Test regress : ;
+rule Stringize
+{
+ MakeLocate $(1) : $(LOCATE_SOURCE) ;
+ SEARCH on $(2) = $(SEARCH_SOURCE) ;
+ Depends $(1) : $(2) ;
+ Clean clean : $(1) ;
+}
+
+actions Stringize
+{
+ $(TOP)/src/stringize "static const char *$(1:B)" $(2) > $(1) ;
+}
+
echo ...build citrun ($(OS))... ;
echo " C++= $(C++)" ;
echo " CITRUN_LIB= $(CITRUN_LIB)" ;
diff --git a/src/Jamfile b/src/Jamfile
@@ -54,6 +54,10 @@ INST_SRCS =
inst_action.cc
inst_ast_visitor.cc ;
+Stringize demo_atlas_glsl.h : demo_atlas.glsl ;
+Stringize demo_vshader_glsl.h : demo_vshader.glsl ;
+Stringize demo_fshader_glsl.h : demo_fshader.glsl ;
+
# Older llvm-config doesn't add -std=c++11
ObjectC++Flags $(INST_SRCS) : -std=c++11 `llvm-config --cxxflags` ;
ObjectC++Flags $(INST_SRCS) : -DCITRUN_LIB=$(CITRUN_LIB) -DCITRUN_PATH=$(CITRUN_PATH) ;
diff --git a/src/demo-atlas-glsl.h b/src/demo-atlas-glsl.h
@@ -1,18 +0,0 @@
-static const char *demo_atlas_glsl =
-"uniform sampler2D u_atlas_tex;\n"
-"uniform ivec4 u_atlas_info;\n"
-"\n"
-"#define GLYPHY_TEXTURE1D_EXTRA_DECLS , sampler2D _tex, ivec4 _atlas_info, ivec2 _atlas_pos\n"
-"#define GLYPHY_TEXTURE1D_EXTRA_ARGS , _tex, _atlas_info, _atlas_pos\n"
-"#define GLYPHY_DEMO_EXTRA_ARGS , u_atlas_tex, u_atlas_info, gi.atlas_pos\n"
-"\n"
-"vec4\n"
-"glyphy_texture1D_func (int offset GLYPHY_TEXTURE1D_EXTRA_DECLS)\n"
-"{\n"
-" ivec2 item_geom = _atlas_info.zw;\n"
-" vec2 pos = (vec2 (_atlas_pos.xy * item_geom +\n"
-" ivec2 (mod (float (offset), float (item_geom.x)), offset / item_geom.x)) +\n"
-" + vec2 (.5, .5)) / vec2(_atlas_info.xy);\n"
-" return texture2D (_tex, pos);\n"
-"}\n"
-;
diff --git a/src/demo-fshader-glsl.h b/src/demo-fshader-glsl.h
@@ -1,87 +0,0 @@
-static const char *demo_fshader_glsl =
-"uniform float u_contrast;\n"
-"uniform float u_gamma_adjust;\n"
-"uniform float u_outline_thickness;\n"
-"uniform bool u_outline;\n"
-"uniform float u_boldness;\n"
-"uniform bool u_debug;\n"
-"\n"
-"varying vec4 v_glyph;\n"
-"\n"
-"\n"
-"#define SQRT2_2 0.70710678118654757 /* 1 / sqrt(2.) */\n"
-"#define SQRT2 1.4142135623730951\n"
-"\n"
-"struct glyph_info_t {\n"
-" ivec2 nominal_size;\n"
-" ivec2 atlas_pos;\n"
-"};\n"
-"\n"
-"glyph_info_t\n"
-"glyph_info_decode (vec4 v)\n"
-"{\n"
-" glyph_info_t gi;\n"
-" gi.nominal_size = (ivec2 (mod (v.zw, 256.)) + 2) / 4;\n"
-" gi.atlas_pos = ivec2 (v_glyph.zw) / 256;\n"
-" return gi;\n"
-"}\n"
-"\n"
-"\n"
-"float\n"
-"antialias (float d)\n"
-"{\n"
-" return smoothstep (-.75, +.75, d);\n"
-"}\n"
-"\n"
-"void\n"
-"main()\n"
-"{\n"
-" vec2 p = v_glyph.xy;\n"
-" glyph_info_t gi = glyph_info_decode (v_glyph);\n"
-"\n"
-" /* isotropic antialiasing */\n"
-" vec2 dpdx = dFdx (p);\n"
-" vec2 dpdy = dFdy (p);\n"
-" float m = length (vec2 (length (dpdx), length (dpdy))) * SQRT2_2;\n"
-"\n"
-" vec4 color = vec4 (0,0,0,1);\n"
-"\n"
-" float gsdist = glyphy_sdf (p, gi.nominal_size GLYPHY_DEMO_EXTRA_ARGS);\n"
-" float sdist = gsdist / m * u_contrast;\n"
-"\n"
-" if (!u_debug) {\n"
-" sdist -= u_boldness * 10.;\n"
-" if (u_outline)\n"
-" sdist = abs (sdist) - u_outline_thickness * .5;\n"
-" if (sdist > 1.)\n"
-" discard;\n"
-" float alpha = antialias (-sdist);\n"
-" if (u_gamma_adjust != 1.)\n"
-" alpha = pow (alpha, 1./u_gamma_adjust);\n"
-" color = vec4 (color.rgb,color.a * alpha);\n"
-" } else {\n"
-" color = vec4 (0,0,0,0);\n"
-"\n"
-" // Color the inside of the glyph a light red\n"
-" color += vec4 (.5,0,0,.5) * smoothstep (1., -1., sdist);\n"
-"\n"
-" float udist = abs (sdist);\n"
-" float gudist = abs (gsdist);\n"
-" // Color the outline red\n"
-" color += vec4 (1,0,0,1) * smoothstep (2., 1., udist);\n"
-" // Color the distance field in green\n"
-" if (!glyphy_isinf (udist))\n"
-" color += vec4(0,.4,0,.4 - (abs(gsdist) / max(float(gi.nominal_size.x), float(gi.nominal_size.y))) * 4.);\n"
-"\n"
-" float pdist = glyphy_point_dist (p, gi.nominal_size GLYPHY_DEMO_EXTRA_ARGS);\n"
-" // Color points green\n"
-" color = mix (vec4 (0,1,0,.5), color, smoothstep (.05, .06, pdist));\n"
-"\n"
-" glyphy_arc_list_t arc_list = glyphy_arc_list (p, gi.nominal_size GLYPHY_DEMO_EXTRA_ARGS);\n"
-" // Color the number of endpoints per cell blue\n"
-" color += vec4 (0,0,1,.1) * float(arc_list.num_endpoints) * 32./255.;\n"
-" }\n"
-"\n"
-" gl_FragColor = color;\n"
-"}\n"
-;
diff --git a/src/demo-shader.cc b/src/demo-shader.cc
@@ -18,9 +18,9 @@
#include "demo-shader.h"
-#include "demo-atlas-glsl.h"
-#include "demo-vshader-glsl.h"
-#include "demo-fshader-glsl.h"
+#include "demo_atlas_glsl.h"
+#include "demo_vshader_glsl.h"
+#include "demo_fshader_glsl.h"
diff --git a/src/demo-vshader-glsl.h b/src/demo-vshader-glsl.h
@@ -1,24 +0,0 @@
-static const char *demo_vshader_glsl =
-"uniform mat4 u_matViewProjection;\n"
-"\n"
-"attribute vec4 a_glyph_vertex;\n"
-"\n"
-"varying vec4 v_glyph;\n"
-"\n"
-"vec4\n"
-"glyph_vertex_transcode (vec2 v)\n"
-"{\n"
-" ivec2 g = ivec2 (v);\n"
-" ivec2 corner = ivec2 (mod (v, 2.));\n"
-" g /= 2;\n"
-" ivec2 nominal_size = ivec2 (mod (vec2(g), 64.));\n"
-" return vec4 (corner * nominal_size, g * 4);\n"
-"}\n"
-"\n"
-"void\n"
-"main()\n"
-"{\n"
-" gl_Position = u_matViewProjection * vec4 (a_glyph_vertex.xy, 0, 1);\n"
-" v_glyph = glyph_vertex_transcode (a_glyph_vertex.zw);\n"
-"}\n"
-;
diff --git a/src/demo_atlas.glsl b/src/demo_atlas.glsl
@@ -0,0 +1,16 @@
+uniform sampler2D u_atlas_tex;
+uniform ivec4 u_atlas_info;
+
+#define GLYPHY_TEXTURE1D_EXTRA_DECLS , sampler2D _tex, ivec4 _atlas_info, ivec2 _atlas_pos
+#define GLYPHY_TEXTURE1D_EXTRA_ARGS , _tex, _atlas_info, _atlas_pos
+#define GLYPHY_DEMO_EXTRA_ARGS , u_atlas_tex, u_atlas_info, gi.atlas_pos
+
+vec4
+glyphy_texture1D_func (int offset GLYPHY_TEXTURE1D_EXTRA_DECLS)
+{
+ ivec2 item_geom = _atlas_info.zw;
+ vec2 pos = (vec2 (_atlas_pos.xy * item_geom +
+ ivec2 (mod (float (offset), float (item_geom.x)), offset / item_geom.x)) +
+ + vec2 (.5, .5)) / vec2(_atlas_info.xy);
+ return texture2D (_tex, pos);
+}
diff --git a/src/demo_fshader.glsl b/src/demo_fshader.glsl
@@ -0,0 +1,85 @@
+uniform float u_contrast;
+uniform float u_gamma_adjust;
+uniform float u_outline_thickness;
+uniform bool u_outline;
+uniform float u_boldness;
+uniform bool u_debug;
+
+varying vec4 v_glyph;
+
+
+#define SQRT2_2 0.70710678118654757 /* 1 / sqrt(2.) */
+#define SQRT2 1.4142135623730951
+
+struct glyph_info_t {
+ ivec2 nominal_size;
+ ivec2 atlas_pos;
+};
+
+glyph_info_t
+glyph_info_decode (vec4 v)
+{
+ glyph_info_t gi;
+ gi.nominal_size = (ivec2 (mod (v.zw, 256.)) + 2) / 4;
+ gi.atlas_pos = ivec2 (v_glyph.zw) / 256;
+ return gi;
+}
+
+
+float
+antialias (float d)
+{
+ return smoothstep (-.75, +.75, d);
+}
+
+void
+main()
+{
+ vec2 p = v_glyph.xy;
+ glyph_info_t gi = glyph_info_decode (v_glyph);
+
+ /* isotropic antialiasing */
+ vec2 dpdx = dFdx (p);
+ vec2 dpdy = dFdy (p);
+ float m = length (vec2 (length (dpdx), length (dpdy))) * SQRT2_2;
+
+ vec4 color = vec4 (0,0,0,1);
+
+ float gsdist = glyphy_sdf (p, gi.nominal_size GLYPHY_DEMO_EXTRA_ARGS);
+ float sdist = gsdist / m * u_contrast;
+
+ if (!u_debug) {
+ sdist -= u_boldness * 10.;
+ if (u_outline)
+ sdist = abs (sdist) - u_outline_thickness * .5;
+ if (sdist > 1.)
+ discard;
+ float alpha = antialias (-sdist);
+ if (u_gamma_adjust != 1.)
+ alpha = pow (alpha, 1./u_gamma_adjust);
+ color = vec4 (color.rgb,color.a * alpha);
+ } else {
+ color = vec4 (0,0,0,0);
+
+ // Color the inside of the glyph a light red
+ color += vec4 (.5,0,0,.5) * smoothstep (1., -1., sdist);
+
+ float udist = abs (sdist);
+ float gudist = abs (gsdist);
+ // Color the outline red
+ color += vec4 (1,0,0,1) * smoothstep (2., 1., udist);
+ // Color the distance field in green
+ if (!glyphy_isinf (udist))
+ color += vec4(0,.4,0,.4 - (abs(gsdist) / max(float(gi.nominal_size.x), float(gi.nominal_size.y))) * 4.);
+
+ float pdist = glyphy_point_dist (p, gi.nominal_size GLYPHY_DEMO_EXTRA_ARGS);
+ // Color points green
+ color = mix (vec4 (0,1,0,.5), color, smoothstep (.05, .06, pdist));
+
+ glyphy_arc_list_t arc_list = glyphy_arc_list (p, gi.nominal_size GLYPHY_DEMO_EXTRA_ARGS);
+ // Color the number of endpoints per cell blue
+ color += vec4 (0,0,1,.1) * float(arc_list.num_endpoints) * 32./255.;
+ }
+
+ gl_FragColor = color;
+}
diff --git a/src/demo_vshader.glsl b/src/demo_vshader.glsl
@@ -0,0 +1,22 @@
+uniform mat4 u_matViewProjection;
+
+attribute vec4 a_glyph_vertex;
+
+varying vec4 v_glyph;
+
+vec4
+glyph_vertex_transcode (vec2 v)
+{
+ ivec2 g = ivec2 (v);
+ ivec2 corner = ivec2 (mod (v, 2.));
+ g /= 2;
+ ivec2 nominal_size = ivec2 (mod (vec2(g), 64.));
+ return vec4 (corner * nominal_size, g * 4);
+}
+
+void
+main()
+{
+ gl_Position = u_matViewProjection * vec4 (a_glyph_vertex.xy, 0, 1);
+ v_glyph = glyph_vertex_transcode (a_glyph_vertex.zw);
+}
diff --git a/src/glyphy/Jamfile b/src/glyphy/Jamfile
@@ -10,3 +10,6 @@ Library libglyphy : glyphy-arc.cc
glyphy-outline.cc
glyphy-sdf.cc
glyphy-shaders.cc ;
+
+Stringize glyphy_common_glsl.h : glyphy-common.glsl ;
+Stringize glyphy_sdf_glsl.h : glyphy-sdf.glsl ;
diff --git a/src/glyphy/glyphy-common-glsl.h b/src/glyphy/glyphy-common-glsl.h
@@ -1,224 +0,0 @@
-static const char *glyphy_common_glsl =
-"/*\n"
-" * Copyright 2012 Google, Inc. All Rights Reserved.\n"
-" *\n"
-" * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
-" * you may not use this file except in compliance with the License.\n"
-" * You may obtain a copy of the License at\n"
-" *\n"
-" * http://www.apache.org/licenses/LICENSE-2.0\n"
-" *\n"
-" * Unless required by applicable law or agreed to in writing, software\n"
-" * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
-" * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
-" * See the License for the specific language governing permissions and\n"
-" * limitations under the License.\n"
-" *\n"
-" * Google Author(s): Behdad Esfahbod, Maysum Panju\n"
-" */\n"
-"\n"
-"\n"
-"#ifndef GLYPHY_INFINITY\n"
-"# define GLYPHY_INFINITY 1e9\n"
-"#endif\n"
-"#ifndef GLYPHY_EPSILON\n"
-"# define GLYPHY_EPSILON 1e-5\n"
-"#endif\n"
-"\n"
-"#ifndef GLYPHY_RGBA\n"
-"# ifdef GLYPHY_BGRA\n"
-"# define GLYPHY_RGBA(v) glyphy_bgra (v)\n"
-"# else\n"
-"# define GLYPHY_RGBA(v) glyphy_rgba (v)\n"
-"# endif\n"
-"#endif\n"
-"\n"
-"vec4\n"
-"glyphy_rgba (const vec4 v)\n"
-"{\n"
-" return v.rgba;\n"
-"}\n"
-"\n"
-"vec4\n"
-"glyphy_bgra (const vec4 v)\n"
-"{\n"
-" return v.bgra;\n"
-"}\n"
-"\n"
-"\n"
-"struct glyphy_arc_t {\n"
-" vec2 p0;\n"
-" vec2 p1;\n"
-" float d;\n"
-"};\n"
-"\n"
-"struct glyphy_arc_endpoint_t {\n"
-" /* Second arc endpoint */\n"
-" vec2 p;\n"
-" /* Infinity if this endpoint does not form an arc with the previous\n"
-" * endpoint. Ie. a \"move_to\". Test with glyphy_isinf().\n"
-" * Arc depth otherwise. */\n"
-" float d;\n"
-"};\n"
-"\n"
-"struct glyphy_arc_list_t {\n"
-" /* Number of endpoints in the list.\n"
-" * Will be zero if we're far away inside or outside, in which case side is set.\n"
-" * Will be -1 if this arc-list encodes a single line, in which case line_* are set. */\n"
-" int num_endpoints;\n"
-"\n"
-" /* If num_endpoints is zero, this specifies whether we are inside (-1)\n"
-" * or outside (+1). Otherwise we're unsure (0). */\n"
-" int side;\n"
-" /* Offset to the arc-endpoints from the beginning of the glyph blob */\n"
-" int offset;\n"
-"\n"
-" /* A single line is all we care about. It's right here. */\n"
-" float line_angle;\n"
-" float line_distance; /* From nominal glyph center */\n"
-"};\n"
-"\n"
-"bool\n"
-"glyphy_isinf (const float v)\n"
-"{\n"
-" return abs (v) >= GLYPHY_INFINITY * .5;\n"
-"}\n"
-"\n"
-"bool\n"
-"glyphy_iszero (const float v)\n"
-"{\n"
-" return abs (v) <= GLYPHY_EPSILON * 2.;\n"
-"}\n"
-"\n"
-"vec2\n"
-"glyphy_ortho (const vec2 v)\n"
-"{\n"
-" return vec2 (-v.y, v.x);\n"
-"}\n"
-"\n"
-"int\n"
-"glyphy_float_to_byte (const float v)\n"
-"{\n"
-" return int (v * (256. - GLYPHY_EPSILON));\n"
-"}\n"
-"\n"
-"ivec4\n"
-"glyphy_vec4_to_bytes (const vec4 v)\n"
-"{\n"
-" return ivec4 (v * (256. - GLYPHY_EPSILON));\n"
-"}\n"
-"\n"
-"ivec2\n"
-"glyphy_float_to_two_nimbles (const float v)\n"
-"{\n"
-" int f = glyphy_float_to_byte (v);\n"
-" return ivec2 (f / 16, int(mod (float(f), 16.)));\n"
-"}\n"
-"\n"
-"/* returns tan (2 * atan (d)) */\n"
-"float\n"
-"glyphy_tan2atan (const float d)\n"
-"{\n"
-" return 2. * d / (1. - d * d);\n"
-"}\n"
-"\n"
-"glyphy_arc_endpoint_t\n"
-"glyphy_arc_endpoint_decode (const vec4 v, const ivec2 nominal_size)\n"
-"{\n"
-" vec2 p = (vec2 (glyphy_float_to_two_nimbles (v.a)) + v.gb) / 16.;\n"
-" float d = v.r;\n"
-" if (d == 0.)\n"
-" d = GLYPHY_INFINITY;\n"
-" else\n"
-"#define GLYPHY_MAX_D .5\n"
-" d = float(glyphy_float_to_byte (d) - 128) * GLYPHY_MAX_D / 127.;\n"
-"#undef GLYPHY_MAX_D\n"
-" return glyphy_arc_endpoint_t (p * vec2(nominal_size), d);\n"
-"}\n"
-"\n"
-"vec2\n"
-"glyphy_arc_center (const glyphy_arc_t a)\n"
-"{\n"
-" return mix (a.p0, a.p1, .5) +\n"
-" glyphy_ortho (a.p1 - a.p0) / (2. * glyphy_tan2atan (a.d));\n"
-"}\n"
-"\n"
-"bool\n"
-"glyphy_arc_wedge_contains (const glyphy_arc_t a, const vec2 p)\n"
-"{\n"
-" float d2 = glyphy_tan2atan (a.d);\n"
-" return dot (p - a.p0, (a.p1 - a.p0) * mat2(1, d2, -d2, 1)) >= 0. &&\n"
-" dot (p - a.p1, (a.p1 - a.p0) * mat2(1, -d2, d2, 1)) <= 0.;\n"
-"}\n"
-"\n"
-"float\n"
-"glyphy_arc_wedge_signed_dist_shallow (const glyphy_arc_t a, const vec2 p)\n"
-"{\n"
-" vec2 v = normalize (a.p1 - a.p0);\n"
-" float line_d = dot (p - a.p0, glyphy_ortho (v));\n"
-" if (a.d == 0.)\n"
-" return line_d;\n"
-"\n"
-" float d0 = dot ((p - a.p0), v);\n"
-" if (d0 < 0.)\n"
-" return sign (line_d) * distance (p, a.p0);\n"
-" float d1 = dot ((a.p1 - p), v);\n"
-" if (d1 < 0.)\n"
-" return sign (line_d) * distance (p, a.p1);\n"
-" float r = 2. * a.d * (d0 * d1) / (d0 + d1);\n"
-" if (r * line_d > 0.)\n"
-" return sign (line_d) * min (abs (line_d + r), min (distance (p, a.p0), distance (p, a.p1)));\n"
-" return line_d + r;\n"
-"}\n"
-"\n"
-"float\n"
-"glyphy_arc_wedge_signed_dist (const glyphy_arc_t a, const vec2 p)\n"
-"{\n"
-" if (abs (a.d) <= .03)\n"
-" return glyphy_arc_wedge_signed_dist_shallow (a, p);\n"
-" vec2 c = glyphy_arc_center (a);\n"
-" return sign (a.d) * (distance (a.p0, c) - distance (p, c));\n"
-"}\n"
-"\n"
-"float\n"
-"glyphy_arc_extended_dist (const glyphy_arc_t a, const vec2 p)\n"
-"{\n"
-" /* Note: this doesn't handle points inside the wedge. */\n"
-" vec2 m = mix (a.p0, a.p1, .5);\n"
-" float d2 = glyphy_tan2atan (a.d);\n"
-" if (dot (p - m, a.p1 - m) < 0.)\n"
-" return dot (p - a.p0, normalize ((a.p1 - a.p0) * mat2(+d2, -1, +1, +d2)));\n"
-" else\n"
-" return dot (p - a.p1, normalize ((a.p1 - a.p0) * mat2(-d2, -1, +1, -d2)));\n"
-"}\n"
-"\n"
-"int\n"
-"glyphy_arc_list_offset (const vec2 p, const ivec2 nominal_size)\n"
-"{\n"
-" ivec2 cell = ivec2 (clamp (floor (p), vec2 (0.,0.), vec2(nominal_size - 1)));\n"
-" return cell.y * nominal_size.x + cell.x;\n"
-"}\n"
-"\n"
-"glyphy_arc_list_t\n"
-"glyphy_arc_list_decode (const vec4 v, const ivec2 nominal_size)\n"
-"{\n"
-" glyphy_arc_list_t l;\n"
-" ivec4 iv = glyphy_vec4_to_bytes (v);\n"
-" l.side = 0; /* unsure */\n"
-" if (iv.r == 0) { /* arc-list encoded */\n"
-" l.offset = (iv.g * 256) + iv.b;\n"
-" l.num_endpoints = iv.a;\n"
-" if (l.num_endpoints == 255) {\n"
-" l.num_endpoints = 0;\n"
-" l.side = -1;\n"
-" } else if (l.num_endpoints == 0)\n"
-" l.side = +1;\n"
-" } else { /* single line encoded */\n"
-" l.num_endpoints = -1;\n"
-" l.line_distance = float(((iv.r - 128) * 256 + iv.g) - 0x4000) / float (0x1FFF)\n"
-" * max (float (nominal_size.x), float (nominal_size.y));\n"
-" l.line_angle = float(-((iv.b * 256 + iv.a) - 0x8000)) / float (0x7FFF) * 3.14159265358979;\n"
-" }\n"
-" return l;\n"
-"}\n"
-;
diff --git a/src/glyphy/glyphy-common.glsl b/src/glyphy/glyphy-common.glsl
@@ -0,0 +1,222 @@
+/*
+ * 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, Maysum Panju
+ */
+
+
+#ifndef GLYPHY_INFINITY
+# define GLYPHY_INFINITY 1e9
+#endif
+#ifndef GLYPHY_EPSILON
+# define GLYPHY_EPSILON 1e-5
+#endif
+
+#ifndef GLYPHY_RGBA
+# ifdef GLYPHY_BGRA
+# define GLYPHY_RGBA(v) glyphy_bgra (v)
+# else
+# define GLYPHY_RGBA(v) glyphy_rgba (v)
+# endif
+#endif
+
+vec4
+glyphy_rgba (const vec4 v)
+{
+ return v.rgba;
+}
+
+vec4
+glyphy_bgra (const vec4 v)
+{
+ return v.bgra;
+}
+
+
+struct glyphy_arc_t {
+ vec2 p0;
+ vec2 p1;
+ float d;
+};
+
+struct glyphy_arc_endpoint_t {
+ /* Second arc endpoint */
+ vec2 p;
+ /* Infinity if this endpoint does not form an arc with the previous
+ * endpoint. Ie. a "move_to". Test with glyphy_isinf().
+ * Arc depth otherwise. */
+ float d;
+};
+
+struct glyphy_arc_list_t {
+ /* Number of endpoints in the list.
+ * Will be zero if we're far away inside or outside, in which case side is set.
+ * Will be -1 if this arc-list encodes a single line, in which case line_* are set. */
+ int num_endpoints;
+
+ /* If num_endpoints is zero, this specifies whether we are inside (-1)
+ * or outside (+1). Otherwise we're unsure (0). */
+ int side;
+ /* Offset to the arc-endpoints from the beginning of the glyph blob */
+ int offset;
+
+ /* A single line is all we care about. It's right here. */
+ float line_angle;
+ float line_distance; /* From nominal glyph center */
+};
+
+bool
+glyphy_isinf (const float v)
+{
+ return abs (v) >= GLYPHY_INFINITY * .5;
+}
+
+bool
+glyphy_iszero (const float v)
+{
+ return abs (v) <= GLYPHY_EPSILON * 2.;
+}
+
+vec2
+glyphy_ortho (const vec2 v)
+{
+ return vec2 (-v.y, v.x);
+}
+
+int
+glyphy_float_to_byte (const float v)
+{
+ return int (v * (256. - GLYPHY_EPSILON));
+}
+
+ivec4
+glyphy_vec4_to_bytes (const vec4 v)
+{
+ return ivec4 (v * (256. - GLYPHY_EPSILON));
+}
+
+ivec2
+glyphy_float_to_two_nimbles (const float v)
+{
+ int f = glyphy_float_to_byte (v);
+ return ivec2 (f / 16, int(mod (float(f), 16.)));
+}
+
+/* returns tan (2 * atan (d)) */
+float
+glyphy_tan2atan (const float d)
+{
+ return 2. * d / (1. - d * d);
+}
+
+glyphy_arc_endpoint_t
+glyphy_arc_endpoint_decode (const vec4 v, const ivec2 nominal_size)
+{
+ vec2 p = (vec2 (glyphy_float_to_two_nimbles (v.a)) + v.gb) / 16.;
+ float d = v.r;
+ if (d == 0.)
+ d = GLYPHY_INFINITY;
+ else
+#define GLYPHY_MAX_D .5
+ d = float(glyphy_float_to_byte (d) - 128) * GLYPHY_MAX_D / 127.;
+#undef GLYPHY_MAX_D
+ return glyphy_arc_endpoint_t (p * vec2(nominal_size), d);
+}
+
+vec2
+glyphy_arc_center (const glyphy_arc_t a)
+{
+ return mix (a.p0, a.p1, .5) +
+ glyphy_ortho (a.p1 - a.p0) / (2. * glyphy_tan2atan (a.d));
+}
+
+bool
+glyphy_arc_wedge_contains (const glyphy_arc_t a, const vec2 p)
+{
+ float d2 = glyphy_tan2atan (a.d);
+ return dot (p - a.p0, (a.p1 - a.p0) * mat2(1, d2, -d2, 1)) >= 0. &&
+ dot (p - a.p1, (a.p1 - a.p0) * mat2(1, -d2, d2, 1)) <= 0.;
+}
+
+float
+glyphy_arc_wedge_signed_dist_shallow (const glyphy_arc_t a, const vec2 p)
+{
+ vec2 v = normalize (a.p1 - a.p0);
+ float line_d = dot (p - a.p0, glyphy_ortho (v));
+ if (a.d == 0.)
+ return line_d;
+
+ float d0 = dot ((p - a.p0), v);
+ if (d0 < 0.)
+ return sign (line_d) * distance (p, a.p0);
+ float d1 = dot ((a.p1 - p), v);
+ if (d1 < 0.)
+ return sign (line_d) * distance (p, a.p1);
+ float r = 2. * a.d * (d0 * d1) / (d0 + d1);
+ if (r * line_d > 0.)
+ return sign (line_d) * min (abs (line_d + r), min (distance (p, a.p0), distance (p, a.p1)));
+ return line_d + r;
+}
+
+float
+glyphy_arc_wedge_signed_dist (const glyphy_arc_t a, const vec2 p)
+{
+ if (abs (a.d) <= .03)
+ return glyphy_arc_wedge_signed_dist_shallow (a, p);
+ vec2 c = glyphy_arc_center (a);
+ return sign (a.d) * (distance (a.p0, c) - distance (p, c));
+}
+
+float
+glyphy_arc_extended_dist (const glyphy_arc_t a, const vec2 p)
+{
+ /* Note: this doesn't handle points inside the wedge. */
+ vec2 m = mix (a.p0, a.p1, .5);
+ float d2 = glyphy_tan2atan (a.d);
+ if (dot (p - m, a.p1 - m) < 0.)
+ return dot (p - a.p0, normalize ((a.p1 - a.p0) * mat2(+d2, -1, +1, +d2)));
+ else
+ return dot (p - a.p1, normalize ((a.p1 - a.p0) * mat2(-d2, -1, +1, -d2)));
+}
+
+int
+glyphy_arc_list_offset (const vec2 p, const ivec2 nominal_size)
+{
+ ivec2 cell = ivec2 (clamp (floor (p), vec2 (0.,0.), vec2(nominal_size - 1)));
+ return cell.y * nominal_size.x + cell.x;
+}
+
+glyphy_arc_list_t
+glyphy_arc_list_decode (const vec4 v, const ivec2 nominal_size)
+{
+ glyphy_arc_list_t l;
+ ivec4 iv = glyphy_vec4_to_bytes (v);
+ l.side = 0; /* unsure */
+ if (iv.r == 0) { /* arc-list encoded */
+ l.offset = (iv.g * 256) + iv.b;
+ l.num_endpoints = iv.a;
+ if (l.num_endpoints == 255) {
+ l.num_endpoints = 0;
+ l.side = -1;
+ } else if (l.num_endpoints == 0)
+ l.side = +1;
+ } else { /* single line encoded */
+ l.num_endpoints = -1;
+ l.line_distance = float(((iv.r - 128) * 256 + iv.g) - 0x4000) / float (0x1FFF)
+ * max (float (nominal_size.x), float (nominal_size.y));
+ l.line_angle = float(-((iv.b * 256 + iv.a) - 0x8000)) / float (0x7FFF) * 3.14159265358979;
+ }
+ return l;
+}
diff --git a/src/glyphy/glyphy-sdf-glsl.h b/src/glyphy/glyphy-sdf-glsl.h
@@ -1,152 +0,0 @@
-static const char *glyphy_sdf_glsl =
-"/*\n"
-" * Copyright 2012 Google, Inc. All Rights Reserved.\n"
-" *\n"
-" * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
-" * you may not use this file except in compliance with the License.\n"
-" * You may obtain a copy of the License at\n"
-" *\n"
-" * http://www.apache.org/licenses/LICENSE-2.0\n"
-" *\n"
-" * Unless required by applicable law or agreed to in writing, software\n"
-" * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
-" * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
-" * See the License for the specific language governing permissions and\n"
-" * limitations under the License.\n"
-" *\n"
-" * Google Author(s): Behdad Esfahbod, Maysum Panju\n"
-" */\n"
-"\n"
-"#ifndef GLYPHY_TEXTURE1D_FUNC\n"
-"#define GLYPHY_TEXTURE1D_FUNC glyphy_texture1D_func\n"
-"#endif\n"
-"#ifndef GLYPHY_TEXTURE1D_EXTRA_DECLS\n"
-"#define GLYPHY_TEXTURE1D_EXTRA_DECLS\n"
-"#endif\n"
-"#ifndef GLYPHY_TEXTURE1D_EXTRA_ARGS\n"
-"#define GLYPHY_TEXTURE1D_EXTRA_ARGS\n"
-"#endif\n"
-"\n"
-"#ifndef GLYPHY_SDF_TEXTURE1D_FUNC\n"
-"#define GLYPHY_SDF_TEXTURE1D_FUNC GLYPHY_TEXTURE1D_FUNC\n"
-"#endif\n"
-"#ifndef GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS\n"
-"#define GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS GLYPHY_TEXTURE1D_EXTRA_DECLS\n"
-"#endif\n"
-"#ifndef GLYPHY_SDF_TEXTURE1D_EXTRA_ARGS\n"
-"#define GLYPHY_SDF_TEXTURE1D_EXTRA_ARGS GLYPHY_TEXTURE1D_EXTRA_ARGS\n"
-"#endif\n"
-"#ifndef GLYPHY_SDF_TEXTURE1D\n"
-"#define GLYPHY_SDF_TEXTURE1D(offset) GLYPHY_RGBA(GLYPHY_SDF_TEXTURE1D_FUNC (offset GLYPHY_TEXTURE1D_EXTRA_ARGS))\n"
-"#endif\n"
-"\n"
-"#ifndef GLYPHY_MAX_NUM_ENDPOINTS\n"
-"#define GLYPHY_MAX_NUM_ENDPOINTS 32\n"
-"#endif\n"
-"\n"
-"glyphy_arc_list_t\n"
-"glyphy_arc_list (const vec2 p, const ivec2 nominal_size GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS)\n"
-"{\n"
-" int cell_offset = glyphy_arc_list_offset (p, nominal_size);\n"
-" vec4 arc_list_data = GLYPHY_SDF_TEXTURE1D (cell_offset);\n"
-" return glyphy_arc_list_decode (arc_list_data, nominal_size);\n"
-"}\n"
-"\n"
-"float\n"
-"glyphy_sdf (const vec2 p, const ivec2 nominal_size GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS)\n"
-"{\n"
-" glyphy_arc_list_t arc_list = glyphy_arc_list (p, nominal_size GLYPHY_SDF_TEXTURE1D_EXTRA_ARGS);\n"
-"\n"
-" /* Short-circuits */\n"
-" if (arc_list.num_endpoints == 0) {\n"
-" /* far-away cell */\n"
-" return GLYPHY_INFINITY * float(arc_list.side);\n"
-" } if (arc_list.num_endpoints == -1) {\n"
-" /* single-line */\n"
-" float angle = arc_list.line_angle;\n"
-" vec2 n = vec2 (cos (angle), sin (angle));\n"
-" return dot (p - (vec2(nominal_size) * .5), n) - arc_list.line_distance;\n"
-" }\n"
-"\n"
-" float side = float(arc_list.side);\n"
-" float min_dist = GLYPHY_INFINITY;\n"
-" glyphy_arc_t closest_arc;\n"
-"\n"
-" glyphy_arc_endpoint_t endpoint_prev, endpoint;\n"
-" endpoint_prev = glyphy_arc_endpoint_decode (GLYPHY_SDF_TEXTURE1D (arc_list.offset), nominal_size);\n"
-" for (int i = 1; i < GLYPHY_MAX_NUM_ENDPOINTS; i++)\n"
-" {\n"
-" if (i >= arc_list.num_endpoints) {\n"
-" break;\n"
-" }\n"
-" endpoint = glyphy_arc_endpoint_decode (GLYPHY_SDF_TEXTURE1D (arc_list.offset + i), nominal_size);\n"
-" glyphy_arc_t a = glyphy_arc_t (endpoint_prev.p, endpoint.p, endpoint.d);\n"
-" endpoint_prev = endpoint;\n"
-" if (glyphy_isinf (a.d)) continue;\n"
-"\n"
-" if (glyphy_arc_wedge_contains (a, p))\n"
-" {\n"
-" float sdist = glyphy_arc_wedge_signed_dist (a, p);\n"
-" float udist = abs (sdist) * (1. - GLYPHY_EPSILON);\n"
-" if (udist <= min_dist) {\n"
-" min_dist = udist;\n"
-" side = sdist <= 0. ? -1. : +1.;\n"
-" }\n"
-" } else {\n"
-" float udist = min (distance (p, a.p0), distance (p, a.p1));\n"
-" if (udist < min_dist) {\n"
-" min_dist = udist;\n"
-" side = 0.; /* unsure */\n"
-" closest_arc = a;\n"
-" } else if (side == 0. && udist == min_dist) {\n"
-" /* If this new distance is the same as the current minimum,\n"
-" * compare extended distances. Take the sign from the arc\n"
-" * with larger extended distance. */\n"
-" float old_ext_dist = glyphy_arc_extended_dist (closest_arc, p);\n"
-" float new_ext_dist = glyphy_arc_extended_dist (a, p);\n"
-"\n"
-" float ext_dist = abs (new_ext_dist) <= abs (old_ext_dist) ?\n"
-" old_ext_dist : new_ext_dist;\n"
-"\n"
-"#ifdef GLYPHY_SDF_PSEUDO_DISTANCE\n"
-" /* For emboldening and stuff: */\n"
-" min_dist = abs (ext_dist);\n"
-"#endif\n"
-" side = sign (ext_dist);\n"
-" }\n"
-" }\n"
-" }\n"
-"\n"
-" if (side == 0.) {\n"
-" // Technically speaking this should not happen, but it does. So try to fix it.\n"
-" float ext_dist = glyphy_arc_extended_dist (closest_arc, p);\n"
-" side = sign (ext_dist);\n"
-" }\n"
-"\n"
-" return min_dist * side;\n"
-"}\n"
-"\n"
-"float\n"
-"glyphy_point_dist (const vec2 p, const ivec2 nominal_size GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS)\n"
-"{\n"
-" glyphy_arc_list_t arc_list = glyphy_arc_list (p, nominal_size GLYPHY_SDF_TEXTURE1D_EXTRA_ARGS);\n"
-"\n"
-" float side = float(arc_list.side);\n"
-" float min_dist = GLYPHY_INFINITY;\n"
-"\n"
-" if (arc_list.num_endpoints == 0)\n"
-" return min_dist;\n"
-"\n"
-" glyphy_arc_endpoint_t endpoint;\n"
-" for (int i = 0; i < GLYPHY_MAX_NUM_ENDPOINTS; i++)\n"
-" {\n"
-" if (i >= arc_list.num_endpoints) {\n"
-" break;\n"
-" }\n"
-" endpoint = glyphy_arc_endpoint_decode (GLYPHY_SDF_TEXTURE1D (arc_list.offset + i), nominal_size);\n"
-" if (glyphy_isinf (endpoint.d)) continue;\n"
-" min_dist = min (min_dist, distance (p, endpoint.p));\n"
-" }\n"
-" return min_dist;\n"
-"}\n"
-;
diff --git a/src/glyphy/glyphy-sdf.glsl b/src/glyphy/glyphy-sdf.glsl
@@ -0,0 +1,150 @@
+/*
+ * 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, Maysum Panju
+ */
+
+#ifndef GLYPHY_TEXTURE1D_FUNC
+#define GLYPHY_TEXTURE1D_FUNC glyphy_texture1D_func
+#endif
+#ifndef GLYPHY_TEXTURE1D_EXTRA_DECLS
+#define GLYPHY_TEXTURE1D_EXTRA_DECLS
+#endif
+#ifndef GLYPHY_TEXTURE1D_EXTRA_ARGS
+#define GLYPHY_TEXTURE1D_EXTRA_ARGS
+#endif
+
+#ifndef GLYPHY_SDF_TEXTURE1D_FUNC
+#define GLYPHY_SDF_TEXTURE1D_FUNC GLYPHY_TEXTURE1D_FUNC
+#endif
+#ifndef GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS
+#define GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS GLYPHY_TEXTURE1D_EXTRA_DECLS
+#endif
+#ifndef GLYPHY_SDF_TEXTURE1D_EXTRA_ARGS
+#define GLYPHY_SDF_TEXTURE1D_EXTRA_ARGS GLYPHY_TEXTURE1D_EXTRA_ARGS
+#endif
+#ifndef GLYPHY_SDF_TEXTURE1D
+#define GLYPHY_SDF_TEXTURE1D(offset) GLYPHY_RGBA(GLYPHY_SDF_TEXTURE1D_FUNC (offset GLYPHY_TEXTURE1D_EXTRA_ARGS))
+#endif
+
+#ifndef GLYPHY_MAX_NUM_ENDPOINTS
+#define GLYPHY_MAX_NUM_ENDPOINTS 32
+#endif
+
+glyphy_arc_list_t
+glyphy_arc_list (const vec2 p, const ivec2 nominal_size GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS)
+{
+ int cell_offset = glyphy_arc_list_offset (p, nominal_size);
+ vec4 arc_list_data = GLYPHY_SDF_TEXTURE1D (cell_offset);
+ return glyphy_arc_list_decode (arc_list_data, nominal_size);
+}
+
+float
+glyphy_sdf (const vec2 p, const ivec2 nominal_size GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS)
+{
+ glyphy_arc_list_t arc_list = glyphy_arc_list (p, nominal_size GLYPHY_SDF_TEXTURE1D_EXTRA_ARGS);
+
+ /* Short-circuits */
+ if (arc_list.num_endpoints == 0) {
+ /* far-away cell */
+ return GLYPHY_INFINITY * float(arc_list.side);
+ } if (arc_list.num_endpoints == -1) {
+ /* single-line */
+ float angle = arc_list.line_angle;
+ vec2 n = vec2 (cos (angle), sin (angle));
+ return dot (p - (vec2(nominal_size) * .5), n) - arc_list.line_distance;
+ }
+
+ float side = float(arc_list.side);
+ float min_dist = GLYPHY_INFINITY;
+ glyphy_arc_t closest_arc;
+
+ glyphy_arc_endpoint_t endpoint_prev, endpoint;
+ endpoint_prev = glyphy_arc_endpoint_decode (GLYPHY_SDF_TEXTURE1D (arc_list.offset), nominal_size);
+ for (int i = 1; i < GLYPHY_MAX_NUM_ENDPOINTS; i++)
+ {
+ if (i >= arc_list.num_endpoints) {
+ break;
+ }
+ endpoint = glyphy_arc_endpoint_decode (GLYPHY_SDF_TEXTURE1D (arc_list.offset + i), nominal_size);
+ glyphy_arc_t a = glyphy_arc_t (endpoint_prev.p, endpoint.p, endpoint.d);
+ endpoint_prev = endpoint;
+ if (glyphy_isinf (a.d)) continue;
+
+ if (glyphy_arc_wedge_contains (a, p))
+ {
+ float sdist = glyphy_arc_wedge_signed_dist (a, p);
+ float udist = abs (sdist) * (1. - GLYPHY_EPSILON);
+ if (udist <= min_dist) {
+ min_dist = udist;
+ side = sdist <= 0. ? -1. : +1.;
+ }
+ } else {
+ float udist = min (distance (p, a.p0), distance (p, a.p1));
+ if (udist < min_dist) {
+ min_dist = udist;
+ side = 0.; /* unsure */
+ closest_arc = a;
+ } else if (side == 0. && udist == min_dist) {
+ /* If this new distance is the same as the current minimum,
+ * compare extended distances. Take the sign from the arc
+ * with larger extended distance. */
+ float old_ext_dist = glyphy_arc_extended_dist (closest_arc, p);
+ float new_ext_dist = glyphy_arc_extended_dist (a, p);
+
+ float ext_dist = abs (new_ext_dist) <= abs (old_ext_dist) ?
+ old_ext_dist : new_ext_dist;
+
+#ifdef GLYPHY_SDF_PSEUDO_DISTANCE
+ /* For emboldening and stuff: */
+ min_dist = abs (ext_dist);
+#endif
+ side = sign (ext_dist);
+ }
+ }
+ }
+
+ if (side == 0.) {
+ // Technically speaking this should not happen, but it does. So try to fix it.
+ float ext_dist = glyphy_arc_extended_dist (closest_arc, p);
+ side = sign (ext_dist);
+ }
+
+ return min_dist * side;
+}
+
+float
+glyphy_point_dist (const vec2 p, const ivec2 nominal_size GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS)
+{
+ glyphy_arc_list_t arc_list = glyphy_arc_list (p, nominal_size GLYPHY_SDF_TEXTURE1D_EXTRA_ARGS);
+
+ float side = float(arc_list.side);
+ float min_dist = GLYPHY_INFINITY;
+
+ if (arc_list.num_endpoints == 0)
+ return min_dist;
+
+ glyphy_arc_endpoint_t endpoint;
+ for (int i = 0; i < GLYPHY_MAX_NUM_ENDPOINTS; i++)
+ {
+ if (i >= arc_list.num_endpoints) {
+ break;
+ }
+ endpoint = glyphy_arc_endpoint_decode (GLYPHY_SDF_TEXTURE1D (arc_list.offset + i), nominal_size);
+ if (glyphy_isinf (endpoint.d)) continue;
+ min_dist = min (min_dist, distance (p, endpoint.p));
+ }
+ return min_dist;
+}
diff --git a/src/glyphy/glyphy-shaders.cc b/src/glyphy/glyphy-shaders.cc
@@ -29,8 +29,8 @@
/* TODO path separator */
#define SHADER_PATH(File) PKGDATADIR "/" File
-#include "glyphy-common-glsl.h"
-#include "glyphy-sdf-glsl.h"
+#include "glyphy_common_glsl.h"
+#include "glyphy_sdf_glsl.h"
const char * glyphy_common_shader_source (void) { return glyphy_common_glsl; }
const char * glyphy_sdf_shader_source (void) { return glyphy_sdf_glsl; }
diff --git a/src/stringize b/src/stringize
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+if test "$#" = 0; then
+ echo "Usage: $0 DECL-SPEC FILE..."
+ exit 1
+fi
+decl="$1"
+shift
+
+echo "$decl ="
+sed '
+s/\\/\\\\/g;
+s/"/\\"/g;
+s/^/"/;
+s/$/\\n"/;
+' "$@"
+echo ";"