Example #1
0
void
sp_clippath_set_bbox(SPClipPath *cp, unsigned int key, NRRect *bbox)
{
    for (SPClipPathView *v = cp->display; v != NULL; v = v->next) {
        if (v->key == key) {
            if (!NR_DF_TEST_CLOSE(v->bbox.x0, bbox->x0, NR_EPSILON) ||
                !NR_DF_TEST_CLOSE(v->bbox.y0, bbox->y0, NR_EPSILON) ||
                !NR_DF_TEST_CLOSE(v->bbox.x1, bbox->x1, NR_EPSILON) ||
                !NR_DF_TEST_CLOSE(v->bbox.y1, bbox->y1, NR_EPSILON)) {
                v->bbox = *bbox;
            }
            break;
        }
    }
}
Example #2
0
static NRFont *
nr_typeface_w32_font_new (NRTypeFace *tf, unsigned int metrics, NRMatrixF *transform)
{
	NRTypeFaceW32 *tfw32;
	NRFont *font;
	float size;

	tfw32 = (NRTypeFaceW32 *) tf;
	size = (float) NR_MATRIX_DF_EXPANSION (transform);

	font = tfw32->fonts;
	while (font != NULL) {
		if (NR_DF_TEST_CLOSE (size, font->size, 0.001 * size) && (font->metrics == metrics)) {
			return nr_font_ref (font);
		}
		font = font->next;
	}
	
	font = nr_font_generic_new (tf, metrics, transform);

	font->next = tfw32->fonts;
	tfw32->fonts = font;

	return font;
}
Example #3
0
void
sp_mask_set_bbox (SPMask *mask, unsigned int key, NRRectF *bbox)
{
	SPMaskView *v;

	for (v = mask->display; v != NULL; v = v->next) {
		if (v->key == key) {
			if (!NR_DF_TEST_CLOSE (v->bbox.x0, bbox->x0, NR_EPSILON_F) ||
			    !NR_DF_TEST_CLOSE (v->bbox.y0, bbox->y0, NR_EPSILON_F) ||
			    !NR_DF_TEST_CLOSE (v->bbox.x1, bbox->x1, NR_EPSILON_F) ||
			    !NR_DF_TEST_CLOSE (v->bbox.y1, bbox->y1, NR_EPSILON_F)) {
				v->bbox = *bbox;
				sp_object_request_update (SP_OBJECT (mask), SP_OBJECT_MODIFIED_FLAG);
			}
			break;
		}
	}
}
Example #4
0
/**
 * Writes the given transform into the repr for the given item.
 */
