static void _cpml_sanity_put_intersections(gint i) { CpmlSegment segment; CpmlPrimitive primitive1, primitive2; CpmlPair pair; /* Set primitive1 to 1.1 and primitive 2 to 2.2, * so there is an intersection point in (1, 1) */ cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path()); cpml_primitive_from_segment(&primitive1, &segment); cpml_segment_next(&segment); cpml_primitive_from_segment(&primitive2, &segment); cpml_primitive_next(&primitive2); switch (i) { case 1: cpml_primitive_put_intersections(NULL, &primitive2, 2, &pair); break; case 2: cpml_primitive_put_intersections(&primitive1, NULL, 2, &pair); break; case 3: cpml_primitive_put_intersections(&primitive1, &primitive2, 2, NULL); break; default: g_test_trap_assert_failed(); break; } }
static void _adg_do_fillet(AdgPath *path, CpmlPrimitive *current) { AdgPathPrivate *data; CpmlPrimitive *last, *current_dup, *last_dup; gdouble radius, offset, pos; CpmlPair center, vector, p[3]; data = path->data; last = &data->last; current_dup = cpml_primitive_deep_dup(current); last_dup = cpml_primitive_deep_dup(last); radius = data->operation.data.fillet.radius; offset = _adg_is_convex(last_dup, current_dup) ? -radius : radius; /* Find the center of the fillet from the intersection between * the last and current primitives offseted by radius */ cpml_primitive_offset(current_dup, offset); cpml_primitive_offset(last_dup, offset); if (cpml_primitive_put_intersections(current_dup, last_dup, 1, ¢er) == 0) { g_warning(_("%s: fillet with radius of %lf is not applicable here"), G_STRLOC, radius); g_free(current_dup); g_free(last_dup); return; } /* Compute the start point of the fillet */ pos = cpml_primitive_get_closest_pos(last_dup, ¢er); cpml_primitive_put_vector_at(last_dup, pos, &vector); cpml_vector_set_length(&vector, offset); cpml_vector_normal(&vector); p[0].x = center.x - vector.x; p[0].y = center.y - vector.y; /* Compute the mid point of the fillet */ cpml_pair_from_cairo(&vector, current->org); vector.x -= center.x; vector.y -= center.y; cpml_vector_set_length(&vector, radius); p[1].x = center.x + vector.x; p[1].y = center.y + vector.y; /* Compute the end point of the fillet */ pos = cpml_primitive_get_closest_pos(current_dup, ¢er); cpml_primitive_put_vector_at(current_dup, pos, &vector); cpml_vector_set_length(&vector, offset); cpml_vector_normal(&vector); p[2].x = center.x - vector.x; p[2].y = center.y - vector.y; g_free(current_dup); g_free(last_dup); /* Change the end point of the last primitive */ cpml_primitive_set_point(last, -1, &p[0]); /* Change the start point of the current primitive */ cpml_primitive_set_point(current, 0, &p[2]); /* Add the fillet arc */ data->operation.action = ADG_ACTION_NONE; adg_path_append(path, CPML_ARC, &p[1], &p[2]); }