/** * adg_point_update: * @point: a pointer to an #AdgPoint * * Updates the internal #CpmlPair of @point. The internal * implementation is protected against multiple calls so it * can be called more times without harms. * * Returns: <constant>TRUE</constant> if @point has been updated or <constant>FALSE</constant> on errors, i.e. when it is bound to a non-existent named pair. * * Since: 1.0 **/ gboolean adg_point_update(AdgPoint *point) { AdgModel *model; const CpmlPair *pair; g_return_val_if_fail(point != NULL, FALSE); if (point->up_to_date) return TRUE; model = point->model; if (model == NULL) { /* A point with explicit coordinates not up to date * is an unexpected condition */ g_warning(_("%s: trying to get a pair from an undefined point"), G_STRLOC); return FALSE; } pair = adg_model_get_named_pair(model, point->name); if (pair == NULL) return FALSE; cpml_pair_copy(&point->pair, pair); point->up_to_date = TRUE; return TRUE; }
static double get_closest_pos(const CpmlPrimitive *line, const CpmlPair *pair) { CpmlPair p1_4[4]; CpmlVector normal; CpmlPair dummy; double pos; cpml_primitive_put_point(line, 0, &p1_4[0]); cpml_primitive_put_point(line, -1, &p1_4[1]); normal.x = p1_4[1].x - p1_4[0].x; normal.y = p1_4[1].y - p1_4[0].y; cpml_vector_normal(&normal); cpml_pair_copy(&p1_4[2], pair); p1_4[3].x = pair->x + normal.x; p1_4[3].y = pair->y + normal.y; /* Ensure to return 0 if intersection() fails */ pos = 0; /* The destination pair cannot be NULL to avoid crashes */ intersection(p1_4, &dummy, &pos); /* Clamp the result to 0..1 */ if (pos < 0) pos = 0; else if (pos > 1.) pos = 1.; return pos; }
/** * adg_path_reflect: * @path: an #AdgPath * @vector: (allow-none): the slope of the axis * * Reflects the first segment or @path around the axis passing * throught (0, 0) and with a @vector slope. The internal segment * is duplicated and the proper transformation (computed from * @vector) to mirror the segment is applied on all its points. * The result is then reversed with cpml_segment_reverse() and * appended to the original path with adg_path_append_segment(). * * For convenience, if @vector is <constant>NULL</constant> the * path is reversed around the x axis <constant>(y = 0)</constant>. * * Since: 1.0 **/ void adg_path_reflect(AdgPath *path, const CpmlVector *vector) { AdgModel *model; cairo_matrix_t matrix; CpmlSegment segment, *dup_segment; g_return_if_fail(ADG_IS_PATH(path)); g_return_if_fail(vector == NULL || vector->x != 0 || vector->y != 0); model = (AdgModel *) path; if (vector == NULL) { cairo_matrix_init_scale(&matrix, 1, -1); } else { CpmlVector slope; gdouble cos2angle, sin2angle; cpml_pair_copy(&slope, vector); cpml_vector_set_length(&slope, 1); if (slope.x == 0 && slope.y == 0) { g_warning(_("%s: the axis of the reflection is not known"), G_STRLOC); return; } sin2angle = 2. * vector->x * vector->y; cos2angle = 2. * vector->x * vector->x - 1; cairo_matrix_init(&matrix, cos2angle, sin2angle, sin2angle, -cos2angle, 0, 0); } if (!adg_trail_put_segment((AdgTrail *) path, 1, &segment)) return; /* No need to reverse an empty segment */ if (segment.num_data == 0 || segment.num_data == 0) return; dup_segment = cpml_segment_deep_dup(&segment); if (dup_segment == NULL) return; cpml_segment_reverse(dup_segment); cpml_segment_transform(dup_segment, &matrix); dup_segment->data[0].header.type = CPML_LINE; adg_path_append_segment(path, dup_segment); g_free(dup_segment); _adg_dup_reverse_named_pairs(model, &matrix); }
static void _adg_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { AdgTableStylePrivate *data = ((AdgTableStyle *) object)->data; switch (prop_id) { case PROP_COLOR_DRESS: data->color_dress = g_value_get_enum(value); break; case PROP_GRID_DRESS: data->grid_dress = g_value_get_enum(value); break; case PROP_FRAME_DRESS: data->frame_dress = g_value_get_enum(value); break; case PROP_TITLE_DRESS: data->title_dress = g_value_get_enum(value); break; case PROP_VALUE_DRESS: data->value_dress = g_value_get_enum(value); break; case PROP_ROW_HEIGHT: data->row_height = g_value_get_double(value); break; case PROP_CELL_PADDING: cpml_pair_copy(&data->cell_padding, g_value_get_boxed(value)); break; case PROP_CELL_SPACING: cpml_pair_copy(&data->cell_spacing, g_value_get_boxed(value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } }
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); } }
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); }
/* With "geometry" is considered any data (point, vector or angle) * that can be cached: this is strictly related on how the arrange() * method works */ static gboolean _adg_update_geometry(AdgADim *adim) { AdgADimPrivate *data; AdgDimStyle *dim_style; gdouble from_offset, to_offset; gdouble spacing, level; CpmlVector vector[3]; CpmlPair center; gdouble distance; data = adim->data; /* Check for cached results */ if (data->geometry_arranged) return TRUE; if (! _adg_get_info(adim, vector, ¢er, &distance)) return FALSE; dim_style = _ADG_GET_DIM_STYLE(adim); from_offset = adg_dim_style_get_from_offset(dim_style); to_offset = adg_dim_style_get_to_offset(dim_style); spacing = adg_dim_style_get_baseline_spacing(dim_style); level = adg_dim_get_level((AdgDim *) adim); /* shift.from1 */ cpml_vector_set_length(&vector[0], from_offset); cpml_pair_copy(&data->shift.from1, &vector[0]); /* shift.base1 */ cpml_vector_set_length(&vector[0], level * spacing); cpml_pair_copy(&data->shift.base1, &vector[0]); /* shift.to1 */ cpml_vector_set_length(&vector[0], to_offset); cpml_pair_copy(&data->shift.to1, &vector[0]); /* shift.from2 */ cpml_vector_set_length(&vector[2], from_offset); cpml_pair_copy(&data->shift.from2, &vector[2]); /* shift.base2 */ cpml_vector_set_length(&vector[2], level * spacing); cpml_pair_copy(&data->shift.base2, &vector[2]); /* shift.to2 */ cpml_vector_set_length(&vector[2], to_offset); cpml_pair_copy(&data->shift.to2, &vector[2]); /* shift.base12 */ cpml_vector_set_length(&vector[1], level * spacing); cpml_pair_copy(&data->shift.base12, &vector[1]); /* Distance can be 0, so the following will leave the * vector array in undefined state */ /* point.base1 */ cpml_vector_set_length(&vector[0], distance); data->point.base1.x = vector[0].x + center.x; data->point.base1.y = vector[0].y + center.y; /* point.base2 */ cpml_vector_set_length(&vector[2], distance); data->point.base2.x = vector[2].x + center.x; data->point.base2.y = vector[2].y + center.y; /* point.base12 */ cpml_vector_set_length(&vector[1], distance); data->point.base12.x = vector[1].x + center.x; data->point.base12.y = vector[1].y + center.y; data->geometry_arranged = TRUE; return TRUE; }