Exemplo n.º 1
0
Arquivo: adg-point.c Projeto: ntd/adg
/**
 * 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;
}
Exemplo n.º 2
0
Arquivo: cpml-line.c Projeto: bert/adg
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;
}
Exemplo n.º 3
0
Arquivo: adg-path.c Projeto: bert/adg
/**
 * 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);
}
Exemplo n.º 4
0
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;
    }
}
Exemplo n.º 5
0
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);
    }
}
Exemplo n.º 6
0
Arquivo: adg-adim.c Projeto: bert/adg
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);
}
Exemplo n.º 7
0
Arquivo: adg-adim.c Projeto: bert/adg
/* 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, &center, &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;
}