static void _adg_property_factor(void) { AdgAlignment *alignment; CpmlPair null_factor, identity_factor; const CpmlPair *factor; CpmlPair *factor_dup; alignment = adg_alignment_new(NULL); null_factor.x = 0; null_factor.y = 0; identity_factor.x = 1; identity_factor.y = 1; /* By default, the alignment should be initialized with a null factor */ factor = adg_alignment_get_factor(alignment); g_assert_true(cpml_pair_equal(factor, &null_factor)); /* Using the public APIs */ adg_alignment_set_factor(alignment, &identity_factor); factor = adg_alignment_get_factor(alignment); g_assert_true(cpml_pair_equal(factor, &identity_factor)); adg_alignment_set_factor_explicit(alignment, 0, 0); factor = adg_alignment_get_factor(alignment); g_assert_true(cpml_pair_equal(factor, &null_factor)); adg_alignment_set_factor(alignment, NULL); factor = adg_alignment_get_factor(alignment); g_assert_true(cpml_pair_equal(factor, &null_factor)); /* Using GObject property methods */ g_object_set(alignment, "factor", &identity_factor, NULL); g_object_get(alignment, "factor", &factor_dup, NULL); g_assert_true(cpml_pair_equal(factor_dup, &identity_factor)); g_free(factor_dup); g_object_set(alignment, "factor", NULL, NULL); g_object_get(alignment, "factor", &factor_dup, NULL); g_assert_true(cpml_pair_equal(factor_dup, &identity_factor)); g_free(factor_dup); g_object_set(alignment, "factor", &null_factor, NULL); g_object_get(alignment, "factor", &factor_dup, NULL); g_assert_true(cpml_pair_equal(factor_dup, &null_factor)); g_free(factor_dup); g_object_unref(alignment); }
static void _adg_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { AdgAlignmentPrivate *data = adg_alignment_get_instance_private((AdgAlignment *) object); const CpmlPair *pair; switch (prop_id) { case PROP_FACTOR: pair = g_value_get_boxed(value); if (! cpml_pair_equal(&data->factor, pair)) { cpml_pair_copy(&data->factor, pair); adg_entity_invalidate((AdgEntity *) object); } break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); } }
/** * adg_point_equal: * @point1: the first point to compare * @point2: the second point to compare * * Compares @point1 and @point2 and returns <constant>TRUE</constant> * if the points are equals. The comparison is made by checking also * the named pairs they are bound to. If you want to compare only * their coordinates, use cpml_pair_equal() directly on the * #AdgPoint structs: * * <informalexample><programlisting language="C"> * if (adg_point_update(point1) && * adg_point_update(point2) && * cpml_pair_equal((CpmlPair *) point1, (CpmlPair *) point2)) * { * ... * } * </programlisting></informalexample> * * <constant>NULL</constant> points are handled gracefully. * * Returns: <constant>TRUE</constant> if @point1 is equal to @point2, <constant>FALSE</constant> otherwise. * * Since: 1.0 **/ gboolean adg_point_equal(const AdgPoint *point1, const AdgPoint *point2) { if (point1 == point2) return TRUE; if (point1 == NULL || point2 == NULL) return FALSE; /* Check if the points are not bound to the same model * or if only one of the two points is explicit */ if (point1->model != point2->model) return FALSE; /* Handle points bound to named pairs */ if (point1->model != NULL) return g_strcmp0(point1->name, point2->name) == 0; /* Handle points with explicit coordinates */ return cpml_pair_equal(&point1->pair, &point2->pair); }
static void _adg_behavior_named_pair(void) { CpmlPair p1 = { 123, 456 }; AdgPoint *explicit_point, *explicit_point2, *model_point; AdgModel *model; CpmlPair *pair; explicit_point = adg_point_new(); g_assert_nonnull(explicit_point); adg_point_set_pair(explicit_point, &p1); explicit_point2 = adg_point_new(); g_assert_nonnull(explicit_point2); adg_point_set_pair_explicit(explicit_point2, p1.x, p1.y); /* Checking comparison APIs */ g_assert_true(adg_point_equal(explicit_point, explicit_point2)); adg_point_set_pair_explicit(explicit_point2, 78, 90); g_assert_false(adg_point_equal(explicit_point, explicit_point2)); pair = (CpmlPair *) explicit_point2; adg_assert_isapprox(pair->x, 78); adg_assert_isapprox(pair->y, 90); pair = adg_point_get_pair(explicit_point); g_assert_true(cpml_pair_equal(pair, &p1)); g_free(pair); model = ADG_MODEL(adg_path_new()); g_assert_nonnull(model); adg_model_set_named_pair(model, "named-pair", &p1); model_point = adg_point_new(); g_assert_nonnull(model_point); adg_point_set_pair_from_model(model_point, model, "named-pair"); pair = adg_point_get_pair(model_point); g_assert_true(cpml_pair_equal(pair, &p1)); g_free(pair); /* Ensure ADG does not consider an explicit point equals to * a point bound to a named pair with the same coordinates */ g_assert_false(adg_point_equal(explicit_point, model_point)); /* Check for lazy evaluation of named pairs */ adg_point_set_pair_from_model(model_point, model, "unexistent-pair"); pair = (CpmlPair *) model_point; adg_assert_isapprox(pair->x, p1.x); adg_assert_isapprox(pair->y, p1.y); /* Check behavior on undefined named pair */ g_assert_false(adg_point_update(model_point)); g_assert_null(adg_point_get_pair(model_point)); adg_point_set_pair_from_model(model_point, model, "named-pair"); g_assert_true(adg_point_update(model_point)); /* Check for case sensitiveness */ adg_point_set_pair_from_model(model_point, model, "Named-Pair"); g_assert_null(adg_point_get_pair(model_point)); g_assert_false(adg_point_update(model_point)); /* Check if adg_point_get_pair() triggers an adg_point_update() */ adg_point_set_pair_from_model(model_point, model, "named-pair"); pair = adg_point_get_pair(model_point); g_assert_true(cpml_pair_equal(pair, &p1)); g_free(pair); adg_point_destroy(explicit_point); adg_point_destroy(model_point); g_object_unref(model); }
static gboolean _adg_get_info(AdgADim *adim, CpmlVector vector[], CpmlPair *center, gdouble *distance) { AdgDim *dim; AdgADimPrivate *data; AdgPoint *ref1_point, *ref2_point, *pos_point; const CpmlPair *ref1, *ref2, *pos; const CpmlPair *org1, *org2; gdouble factor; dim = (AdgDim *) adim; data = adim->data; ref1_point = adg_dim_get_ref1(dim); ref2_point = adg_dim_get_ref2(dim); pos_point = adg_dim_get_pos(dim); /* Check if the needed points are all properly defined */ if (! adg_point_update(ref1_point) || ! adg_point_update(ref2_point) || ! adg_point_update(pos_point) || ! adg_point_update(data->org1) || ! adg_point_update(data->org2)) { return FALSE; } ref1 = (CpmlPair *) ref1_point; ref2 = (CpmlPair *) ref2_point; pos = (CpmlPair *) pos_point; org1 = (CpmlPair *) data->org1; org2 = (CpmlPair *) data->org2; /* Check if the given points have valid coordinates */ if (cpml_pair_equal(ref1, org1)) { g_warning(_("%s: ref1 and org1 cannot be coincidents (%lf, %lf)"), G_STRLOC, ref1->x, ref1->y); return FALSE; } if (cpml_pair_equal(ref2, org2)) { g_warning(_("%s: ref2 and org2 cannot be coincidents (%lf, %lf)"), G_STRLOC, ref2->x, ref2->y); return FALSE; } vector[0].x = ref1->x - org1->x; vector[0].y = ref1->y - org1->y; vector[2].x = ref2->x - org2->x; vector[2].y = ref2->y - org2->y; factor = vector[0].x * vector[2].y - vector[0].y * vector[2].x; if (factor == 0) { /* Parallel lines: hang with an error message */ g_warning(_("%s: trying to set an angular dimension on parallel lines"), G_STRLOC); return FALSE; } factor = ((ref1->y - ref2->y) * vector[2].x - (ref1->x - ref2->x) * vector[2].y) / factor; center->x = ref1->x + vector[0].x * factor; center->y = ref1->y + vector[0].y * factor; *distance = cpml_pair_distance(center, pos); data->angle1 = cpml_vector_angle(&vector[0]); data->angle2 = cpml_vector_angle(&vector[2]); while (data->angle2 < data->angle1) data->angle2 += G_PI * 2; cpml_vector_from_angle(&vector[1], (data->angle1 + data->angle2) / 2); return TRUE; }