42 struct fastuidraw_banded_rays_band
48 struct fastuidraw_banded_rays_curve
53 struct fastuidraw_banded_rays_distance_type
55 float distance_increment;
56 float distance_decrement;
60 fastuidraw_banded_rays_init_distance(out fastuidraw_banded_rays_distance_type nv)
66 nv.distance_increment = nv.distance_decrement = 120.0;
70 fastuidraw_banded_rays_update_distance(in
float dist, in
bool is_increment,
71 inout fastuidraw_banded_rays_distance_type nv)
81 nv.distance_increment = min(nv.distance_increment, dist);
85 nv.distance_decrement = min(nv.distance_decrement, dist);
90 fastuidraw_banded_rays_load_band(in uint loc, out fastuidraw_banded_rays_band band)
96 fastuidraw_banded_rays_numcurves_numbits,
99 fastuidraw_banded_rays_curveoffset_numbits,
104 fastuidraw_banded_rays_load_point(in uint loc)
110 fastuidraw_banded_rays_load_curve(in uint loc, out fastuidraw_banded_rays_curve curve)
112 curve.p1 = fastuidraw_banded_rays_load_point(loc);
113 curve.p2 = fastuidraw_banded_rays_load_point(loc + 1u);
114 curve.p3 = fastuidraw_banded_rays_load_point(loc + 2u);
118 fastuidraw_banded_rays_compute_winding_contribution(in fastuidraw_banded_rays_curve curve,
119 inout fastuidraw_banded_rays_distance_type dst,
120 in
float winding_effect_multiplier)
125 float t1, t2, x1, x2, y1, y2;
126 const float quad_tol = 0.0001;
131 A = curve.p1 - 2.0 * curve.p2 + curve.p3;
132 B = curve.p1 - curve.p2;
135 use_t1 = (curve.p3.y < 0.0 && curve.p1.y > 0.0)
136 || (curve.p3.y < 0.0 && curve.p2.y > 0.0)
137 || (curve.p1.y >= 0.0 && curve.p2.y < 0.0);
139 use_t2 = (curve.p1.y < 0 && curve.p2.y > 0.0)
140 || (curve.p1.y < 0.0 && curve.p3.y > 0.0)
141 || (curve.p3.y >= 0.0 && curve.p2.y < 0.0);
143 if (abs(A.y) > quad_tol)
147 D = B.
y * B.y - A.y * C.y;
151 use_t1 = use_t2 =
false;
164 t1 = t2 = 0.5 * C.y / B.y;
169 x1 = (A.x * t1 - B.x * 2.0) * t1 + C.x;
175 fastuidraw_banded_rays_update_distance(abs(x1), winding_effect_multiplier * x1 < 0.0, dst);
180 x2 = (A.x * t2 - B.x * 2.0) * t2 + C.x;
186 fastuidraw_banded_rays_update_distance(abs(x2), winding_effect_multiplier * x2 > 0.0, dst);
193 fastuidraw_banded_rays_compute_coverage_from_band(in uint curve_offset,
197 in
float ray_direction,
198 in
float coordinate_permutation_factor,
200 inout fastuidraw_banded_rays_distance_type nv)
208 coordinate_permutation_factor *= ray_direction;
212 for (uint c = 0u, curve_src = curve_offset; c < num_curves; curve_src += 3u, ++c)
214 fastuidraw_banded_rays_curve curve;
216 fastuidraw_banded_rays_load_curve(curve_src, curve);
219 curve.p1 -= glyph_coord;
220 curve.p2 -= glyph_coord;
221 curve.p3 -= glyph_coord;
224 curve.p1.x *= ray_direction;;
225 curve.p2.x *= ray_direction;
226 curve.p3.x *= ray_direction;
228 if (max(curve.p1.x, max(curve.p2.x, curve.p3.x)) < -0.5)
231 winding += fastuidraw_banded_rays_compute_winding_contribution(curve, nv, coordinate_permutation_factor);
234 winding *= int(coordinate_permutation_factor);
253 in
vec2 glyph_coord_fwidth,
254 in uint num_vertical_bands,
255 in uint num_horizontal_bands,
256 in
bool use_odd_even_rule)
258 uint horiz_band_offset, vert_band_offset;
259 uint c, curve_src, num_curves, curve_offset;
260 vec2 ray_direction, em, band_factor;
261 fastuidraw_banded_rays_distance_type nv;
263 uint horiz_band, vert_band;
264 fastuidraw_banded_rays_band horiz_band_data, vert_band_data;
266 em =
vec2(1.0, 1.0) / glyph_coord_fwidth;
267 fastuidraw_banded_rays_init_distance(nv);
274 band_factor = fastuidraw_banded_rays_glyph_coord_half_recip *
vec2(num_vertical_bands, num_horizontal_bands);
275 vert_band = min(num_vertical_bands - 1u,
276 uint(band_factor.x * (glyph_coord.x + fastuidraw_banded_rays_glyph_coord)));
277 horiz_band = min(num_horizontal_bands - 1u,
278 uint(band_factor.y * (glyph_coord.y + fastuidraw_banded_rays_glyph_coord)));
281 horiz_band_offset = horiz_band;
282 if (glyph_coord.x < 0.0)
284 horiz_band_offset += num_horizontal_bands;
285 ray_direction.x = -1.0;
289 ray_direction.x = 1.0;
292 vert_band_offset = vert_band + 2u * num_horizontal_bands;
293 if (glyph_coord.y < 0.0)
295 vert_band_offset += num_vertical_bands;
296 ray_direction.y = -1.0;
300 ray_direction.y = +1.0;
304 fastuidraw_banded_rays_load_band(glyph_data_location + horiz_band_offset, horiz_band_data);
305 fastuidraw_banded_rays_load_band(glyph_data_location + vert_band_offset, vert_band_data);
307 fastuidraw_banded_rays_compute_coverage_from_band(horiz_band_data.curve_offset + glyph_data_location,
308 horiz_band_data.num_curves, glyph_coord,
309 em.x, ray_direction.x, 1.0, winding.x, nv);
317 fastuidraw_banded_rays_compute_coverage_from_band(vert_band_data.curve_offset + glyph_data_location,
318 vert_band_data.num_curves, glyph_coord.yx,
319 em.y, ray_direction.y, -1.0, winding.y, nv);
322 int winding_number = winding.x;
324 if (winding_number == 0 || use_odd_even_rule)
326 distance = min(nv.distance_increment,
327 nv.distance_decrement);
329 else if (winding_number == -1)
331 distance = nv.distance_increment;
333 else if (winding_number == 1)
335 distance = nv.distance_decrement;
342 distance = min(distance, 0.5);
343 winding_number = (use_odd_even_rule && (winding_number & 1) == 0) ? 0 : winding_number;
344 cvg = (winding_number != 0) ?
#define fastuidraw_fetch_glyph_data_fp16x2(X)
#define FASTUIDRAW_EXTRACT_BITS(bit0, num_bits, src)
#define fastuidraw_fetch_glyph_data(X)
float fastuidraw_banded_rays_compute_coverage(in uint glyph_data_location, in vec2 glyph_coord, in vec2 glyph_coord_fwidth, in uint num_vertical_bands, in uint num_horizontal_bands, in bool use_odd_even_rule)