1 static const char *glyphy_sdf_glsl = 2 "/*\n" 3 " * Copyright 2012 Google, Inc. All Rights Reserved.\n" 4 " *\n" 5 " * Licensed under the Apache License, Version 2.0 (the \"License\");\n" 6 " * you may not use this file except in compliance with the License.\n" 7 " * You may obtain a copy of the License at\n" 8 " *\n" 9 " * http://www.apache.org/licenses/LICENSE-2.0\n" 10 " *\n" 11 " * Unless required by applicable law or agreed to in writing, software\n" 12 " * distributed under the License is distributed on an \"AS IS\" BASIS,\n" 13 " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" 14 " * See the License for the specific language governing permissions and\n" 15 " * limitations under the License.\n" 16 " *\n" 17 " * Google Author(s): Behdad Esfahbod, Maysum Panju\n" 18 " */\n" 19 "\n" 20 "#ifndef GLYPHY_TEXTURE1D_FUNC\n" 21 "#define GLYPHY_TEXTURE1D_FUNC glyphy_texture1D_func\n" 22 "#endif\n" 23 "#ifndef GLYPHY_TEXTURE1D_EXTRA_DECLS\n" 24 "#define GLYPHY_TEXTURE1D_EXTRA_DECLS\n" 25 "#endif\n" 26 "#ifndef GLYPHY_TEXTURE1D_EXTRA_ARGS\n" 27 "#define GLYPHY_TEXTURE1D_EXTRA_ARGS\n" 28 "#endif\n" 29 "\n" 30 "#ifndef GLYPHY_SDF_TEXTURE1D_FUNC\n" 31 "#define GLYPHY_SDF_TEXTURE1D_FUNC GLYPHY_TEXTURE1D_FUNC\n" 32 "#endif\n" 33 "#ifndef GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS\n" 34 "#define GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS GLYPHY_TEXTURE1D_EXTRA_DECLS\n" 35 "#endif\n" 36 "#ifndef GLYPHY_SDF_TEXTURE1D_EXTRA_ARGS\n" 37 "#define GLYPHY_SDF_TEXTURE1D_EXTRA_ARGS GLYPHY_TEXTURE1D_EXTRA_ARGS\n" 38 "#endif\n" 39 "#ifndef GLYPHY_SDF_TEXTURE1D\n" 40 "#define GLYPHY_SDF_TEXTURE1D(offset) GLYPHY_RGBA(GLYPHY_SDF_TEXTURE1D_FUNC (offset GLYPHY_TEXTURE1D_EXTRA_ARGS))\n" 41 "#endif\n" 42 "\n" 43 "#ifndef GLYPHY_MAX_NUM_ENDPOINTS\n" 44 "#define GLYPHY_MAX_NUM_ENDPOINTS 32\n" 45 "#endif\n" 46 "\n" 47 "glyphy_arc_list_t\n" 48 "glyphy_arc_list (const vec2 p, const ivec2 nominal_size GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS)\n" 49 "{\n" 50 " int cell_offset = glyphy_arc_list_offset (p, nominal_size);\n" 51 " vec4 arc_list_data = GLYPHY_SDF_TEXTURE1D (cell_offset);\n" 52 " return glyphy_arc_list_decode (arc_list_data, nominal_size);\n" 53 "}\n" 54 "\n" 55 "float\n" 56 "glyphy_sdf (const vec2 p, const ivec2 nominal_size GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS)\n" 57 "{\n" 58 " glyphy_arc_list_t arc_list = glyphy_arc_list (p, nominal_size GLYPHY_SDF_TEXTURE1D_EXTRA_ARGS);\n" 59 "\n" 60 " /* Short-circuits */\n" 61 " if (arc_list.num_endpoints == 0) {\n" 62 " /* far-away cell */\n" 63 " return GLYPHY_INFINITY * float(arc_list.side);\n" 64 " } if (arc_list.num_endpoints == -1) {\n" 65 " /* single-line */\n" 66 " float angle = arc_list.line_angle;\n" 67 " vec2 n = vec2 (cos (angle), sin (angle));\n" 68 " return dot (p - (vec2(nominal_size) * .5), n) - arc_list.line_distance;\n" 69 " }\n" 70 "\n" 71 " float side = float(arc_list.side);\n" 72 " float min_dist = GLYPHY_INFINITY;\n" 73 " glyphy_arc_t closest_arc;\n" 74 "\n" 75 " glyphy_arc_endpoint_t endpoint_prev, endpoint;\n" 76 " endpoint_prev = glyphy_arc_endpoint_decode (GLYPHY_SDF_TEXTURE1D (arc_list.offset), nominal_size);\n" 77 " for (int i = 1; i < GLYPHY_MAX_NUM_ENDPOINTS; i++)\n" 78 " {\n" 79 " if (i >= arc_list.num_endpoints) {\n" 80 " break;\n" 81 " }\n" 82 " endpoint = glyphy_arc_endpoint_decode (GLYPHY_SDF_TEXTURE1D (arc_list.offset + i), nominal_size);\n" 83 " glyphy_arc_t a = glyphy_arc_t (endpoint_prev.p, endpoint.p, endpoint.d);\n" 84 " endpoint_prev = endpoint;\n" 85 " if (glyphy_isinf (a.d)) continue;\n" 86 "\n" 87 " if (glyphy_arc_wedge_contains (a, p))\n" 88 " {\n" 89 " float sdist = glyphy_arc_wedge_signed_dist (a, p);\n" 90 " float udist = abs (sdist) * (1. - GLYPHY_EPSILON);\n" 91 " if (udist <= min_dist) {\n" 92 " min_dist = udist;\n" 93 " side = sdist <= 0. ? -1. : +1.;\n" 94 " }\n" 95 " } else {\n" 96 " float udist = min (distance (p, a.p0), distance (p, a.p1));\n" 97 " if (udist < min_dist) {\n" 98 " min_dist = udist;\n" 99 " side = 0.; /* unsure */\n" 100 " closest_arc = a;\n" 101 " } else if (side == 0. && udist == min_dist) {\n" 102 " /* If this new distance is the same as the current minimum,\n" 103 " * compare extended distances. Take the sign from the arc\n" 104 " * with larger extended distance. */\n" 105 " float old_ext_dist = glyphy_arc_extended_dist (closest_arc, p);\n" 106 " float new_ext_dist = glyphy_arc_extended_dist (a, p);\n" 107 "\n" 108 " float ext_dist = abs (new_ext_dist) <= abs (old_ext_dist) ?\n" 109 " old_ext_dist : new_ext_dist;\n" 110 "\n" 111 "#ifdef GLYPHY_SDF_PSEUDO_DISTANCE\n" 112 " /* For emboldening and stuff: */\n" 113 " min_dist = abs (ext_dist);\n" 114 "#endif\n" 115 " side = sign (ext_dist);\n" 116 " }\n" 117 " }\n" 118 " }\n" 119 "\n" 120 " if (side == 0.) {\n" 121 " // Technically speaking this should not happen, but it does. So try to fix it.\n" 122 " float ext_dist = glyphy_arc_extended_dist (closest_arc, p);\n" 123 " side = sign (ext_dist);\n" 124 " }\n" 125 "\n" 126 " return min_dist * side;\n" 127 "}\n" 128 "\n" 129 "float\n" 130 "glyphy_point_dist (const vec2 p, const ivec2 nominal_size GLYPHY_SDF_TEXTURE1D_EXTRA_DECLS)\n" 131 "{\n" 132 " glyphy_arc_list_t arc_list = glyphy_arc_list (p, nominal_size GLYPHY_SDF_TEXTURE1D_EXTRA_ARGS);\n" 133 "\n" 134 " float side = float(arc_list.side);\n" 135 " float min_dist = GLYPHY_INFINITY;\n" 136 "\n" 137 " if (arc_list.num_endpoints == 0)\n" 138 " return min_dist;\n" 139 "\n" 140 " glyphy_arc_endpoint_t endpoint_prev, endpoint;\n" 141 " endpoint_prev = glyphy_arc_endpoint_decode (GLYPHY_SDF_TEXTURE1D (arc_list.offset), nominal_size);\n" 142 " for (int i = 1; i < GLYPHY_MAX_NUM_ENDPOINTS; i++)\n" 143 " {\n" 144 " if (i >= arc_list.num_endpoints) {\n" 145 " break;\n" 146 " }\n" 147 " endpoint = glyphy_arc_endpoint_decode (GLYPHY_SDF_TEXTURE1D (arc_list.offset + i), nominal_size);\n" 148 " if (glyphy_isinf (endpoint.d)) continue;\n" 149 " min_dist = min (min_dist, distance (p, endpoint.p));\n" 150 " }\n" 151 " return min_dist;\n" 152 "}\n" 153 ; 154