/** * adg_point_get_pair: * @point: an #AdgPoint * * #AdgPoint is an evolution of the pair concept but internally the * relevant data is still stored in an #CpmlPair struct. This function * returns a copy of the internally owned pair. * * <note><para> * The #CpmlPair is the first field of an #AdgPoint struct so casting * is allowed between them and, in fact, it is often more convenient * than calling this function. Just remember to update the internal * pair by using adg_point_update() before. * </para></note> * * Returns: (transfer full): the pair of @point or <constant>NULL</constant> if the named pair does not exist. * * Since: 1.0 **/ CpmlPair * adg_point_get_pair(AdgPoint *point) { g_return_val_if_fail(point != NULL, NULL); if (! adg_point_update(point)) return NULL; return cpml_pair_dup(& point->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; }