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; }
static void _adg_arrange(AdgEntity *entity) { AdgADim *adim; AdgDim *dim; AdgADimPrivate *data; AdgAlignment *quote; const cairo_matrix_t *global, *local; CpmlPair ref1, ref2, base1, base12, base2; CpmlPair pair; CpmlExtents extents; AdgEntity *marker_entity; if (_ADG_OLD_ENTITY_CLASS->arrange) _ADG_OLD_ENTITY_CLASS->arrange(entity); adim = (AdgADim *) entity; if (! _adg_update_geometry(adim)) return; dim = (AdgDim *) adim; data = adim->data; quote = adg_dim_get_quote(dim); _adg_update_entities(adim); if (data->cairo.path.status == CAIRO_STATUS_SUCCESS) { AdgEntity *quote_entity = (AdgEntity *) quote; adg_entity_set_global_map(quote_entity, &data->quote.global_map); return; } global = adg_entity_get_global_matrix(entity); local = adg_entity_get_local_matrix(entity); extents.is_defined = FALSE; cpml_pair_copy(&ref1, (CpmlPair *) adg_dim_get_ref1(dim)); cpml_pair_copy(&ref2, (CpmlPair *) adg_dim_get_ref2(dim)); cpml_pair_copy(&base1, &data->point.base1); cpml_pair_copy(&base12, &data->point.base12); cpml_pair_copy(&base2, &data->point.base2); /* Apply the local matrix to the relevant points */ cpml_pair_transform(&ref1, local); cpml_pair_transform(&ref2, local); cpml_pair_transform(&base1, local); cpml_pair_transform(&base12, local); cpml_pair_transform(&base2, local); /* Combine points and global shifts to build the path */ pair.x = ref1.x + data->shift.from1.x; pair.y = ref1.y + data->shift.from1.y; cpml_pair_to_cairo(&pair, &data->cairo.data[6]); pair.x = base1.x + data->shift.base1.x; pair.y = base1.y + data->shift.base1.y; cpml_pair_to_cairo(&pair, &data->cairo.data[1]); pair.x += data->shift.to1.x; pair.y += data->shift.to1.y; cpml_pair_to_cairo(&pair, &data->cairo.data[8]); pair.x = base12.x + data->shift.base12.x; pair.y = base12.y + data->shift.base12.y; cpml_pair_to_cairo(&pair, &data->cairo.data[3]); pair.x = ref2.x + data->shift.from2.x; pair.y = ref2.y + data->shift.from2.y; cpml_pair_to_cairo(&pair, &data->cairo.data[10]); pair.x = base2.x + data->shift.base2.x; pair.y = base2.y + data->shift.base2.y; cpml_pair_to_cairo(&pair, &data->cairo.data[4]); pair.x += data->shift.to2.x; pair.y += data->shift.to2.y; cpml_pair_to_cairo(&pair, &data->cairo.data[12]); /* Play with header lengths to show or hide the extension lines */ if (data->has_extension1) { data->cairo.data[7].header.length = data->has_extension2 ? 2 : 6; } else { data->cairo.data[2].header.length = data->has_extension2 ? 7 : 11; } data->cairo.path.status = CAIRO_STATUS_SUCCESS; /* Arrange the quote */ if (quote != NULL) { AdgEntity *quote_entity; gdouble angle; cairo_matrix_t map; quote_entity = (AdgEntity *) quote; angle = adg_dim_quote_angle(dim, (data->angle1 + data->angle2) / 2 + G_PI_2); cpml_pair_from_cairo(&pair, &data->cairo.data[3]); adg_alignment_set_factor_explicit(quote, 0.5, 0); cairo_matrix_init_translate(&map, pair.x, pair.y); cairo_matrix_rotate(&map, angle); adg_entity_set_global_map(quote_entity, &map); adg_entity_arrange(quote_entity); cpml_extents_add(&extents, adg_entity_get_extents(quote_entity)); adg_matrix_copy(&data->quote.global_map, &map); } /* Arrange the trail */ if (data->trail != NULL) { CpmlExtents trail_extents; cpml_extents_copy(&trail_extents, adg_trail_get_extents(data->trail)); cpml_extents_transform(&trail_extents, global); cpml_extents_add(&extents, &trail_extents); } else { _adg_dispose_markers(adim); } /* Arrange the markers */ if (data->marker1 != NULL) { marker_entity = (AdgEntity *) data->marker1; adg_marker_set_segment(data->marker1, data->trail, 1); adg_entity_local_changed(marker_entity); adg_entity_arrange(marker_entity); cpml_extents_add(&extents, adg_entity_get_extents(marker_entity)); } if (data->marker2 != NULL) { marker_entity = (AdgEntity *) data->marker2; adg_marker_set_segment(data->marker2, data->trail, 1); adg_entity_local_changed(marker_entity); adg_entity_arrange(marker_entity); cpml_extents_add(&extents, adg_entity_get_extents(marker_entity)); } adg_entity_set_extents(entity, &extents); }
static void _adg_property_ref1(void) { AdgDim *dim; AdgModel *model; AdgPoint *origin, *explicit_point, *model_point; AdgPoint *ref1; dim = ADG_DIM(adg_rdim_new()); model = ADG_MODEL(adg_path_new()); origin = adg_point_new(); explicit_point = adg_point_new(); model_point = adg_point_new(); adg_point_set_pair_explicit(origin, 0, 0); adg_point_set_pair_explicit(explicit_point, 123, 321); adg_model_set_named_pair(model, "named-pair", (CpmlPair *) explicit_point); adg_point_set_pair_from_model(model_point, model, "named-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)); ref1 = adg_dim_get_ref1(dim); g_assert_null(ref1); /* Using the public APIs */ adg_dim_set_ref1_explicit(dim, 0, 0); ref1 = adg_dim_get_ref1(dim); g_assert_true(adg_point_equal(ref1, origin)); adg_dim_set_ref1(dim, NULL); ref1 = adg_dim_get_ref1(dim); g_assert_null(ref1); adg_dim_set_ref1(dim, explicit_point); ref1 = adg_dim_get_ref1(dim); g_assert_true(adg_point_equal(ref1, explicit_point)); adg_dim_set_ref1_from_model(dim, model, "dummy"); ref1 = adg_dim_get_ref1(dim); g_assert_nonnull(ref1); adg_dim_set_ref1_from_model(dim, model, "named-pair"); ref1 = adg_dim_get_ref1(dim); g_assert_true(adg_point_equal(ref1, model_point)); /* Using GObject property methods */ g_object_set(dim, "ref1", origin, NULL); g_object_get(dim, "ref1", &ref1, NULL); g_assert_true(adg_point_equal(ref1, origin)); adg_point_destroy(ref1); g_object_set(dim, "ref1", NULL, NULL); g_object_get(dim, "ref1", &ref1, NULL); g_assert_null(ref1); g_object_set(dim, "ref1", explicit_point, NULL); g_object_get(dim, "ref1", &ref1, NULL); g_assert_true(adg_point_equal(ref1, explicit_point)); adg_point_destroy(ref1); adg_dim_set_ref1_from_model(dim, model, "dummy"); g_object_get(dim, "ref1", &ref1, NULL); g_assert_nonnull(ref1); adg_point_destroy(ref1); g_object_set(dim, "ref1", model_point, NULL); g_object_get(dim, "ref1", &ref1, NULL); g_assert_true(adg_point_equal(ref1, model_point)); adg_point_destroy(ref1); adg_point_destroy(origin); adg_point_destroy(explicit_point); adg_point_destroy(model_point); adg_entity_destroy(ADG_ENTITY(dim)); g_object_unref(model); }