/** * cpml_segment_offset: * @segment: a #CpmlSegment * @offset: the offset distance * * Offsets a segment of the specified amount, that is builds a "parallel" * segment at the @offset distance from the original one and returns the * result by replacing the original @segment. * * <important> * <title>TODO</title> * <itemizedlist> * <listitem>Closed path are not yet managed: an elegant solution is not * so obvious: use <function>cpml_close_offset</function> when * will be available.</listitem> * <listitem>Degenerated primitives, such as lines of length 0, are not * managed properly.</listitem> * </itemizedlist> * </important> * * Since: 1.0 **/ void cpml_segment_offset(CpmlSegment *segment, double offset) { CpmlPrimitive primitive; CpmlPrimitive last_primitive; CpmlPair old_end; cairo_path_data_t org, *old_org; int first_cycle; cpml_primitive_from_segment(&primitive, segment); first_cycle = 1; do { if (! first_cycle) { cpml_pair_to_cairo(&old_end, &org); old_org = primitive.org; primitive.org = &org; } cpml_primitive_put_point(&primitive, -1, &old_end); cpml_primitive_offset(&primitive, offset); if (! first_cycle) { cpml_primitive_join(&last_primitive, &primitive); primitive.org = old_org; } cpml_primitive_copy(&last_primitive, &primitive); first_cycle = 0; } while (cpml_primitive_next(&primitive)); }
static void _cpml_sanity_join(gint i) { CpmlSegment segment; CpmlPrimitive primitive; cpml_segment_from_cairo(&segment, (cairo_path_t *) adg_test_path()); cpml_primitive_from_segment(&primitive, &segment); switch (i) { case 1: cpml_primitive_join(NULL, &primitive); break; case 2: cpml_primitive_join(&primitive, NULL); break; default: g_test_trap_assert_failed(); break; } }
cairo_path_t path = { CAIRO_STATUS_SUCCESS, path_data, G_N_ELEMENTS(path_data) }; CpmlSegment segment; CpmlPrimitive primitive1, primitive2; cpml_segment_from_cairo(&segment, &path); cpml_primitive_from_segment(&primitive1, &segment); cpml_primitive_copy(&primitive2, &primitive1); cpml_primitive_next(&primitive2); /* primitive1 and primitive2 are already joint */ g_assert_cmpint(cpml_primitive_join(&primitive1, &primitive2), ==, 1); adg_assert_isapprox((primitive2.org)->point.x, 2); adg_assert_isapprox((primitive2.org)->point.y, 0); cpml_primitive_next(&primitive2); /* Now primitive1 and primitive2 are divergent, * hence cannot be joined */ g_assert_cmpint(cpml_primitive_join(&primitive1, &primitive2), ==, 0); cpml_primitive_next(&primitive2); g_assert_cmpint(cpml_primitive_join(&primitive1, &primitive2), ==, 1); adg_assert_isapprox((primitive2.org)->point.x, 1); adg_assert_isapprox((primitive2.org)->point.y, 0); } static void