42 struct fastuidraw_restricted_rays_transformation
45 vec2 t_vector, jq_vector;
46 float reference_location, orientation;
49 struct fastuidraw_restricted_rays_curve_type
55 struct fastuidraw_restricted_rays_box_type
57 vec2 min_point, max_point, center_point, size;
60 struct fastuidraw_restricted_rays_distance_type
62 float distance_increment;
63 float distance_decrement;
66 struct fastuidraw_restricted_rays_winding_sample_type
68 int reference_winding;
69 vec2 reference_position;
73 fastuidraw_restricted_rays_init_distance(out fastuidraw_restricted_rays_distance_type nv)
79 nv.distance_increment = nv.distance_decrement = 120.0;
83 fastuidraw_restricted_rays_update_distance(in
float dist, in
bool is_increment,
84 inout fastuidraw_restricted_rays_distance_type nv)
93 nv.distance_increment = min(nv.distance_increment, dist);
97 nv.distance_decrement = min(nv.distance_decrement, dist);
102 fastuidraw_restricted_rays_update_distance(in
vec2 p, in
bool is_increment,
103 inout fastuidraw_restricted_rays_distance_type nv)
107 d = abs(p.x) + abs(p.y);
108 fastuidraw_restricted_rays_update_distance(d, is_increment, nv);
112 fastuidraw_restricted_rays_is_increment(in
vec2 p, in
vec2 dp)
122 det = p.x * dp.y - p.y * dp.x;
127 fastuidraw_restricted_rays_update_distance(in
vec2 p, in
vec2 dp,
128 inout fastuidraw_restricted_rays_distance_type nv)
130 fastuidraw_restricted_rays_update_distance(p, fastuidraw_restricted_rays_is_increment(p, dp), nv);
134 fastuidaw_restricted_rays_compute_box(in
vec2 p,
135 in uint data_location,
136 out fastuidraw_restricted_rays_box_type box,
142 box.min_point =
vec2(-fastuidraw_restricted_rays_glyph_coord_value, -fastuidraw_restricted_rays_glyph_coord_value);
143 box.max_point =
vec2(fastuidraw_restricted_rays_glyph_coord_value, fastuidraw_restricted_rays_glyph_coord_value);
145 offset = data_location;
148 while((v & fastuidraw_restricted_rays_hierarchy_node_mask) != 0u)
152 bool take_max_choice;
157 split_pt = 0.5 * (box.min_point.x + box.max_point.x);
158 take_max_choice = (p.x > split_pt);
159 box.min_point.x = (take_max_choice) ? split_pt : box.min_point.x;
160 box.max_point.x = (take_max_choice) ? box.max_point.x : split_pt;
164 split_pt = 0.5 * (box.min_point.y + box.max_point.y);
165 take_max_choice = (p.y > split_pt);
166 box.min_point.y = (take_max_choice) ? split_pt : box.min_point.y;
167 box.max_point.y = (take_max_choice) ? box.max_point.y : split_pt;
170 bit0 = (take_max_choice) ?
171 fastuidraw_restricted_rays_hierarchy_child1_bit:
172 fastuidraw_restricted_rays_hierarchy_child0_bit;
174 fastuidraw_restricted_rays_hierarchy_child_num_bits,
176 offset += data_location;
180 box.size = box.max_point - box.min_point;
181 box.center_point = 0.5 * (box.min_point + box.max_point);
183 fastuidraw_restricted_rays_hierarchy_curve_list_num_bits,
186 fastuidraw_restricted_rays_hierarchy_curve_list_size_num_bits,
193 fastuidraw_restricted_rays_unpack_point(in uint ptr)
199 fastuidraw_restricted_rays_compute_transformation(in
vec2 frag_point,
200 in
vec2 frag_point_dx,
201 in
vec2 frag_point_dy,
202 in
vec2 reference_point,
203 out fastuidraw_restricted_rays_transformation tr)
254 vec2 q, top_row, bottom_row, em;
257 tr.translation = frag_point;
258 q = reference_point - frag_point;
259 tr.jq_vector.
x = -q.y;
260 tr.jq_vector.y = q.x;
267 top_row.x = -(c * c + d * d);
268 top_row.y = bottom_row.x = (a * c + b * d);
269 bottom_row.y = -(a * a + b * b);
271 tr.t_vector.x =
dot(top_row, q);
272 tr.t_vector.y =
dot(bottom_row, q);
277 em.x = abs(
dot(tr.t_vector, frag_point_dx)) + abs(
dot(tr.t_vector, frag_point_dy));
278 em.y = abs(
dot(tr.jq_vector, frag_point_dx)) + abs(
dot(tr.jq_vector, frag_point_dy));
286 const float min_em = 1e-7;
287 em.x = max(em.x, min_em);
288 em.y = max(em.y, min_em);
291 tr.jq_vector /= em.y;
292 tr.reference_location =
dot(tr.t_vector, q);
294 if (tr.reference_location < 0.0)
299 tr.t_vector = -tr.t_vector;
300 tr.reference_location = -tr.reference_location;
305 det = (tr.t_vector.x * tr.jq_vector.y - tr.t_vector.y * tr.jq_vector.x);
313 tr.jq_vector = -tr.jq_vector;
318 fastuidraw_restricted_rays_apply_transformation(in
vec2 p,
319 in fastuidraw_restricted_rays_transformation tr)
322 return vec2(
dot(tr.t_vector, p),
323 dot(tr.jq_vector, p));
327 fastuidraw_restricted_rays_compute_winding_contribution(in fastuidraw_restricted_rays_curve_type curve,
328 in fastuidraw_restricted_rays_transformation tr,
329 inout fastuidraw_restricted_rays_distance_type dst)
334 float t1, t2, x1, x2, y1, y2;
335 const float quad_tol = 0.0001;
337 curve.p1 = fastuidraw_restricted_rays_apply_transformation(curve.p1, tr);
338 curve.p2 = fastuidraw_restricted_rays_apply_transformation(curve.p2, tr);
339 curve.p3 = fastuidraw_restricted_rays_apply_transformation(curve.p3, tr);
341 A = curve.p1 - 2.0 * curve.p2 + curve.p3;
342 B = curve.p1 - curve.p2;
454 use_t1 = (curve.p3.y < 0.0 && curve.p1.y > 0.0)
455 || (curve.p3.y < 0.0 && curve.p2.y > 0.0)
456 || (curve.p1.y >= 0.0 && curve.p2.y < 0.0);
458 use_t2 = (curve.p1.y < 0 && curve.p2.y > 0.0)
459 || (curve.p1.y < 0.0 && curve.p3.y > 0.0)
460 || (curve.p3.y >= 0.0 && curve.p2.y < 0.0);
462 if (curve.is_quadratic && abs(A.y) > quad_tol)
466 D = B.y * B.y - A.y * C.y;
473 use_t1 = use_t2 =
false;
486 t1 = t2 = 0.5 * C.y / B.y;
501 x1 = (A.x * t1 - B.x * 2.0) * t1 + C.x;
502 if (x1 <= tr.reference_location && x1 >= 0.0)
506 fastuidraw_restricted_rays_update_distance(abs(x1), x1 < 0.0, dst);
511 x2 = (A.x * t2 - B.x * 2.0) * t2 + C.x;
512 if (x2 <= tr.reference_location && x2 >= 0.0)
516 fastuidraw_restricted_rays_update_distance(abs(x2), x2 > 0.0, dst);
525 if (curve.is_quadratic && abs(A.x) > quad_tol)
529 D = B.x * B.x - A.x * C.x;
532 use_t1 = use_t2 =
false;
536 float rA = 1.0 / A.x;
542 use_t1 = (t1 >= 0.0 && t1 <= 1.0);
543 use_t2 = (t2 >= 0.0 && t2 <= 1.0);
548 t1 = t2 = 0.5 * C.x / B.x;
549 use_t1 = (curve.p1.x > 0.0 && curve.p3.x < 0.0);
550 use_t2 = (curve.p1.x < 0.0 && curve.p3.x > 0.0);
560 y1 = (A.y * t1 - B.y * 2.0) * t1 + C.y;
561 fastuidraw_restricted_rays_update_distance(abs(y1), y1 > 0.0, dst);
566 y2 = (A.y * t2 - B.y * 2.0) * t2 + C.y;
567 fastuidraw_restricted_rays_update_distance(abs(y2), y2 < 0.0, dst);
597 fastuidraw_restricted_rays_load_curve(in uint raw,
598 in uint glyph_data_location,
599 out fastuidraw_restricted_rays_curve_type curve)
604 fastuidraw_restricted_rays_curve_num_bits,
606 curve.is_quadratic = (raw & fastuidraw_restricted_rays_curve_is_quadratic_mask) != 0u;
608 curve.p1 = fastuidraw_restricted_rays_unpack_point(curve_src);
609 curve.p2 = fastuidraw_restricted_rays_unpack_point(curve_src + 1u);
611 if (curve.is_quadratic)
613 curve.p3 = fastuidraw_restricted_rays_unpack_point(curve_src + 2u);
618 curve.p2 = 0.5 * (curve.p1 + curve.p3);
623 fastuidraw_restricted_rays_load_and_process_curve(in uint raw,
624 in uint glyph_data_location,
625 in fastuidraw_restricted_rays_transformation tr,
626 inout fastuidraw_restricted_rays_distance_type nv)
628 fastuidraw_restricted_rays_curve_type curve_data;
631 fastuidraw_restricted_rays_load_curve(raw,
637 fastuidraw_restricted_rays_compute_winding_contribution(curve_data, tr, nv);
642 fastuidraw_restricted_rays_load_winding_reference(in uint location,
643 in fastuidraw_restricted_rays_box_type box,
644 out fastuidraw_restricted_rays_winding_sample_type s)
646 uint texel, biased_winding;
648 vec2 position, delta;
650 position = box.min_point;
654 fastuidraw_restricted_rays_winding_value_num_bits, texel);
656 fastuidraw_restricted_rays_position_delta_num_bits, texel);
658 fastuidraw_restricted_rays_position_delta_num_bits, texel);
660 delta =
vec2(uint_delta) * box.
size;
661 delta /= float(fastuidraw_restricted_rays_position_delta_divide);
664 s.reference_position = position;
665 s.reference_winding = int(biased_winding) - int(fastuidraw_restricted_rays_winding_value_bias);
671 in
vec2 glyph_coord_dx,
672 in
vec2 glyph_coord_dy,
673 in
bool use_odd_even_rule
674 #ifdef FASTUIDRAW_DEBUG
675 ,out fastuidraw_restricted_rays_box_type out_texel_box,
676 out fastuidraw_restricted_rays_winding_sample_type out_S,
677 out
int out_winding_number, out uint out_num_curves,
678 out fastuidraw_restricted_rays_distance_type out_nv
682 uint src, c, curve_list, winding_sample_data_location;
683 fastuidraw_restricted_rays_transformation tr;
684 fastuidraw_restricted_rays_box_type texel_box;
685 fastuidraw_restricted_rays_winding_sample_type S;
688 fastuidraw_restricted_rays_distance_type nv;
690 winding_sample_data_location =
691 fastuidaw_restricted_rays_compute_box(glyph_coord,
693 texel_box, curve_list, num_curves);
694 fastuidraw_restricted_rays_init_distance(nv);
695 fastuidraw_restricted_rays_load_winding_reference(winding_sample_data_location,
698 fastuidraw_restricted_rays_compute_transformation(glyph_coord,
699 glyph_coord_dx, glyph_coord_dy,
700 S.reference_position, tr);
701 winding_number = S.reference_winding;
703 src = curve_list + glyph_data_location;
704 for (c = 0u; c < num_curves; c += 2u)
706 uint cA, cB, curve_pair;
712 fastuidraw_restricted_rays_curve_entry_num_bits,
714 winding_number += fastuidraw_restricted_rays_load_and_process_curve(cA, glyph_data_location, tr, nv);
716 if (c + 1u < num_curves)
719 fastuidraw_restricted_rays_curve_entry_num_bits,
721 winding_number += fastuidraw_restricted_rays_load_and_process_curve(cB, glyph_data_location, tr, nv);
734 if (winding_number == 0 || use_odd_even_rule)
736 distance = min(nv.distance_increment,
737 nv.distance_decrement);
739 else if (winding_number == -1)
741 distance = nv.distance_increment;
743 else if (winding_number == 1)
745 distance = nv.distance_decrement;
752 distance = min(distance, 0.5);
753 winding_number = (use_odd_even_rule && (winding_number & 1) == 0) ? 0 : winding_number;
754 cvg = (winding_number != 0) ?
758 #ifdef FASTUIDRAW_DEBUG 760 out_texel_box = texel_box;
762 out_winding_number = winding_number;
763 out_num_curves = num_curves;
771 #ifdef FASTUIDRAW_DEBUG 775 in
vec2 glyph_coord_dx,
776 in
vec2 glyph_coord_dy,
777 in
bool use_odd_even_rule)
779 fastuidraw_restricted_rays_box_type texel_box;
780 fastuidraw_restricted_rays_winding_sample_type S;
781 fastuidraw_restricted_rays_distance_type nv;
787 glyph_coord_dx, glyph_coord_dy,
789 texel_box, S, winding_number,
807 in
vec2 glyph_coord_dx,
808 in
vec2 glyph_coord_dy,
809 in
bool use_odd_even_rule);
float fastuidraw_restricted_rays_compute_coverage(in uint glyph_data_location, in vec2 glyph_coord, in vec2 glyph_coord_dx, in vec2 glyph_coord_dy, in bool use_odd_even_rule)
#define fastuidraw_fetch_glyph_data_fp16x2(X)
vecN< uint32_t, 2 > uvec2
#define FASTUIDRAW_EXTRACT_BITS(bit0, num_bits, src)
T dot(const vecN< T, N > &a, const vecN< T, N > &b)
#define fastuidraw_fetch_glyph_data(X)