static void
sp_path_write_transform (SPItem *item, SPRepr *repr, NRMatrixF *transform)
{
	SPPath *path;
	SPShape *shape;
	NRBPath dpath, spath;
	double ex;
	gchar *svgpath;
	SPStyle *style;

	path = (SPPath *) item;
	shape = (SPShape *) item;

	/* Calculate the DF */
	ex = NR_MATRIX_DF_EXPANSION (transform);

	/* Take the path for the shape, write it as an svgpath, and add it to the repr */
	spath.path = shape->curve->bpath;
	nr_path_duplicate_transform (&dpath, &spath, transform);
	svgpath = sp_svg_write_path (dpath.path);
	sp_repr_set_attr (repr, "d", svgpath);
	g_free (svgpath);
	nr_free (dpath.path);

	/* Wrte the style info into the repr */
	style = SP_OBJECT_STYLE (item);
	if (style->stroke.type != SP_PAINT_TYPE_NONE) {
		if (!NR_DF_TEST_CLOSE (ex, 1.0, NR_EPSILON_D)) {
			gchar *str;
			/* Scale changed, so we have to adjust stroke width */
			style->stroke_width.computed *= ex;
			if (style->stroke_dash.n_dash != 0) {
				int i;
				for (i = 0; i < style->stroke_dash.n_dash; i++) style->stroke_dash.dash[i] *= ex;
				style->stroke_dash.offset *= ex;
			}
			str = sp_style_write_difference (style, SP_OBJECT_STYLE (SP_OBJECT_PARENT (item)));
			sp_repr_set_attr (repr, "style", str);
			g_free (str);
		}
	}
	sp_repr_set_attr (repr, "transform", NULL);
}
Example #5
0
NRRenderer *
nr_rgradient_renderer_setup(NRRGradientRenderer *rgr,
                            unsigned char const *cv,
                            unsigned spread,
                            NR::Matrix const *gs2px,
                            float cx, float cy,
                            float fx, float fy,
                            float r)
{
    rgr->vector = cv;
    rgr->spread = spread;

    if (r < NR_EPSILON) {
        rgr->render = nr_rgradient_render_block_end;
    } else if (NR_DF_TEST_CLOSE(cx, fx, NR_EPSILON) &&
               NR_DF_TEST_CLOSE(cy, fy, NR_EPSILON)) {
        rgr->render = render<SymmetricRadial>;

        rgr->px2gs = gs2px->inverse();
        rgr->px2gs[0] *= (NR_GRADIENT_VECTOR_LENGTH-1) / r;
        rgr->px2gs[1] *= (NR_GRADIENT_VECTOR_LENGTH-1) / r;
        rgr->px2gs[2] *= (NR_GRADIENT_VECTOR_LENGTH-1) / r;
        rgr->px2gs[3] *= (NR_GRADIENT_VECTOR_LENGTH-1) / r;
        rgr->px2gs[4] -= cx;
        rgr->px2gs[5] -= cy;
        rgr->px2gs[4] *= (NR_GRADIENT_VECTOR_LENGTH-1) / r;
        rgr->px2gs[5] *= (NR_GRADIENT_VECTOR_LENGTH-1) / r;
        rgr->px2gs[4] += 0.5*(rgr->px2gs[0]+rgr->px2gs[2]); // These offsets make sure the gradient is sampled in the MIDDLE of each pixel
        rgr->px2gs[5] += 0.5*(rgr->px2gs[1]+rgr->px2gs[3]);

        rgr->cx = 0.0;
        rgr->cy = 0.0;
        rgr->fx = rgr->cx;
        rgr->fy = rgr->cy;
        rgr->r = 1.0;
    } else {
        rgr->render = render<Radial>;

        NR::Coord const df = hypot(fx - cx, fy - cy);
        if (df >= r) {
            fx = cx + (fx - cx ) * r / (float) df;
            fy = cy + (fy - cy ) * r / (float) df;
        }

        NR::Matrix n2gs;
        n2gs[0] = cx - fx;
        n2gs[1] = cy - fy;
        n2gs[2] = cy - fy;
        n2gs[3] = fx - cx;
        n2gs[4] = fx;
        n2gs[5] = fy;

        NR::Matrix n2px;
        n2px = n2gs * (*gs2px);
        rgr->px2gs = n2px.inverse();
        rgr->px2gs[4] += 0.5*(rgr->px2gs[0]+rgr->px2gs[2]); // These offsets make sure the gradient is sampled in the MIDDLE of each pixel
        rgr->px2gs[5] += 0.5*(rgr->px2gs[1]+rgr->px2gs[3]);

        rgr->cx = 1.0;
        rgr->cy = 0.0;
        rgr->fx = 0.0;
        rgr->fy = 0.0;
        rgr->r = r / (float) hypot(fx - cx, fy - cy);
        rgr->C = 1.0F - rgr->r * rgr->r;
        /* INVARIANT: C < 0 */
        rgr->C = MIN(rgr->C, -NR_EPSILON);
    }

    return (NRRenderer *) rgr;
}
Example #6
0
void
sp_align_distribute_v_clicked (GtkWidget *widget, const gchar *layout)
{
	SPDesktop *desktop;
	SPSelection *selection;
	const GSList *slist, *l;
	struct _SPBBoxSort *bbs;
	int len, pos;
	unsigned int changed;

	desktop = SP_ACTIVE_DESKTOP;
	if (!desktop) return;

	selection = SP_DT_SELECTION (desktop);
	slist = sp_selection_item_list (selection);
	if (!slist) return;
	if (!slist->next) return;

	len = g_slist_length ((GSList *) slist);
	bbs = g_new (struct _SPBBoxSort, len);
	pos = 0;
	for (l = slist; l != NULL; l = l->next) {
		bbs[pos].item = SP_ITEM (l->data);
		sp_item_bbox_desktop (bbs[pos].item, &bbs[pos].bbox);
		bbs[pos].anchor = 0.5 * layout[0] * bbs[pos].bbox.y0 + 0.5 * layout[1] * bbs[pos].bbox.y1;
		pos += 1;
	}

	qsort (bbs, len, sizeof (struct _SPBBoxSort), sp_align_bbox_sort);

	changed = FALSE;

	if (!layout[2]) {
		float dist, step;
		int i;
		dist = bbs[len - 1].anchor - bbs[0].anchor;
		step = dist / (len - 1);
		for (i = 0; i < len; i++) {
			float pos;
			pos = bbs[0].anchor + i * step;
			if (!NR_DF_TEST_CLOSE (pos, bbs[i].anchor, 1e-6)) {
				sp_item_move_rel (bbs[i].item, 0.0, pos - bbs[i].anchor);
				changed = TRUE;
			}
		}
	} else {
		/* Damn I am not sure, how to order them initially (Lauris) */
		float dist, span, step, pos;
		int i;
		dist = bbs[len - 1].bbox.y1 - bbs[0].bbox.y0;
		span = 0;
		for (i = 0; i < len; i++) span += (bbs[i].bbox.y1 - bbs[i].bbox.y0);
		step = (dist - span) / (len - 1);
		pos = bbs[0].bbox.y0;
		for (i = 0; i < len; i++) {
			if (!NR_DF_TEST_CLOSE (pos, bbs[i].bbox.y0, 1e-6)) {
				sp_item_move_rel (bbs[i].item, 0.0, pos - bbs[i].bbox.y0);
				changed = TRUE;
			}
			pos += (bbs[i].bbox.y1 - bbs[i].bbox.y0);
			pos += step;
		}
	}

	g_free (bbs);

	if (changed) {
		sp_selection_changed (selection);
		sp_document_done (SP_DT_DOCUMENT (desktop));
	}
}