summaryrefslogtreecommitdiffstats
path: root/src/display
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2015-12-08 11:05:08 +0000
committerjabiertxof <jabier.arraiza@marker.es>2015-12-08 11:05:08 +0000
commitd79bd642b3214f1c44d7c1268e8adcb7bd55fffc (patch)
tree74a8529da5f23996ba4b358c045a7588f8c27f24 /src/display
parentminor changes (diff)
parentmerge lp:~inkscape.dev/inkscape/lock_guides (diff)
downloadinkscape-d79bd642b3214f1c44d7c1268e8adcb7bd55fffc.tar.gz
inkscape-d79bd642b3214f1c44d7c1268e8adcb7bd55fffc.zip
update to trunk
(bzr r14272.1.11)
Diffstat (limited to 'src/display')
-rw-r--r--src/display/canvas-text.cpp6
-rw-r--r--src/display/curve.cpp2
-rw-r--r--src/display/drawing-image.cpp2
-rw-r--r--src/display/guideline.cpp18
-rw-r--r--src/display/guideline.h2
-rw-r--r--src/display/nr-filter-image.cpp2
-rw-r--r--src/display/nr-filter-offset.cpp4
-rw-r--r--src/display/nr-filter-primitive.cpp19
-rw-r--r--src/display/nr-filter-slot.cpp21
-rw-r--r--src/display/nr-filter-slot.h8
-rw-r--r--src/display/nr-filter-tile.cpp99
-rw-r--r--src/display/nr-filter-tile.h1
-rw-r--r--src/display/nr-style.cpp2
-rw-r--r--src/display/nr-style.h1
-rw-r--r--src/display/sp-ctrlpoint.cpp28
-rw-r--r--src/display/sp-ctrlpoint.h6
16 files changed, 188 insertions, 33 deletions
diff --git a/src/display/canvas-text.cpp b/src/display/canvas-text.cpp
index 5ad87b4ef..7c019caf5 100644
--- a/src/display/canvas-text.cpp
+++ b/src/display/canvas-text.cpp
@@ -266,10 +266,10 @@ sp_canvastext_set_coords (SPCanvasText *ct, gdouble x0, gdouble y0)
void
sp_canvastext_set_coords (SPCanvasText *ct, const Geom::Point start)
{
- Geom::Point pos = ct->desktop->doc2dt(start);
-
- g_return_if_fail (ct != NULL);
+ g_return_if_fail (ct && ct->desktop);
g_return_if_fail (SP_IS_CANVASTEXT (ct));
+
+ Geom::Point pos = ct->desktop->doc2dt(start);
if (DIFFER (pos[0], ct->s[Geom::X]) || DIFFER (pos[1], ct->s[Geom::Y])) {
ct->s[Geom::X] = pos[0];
diff --git a/src/display/curve.cpp b/src/display/curve.cpp
index 3024d1276..b6c387034 100644
--- a/src/display/curve.cpp
+++ b/src/display/curve.cpp
@@ -496,7 +496,7 @@ SPCurve::append(SPCurve const *curve2,
_pathv.push_back( (*it) );
}
- for (it++; it != curve2->_pathv.end(); ++it) {
+ for (++it; it != curve2->_pathv.end(); ++it) {
_pathv.push_back( (*it) );
}
} else {
diff --git a/src/display/drawing-image.cpp b/src/display/drawing-image.cpp
index 1594614ac..2a943d16c 100644
--- a/src/display/drawing-image.cpp
+++ b/src/display/drawing-image.cpp
@@ -132,7 +132,7 @@ unsigned DrawingImage::_renderItem(DrawingContext &dc, Geom::IntRect const &/*ar
}
}
- dc.paint(_opacity);
+ dc.paint(1);
} else { // outline; draw a rect instead
diff --git a/src/display/guideline.cpp b/src/display/guideline.cpp
index 44bbd14bd..4b7ea59ab 100644
--- a/src/display/guideline.cpp
+++ b/src/display/guideline.cpp
@@ -53,6 +53,7 @@ static void sp_guideline_init(SPGuideLine *gl)
{
gl->rgba = 0x0000ff7f;
+ gl->locked = false;
gl->normal_to_line = Geom::Point(0,1);
gl->angle = 3.14159265358979323846/2;
gl->point_on_line = Geom::Point(0,0);
@@ -177,9 +178,16 @@ static void sp_guideline_update(SPCanvasItem *item, Geom::Affine const &affine,
gl->affine = affine;
+ if (gl->locked) {
+ sp_ctrlpoint_set_circle(gl->origin, false);
+ sp_ctrlpoint_set_lenght(gl->origin, 6);
+ } else {
+ sp_ctrlpoint_set_circle(gl->origin, true);
+ sp_ctrlpoint_set_lenght(gl->origin, 4);
+ }
sp_ctrlpoint_set_coords(gl->origin, gl->point_on_line);
sp_canvas_item_request_update(SP_CANVAS_ITEM (gl->origin));
-
+
Geom::Point pol_transformed = gl->point_on_line*affine;
if (gl->is_horizontal()) {
sp_canvas_update_bbox (item, -1000000, round(pol_transformed[Geom::Y] - 16), 1000000, round(pol_transformed[Geom::Y] + 1));
@@ -189,6 +197,7 @@ static void sp_guideline_update(SPCanvasItem *item, Geom::Affine const &affine,
//TODO: labels in angled guidelines are not showing up for some reason.
sp_canvas_update_bbox (item, -1000000, -1000000, 1000000, 1000000);
}
+
}
// Returns 0.0 if point is on the guideline
@@ -219,6 +228,7 @@ SPCanvasItem *sp_guideline_new(SPCanvasGroup *parent, char* label, Geom::Point p
normal.normalize();
gl->label = label;
+ gl->locked = false;
gl->normal_to_line = normal;
gl->angle = tan( -gl->normal_to_line[Geom::X] / gl->normal_to_line[Geom::Y]);
sp_guideline_set_position(gl, point_on_line);
@@ -238,6 +248,12 @@ void sp_guideline_set_label(SPGuideLine *gl, const char* label)
sp_canvas_item_request_update(SP_CANVAS_ITEM (gl));
}
+void sp_guideline_set_locked(SPGuideLine *gl, const bool locked)
+{
+ gl->locked = locked;
+ sp_canvas_item_request_update(SP_CANVAS_ITEM (gl));
+}
+
void sp_guideline_set_position(SPGuideLine *gl, Geom::Point point_on_line)
{
gl->point_on_line = point_on_line;
diff --git a/src/display/guideline.h b/src/display/guideline.h
index 2d9a87d9b..778517f1d 100644
--- a/src/display/guideline.h
+++ b/src/display/guideline.h
@@ -32,6 +32,7 @@ struct SPGuideLine {
guint32 rgba;
char* label;
+ bool locked;
Geom::Point normal_to_line;
Geom::Point point_on_line;
double angle;
@@ -51,6 +52,7 @@ GType sp_guideline_get_type();
SPCanvasItem *sp_guideline_new(SPCanvasGroup *parent, char* label, Geom::Point point_on_line, Geom::Point normal);
void sp_guideline_set_label(SPGuideLine *gl, const char* label);
+void sp_guideline_set_locked(SPGuideLine *gl, const bool locked);
void sp_guideline_set_position(SPGuideLine *gl, Geom::Point point_on_line);
void sp_guideline_set_normal(SPGuideLine *gl, Geom::Point normal_to_line);
void sp_guideline_set_color(SPGuideLine *gl, unsigned int rgba);
diff --git a/src/display/nr-filter-image.cpp b/src/display/nr-filter-image.cpp
index 179ba0e0a..af89d98e0 100644
--- a/src/display/nr-filter-image.cpp
+++ b/src/display/nr-filter-image.cpp
@@ -56,6 +56,8 @@ void FilterImage::render_cairo(FilterSlot &slot)
// Note: viewport calculation in non-trivial. Do not rely
// on get_matrix_primitiveunits2pb().
Geom::Rect vp = filter_primitive_area( slot.get_units() );
+ slot.set_primitive_area(_output, vp); // Needed for tiling
+
double feImageX = vp.min()[Geom::X];
double feImageY = vp.min()[Geom::Y];
double feImageWidth = vp.width();
diff --git a/src/display/nr-filter-offset.cpp b/src/display/nr-filter-offset.cpp
index af1081abe..93bab7d39 100644
--- a/src/display/nr-filter-offset.cpp
+++ b/src/display/nr-filter-offset.cpp
@@ -37,9 +37,11 @@ void FilterOffset::render_cairo(FilterSlot &slot)
cairo_surface_t *out = ink_cairo_surface_create_identical(in);
// color_interpolation_filters for out same as in. See spec (DisplacementMap).
copy_cairo_surface_ci(in, out);
-
cairo_t *ct = cairo_create(out);
+ Geom::Rect vp = filter_primitive_area( slot.get_units() );
+ slot.set_primitive_area(_output, vp); // Needed for tiling
+
// Handle bounding box case
double x = dx;
double y = dy;
diff --git a/src/display/nr-filter-primitive.cpp b/src/display/nr-filter-primitive.cpp
index c8b569036..ea72efff0 100644
--- a/src/display/nr-filter-primitive.cpp
+++ b/src/display/nr-filter-primitive.cpp
@@ -110,17 +110,12 @@ void FilterPrimitive::set_subregion(SVGLength const &x, SVGLength const &y,
Geom::Rect FilterPrimitive::filter_primitive_area(FilterUnits const &units)
{
- Geom::OptRect const bb_opt = units.get_item_bbox();
Geom::OptRect const fa_opt = units.get_filter_area();
- Geom::Rect bb;
- Geom::Rect fa;
- if (!bb_opt || !fa_opt) {
+ if (!fa_opt) {
+ std::cerr << "FilterPrimitive::filter_primitive_area: filter area undefined." << std::endl;
return Geom::Rect (Geom::Point(0.,0.), Geom::Point(0.,0.));
- } else {
- bb = *bb_opt;
- fa = *fa_opt;
}
-
+ Geom::Rect fa = *fa_opt;
// x, y, width, and height are independently defined (i.e. one can be defined, by default, to
// the filter area (via default value ) while another is defined relative to the bounding
@@ -138,6 +133,14 @@ Geom::Rect FilterPrimitive::filter_primitive_area(FilterUnits const &units)
if( units.get_primitive_units() == SP_FILTER_UNITS_OBJECTBOUNDINGBOX ) {
+ Geom::OptRect const bb_opt = units.get_item_bbox();
+ if (!bb_opt) {
+ std::cerr << "FilterPrimitive::filter_primitive_area: bounding box undefined and 'primitiveUnits' is 'objectBoundingBox'." << std::endl;
+ return Geom::Rect (Geom::Point(0.,0.), Geom::Point(0.,0.));
+ }
+ Geom::Rect bb = *bb_opt;
+
+
// Update computed values for ex, em, %.
// For %, assumes primitive unit is objectBoundingBox.
// TODO: fetch somehow the object ex and em lengths; 12, 6 are just dummy values.
diff --git a/src/display/nr-filter-slot.cpp b/src/display/nr-filter-slot.cpp
index e4c2f048e..a6e0c5c4e 100644
--- a/src/display/nr-filter-slot.cpp
+++ b/src/display/nr-filter-slot.cpp
@@ -232,6 +232,27 @@ void FilterSlot::set(int slot_nr, cairo_surface_t *surface)
_last_out = slot_nr;
}
+void FilterSlot::set_primitive_area(int slot_nr, Geom::Rect &area)
+{
+ if (slot_nr == NR_FILTER_SLOT_NOT_SET)
+ slot_nr = NR_FILTER_UNNAMED_SLOT;
+
+ _primitiveAreas[slot_nr] = area;
+}
+
+Geom::Rect FilterSlot::get_primitive_area(int slot_nr)
+{
+ if (slot_nr == NR_FILTER_SLOT_NOT_SET)
+ slot_nr = _last_out;
+
+ PrimitiveAreaMap::iterator s = _primitiveAreas.find(slot_nr);
+
+ if (s == _primitiveAreas.end()) {
+ return *(_units.get_filter_area());
+ }
+ return s->second;
+}
+
int FilterSlot::get_slot_count()
{
return _slots.size();
diff --git a/src/display/nr-filter-slot.h b/src/display/nr-filter-slot.h
index 987dedfd1..166b2e718 100644
--- a/src/display/nr-filter-slot.h
+++ b/src/display/nr-filter-slot.h
@@ -54,6 +54,9 @@ public:
cairo_surface_t *get_result(int slot_nr);
+ void set_primitive_area(int slot, Geom::Rect &area);
+ Geom::Rect get_primitive_area(int slot);
+
/** Returns the number of slots in use. */
int get_slot_count();
@@ -75,6 +78,11 @@ public:
private:
typedef std::map<int, cairo_surface_t *> SlotMap;
SlotMap _slots;
+
+ // We need to keep track of the primitive area as this is needed in feTile
+ typedef std::map<int, Geom::Rect> PrimitiveAreaMap;
+ PrimitiveAreaMap _primitiveAreas;
+
DrawingItem *_item;
//Geom::Rect _source_bbox; ///< bounding box of source graphic surface
diff --git a/src/display/nr-filter-tile.cpp b/src/display/nr-filter-tile.cpp
index 93ca50210..913812828 100644
--- a/src/display/nr-filter-tile.cpp
+++ b/src/display/nr-filter-tile.cpp
@@ -10,6 +10,8 @@
*/
#include <glib.h>
+
+#include "display/cairo-utils.h"
#include "display/nr-filter-tile.h"
#include "display/nr-filter-slot.h"
#include "display/nr-filter-units.h"
@@ -30,16 +32,105 @@ FilterTile::~FilterTile()
void FilterTile::render_cairo(FilterSlot &slot)
{
+ // FIX ME!
static bool tile_warning = false;
-
-//IMPLEMENT ME!
if (!tile_warning) {
- g_warning("Renderer for feTile is not implemented.");
+ g_warning("Renderer for feTile has non-optimal implementation, expect slowness and bugs.");
tile_warning = true;
}
+ // Fixing isn't so easy as the Inkscape renderer breaks the canvas into "rendering" tiles for
+ // faster rendering. (The "rendering" tiles are not the same as the tiles in this primitive.)
+ // Only if the the feTile tile source falls inside the current "rendering" tile will the tile
+ // image be available.
+
+ // This input source contains only the "rendering" tile.
cairo_surface_t *in = slot.getcairo(_input);
- slot.set(_output, in);
+
+ // For debugging
+ // static int i = 0;
+ // ++i;
+ // std::stringstream filename;
+ // filename << "dump." << i << ".png";
+ // cairo_surface_write_to_png( in, filename.str().c_str() );
+
+ // This is the feTile source area as determined by the input primitive area (see SVG spec).
+ Geom::Rect tile_area = slot.get_primitive_area(_input);
+
+ if( tile_area.width() == 0.0 || tile_area.height() == 0.0 ) {
+
+ slot.set(_output, in);
+ std::cerr << "FileTile::render_cairo: tile has zero width or height" << std::endl;
+
+ } else {
+
+ cairo_surface_t *out = ink_cairo_surface_create_identical(in);
+ // color_interpolation_filters for out same as in.
+ copy_cairo_surface_ci(in, out);
+ cairo_t *ct = cairo_create(out);
+
+ // The rectangle of the "rendering" tile.
+ Geom::Rect sa = slot.get_slot_area();
+
+ Geom::Affine trans = slot.get_units().get_matrix_user2pb();
+
+ // Create feTile tile ----------------
+
+ // Get tile area in pixbuf units (tile transformed).
+ Geom::Rect tt = tile_area * trans;
+
+ // Shift between "rendering" tile and feTile tile
+ Geom::Point shift = sa.min() - tt.min();
+
+ // Create feTile tile surface
+ cairo_surface_t *tile = cairo_surface_create_similar(in, cairo_surface_get_content(in),
+ tt.width(), tt.height());
+ cairo_t *ct_tile = cairo_create(tile);
+ cairo_set_source_surface(ct_tile, in, shift[Geom::X], shift[Geom::Y]);
+ cairo_paint(ct_tile);
+
+ // Paint tiles ------------------
+
+ // For debugging
+ // std::stringstream filename;
+ // filename << "tile." << i << ".png";
+ // cairo_surface_write_to_png( tile, filename.str().c_str() );
+
+ // Determine number of feTile rows and columns
+ Geom::Rect pr = filter_primitive_area( slot.get_units() );
+ int tile_cols = ceil( pr.width() / tile_area.width() );
+ int tile_rows = ceil( pr.height() / tile_area.height() );
+
+ // Do tiling (TO DO: restrict to slot area.)
+ for( int col=0; col < tile_cols; ++col ) {
+ for( int row=0; row < tile_rows; ++row ) {
+
+ Geom::Point offset( col*tile_area.width(), row*tile_area.height() );
+ offset *= trans;
+ offset[Geom::X] -= trans[4];
+ offset[Geom::Y] -= trans[5];
+
+ cairo_set_source_surface(ct, tile, offset[Geom::X], offset[Geom::Y]);
+ cairo_paint(ct);
+ }
+ }
+ slot.set(_output, out);
+
+ // Clean up
+ cairo_destroy(ct);
+ cairo_surface_destroy(out);
+ cairo_destroy(ct_tile);
+ cairo_surface_destroy(tile);
+ }
+}
+
+void FilterTile::area_enlarge(Geom::IntRect &area, Geom::Affine const &trans)
+{
+ // We need to enlarge enough to get tile source... we don't the area of the source tile in this
+ // function so we guess. This is VERY inefficient.
+ Geom::Point enlarge(200, 200);
+ enlarge *= trans;
+ area.expandBy( enlarge[Geom::X] < 100 ? 100: enlarge[Geom::X] );
}
double FilterTile::complexity(Geom::Affine const &)
diff --git a/src/display/nr-filter-tile.h b/src/display/nr-filter-tile.h
index 29087f2d6..239ecff4b 100644
--- a/src/display/nr-filter-tile.h
+++ b/src/display/nr-filter-tile.h
@@ -26,6 +26,7 @@ public:
virtual ~FilterTile();
virtual void render_cairo(FilterSlot &slot);
+ virtual void area_enlarge(Geom::IntRect &area, Geom::Affine const &trans);
virtual double complexity(Geom::Affine const &ctm);
};
diff --git a/src/display/nr-style.cpp b/src/display/nr-style.cpp
index 1740785e2..8b82a1dff 100644
--- a/src/display/nr-style.cpp
+++ b/src/display/nr-style.cpp
@@ -68,7 +68,6 @@ NRStyle::NRStyle()
, tspan_width(0)
, ascender(0)
, descender(0)
- , line_gap(0)
, underline_thickness(0)
, underline_position(0)
, line_through_thickness(0)
@@ -330,7 +329,6 @@ void NRStyle::set(SPStyle *style, SPStyle *context_style)
tspan_width = style->text_decoration_data.tspan_width;
ascender = style->text_decoration_data.ascender;
descender = style->text_decoration_data.descender;
- line_gap = style->text_decoration_data.line_gap;
underline_thickness = style->text_decoration_data.underline_thickness;
underline_position = style->text_decoration_data.underline_position;
line_through_thickness = style->text_decoration_data.line_through_thickness;
diff --git a/src/display/nr-style.h b/src/display/nr-style.h
index 5f78795d3..6c652311a 100644
--- a/src/display/nr-style.h
+++ b/src/display/nr-style.h
@@ -115,7 +115,6 @@ struct NRStyle {
float tspan_width;
float ascender;
float descender;
- float line_gap;
float underline_thickness;
float underline_position;
float line_through_thickness;
diff --git a/src/display/sp-ctrlpoint.cpp b/src/display/sp-ctrlpoint.cpp
index 1082cb1b3..19dbbc130 100644
--- a/src/display/sp-ctrlpoint.cpp
+++ b/src/display/sp-ctrlpoint.cpp
@@ -42,7 +42,8 @@ sp_ctrlpoint_init (SPCtrlPoint *ctrlpoint)
ctrlpoint->rgba = 0x0000ff7f;
ctrlpoint->pt[Geom::X] = ctrlpoint->pt[Geom::Y] = 0.0;
ctrlpoint->item=NULL;
- ctrlpoint->radius = 2;
+ ctrlpoint->lenght = 4;
+ ctrlpoint->is_circle = true;
}
static void sp_ctrlpoint_destroy(SPCanvasItem *object)
@@ -75,8 +76,11 @@ sp_ctrlpoint_render (SPCanvasItem *item, SPCanvasBuf *buf)
cairo_new_path(buf->ct);
Geom::Point pt = cp->pt * cp->affine;
-
- cairo_arc(buf->ct, pt[Geom::X] - buf->rect.left(), pt[Geom::Y] - buf->rect.top(), cp->radius, 0.0, 2 * M_PI);
+ if( cp->is_circle ) {
+ cairo_arc(buf->ct, pt[Geom::X] - buf->rect.left(), pt[Geom::Y] - buf->rect.top(), cp->lenght/2.0, 0.0, 2 * M_PI);
+ } else {
+ cairo_rectangle(buf->ct, pt[Geom::X] - buf->rect.left() - cp->lenght/2.0, pt[Geom::Y] - buf->rect.top() - cp->lenght/2.0 , cp->lenght, cp->lenght);
+ }
cairo_stroke(buf->ct);
}
@@ -96,10 +100,10 @@ static void sp_ctrlpoint_update(SPCanvasItem *item, Geom::Affine const &affine,
Geom::Point pt = cp->pt * affine;
- item->x1 = pt[Geom::X] - cp->radius;
- item->y1 = pt[Geom::Y] - cp->radius;
- item->x2 = pt[Geom::X] + cp->radius;
- item->y2 = pt[Geom::Y] + cp->radius;
+ item->x1 = pt[Geom::X] - cp->lenght;
+ item->y1 = pt[Geom::Y] - cp->lenght;
+ item->x2 = pt[Geom::X] + cp->lenght;
+ item->y2 = pt[Geom::Y] + cp->lenght;
item->canvas->requestRedraw((int)item->x1 - 15, (int)item->y1 - 15,
(int)item->x1 + 15, (int)item->y1 + 15);
@@ -142,9 +146,15 @@ sp_ctrlpoint_set_coords (SPCtrlPoint *cp, const Geom::Point pt)
}
void
-sp_ctrlpoint_set_radius (SPCtrlPoint *cp, const double r)
+sp_ctrlpoint_set_lenght (SPCtrlPoint *cp, const double r)
+{
+ cp->lenght = r;
+}
+
+void
+sp_ctrlpoint_set_circle (SPCtrlPoint *cp, const bool circle)
{
- cp->radius = r;
+ cp->is_circle = circle;
}
/*
diff --git a/src/display/sp-ctrlpoint.h b/src/display/sp-ctrlpoint.h
index a7a5475b7..02e61caf0 100644
--- a/src/display/sp-ctrlpoint.h
+++ b/src/display/sp-ctrlpoint.h
@@ -25,7 +25,8 @@ struct SPCtrlPoint : public SPCanvasItem {
guint32 rgba;
Geom::Point pt;
Geom::Affine affine;
- double radius;
+ double lenght;
+ bool is_circle;
};
struct SPCtrlPointClass : public SPCanvasItemClass{};
@@ -34,7 +35,8 @@ GType sp_ctrlpoint_get_type (void);
void sp_ctrlpoint_set_color (SPCtrlPoint *cp, guint32 rgba);
void sp_ctrlpoint_set_coords (SPCtrlPoint *cp, const gdouble x, const gdouble y);
void sp_ctrlpoint_set_coords (SPCtrlPoint *cp, const Geom::Point pt);
-void sp_ctrlpoint_set_radius (SPCtrlPoint *cp, const double r);
+void sp_ctrlpoint_set_lenght (SPCtrlPoint *cp, const double r);
+void sp_ctrlpoint_set_circle (SPCtrlPoint *cp, const bool circle);