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; } } }
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; }
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; } } }
/** * 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); }
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; }
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)); } }