diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2014-11-23 23:36:49 +0000 |
|---|---|---|
| committer | Jabiertxof <jtx@jtx.marker.es> | 2014-11-23 23:36:49 +0000 |
| commit | 0969085ddf607a7a98cf7fd6d9b10da5fbebe62d (patch) | |
| tree | 59b2bc9ed3412ab2de4c703ef30342dfe2401704 /src/display | |
| parent | refactor from lastApplied (diff) | |
| parent | Fixed a bug pointed by suv running from comand line, also removed another des... (diff) | |
| download | inkscape-0969085ddf607a7a98cf7fd6d9b10da5fbebe62d.tar.gz inkscape-0969085ddf607a7a98cf7fd6d9b10da5fbebe62d.zip | |
fixing to trunk
(bzr r12588.1.34)
Diffstat (limited to 'src/display')
85 files changed, 1370 insertions, 1076 deletions
diff --git a/src/display/CMakeLists.txt b/src/display/CMakeLists.txt index 20424c845..800c4d0d4 100644 --- a/src/display/CMakeLists.txt +++ b/src/display/CMakeLists.txt @@ -13,6 +13,7 @@ set(display_SRC drawing-group.cpp drawing-image.cpp drawing-item.cpp + drawing-pattern.cpp drawing-shape.cpp drawing-surface.cpp drawing-text.cpp @@ -75,6 +76,7 @@ set(display_SRC drawing-group.h drawing-image.h drawing-item.h + drawing-pattern.h drawing-shape.h drawing-surface.h drawing-text.h diff --git a/src/display/Makefile_insert b/src/display/Makefile_insert index abbd89a68..2355c3653 100644 --- a/src/display/Makefile_insert +++ b/src/display/Makefile_insert @@ -33,6 +33,8 @@ ink_common_sources += \ display/drawing-image.h \ display/drawing-item.cpp \ display/drawing-item.h \ + display/drawing-pattern.cpp \ + display/drawing-pattern.h \ display/drawing-shape.cpp \ display/drawing-shape.h \ display/drawing-surface.cpp \ diff --git a/src/display/cairo-templates.h b/src/display/cairo-templates.h index 57ec98f81..a49f925c3 100644 --- a/src/display/cairo-templates.h +++ b/src/display/cairo-templates.h @@ -16,6 +16,8 @@ #include "config.h" #endif +#include <glib.h> + #ifdef HAVE_OPENMP #include <omp.h> #include "preferences.h" @@ -25,7 +27,6 @@ static const int OPENMP_THRESHOLD = 2048; #include <algorithm> #include <cairo.h> -#include <glib.h> #include <math.h> #include "display/nr-3dutils.h" #include "display/cairo-utils.h" diff --git a/src/display/cairo-utils.cpp b/src/display/cairo-utils.cpp index 5b358ade7..e1f12b04b 100644 --- a/src/display/cairo-utils.cpp +++ b/src/display/cairo-utils.cpp @@ -19,19 +19,20 @@ #include <glibmm/fileutils.h> #include <2geom/pathvector.h> #include <2geom/bezier-curve.h> +#include <2geom/elliptical-arc.h> #include <2geom/hvlinesegment.h> #include <2geom/affine.h> #include <2geom/point.h> #include <2geom/path.h> #include <2geom/transforms.h> #include <2geom/sbasis-to-bezier.h> +#include <gdk-pixbuf/gdk-pixbuf.h> + #include "color.h" #include "style.h" #include "helper/geom-curves.h" #include "display/cairo-templates.h" -static void ink_cairo_pixbuf_cleanup(guchar *, void *); - /** * Key for cairo_surface_t to keep track of current color interpolation value * Only the address of the structure is used, it is never initialized. See: @@ -502,7 +503,17 @@ void Pixbuf::ensurePixelFormat(PixelFormat fmt) static void feed_curve_to_cairo(cairo_t *cr, Geom::Curve const &c, Geom::Affine const & trans, Geom::Rect view, bool optimize_stroke) { - if( is_straight_curve(c) ) + using Geom::X; + using Geom::Y; + + unsigned order = 0; + if (Geom::BezierCurve const* b = dynamic_cast<Geom::BezierCurve const*>(&c)) { + order = b->order(); + } + + // handle the three typical curve cases + switch (order) { + case 1: { Geom::Point end_tr = c.finalPoint() * trans; if (!optimize_stroke) { @@ -516,57 +527,97 @@ feed_curve_to_cairo(cairo_t *cr, Geom::Curve const &c, Geom::Affine const & tran } } } - else if(Geom::QuadraticBezier const *quadratic_bezier = dynamic_cast<Geom::QuadraticBezier const*>(&c)) { + break; + case 2: + { + Geom::QuadraticBezier const *quadratic_bezier = static_cast<Geom::QuadraticBezier const*>(&c); std::vector<Geom::Point> points = quadratic_bezier->points(); points[0] *= trans; points[1] *= trans; points[2] *= trans; + // degree-elevate to cubic Bezier, since Cairo doesn't do quadratic Beziers Geom::Point b1 = points[0] + (2./3) * (points[1] - points[0]); Geom::Point b2 = b1 + (1./3) * (points[2] - points[0]); if (!optimize_stroke) { - cairo_curve_to(cr, b1[0], b1[1], b2[0], b2[1], points[2][0], points[2][1]); + cairo_curve_to(cr, b1[X], b1[Y], b2[X], b2[Y], points[2][X], points[2][Y]); } else { Geom::Rect swept(points[0], points[2]); swept.expandTo(points[1]); if (swept.intersects(view)) { - cairo_curve_to(cr, b1[0], b1[1], b2[0], b2[1], points[2][0], points[2][1]); + cairo_curve_to(cr, b1[X], b1[Y], b2[X], b2[Y], points[2][X], points[2][Y]); } else { - cairo_move_to(cr, points[2][0], points[2][1]); + cairo_move_to(cr, points[2][X], points[2][Y]); } } } - else if(Geom::CubicBezier const *cubic_bezier = dynamic_cast<Geom::CubicBezier const*>(&c)) { + break; + case 3: + { + Geom::CubicBezier const *cubic_bezier = static_cast<Geom::CubicBezier const*>(&c); std::vector<Geom::Point> points = cubic_bezier->points(); //points[0] *= trans; // don't do this one here for fun: it is only needed for optimized strokes points[1] *= trans; points[2] *= trans; points[3] *= trans; if (!optimize_stroke) { - cairo_curve_to(cr, points[1][0], points[1][1], points[2][0], points[2][1], points[3][0], points[3][1]); + cairo_curve_to(cr, points[1][X], points[1][Y], points[2][X], points[2][Y], points[3][X], points[3][Y]); } else { points[0] *= trans; // didn't transform this point yet Geom::Rect swept(points[0], points[3]); swept.expandTo(points[1]); swept.expandTo(points[2]); if (swept.intersects(view)) { - cairo_curve_to(cr, points[1][0], points[1][1], points[2][0], points[2][1], points[3][0], points[3][1]); + cairo_curve_to(cr, points[1][X], points[1][Y], points[2][X], points[2][Y], points[3][X], points[3][Y]); } else { - cairo_move_to(cr, points[3][0], points[3][1]); + cairo_move_to(cr, points[3][X], points[3][Y]); } } } -// else if(Geom::SVGEllipticalArc const *svg_elliptical_arc = dynamic_cast<Geom::SVGEllipticalArc *>(c)) { -// //TODO: get at the innards and spit them out to cairo -// } - else { - //this case handles sbasis as well as all other curve types - Geom::Path sbasis_path = Geom::cubicbezierpath_from_sbasis(c.toSBasis(), 0.1); - - //recurse to convert the new path resulting from the sbasis to svgd - for(Geom::Path::iterator iter = sbasis_path.begin(); iter != sbasis_path.end(); ++iter) { - feed_curve_to_cairo(cr, *iter, trans, view, optimize_stroke); + break; + default: + { + if (Geom::EllipticalArc const *a = dynamic_cast<Geom::EllipticalArc const*>(&c)) { + //if (!optimize_stroke || a->boundsFast().intersects(view)) { + Geom::Affine xform = a->unitCircleTransform() * trans; + Geom::Point ang(a->initialAngle().radians(), a->finalAngle().radians()); + + // Apply the transformation to the current context + cairo_matrix_t cm; + cm.xx = xform[0]; + cm.xy = xform[2]; + cm.x0 = xform[4]; + cm.yx = xform[1]; + cm.yy = xform[3]; + cm.y0 = xform[5]; + + cairo_save(cr); + cairo_transform(cr, &cm); + + // Draw the circle + if (a->sweep()) { + cairo_arc(cr, 0, 0, 1, ang[0], ang[1]); + } else { + cairo_arc_negative(cr, 0, 0, 1, ang[0], ang[1]); + } + // Revert the current context + cairo_restore(cr); + //} else { + // Geom::Point f = a->finalPoint() * trans; + // cairo_move_to(cr, f[X], f[Y]); + //} + } else { + // handles sbasis as well as all other curve types + // this is very slow + Geom::Path sbasis_path = Geom::cubicbezierpath_from_sbasis(c.toSBasis(), 0.1); + + // recurse to convert the new path resulting from the sbasis to svgd + for (Geom::Path::iterator iter = sbasis_path.begin(); iter != sbasis_path.end(); ++iter) { + feed_curve_to_cairo(cr, *iter, trans, view, optimize_stroke); + } } } + break; + } } @@ -579,7 +630,7 @@ feed_path_to_cairo (cairo_t *ct, Geom::Path const &path) cairo_move_to(ct, path.initialPoint()[0], path.initialPoint()[1] ); - for(Geom::Path::const_iterator cit = path.begin(); cit != path.end_open(); ++cit) { + for (Geom::Path::const_iterator cit = path.begin(); cit != path.end_open(); ++cit) { feed_curve_to_cairo(ct, *cit, Geom::identity(), Geom::Rect(), false); // optimize_stroke is false, so the view rect is not used } @@ -1119,7 +1170,7 @@ GdkPixbuf *ink_pixbuf_create_from_cairo_surface(cairo_surface_t *s) * to gdk_pixbuf_new_from_data when creating a GdkPixbuf backed by * a Cairo surface. */ -static void ink_cairo_pixbuf_cleanup(guchar * /*pixels*/, void *data) +void ink_cairo_pixbuf_cleanup(guchar * /*pixels*/, void *data) { cairo_surface_t *surface = static_cast<cairo_surface_t*>(data); cairo_surface_destroy(surface); diff --git a/src/display/cairo-utils.h b/src/display/cairo-utils.h index 505e2ca77..2a7e460e8 100644 --- a/src/display/cairo-utils.h +++ b/src/display/cairo-utils.h @@ -12,15 +12,16 @@ #ifndef SEEN_INKSCAPE_DISPLAY_CAIRO_UTILS_H #define SEEN_INKSCAPE_DISPLAY_CAIRO_UTILS_H +#include <2geom/forward.h> #include <boost/noncopyable.hpp> -//#include <glibmm/threads.h> // workaround -#include <glib.h> #include <cairomm/cairomm.h> -//#include <gdkmm/pixbuf.h> -#include <2geom/forward.h> #include "style.h" struct SPColor; +typedef struct _GdkPixbuf GdkPixbuf; + +void ink_cairo_pixbuf_cleanup(unsigned char *, void *); +void convert_pixbuf_argb32_to_normal(GdkPixbuf *pb); namespace Inkscape { diff --git a/src/display/canvas-arena.cpp b/src/display/canvas-arena.cpp index 404a94828..8738b93e4 100644 --- a/src/display/canvas-arena.cpp +++ b/src/display/canvas-arena.cpp @@ -11,7 +11,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include <gtk/gtk.h> +#include <gtkmm.h> #include "display/sp-canvas-util.h" #include "helper/sp-marshal.h" @@ -30,8 +30,6 @@ enum { LAST_SIGNAL }; -static void sp_canvas_arena_class_init(SPCanvasArenaClass *klass); -static void sp_canvas_arena_init(SPCanvasArena *group); static void sp_canvas_arena_destroy(SPCanvasItem *object); static void sp_canvas_arena_item_deleted(SPCanvasArena *arena, Inkscape::DrawingItem *item); @@ -46,7 +44,6 @@ static gint sp_canvas_arena_send_event (SPCanvasArena *arena, GdkEvent *event); static void sp_canvas_arena_request_update (SPCanvasArena *ca, DrawingItem *item); static void sp_canvas_arena_request_render (SPCanvasArena *ca, Geom::IntRect const &area); -static SPCanvasItemClass *parent_class; static guint signals[LAST_SIGNAL] = {0}; struct CachePrefObserver : public Inkscape::Preferences::Observer { @@ -70,33 +67,13 @@ struct CachePrefObserver : public Inkscape::Preferences::Observer { SPCanvasArena *_arena; }; -GType -sp_canvas_arena_get_type (void) -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof (SPCanvasArenaClass), - NULL, NULL, - (GClassInitFunc) sp_canvas_arena_class_init, - NULL, NULL, - sizeof (SPCanvasArena), - 0, - (GInstanceInitFunc) sp_canvas_arena_init, - NULL - }; - type = g_type_register_static (SP_TYPE_CANVAS_ITEM, "SPCanvasArena", &info, (GTypeFlags)0); - } - return type; -} +G_DEFINE_TYPE(SPCanvasArena, sp_canvas_arena, SP_TYPE_CANVAS_ITEM); static void sp_canvas_arena_class_init (SPCanvasArenaClass *klass) { SPCanvasItemClass *item_class = (SPCanvasItemClass *) klass; - parent_class = (SPCanvasItemClass*)g_type_class_peek_parent (klass); - signals[ARENA_EVENT] = g_signal_new ("arena_event", G_TYPE_FROM_CLASS(item_class), G_SIGNAL_RUN_LAST, @@ -149,8 +126,8 @@ static void sp_canvas_arena_destroy(SPCanvasItem *object) delete arena->observer; arena->drawing.~Drawing(); - if (SP_CANVAS_ITEM_CLASS(parent_class)->destroy) - (* SP_CANVAS_ITEM_CLASS(parent_class)->destroy) (object); + if (SP_CANVAS_ITEM_CLASS(sp_canvas_arena_parent_class)->destroy) + SP_CANVAS_ITEM_CLASS(sp_canvas_arena_parent_class)->destroy(object); } static void @@ -158,8 +135,8 @@ sp_canvas_arena_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned { SPCanvasArena *arena = SP_CANVAS_ARENA (item); - if (((SPCanvasItemClass *) parent_class)->update) - (* ((SPCanvasItemClass *) parent_class)->update) (item, affine, flags); + if (SP_CANVAS_ITEM_CLASS(sp_canvas_arena_parent_class)->update) + SP_CANVAS_ITEM_CLASS(sp_canvas_arena_parent_class)->update(item, affine, flags); arena->ctx.ctm = affine; @@ -227,7 +204,7 @@ sp_canvas_arena_point (SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_ { SPCanvasArena *arena = SP_CANVAS_ARENA (item); - arena->drawing.update(Geom::IntRect::infinite(), arena->ctx, DrawingItem::STATE_PICK); + arena->drawing.update(Geom::IntRect::infinite(), arena->ctx, DrawingItem::STATE_PICK | DrawingItem::STATE_BBOX); DrawingItem *picked = arena->drawing.pick(p, arena->drawing.delta, arena->sticky); arena->picked = picked; diff --git a/src/display/canvas-arena.h b/src/display/canvas-arena.h index 26f19732d..15bbc2ee0 100644 --- a/src/display/canvas-arena.h +++ b/src/display/canvas-arena.h @@ -13,15 +13,13 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include <cairo.h> #include <2geom/rect.h> + #include "display/drawing.h" #include "display/drawing-item.h" #include "display/sp-canvas.h" #include "display/sp-canvas-item.h" -G_BEGIN_DECLS - #define SP_TYPE_CANVAS_ARENA (sp_canvas_arena_get_type ()) #define SP_CANVAS_ARENA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_CANVAS_ARENA, SPCanvasArena)) #define SP_CANVAS_ARENA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_CANVAS_ARENA, SPCanvasArenaClass)) @@ -30,6 +28,7 @@ G_BEGIN_DECLS typedef struct _SPCanvasArena SPCanvasArena; typedef struct _SPCanvasArenaClass SPCanvasArenaClass; +typedef struct _cairo_surface cairo_surface_t; struct CachePrefObserver; namespace Inkscape { @@ -39,7 +38,6 @@ class DrawingItem; } // namespace Inkscape - struct _SPCanvasArena { SPCanvasItem item; @@ -70,6 +68,4 @@ void sp_canvas_arena_set_sticky (SPCanvasArena *ca, gboolean sticky); void sp_canvas_arena_render_surface (SPCanvasArena *ca, cairo_surface_t *surface, Geom::IntRect const &area); -G_END_DECLS - #endif // SEEN_SP_CANVAS_ARENA_H diff --git a/src/display/canvas-axonomgrid.cpp b/src/display/canvas-axonomgrid.cpp index 312a8d655..592c962a6 100644 --- a/src/display/canvas-axonomgrid.cpp +++ b/src/display/canvas-axonomgrid.cpp @@ -387,6 +387,9 @@ _wr.setUpdating (false); _rcp_gmcol->setRgba32 (empcolor); _rsi->setValue (empspacing); + _rsu_ox->setProgrammatically = false; + _rsu_oy->setProgrammatically = false; + return table; } diff --git a/src/display/canvas-axonomgrid.h b/src/display/canvas-axonomgrid.h index 3888a3dc4..92cdb4c50 100644 --- a/src/display/canvas-axonomgrid.h +++ b/src/display/canvas-axonomgrid.h @@ -26,11 +26,11 @@ public: CanvasAxonomGrid(SPNamedView * nv, Inkscape::XML::Node * in_repr, SPDocument * in_doc); virtual ~CanvasAxonomGrid(); - void Update (Geom::Affine const &affine, unsigned int flags); - void Render (SPCanvasBuf *buf); + virtual void Update (Geom::Affine const &affine, unsigned int flags); + virtual void Render (SPCanvasBuf *buf); - void readRepr(); - void onReprAttrChanged (Inkscape::XML::Node * repr, const gchar *key, const gchar *oldval, const gchar *newval, bool is_interactive); + virtual void readRepr(); + virtual void onReprAttrChanged (Inkscape::XML::Node * repr, char const *key, char const *oldval, char const *newval, bool is_interactive); double lengthy; /**< The lengths of the primary y-axis */ double angle_deg[3]; /**< Angle of each axis (note that angle[2] == 0) */ diff --git a/src/display/canvas-bpath.cpp b/src/display/canvas-bpath.cpp index ee9e14f10..46b59d25a 100644 --- a/src/display/canvas-bpath.cpp +++ b/src/display/canvas-bpath.cpp @@ -11,9 +11,6 @@ * */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif #include <sstream> #include <string.h> #include "desktop.h" @@ -27,42 +24,18 @@ #include "helper/geom.h" #include "display/sp-canvas.h" -static void sp_canvas_bpath_class_init (SPCanvasBPathClass *klass); -static void sp_canvas_bpath_init (SPCanvasBPath *path); static void sp_canvas_bpath_destroy(SPCanvasItem *object); static void sp_canvas_bpath_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); static void sp_canvas_bpath_render (SPCanvasItem *item, SPCanvasBuf *buf); static double sp_canvas_bpath_point (SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_item); -static SPCanvasItemClass *parent_class; - -GType -sp_canvas_bpath_get_type (void) -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof (SPCanvasBPathClass), - NULL, NULL, - (GClassInitFunc) sp_canvas_bpath_class_init, - NULL, NULL, - sizeof (SPCanvasBPath), - 0, - (GInstanceInitFunc) sp_canvas_bpath_init, - NULL - }; - type = g_type_register_static (SP_TYPE_CANVAS_ITEM, "SPCanvasBPath", &info, (GTypeFlags)0); - } - return type; -} +G_DEFINE_TYPE(SPCanvasBPath, sp_canvas_bpath, SP_TYPE_CANVAS_ITEM); static void sp_canvas_bpath_class_init(SPCanvasBPathClass *klass) { SPCanvasItemClass *item_class = (SPCanvasItemClass *) klass; - parent_class = (SPCanvasItemClass*)g_type_class_peek_parent (klass); - item_class->destroy = sp_canvas_bpath_destroy; item_class->update = sp_canvas_bpath_update; item_class->render = sp_canvas_bpath_render; @@ -90,8 +63,8 @@ static void sp_canvas_bpath_destroy(SPCanvasItem *object) cbp->curve = cbp->curve->unref(); } - if (SP_CANVAS_ITEM_CLASS(parent_class)->destroy) - (* SP_CANVAS_ITEM_CLASS(parent_class)->destroy) (object); + if (SP_CANVAS_ITEM_CLASS(sp_canvas_bpath_parent_class)->destroy) + (* SP_CANVAS_ITEM_CLASS(sp_canvas_bpath_parent_class)->destroy) (object); } static void sp_canvas_bpath_update(SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags) @@ -100,8 +73,8 @@ static void sp_canvas_bpath_update(SPCanvasItem *item, Geom::Affine const &affin item->canvas->requestRedraw((int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); - if (reinterpret_cast<SPCanvasItemClass *>(parent_class)->update) { - reinterpret_cast<SPCanvasItemClass *>(parent_class)->update(item, affine, flags); + if (reinterpret_cast<SPCanvasItemClass *>(sp_canvas_bpath_parent_class)->update) { + reinterpret_cast<SPCanvasItemClass *>(sp_canvas_bpath_parent_class)->update(item, affine, flags); } sp_canvas_item_reset_bounds (item); diff --git a/src/display/canvas-grid.cpp b/src/display/canvas-grid.cpp index 4b1dbd1ed..2eeaa7006 100644 --- a/src/display/canvas-grid.cpp +++ b/src/display/canvas-grid.cpp @@ -71,42 +71,16 @@ static gchar const *const grid_svgname[] = { // ########################################################## // Grid CanvasItem -static void grid_canvasitem_class_init (GridCanvasItemClass *klass); -static void grid_canvasitem_init (GridCanvasItem *grid); static void grid_canvasitem_destroy(SPCanvasItem *object); static void grid_canvasitem_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); static void grid_canvasitem_render (SPCanvasItem *item, SPCanvasBuf *buf); -static SPCanvasItemClass * parent_class; - -GType -grid_canvasitem_get_type (void) -{ - static GType grid_canvasitem_type = 0; - - if (!grid_canvasitem_type) { - GTypeInfo grid_canvasitem_info = { - sizeof (GridCanvasItemClass), - NULL, NULL, - (GClassInitFunc) grid_canvasitem_class_init, - NULL, NULL, - sizeof (GridCanvasItem), - 0, - (GInstanceInitFunc) grid_canvasitem_init, - NULL - }; - - grid_canvasitem_type = g_type_register_static(SPCanvasItem::getType(), "GridCanvasItem", &grid_canvasitem_info, GTypeFlags(0)); - } - return grid_canvasitem_type; -} +G_DEFINE_TYPE(GridCanvasItem, grid_canvasitem, SP_TYPE_CANVAS_ITEM); static void grid_canvasitem_class_init(GridCanvasItemClass *klass) { SPCanvasItemClass *item_class = (SPCanvasItemClass *) klass; - parent_class = (SPCanvasItemClass*)g_type_class_peek_parent (klass); - item_class->destroy = grid_canvasitem_destroy; item_class->update = grid_canvasitem_update; item_class->render = grid_canvasitem_render; @@ -123,8 +97,8 @@ static void grid_canvasitem_destroy(SPCanvasItem *object) g_return_if_fail (object != NULL); g_return_if_fail (INKSCAPE_IS_GRID_CANVASITEM (object)); - if (SP_CANVAS_ITEM_CLASS(parent_class)->destroy) - (* SP_CANVAS_ITEM_CLASS(parent_class)->destroy) (object); + if (SP_CANVAS_ITEM_CLASS(grid_canvasitem_parent_class)->destroy) + (* SP_CANVAS_ITEM_CLASS(grid_canvasitem_parent_class)->destroy) (object); } /** @@ -145,8 +119,8 @@ grid_canvasitem_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned { GridCanvasItem *gridcanvasitem = INKSCAPE_GRID_CANVASITEM (item); - if (parent_class->update) - (* parent_class->update) (item, affine, flags); + if (SP_CANVAS_ITEM_CLASS(grid_canvasitem_parent_class)->update) + SP_CANVAS_ITEM_CLASS(grid_canvasitem_parent_class)->update(item, affine, flags); if (gridcanvasitem->grid) { gridcanvasitem->grid->Update(affine, flags); diff --git a/src/display/canvas-grid.h b/src/display/canvas-grid.h index 5a23dee52..557bd6dab 100644 --- a/src/display/canvas-grid.h +++ b/src/display/canvas-grid.h @@ -82,7 +82,7 @@ public: virtual void Render (SPCanvasBuf *buf) = 0; virtual void readRepr() = 0; - virtual void onReprAttrChanged (Inkscape::XML::Node * /*repr*/, const gchar */*key*/, const gchar */*oldval*/, const gchar */*newval*/, bool /*is_interactive*/) = 0; + virtual void onReprAttrChanged (Inkscape::XML::Node * /*repr*/, char const */*key*/, char const */*oldval*/, char const */*newval*/, bool /*is_interactive*/) = 0; Gtk::Widget * newWidget(); @@ -129,11 +129,11 @@ public: CanvasXYGrid(SPNamedView * nv, Inkscape::XML::Node * in_repr, SPDocument * in_doc); virtual ~CanvasXYGrid(); - void Update (Geom::Affine const &affine, unsigned int flags); - void Render (SPCanvasBuf *buf); + virtual void Update (Geom::Affine const &affine, unsigned int flags); + virtual void Render (SPCanvasBuf *buf); - void readRepr(); - void onReprAttrChanged (Inkscape::XML::Node * repr, const gchar *key, const gchar *oldval, const gchar *newval, bool is_interactive); + virtual void readRepr(); + virtual void onReprAttrChanged (Inkscape::XML::Node * repr, char const *key, char const *oldval, char const *newval, bool is_interactive); Geom::Point spacing; /**< Spacing between elements of the grid */ bool scaled[2]; /**< Whether the grid is in scaled mode, which can diff --git a/src/display/canvas-temporary-item-list.cpp b/src/display/canvas-temporary-item-list.cpp index b0fec98b5..60ead11ce 100644 --- a/src/display/canvas-temporary-item-list.cpp +++ b/src/display/canvas-temporary-item-list.cpp @@ -10,9 +10,8 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "display/canvas-temporary-item-list.h" - #include "display/canvas-temporary-item.h" +#include "display/canvas-temporary-item-list.h" namespace Inkscape { namespace Display { @@ -35,7 +34,7 @@ TemporaryItemList::~TemporaryItemList() /* Note that TemporaryItem or TemporaryItemList is responsible for deletion and such, so this return pointer can safely be ignored. */ TemporaryItem * -TemporaryItemList::add_item(SPCanvasItem *item, guint lifetime) +TemporaryItemList::add_item(SPCanvasItem *item, unsigned int lifetime) { // beware of strange things happening due to very short timeouts TemporaryItem * tempitem = new TemporaryItem(item, lifetime); diff --git a/src/display/canvas-temporary-item-list.h b/src/display/canvas-temporary-item-list.h index d204c692f..471bb99b9 100644 --- a/src/display/canvas-temporary-item-list.h +++ b/src/display/canvas-temporary-item-list.h @@ -11,7 +11,6 @@ */ #include <list> -#include <glib.h> struct SPCanvasItem; class SPDesktop; @@ -22,14 +21,14 @@ namespace Display { class TemporaryItem; /** - * Provides a class that can contain active TemporaryItem's on a desktop. + * Provides a class that can contain active TemporaryItem[s] on a desktop. */ class TemporaryItemList { public: TemporaryItemList(SPDesktop *desktop); virtual ~TemporaryItemList(); - TemporaryItem* add_item (SPCanvasItem *item, guint lifetime); + TemporaryItem* add_item (SPCanvasItem *item, unsigned int lifetime); void delete_item (TemporaryItem * tempitem); protected: diff --git a/src/display/canvas-temporary-item.cpp b/src/display/canvas-temporary-item.cpp index 551ea1536..f55c8bf4e 100644 --- a/src/display/canvas-temporary-item.cpp +++ b/src/display/canvas-temporary-item.cpp @@ -16,7 +16,7 @@ #include "display/canvas-temporary-item.h" -#include <gtk/gtk.h> +#include <glib.h> #include "display/sp-canvas-item.h" namespace Inkscape { @@ -54,9 +54,9 @@ TemporaryItem::~TemporaryItem() } } -/* static method*/ -gboolean TemporaryItem::_timeout(gpointer data) { - TemporaryItem *tempitem = reinterpret_cast<TemporaryItem *>(data); +/* static method */ +int TemporaryItem::_timeout(void* data) { + TemporaryItem *tempitem = static_cast<TemporaryItem *>(data); tempitem->timeout_id = 0; tempitem->signal_timeout.emit(tempitem); delete tempitem; diff --git a/src/display/canvas-temporary-item.h b/src/display/canvas-temporary-item.h index 09d243fa1..39ca2fc65 100644 --- a/src/display/canvas-temporary-item.h +++ b/src/display/canvas-temporary-item.h @@ -11,9 +11,8 @@ */ -#include <stddef.h> -#include <sigc++/sigc++.h> -#include <glib.h> +#include <cstddef> +#include <sigc++/signal.h> struct SPCanvasItem; @@ -25,7 +24,7 @@ namespace Display { */ class TemporaryItem { public: - TemporaryItem(SPCanvasItem *item, guint lifetime, bool destroy_on_deselect = false); + TemporaryItem(SPCanvasItem *item, unsigned int lifetime, bool destroy_on_deselect = false); virtual ~TemporaryItem(); sigc::signal<void, TemporaryItem *> signal_timeout; @@ -34,10 +33,10 @@ protected: friend class TemporaryItemList; SPCanvasItem * canvasitem; /** The item we are holding on to */ - guint timeout_id; /** ID by which glib knows the timeout event */ + unsigned int timeout_id; /** ID by which glib knows the timeout event */ bool destroy_on_deselect; // only destroy when parent item is deselected, not when mouse leaves - static gboolean _timeout(gpointer data); ///< callback for when lifetime expired + static int _timeout(void* data); ///< callback for when lifetime expired private: TemporaryItem(const TemporaryItem&); diff --git a/src/display/canvas-text.cpp b/src/display/canvas-text.cpp index fe60d9c65..5ad87b4ef 100644 --- a/src/display/canvas-text.cpp +++ b/src/display/canvas-text.cpp @@ -12,10 +12,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - #include <sstream> #include <string.h> @@ -26,42 +22,17 @@ #include "color.h" #include "display/sp-canvas.h" -static void sp_canvastext_class_init (SPCanvasTextClass *klass); -static void sp_canvastext_init (SPCanvasText *canvastext); static void sp_canvastext_destroy(SPCanvasItem *object); static void sp_canvastext_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); static void sp_canvastext_render (SPCanvasItem *item, SPCanvasBuf *buf); -static SPCanvasItemClass *parent_class_ct; - -GType -sp_canvastext_get_type (void) -{ - static GType type = 0; - - if (!type) { - GTypeInfo info = { - sizeof (SPCanvasTextClass), - NULL, NULL, - (GClassInitFunc) sp_canvastext_class_init, - NULL, NULL, - sizeof (SPCanvasText), - 0, - (GInstanceInitFunc) sp_canvastext_init, - NULL - }; - type = g_type_register_static (SP_TYPE_CANVAS_ITEM, "SPCanvasText", &info, (GTypeFlags)0); - } - return type; -} +G_DEFINE_TYPE(SPCanvasText, sp_canvastext, SP_TYPE_CANVAS_ITEM); static void sp_canvastext_class_init(SPCanvasTextClass *klass) { SPCanvasItemClass *item_class = SP_CANVAS_ITEM_CLASS(klass); - parent_class_ct = SP_CANVAS_ITEM_CLASS(g_type_class_peek_parent(klass)); - item_class->destroy = sp_canvastext_destroy; item_class->update = sp_canvastext_update; item_class->render = sp_canvastext_render; @@ -101,8 +72,8 @@ static void sp_canvastext_destroy(SPCanvasItem *object) canvastext->text = NULL; canvastext->item = NULL; - if (SP_CANVAS_ITEM_CLASS(parent_class_ct)->destroy) - (* SP_CANVAS_ITEM_CLASS(parent_class_ct)->destroy) (object); + if (SP_CANVAS_ITEM_CLASS(sp_canvastext_parent_class)->destroy) + SP_CANVAS_ITEM_CLASS(sp_canvastext_parent_class)->destroy(object); } static void @@ -151,8 +122,8 @@ sp_canvastext_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned i item->canvas->requestRedraw((int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); - if (parent_class_ct->update) - (* parent_class_ct->update) (item, affine, flags); + if (SP_CANVAS_ITEM_CLASS(sp_canvastext_parent_class)->update) + SP_CANVAS_ITEM_CLASS(sp_canvastext_parent_class)->update(item, affine, flags); sp_canvas_item_reset_bounds (item); diff --git a/src/display/curve.cpp b/src/display/curve.cpp index 50f4c8954..54a62939d 100644 --- a/src/display/curve.cpp +++ b/src/display/curve.cpp @@ -1,10 +1,4 @@ -#define __CURVE_C__ - -/** \file - * Routines for SPCurve and for its Geom::PathVector - */ - -/* +/** * Authors: * Lauris Kaplinski <lauris@kaplinski.com> * Johan Engelen @@ -14,7 +8,7 @@ * Copyright (C) 2002 Lauris Kaplinski * Copyright (C) 2008 Johan Engelen * - * Released under GNU GPL + * Released under GNU GPL, see file 'COPYING' for more information */ #include "display/curve.h" @@ -25,6 +19,10 @@ #include <2geom/sbasis-to-bezier.h> #include <2geom/point.h> +/** + * Routines for SPCurve and for its Geom::PathVector + */ + /* Constructors */ /** @@ -50,7 +48,7 @@ SPCurve::new_from_rect(Geom::Rect const &rect, bool all_four_sides) Geom::Point p = rect.corner(0); c->moveto(p); - for (int i=3; i>=1; i--) { + for (int i=3; i>=1; --i) { c->lineto(rect.corner(i)); } @@ -89,10 +87,10 @@ SPCurve::get_pathvector() const * Returns the number of segments of all paths summed * This count includes the closing line segment of a closed path. */ -guint +size_t SPCurve::get_segment_count() const { - guint nr = 0; + size_t nr = 0; for(Geom::PathVector::const_iterator it = _pathv.begin(); it != _pathv.end(); ++it) { nr += (*it).size(); @@ -202,7 +200,7 @@ SPCurve::reset() * Calls SPCurve::moveto() with point made of given coordinates. */ void -SPCurve::moveto(gdouble x, gdouble y) +SPCurve::moveto(double x, double y) { moveto(Geom::Point(x, y)); } @@ -231,7 +229,7 @@ SPCurve::lineto(Geom::Point const &p) * Calls SPCurve::lineto( Geom::Point(x,y) ) */ void -SPCurve::lineto(gdouble x, gdouble y) +SPCurve::lineto(double x, double y) { lineto(Geom::Point(x,y)); } @@ -251,7 +249,7 @@ SPCurve::quadto(Geom::Point const &p1, Geom::Point const &p2) * All coordinates must be finite. */ void -SPCurve::quadto(gdouble x1, gdouble y1, gdouble x2, gdouble y2) +SPCurve::quadto(double x1, double y1, double x2, double y2) { quadto( Geom::Point(x1,y1), Geom::Point(x2,y2) ); } @@ -271,7 +269,7 @@ SPCurve::curveto(Geom::Point const &p0, Geom::Point const &p1, Geom::Point const * All coordinates must be finite. */ void -SPCurve::curveto(gdouble x0, gdouble y0, gdouble x1, gdouble y1, gdouble x2, gdouble y2) +SPCurve::curveto(double x0, double y0, double x1, double y1, double x2, double y2) { curveto( Geom::Point(x0,y0), Geom::Point(x1,y1), Geom::Point(x2,y2) ); } @@ -522,7 +520,7 @@ SPCurve::append(SPCurve const *curve2, * When one of the curves is empty, this curves path becomes the non-empty path. */ SPCurve * -SPCurve::append_continuous(SPCurve const *c1, gdouble tolerance) +SPCurve::append_continuous(SPCurve const *c1, double tolerance) { using Geom::X; using Geom::Y; @@ -632,10 +630,10 @@ SPCurve::move_endpoints(Geom::Point const &new_p0, Geom::Point const &new_p1) * Sum of nodes in all the paths. When a path is closed, and its closing line segment is of zero-length, * this function will not count the closing knot double (so basically ignores the closing line segment when it has zero length) */ -guint +size_t SPCurve::nodes_in_path() const { - guint nr = 0; + size_t nr = 0; for(Geom::PathVector::const_iterator it = _pathv.begin(); it != _pathv.end(); ++it) { nr += (*it).size(); @@ -686,4 +684,4 @@ SPCurve::last_point_additive_move(Geom::Point const & p) fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8: diff --git a/src/display/curve.h b/src/display/curve.h index 4866655c4..5fad75b18 100644 --- a/src/display/curve.h +++ b/src/display/curve.h @@ -1,8 +1,5 @@ -#ifndef SEEN_DISPLAY_CURVE_H -#define SEEN_DISPLAY_CURVE_H - -/* - * Author: +/** + * Authors: * Lauris Kaplinski <lauris@kaplinski.com> * * Copyright (C) 2000 Lauris Kaplinski @@ -10,17 +7,20 @@ * Copyright (C) 2002 Lauris Kaplinski * Copyright (C) 2008 Johan Engelen * - * Released under GNU GPL + * Released under GNU GPL, see file 'COPYING' for more information */ -#include <glib.h> +#ifndef SEEN_DISPLAY_CURVE_H +#define SEEN_DISPLAY_CURVE_H #include <2geom/forward.h> - +#include <cstddef> #include <boost/optional.hpp> +extern "C" { typedef struct _GSList GSList; } + /** - * Wrapper around a Geom::PathVector objects. + * Wrapper around a Geom::PathVector object. */ class SPCurve { public: @@ -39,8 +39,8 @@ public: SPCurve * copy() const; - guint get_segment_count() const; - guint nodes_in_path() const; + size_t get_segment_count() const; + size_t nodes_in_path() const; bool is_empty() const; bool is_closed() const; @@ -56,13 +56,13 @@ public: void reset(); void moveto(Geom::Point const &p); - void moveto(gdouble x, gdouble y); + void moveto(double x, double y); void lineto(Geom::Point const &p); - void lineto(gdouble x, gdouble y); + void lineto(double x, double y); void quadto(Geom::Point const &p1, Geom::Point const &p2); - void quadto(gdouble x1, gdouble y1, gdouble x2, gdouble y2); + void quadto(double x1, double y1, double x2, double y2); void curveto(Geom::Point const &p0, Geom::Point const &p1, Geom::Point const &p2); - void curveto(gdouble x0, gdouble y0, gdouble x1, gdouble y1, gdouble x2, gdouble y2); + void curveto(double x0, double y0, double x1, double y1, double x2, double y2); void closepath(); void closepath_current(); void backspace(); @@ -73,14 +73,14 @@ public: void last_point_additive_move(Geom::Point const & p); void append(SPCurve const *curve2, bool use_lineto); - SPCurve * append_continuous(SPCurve const *c1, gdouble tolerance); + SPCurve * append_continuous(SPCurve const *c1, double tolerance); SPCurve * create_reverse() const; GSList * split() const; static SPCurve * concat(GSList const *list); protected: - gint _refcount; + size_t _refcount; Geom::PathVector _pathv; @@ -90,7 +90,7 @@ private: SPCurve& operator=(const SPCurve&); }; -#endif /* !SEEN_DISPLAY_CURVE_H */ +#endif // !SEEN_DISPLAY_CURVE_H /* Local Variables: @@ -101,4 +101,4 @@ private: fill-column:99 End: */ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/display/drawing-context.h b/src/display/drawing-context.h index d990bcb73..a15e0d0e5 100644 --- a/src/display/drawing-context.h +++ b/src/display/drawing-context.h @@ -12,13 +12,13 @@ #ifndef SEEN_INKSCAPE_DISPLAY_DRAWING_CONTEXT_H #define SEEN_INKSCAPE_DISPLAY_DRAWING_CONTEXT_H -#include <boost/utility.hpp> -#include <glib.h> -#include <cairo.h> #include <2geom/affine.h> #include <2geom/angle.h> #include <2geom/rect.h> #include <2geom/transforms.h> +#include <boost/utility.hpp> +#include <cairo.h> +typedef unsigned int guint32; namespace Inkscape { @@ -61,6 +61,7 @@ public: cairo_curve_to(_ct, p1[Geom::X], p1[Geom::Y], p2[Geom::X], p2[Geom::Y], p3[Geom::X], p3[Geom::Y]); } void arc(Geom::Point const ¢er, double radius, Geom::AngleInterval const &angle); + void closePath() { cairo_close_path(_ct); } void rectangle(Geom::Rect const &r) { cairo_rectangle(_ct, r.left(), r.top(), r.width(), r.height()); } diff --git a/src/display/drawing-group.cpp b/src/display/drawing-group.cpp index 38ace001f..bce89d70e 100644 --- a/src/display/drawing-group.cpp +++ b/src/display/drawing-group.cpp @@ -9,13 +9,14 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "display/cairo-utils.h" #include "display/drawing.h" #include "display/drawing-context.h" #include "display/drawing-item.h" #include "display/drawing-group.h" #include "style.h" +#include "display/cairo-utils.h" + namespace Inkscape { DrawingGroup::DrawingGroup(Drawing &drawing) diff --git a/src/display/drawing-group.h b/src/display/drawing-group.h index 651e9d8af..ab1f9895d 100644 --- a/src/display/drawing-group.h +++ b/src/display/drawing-group.h @@ -14,7 +14,7 @@ #include "display/drawing-item.h" -struct SPStyle; +class SPStyle; namespace Inkscape { diff --git a/src/display/drawing-image.cpp b/src/display/drawing-image.cpp index 5844c8b08..e56f3e58b 100644 --- a/src/display/drawing-image.cpp +++ b/src/display/drawing-image.cpp @@ -10,13 +10,15 @@ */ #include <2geom/bezier-curve.h> -#include "display/cairo-utils.h" + #include "display/drawing.h" #include "display/drawing-context.h" #include "display/drawing-image.h" #include "preferences.h" #include "style.h" +#include "display/cairo-utils.h" + namespace Inkscape { DrawingImage::DrawingImage(Drawing &drawing) @@ -106,7 +108,10 @@ unsigned DrawingImage::_renderItem(DrawingContext &dc, Geom::IntRect const &/*ar { bool outline = _drawing.outline(); - if (!outline) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + bool imgoutline = prefs->getBool("/options/rendering/imageinoutlinemode", false); + + if (!outline || imgoutline) { if (!_pixbuf) return RENDER_OK; Inkscape::DrawingContext::Save save(dc); @@ -141,7 +146,7 @@ unsigned DrawingImage::_renderItem(DrawingContext &dc, Geom::IntRect const &/*ar dc.paint(_opacity); } else { // outline; draw a rect instead - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + guint32 rgba = prefs->getInt("/options/wireframecolors/images", 0xff0000ff); { Inkscape::DrawingContext::Save save(dc); diff --git a/src/display/drawing-item.cpp b/src/display/drawing-item.cpp index ccf905e81..8ed74b550 100644 --- a/src/display/drawing-item.cpp +++ b/src/display/drawing-item.cpp @@ -10,20 +10,22 @@ */ #include <climits> -#include "display/cairo-utils.h" -#include "display/cairo-templates.h" + #include "display/drawing.h" #include "display/drawing-context.h" #include "display/drawing-item.h" #include "display/drawing-group.h" +#include "display/drawing-pattern.h" #include "display/drawing-surface.h" #include "nr-filter.h" #include "preferences.h" #include "style.h" +#include "display/cairo-utils.h" +#include "display/cairo-templates.h" + namespace Inkscape { -#ifdef WITH_CSSBLEND void set_cairo_blend_operator( DrawingContext &dc, unsigned blend_mode ) { // All of the blend modes are implemented in Cairo as of 1.10. @@ -81,7 +83,6 @@ void set_cairo_blend_operator( DrawingContext &dc, unsigned blend_mode ) { break; } } -#endif /** * @class DrawingItem @@ -112,6 +113,8 @@ DrawingItem::DrawingItem(Drawing &drawing) , _transform(NULL) , _clip(NULL) , _mask(NULL) + , _fill_pattern(NULL) + , _stroke_pattern(NULL) , _filter(NULL) , _user_data(NULL) , _cache(NULL) @@ -129,7 +132,7 @@ DrawingItem::DrawingItem(Drawing &drawing) , _pick_children(0) , _antialias(1) , _isolation(SP_CSS_ISOLATION_AUTO) - , _blend_mode(SP_CSS_BLEND_NORMAL) + , _mix_blend_mode(SP_CSS_BLEND_NORMAL) {} DrawingItem::~DrawingItem() @@ -166,6 +169,12 @@ DrawingItem::~DrawingItem() case CHILD_ROOT: _drawing._root = NULL; break; + case CHILD_FILL_PATTERN: + _parent->_fill_pattern = NULL; + break; + case CHILD_STROKE_PATTERN: + _parent->_stroke_pattern = NULL; + break; default: ; } @@ -174,6 +183,8 @@ DrawingItem::~DrawingItem() } clearChildren(); delete _transform; + delete _stroke_pattern; + delete _fill_pattern; delete _clip; delete _mask; delete _filter; @@ -293,10 +304,10 @@ DrawingItem::setIsolation(unsigned isolation) } void -DrawingItem::setBlendMode(unsigned blend_mode) +DrawingItem::setBlendMode(unsigned mix_blend_mode) { - _blend_mode = blend_mode; - //if( blend_mode != 0 ) std::cout << "setBlendMode: " << blend_mode << std::endl; + _mix_blend_mode = mix_blend_mode; + //if( mix_blend_mode != 0 ) std::cout << "setBlendMode: " << mix_blend_mode << std::endl; _markForRendering(); } @@ -368,6 +379,34 @@ DrawingItem::setMask(DrawingItem *item) _markForUpdate(STATE_ALL, true); } +void +DrawingItem::setFillPattern(DrawingPattern *pattern) +{ + _markForRendering(); + delete _fill_pattern; + _fill_pattern = pattern; + if (pattern) { + pattern->_parent = this; + assert(pattern->_child_type == CHILD_ORPHAN); + pattern->_child_type = CHILD_FILL_PATTERN; + } + _markForUpdate(STATE_ALL, true); +} + +void +DrawingItem::setStrokePattern(DrawingPattern *pattern) +{ + _markForRendering(); + delete _stroke_pattern; + _stroke_pattern = pattern; + if (pattern) { + pattern->_parent = this; + assert(pattern->_child_type == CHILD_ORPHAN); + pattern->_child_type = CHILD_STROKE_PATTERN; + } + _markForUpdate(STATE_ALL, true); +} + /// Move this item to the given place in the Z order of siblings. /// Does nothing if the item has no parent. void @@ -409,7 +448,7 @@ DrawingItem::setItemBounds(Geom::OptRect const &bounds) * @param reset State fields that should be reset before processing them. This is * a means to force a recomputation of internal data even if the item * considers it up to date. Mainly for internal use, such as - * propagating bunding box recomputation to children when the item's + * propagating bounding box recomputation to children when the item's * transform changes. */ void @@ -532,6 +571,12 @@ DrawingItem::update(Geom::IntRect const &area, UpdateContext const &ctx, unsigne if (to_update & STATE_RENDER) { // now that we know drawbox, dirty the corresponding rect on canvas // unless filtered, groups do not need to render by themselves, only their members + if (_fill_pattern) { + _fill_pattern->update(area, child_ctx, flags, reset); + } + if (_stroke_pattern) { + _stroke_pattern->update(area, child_ctx, flags, reset); + } if (!is_drawing_group(this) || (_filter && render_filters)) { _markForRendering(); } @@ -594,9 +639,8 @@ DrawingItem::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flag if (_cached) { if (_cache) { _cache->prepare(); -#ifdef WITH_CSSBLEND - set_cairo_blend_operator( dc, _blend_mode ); -#endif + set_cairo_blend_operator( dc, _mix_blend_mode ); + _cache->paintFromCache(dc, carea); if (!carea) return RENDER_OK; } else { @@ -625,10 +669,8 @@ DrawingItem::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flag nir |= (_filter != NULL && render_filters); // 3. it has a filter nir |= needs_opacity; // 4. it is non-opaque nir |= (_cache != NULL); // 5. it is cached -#ifdef WITH_CSSBLEND - nir |= (_blend_mode != SP_CSS_BLEND_NORMAL); // 6. Blend mode not normal + nir |= (_mix_blend_mode != SP_CSS_BLEND_NORMAL); // 6. Blend mode not normal nir |= (_isolation == SP_CSS_ISOLATION_ISOLATE); // 7. Explicit isolatiom -#endif /* How the rendering is done. * @@ -740,9 +782,7 @@ DrawingItem::render(DrawingContext &dc, Geom::IntRect const &area, unsigned flag } dc.rectangle(*carea); dc.setSource(&intermediate); -#ifdef WITH_CSSBLEND - set_cairo_blend_operator( dc, _blend_mode ); -#endif + set_cairo_blend_operator( dc, _mix_blend_mode ); dc.fill(); dc.setSource(0,0,0,0); // the call above is to clear a ref on the intermediate surface held by dc @@ -974,7 +1014,7 @@ DrawingItem::_setStyleCommon(SPStyle *&_style, SPStyle *style) if (_style) sp_style_unref(_style); _style = style; - if (style->filter.set && style->getFilter()) { + if (style && style->filter.set && style->getFilter()) { if (!_filter) { int primitives = sp_filter_primitive_count(SP_FILTER(style->getFilter())); _filter = new Inkscape::Filters::Filter(primitives); diff --git a/src/display/drawing-item.h b/src/display/drawing-item.h index db803cf60..9b399e6e3 100644 --- a/src/display/drawing-item.h +++ b/src/display/drawing-item.h @@ -12,15 +12,15 @@ #ifndef SEEN_INKSCAPE_DISPLAY_DRAWING_ITEM_H #define SEEN_INKSCAPE_DISPLAY_DRAWING_ITEM_H -#include <list> -#include <exception> +#include <2geom/rect.h> +#include <2geom/affine.h> #include <boost/operators.hpp> #include <boost/utility.hpp> #include <boost/intrusive/list.hpp> -#include <2geom/rect.h> -#include <2geom/affine.h> +#include <exception> +#include <list> -struct SPStyle; +class SPStyle; namespace Inkscape { @@ -28,6 +28,7 @@ class Drawing; class DrawingCache; class DrawingContext; class DrawingItem; +class DrawingPattern; namespace Filters { @@ -114,6 +115,8 @@ public: void setTransform(Geom::Affine const &trans); void setClip(DrawingItem *item); void setMask(DrawingItem *item); + void setFillPattern(DrawingPattern *pattern); + void setStrokePattern(DrawingPattern *pattern); void setZOrder(unsigned z); void setItemBounds(Geom::OptRect const &bounds); void setFilterBounds(Geom::OptRect const &bounds); @@ -135,8 +138,8 @@ protected: CHILD_CLIP = 2, // referenced by _clip member of parent CHILD_MASK = 3, // referenced by _mask member of parent CHILD_ROOT = 4, // root item of _drawing - CHILD_FILL_PATTERN = 5, // not yet implemented: referenced by fill pattern of parent - CHILD_STROKE_PATTERN = 6 // not yet implemented: referenced by stroke pattern of parent + CHILD_FILL_PATTERN = 5, // referenced by fill pattern of parent + CHILD_STROKE_PATTERN = 6 // referenced by stroke pattern of parent }; enum RenderResult { RENDER_OK = 0, @@ -185,6 +188,8 @@ protected: DrawingItem *_clip; DrawingItem *_mask; + DrawingPattern *_fill_pattern; + DrawingPattern *_stroke_pattern; Inkscape::Filters::Filter *_filter; void *_user_data; ///< Used to associate DrawingItems with SPItems that created them DrawingCache *_cache; @@ -209,7 +214,7 @@ protected: unsigned _antialias : 1; ///< Whether to use antialiasing unsigned _isolation : 1; - unsigned _blend_mode : 4; + unsigned _mix_blend_mode : 4; friend class Drawing; }; diff --git a/src/display/drawing-pattern.cpp b/src/display/drawing-pattern.cpp new file mode 100644 index 000000000..d0bf5de58 --- /dev/null +++ b/src/display/drawing-pattern.cpp @@ -0,0 +1,194 @@ +/** + * @file + * Canvas belonging to SVG pattern. + *//* + * Authors: + * Tomasz Boczkowski <penginsbacon@gmail.com> + * + * Copyright (C) 2014 Authors + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "display/cairo-utils.h" +#include "display/drawing-context.h" +#include "display/drawing-pattern.h" +#include "display/drawing-surface.h" + +namespace Inkscape { + +DrawingPattern::DrawingPattern(Drawing &drawing, bool debug) + : DrawingGroup(drawing) + , _pattern_to_user(NULL) + , _overflow_steps(1) + , _debug(debug) +{ +} + +DrawingPattern::~DrawingPattern() +{ + delete _pattern_to_user; // delete NULL; is safe +} + +void +DrawingPattern::setPatternToUserTransform(Geom::Affine const &new_trans) { + Geom::Affine current; + if (_pattern_to_user) { + current = *_pattern_to_user; + } + + if (!Geom::are_near(current, new_trans, 1e-18)) { + // mark the area where the object was for redraw. + _markForRendering(); + if (new_trans.isIdentity()) { + delete _pattern_to_user; // delete NULL; is safe + _pattern_to_user = NULL; + } else { + _pattern_to_user = new Geom::Affine(new_trans); + } + _markForUpdate(STATE_ALL, true); + } +} + +void +DrawingPattern::setTileRect(Geom::Rect const &tile_rect) { + _tile_rect = tile_rect; +} + +void +DrawingPattern::setOverflow(Geom::Affine initial_transform, int steps, Geom::Affine step_transform) { + _overflow_initial_transform = initial_transform; + _overflow_steps = steps; + _overflow_step_transform = step_transform; +} + +cairo_pattern_t * +DrawingPattern::renderPattern(float opacity) { + bool needs_opacity = (1.0 - opacity) >= 1e-3; + bool visible = opacity >= 1e-3; + + if (!visible) { + return NULL; + } + + if (!_tile_rect || (_tile_rect->area() == 0)) { + return NULL; + } + Geom::Rect pattern_tile = *_tile_rect; + + //TODO: If pattern_to_user set it to identity transform + + // The DrawingSurface class handles the mapping from "logical space" + // (coordinates in the rendering) to "physical space" (surface pixels). + // An oversampling is done as the pattern may not pixel align with the final surface. + // The cairo surface is created when the DrawingContext is declared. + // Create drawing surface with size of pattern tile (in pattern space) but with number of pixels + // based on required resolution (c). + Inkscape::DrawingSurface pattern_surface(pattern_tile, _pattern_resolution); + Inkscape::DrawingContext dc(pattern_surface); + dc.transform( pattern_surface.drawingTransform().inverse() ); + + pattern_tile *= pattern_surface.drawingTransform(); + Geom::IntRect one_tile = pattern_tile.roundOutwards(); + + // Render pattern. + if (needs_opacity) { + dc.pushGroup(); // this group is for pattern + opacity + } + + if (_debug) { + dc.setSource(0.8, 0.0, 0.8); + dc.paint(); + } + + //FIXME: What flags to choose? + if (_overflow_steps == 1) { + render(dc, one_tile, RENDER_DEFAULT); + } else { + //Overflow transforms need to be transformed to the new coordinate system + //introduced by dc.transform( pattern_surface.drawingTransform().inverse() ); + Geom::Affine dt = pattern_surface.drawingTransform(); + Geom::Affine idt = pattern_surface.drawingTransform().inverse(); + Geom::Affine initial_transform = idt * _overflow_initial_transform * dt; + Geom::Affine step_transform = idt * _overflow_step_transform * dt; + + dc.transform(initial_transform); + for (int i = 0; i < _overflow_steps; i++) { + render(dc, one_tile, RENDER_DEFAULT); + dc.transform(step_transform); + } + } + + //Uncomment to debug + // cairo_surface_t* raw = pattern_surface.raw(); + // std::cout << " cairo_surface (sp-pattern): " + // << " width: " << cairo_image_surface_get_width( raw ) + // << " height: " << cairo_image_surface_get_height( raw ) + // << std::endl; + // std::string filename = "drawing-pattern.png"; + // cairo_surface_write_to_png( pattern_surface.raw(), filename.c_str() ); + + if (needs_opacity) { + dc.popGroupToSource(); // pop raw pattern + dc.paint(opacity); // apply opacity + } + + cairo_pattern_t *cp = cairo_pattern_create_for_surface(pattern_surface.raw()); + // Apply transformation to user space. Also compensate for oversampling. + if (_pattern_to_user) { + ink_cairo_pattern_set_matrix(cp, _pattern_to_user->inverse() * pattern_surface.drawingTransform()); + } else { + ink_cairo_pattern_set_matrix(cp, pattern_surface.drawingTransform()); + } + + if (_debug) { + cairo_pattern_set_extend(cp, CAIRO_EXTEND_NONE); + } else { + cairo_pattern_set_extend(cp, CAIRO_EXTEND_REPEAT); + } + + return cp; +} + +// TODO investigate if area should be used. +unsigned DrawingPattern::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx, unsigned flags, unsigned reset) +{ + UpdateContext pattern_ctx; + + if (!_tile_rect || (_tile_rect->area() == 0)) { + return STATE_NONE; + } + + Geom::Rect pattern_tile = *_tile_rect; + Geom::Coord det_ctm = ctx.ctm.descrim(); + Geom::Coord det_ps2user = _pattern_to_user ? _pattern_to_user->descrim() : 1.0; + Geom::Coord det_child_transform = _child_transform ? _child_transform->descrim() : 1.0; + const double oversampling = 2.0; + double scale = det_ctm*det_ps2user*det_child_transform * oversampling; + //FIXME: When scale is too big (zooming in a hatch), cairo doesn't render the pattern + //More precisely it fails when seting pattern matrix in DrawingPattern::renderPattern + //Fully correct solution should make use of visible area bbox and change hach tile rect + //accordingly + if (scale > 25) { + scale = 25; + } + Geom::Point c(pattern_tile.dimensions()*scale*oversampling); + _pattern_resolution = c.ceil(); + + Inkscape::DrawingSurface pattern_surface(pattern_tile, _pattern_resolution); + + pattern_ctx.ctm = pattern_surface.drawingTransform(); + return DrawingGroup::_updateItem(Geom::IntRect::infinite(), pattern_ctx, flags, reset); +} + +} // end namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/display/drawing-pattern.h b/src/display/drawing-pattern.h new file mode 100644 index 000000000..7483ba067 --- /dev/null +++ b/src/display/drawing-pattern.h @@ -0,0 +1,87 @@ +/** + * @file + * Canvas belonging to SVG pattern. + *//* + * Authors: + * Tomasz Boczkowski <penginsbacon@gmail.com> + * + * Copyright (C) 2014 Authors + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef SEEN_INKSCAPE_DISPLAY_DRAWING_PATTERN_H +#define SEEN_INKSCAPE_DISPLAY_DRAWING_PATTERN_H + +#include "display/drawing-group.h" + +typedef struct _cairo_pattern cairo_pattern_t; +class SPStyle; + +namespace Inkscape { + +/** + * @brief Drawing tree node used for rendering paints. + * + * DrawingPattern is used for rendering patterns and hatches. + * + * It renders it's children to a cairo_pattern_t structure that can be + * applied as source for fill or stroke operations. + */ +class DrawingPattern + : public DrawingGroup +{ +public: + DrawingPattern(Drawing &drawing, bool debug = false); + ~DrawingPattern(); + + /** + * Set the transformation from pattern to user coordinate systems. + * @see SPPattern description for explanation of coordinate systems. + */ + void setPatternToUserTransform(Geom::Affine const &new_trans); + /** + * Set the tile rect position and dimentions in content coordinate system + */ + void setTileRect(Geom::Rect const &tile_rect); + /** + * Turn on overflow rendering. + * + * Overflow is implemented as repeated rendering of pattern contents. In every step + * a translation transform is applied. + */ + void setOverflow(Geom::Affine initial_transform, int steps, Geom::Affine step_transform); + /** + * Render the pattern. + * + * Returns caito_pattern_t structure that can be set as source surface. + */ + cairo_pattern_t *renderPattern(float opacity); +protected: + virtual unsigned _updateItem(Geom::IntRect const &area, UpdateContext const &ctx, + unsigned flags, unsigned reset); + + Geom::Affine *_pattern_to_user; + Geom::Affine _overflow_initial_transform; + Geom::Affine _overflow_step_transform; + int _overflow_steps; + Geom::OptRect _tile_rect; + bool _debug; + Geom::IntPoint _pattern_resolution; +}; + +bool is_drawing_group(DrawingItem *item); + +} // end namespace Inkscape + +#endif // !SEEN_INKSCAPE_DISPLAY_DRAWING_PATTERN_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/display/drawing-shape.cpp b/src/display/drawing-shape.cpp index 92d71fad3..66160638f 100644 --- a/src/display/drawing-shape.cpp +++ b/src/display/drawing-shape.cpp @@ -9,7 +9,7 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include <glib.h> +#include <glibmm.h> #include <2geom/curves.h> #include <2geom/pathvector.h> #include <2geom/path-sink.h> @@ -149,14 +149,13 @@ DrawingShape::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx, u return STATE_ALL; } -#ifdef WITH_SVG2 void DrawingShape::_renderFill(DrawingContext &dc) { Inkscape::DrawingContext::Save save(dc); dc.transform(_ctm); - bool has_fill = _nrstyle.prepareFill(dc, _item_bbox); + bool has_fill = _nrstyle.prepareFill(dc, _item_bbox, _fill_pattern); if( has_fill ) { dc.path(_curve->get_pathvector()); @@ -172,7 +171,7 @@ DrawingShape::_renderStroke(DrawingContext &dc) Inkscape::DrawingContext::Save save(dc); dc.transform(_ctm); - bool has_stroke = _nrstyle.prepareStroke(dc, _item_bbox); + bool has_stroke = _nrstyle.prepareStroke(dc, _item_bbox, _stroke_pattern); has_stroke &= (_nrstyle.stroke_width != 0); if( has_stroke ) { @@ -183,7 +182,6 @@ DrawingShape::_renderStroke(DrawingContext &dc) dc.newPath(); // clear path } } -#endif void DrawingShape::_renderMarkers(DrawingContext &dc, Geom::IntRect const &area, unsigned flags, DrawingItem *stop_at) @@ -222,10 +220,9 @@ DrawingShape::_renderItem(DrawingContext &dc, Geom::IntRect const &area, unsigne } -#ifdef WITH_SVG2 if( _nrstyle.paint_order_layer[0] == NRStyle::PAINT_ORDER_NORMAL ) { // This is the most common case, special case so we don't call get_pathvector(), etc. twice -#endif + { // we assume the context has no path Inkscape::DrawingContext::Save save(dc); @@ -234,8 +231,8 @@ DrawingShape::_renderItem(DrawingContext &dc, Geom::IntRect const &area, unsigne // update fill and stroke paints. // this cannot be done during nr_arena_shape_update, because we need a Cairo context // to render svg:pattern - bool has_fill = _nrstyle.prepareFill(dc, _item_bbox); - bool has_stroke = _nrstyle.prepareStroke(dc, _item_bbox); + bool has_fill = _nrstyle.prepareFill(dc, _item_bbox, _fill_pattern); + bool has_stroke = _nrstyle.prepareStroke(dc, _item_bbox, _stroke_pattern); has_stroke &= (_nrstyle.stroke_width != 0); if (has_fill || has_stroke) { @@ -255,7 +252,6 @@ DrawingShape::_renderItem(DrawingContext &dc, Geom::IntRect const &area, unsigne _renderMarkers(dc, area, flags, stop_at); return RENDER_OK; -#ifdef WITH_SVG2 } // Handle different paint orders @@ -276,7 +272,6 @@ DrawingShape::_renderItem(DrawingContext &dc, Geom::IntRect const &area, unsigne } } return RENDER_OK; -#endif } void DrawingShape::_clipItem(DrawingContext &dc, Geom::IntRect const & /*area*/) diff --git a/src/display/drawing-shape.h b/src/display/drawing-shape.h index 405c789e0..9d93a642f 100644 --- a/src/display/drawing-shape.h +++ b/src/display/drawing-shape.h @@ -15,7 +15,7 @@ #include "display/drawing-item.h" #include "display/nr-style.h" -struct SPStyle; +class SPStyle; class SPCurve; namespace Inkscape { @@ -39,10 +39,8 @@ protected: virtual DrawingItem *_pickItem(Geom::Point const &p, double delta, unsigned flags); virtual bool _canClip(); -#ifdef WITH_SVG2 void _renderFill(DrawingContext &dc); void _renderStroke(DrawingContext &dc); -#endif void _renderMarkers(DrawingContext &dc, Geom::IntRect const &area, unsigned flags, DrawingItem *stop_at); diff --git a/src/display/drawing-surface.h b/src/display/drawing-surface.h index e937cca55..7bec1606a 100644 --- a/src/display/drawing-surface.h +++ b/src/display/drawing-surface.h @@ -14,11 +14,16 @@ #include <boost/shared_ptr.hpp> #include <cairo.h> -#include <gdk-pixbuf/gdk-pixbuf.h> #include <2geom/affine.h> #include <2geom/rect.h> #include <2geom/transforms.h> +extern "C" { +typedef struct _cairo cairo_t; +typedef struct _cairo_surface cairo_surface_t; +typedef struct _cairo_region cairo_region_t; +} + namespace Inkscape { class DrawingContext; diff --git a/src/display/drawing-text.cpp b/src/display/drawing-text.cpp index a280e221a..afe661b2e 100644 --- a/src/display/drawing-text.cpp +++ b/src/display/drawing-text.cpp @@ -9,8 +9,8 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "display/cairo-utils.h" -#include "display/canvas-bpath.h" // for SPWindRule (WTF!) +//#include "display/cairo-utils.h" +//#include "display/canvas-bpath.h" // for SPWindRule (WTF!) #include "display/drawing.h" #include "display/drawing-context.h" #include "display/drawing-surface.h" @@ -20,6 +20,9 @@ #include "style.h" #include "2geom/pathvector.h" +#include "display/cairo-utils.h" +#include "display/canvas-bpath.h" + namespace Inkscape { @@ -67,16 +70,14 @@ unsigned DrawingGlyphs::_updateItem(Geom::IntRect const &/*area*/, UpdateContext _pick_bbox = Geom::IntRect(); _bbox = Geom::IntRect(); -/* orignally it did the one line below, - but it did not handle ws characters at all, and it had problems with scaling for overline/underline. - Replaced with the section below, which seems to be much more stable. - - Geom::OptRect b = bounds_exact_transformed(*_font->PathVector(_glyph), ctx.ctm); -*/ - /* Make a bounding box that is a little taller and lower (currently 10% extra) than the font's drawing box. Extra space is - to hold overline or underline, if present. All characters in a font use the same ascent and descent, - but different widths. This lets leading and trailing spaces have text decorations. If it is not done - the bounding box is limited to the box surrounding the drawn parts of visible glyphs only, and draws outside are ignored. + /* + Make a bounding box for drawing that is a little taller and lower (currently 10% extra) than + the font's drawing box. Extra space is to hold overline or underline, if present. All + characters in a font use the same ascent and descent, but different widths. This lets leading + and trailing spaces have text decorations. If it is not done the bounding box is limited to + the box surrounding the drawn parts of visible glyphs only, and draws outside are ignored. + The box is also a hair wider than the text, since the glyphs do not always start or end at + the left and right edges of the box defined in the font. */ float scale_bigbox = 1.0; @@ -84,9 +85,45 @@ unsigned DrawingGlyphs::_updateItem(Geom::IntRect const &/*area*/, UpdateContext scale_bigbox /= _transform->descrim(); } - Geom::Rect bigbox(Geom::Point(0.0, _asc*scale_bigbox*1.1),Geom::Point(_width*scale_bigbox, -_dsc*scale_bigbox*1.1)); + Geom::Rect bigbox(Geom::Point(-_width*scale_bigbox*0.1, _asc*scale_bigbox*1.1),Geom::Point(_width*scale_bigbox, -_dsc*scale_bigbox*1.1)); Geom::Rect b = bigbox * ctx.ctm; + /* + The pick box matches the characters as best as it can, leaving no extra space above or below + for decorations. The pathvector may include spaces, and spaces have no drawable glyph. + Catch those and do not pass them to bounds_exact_transformed(), which crashes Inkscape if it + sees a nondrawable glyph. Instead mock up a pickbox for them using font characteristics. + There may also be some other similar white space characters in some other unforeseen context + which should be handled by this code as well.. + */ + + Geom::OptRect pb; + if(_drawable){ + pb = bounds_exact_transformed(*_font->PathVector(_glyph), ctx.ctm); + } + if(!pb){ // Fallback + Geom::Rect pbigbox(Geom::Point(0.0, _asc*scale_bigbox*0.66),Geom::Point(_width*scale_bigbox, 0.0)); + pb = pbigbox * ctx.ctm; + } + +#if 0 + /* FIXME if this is commented out then not even an approximation of pick on decorations */ + /* adjust the pick box up or down to include the decorations. + This is only approximate since at this point we don't know how wide that line is, if it has + an unusual offset, and so forth. The selection point is set at what is roughly the center of + the decoration (vertically) for the wide ones, like wavy and double line. + The text decorations are not actually selectable. + */ + if (_decorations.overline || _decorations.underline) { + double top = _asc*scale_bigbox*0.66; + double bot = 0; + if (_decorations.overline) { top = _asc * scale_bigbox * 1.025; } + if (_decorations.underline) { bot = -_dsc * scale_bigbox * 0.2; } + Geom::Rect padjbox(Geom::Point(0.0, top),Geom::Point(_width*scale_bigbox, bot)); + pb.unionWith(padjbox * ctx.ctm); + } +#endif + if (ggroup->_nrstyle.stroke.type != NRStyle::PAINT_NONE) { // this expands the selection box for cases where the stroke is "thick" float scale = ctx.ctm.descrim(); @@ -96,10 +133,11 @@ unsigned DrawingGlyphs::_updateItem(Geom::IntRect const &/*area*/, UpdateContext float width = MAX(0.125, ggroup->_nrstyle.stroke_width * scale); if ( fabs(ggroup->_nrstyle.stroke_width * scale) > 0.01 ) { // FIXME: this is always true b.expandBy(0.5 * width); + pb->expandBy(0.5 * width); } // save bbox without miters for picking - _pick_bbox = b.roundOutwards(); + _pick_bbox = pb->roundOutwards(); float miterMax = width * ggroup->_nrstyle.miter_limit; if ( miterMax > 0.01 ) { @@ -110,35 +148,31 @@ unsigned DrawingGlyphs::_updateItem(Geom::IntRect const &/*area*/, UpdateContext _bbox = b.roundOutwards(); } else { _bbox = b.roundOutwards(); - _pick_bbox = *_bbox; + _pick_bbox = pb->roundOutwards(); } -/* -std::cout << "DEBUG _bbox" -<< " { " << _bbox->min()[Geom::X] << " , " << _bbox->min()[Geom::Y] -<< " } , { " << _bbox->max()[Geom::X] << " , " << _bbox->max()[Geom::Y] -<< " }" << std::endl; -*/ return STATE_ALL; } -DrawingItem * -DrawingGlyphs::_pickItem(Geom::Point const &p, double delta, unsigned /*flags*/) +DrawingItem *DrawingGlyphs::_pickItem(Geom::Point const &p, double /*delta*/, unsigned /*flags*/) { DrawingText *ggroup = dynamic_cast<DrawingText *>(_parent); if (!ggroup) { throw InvalidItemException(); } + DrawingItem *result = NULL; bool invisible = (ggroup->_nrstyle.fill.type == NRStyle::PAINT_NONE) && (ggroup->_nrstyle.stroke.type == NRStyle::PAINT_NONE); - if (!_font || !_bbox || (!_drawing.outline() && invisible) ) { - return NULL; - } - // With text we take a simple approach: pick if the point is in a character bbox - Geom::Rect expanded(_pick_bbox); - expanded.expandBy(delta); - if (expanded.contains(p)) return this; - return NULL; + if (_font && _bbox && (_drawing.outline() || !invisible) ) { + // With text we take a simple approach: pick if the point is in a character bbox + Geom::Rect expanded(_pick_bbox); + // FIXME, why expand by delta? When is the next line needed? + // expanded.expandBy(delta); + if (expanded.contains(p)) { + result = this; + } + } + return result; } @@ -195,7 +229,7 @@ DrawingText::_updateItem(Geom::IntRect const &area, UpdateContext const &ctx, un return DrawingGroup::_updateItem(area, ctx, flags, reset); } -void DrawingText::decorateStyle(DrawingContext &dc, double vextent, double xphase, Geom::Point const &p1, Geom::Point const &p2) +void DrawingText::decorateStyle(DrawingContext &dc, double vextent, double xphase, Geom::Point const &p1, Geom::Point const &p2, double thickness) { double wave[16]={ 0.000000, 0.382499, 0.706825, 0.923651, 1.000000, 0.923651, 0.706825, 0.382499, @@ -213,7 +247,6 @@ void DrawingText::decorateStyle(DrawingContext &dc, double vextent, double xphas 4, 3, 2, 1, -4, -3, -2, -1 }; - Geom::Point p3,p4,ps,pf; double step = vextent/32.0; unsigned i = 15 & (unsigned) round(xphase/step); // xphase is >= 0.0 @@ -221,26 +254,19 @@ void DrawingText::decorateStyle(DrawingContext &dc, double vextent, double xphas This allows decoration continuity within the line, and does not step outside the clip box off the end For the first/last section on the line though, stay well clear of the edge, or when the text is dragged it may "spray" pixels. - if(_nrstyle.tspan_line_end){ pf = p2 - Geom::Point(2*step, 0.0); } - else { pf = p2; } - if(_nrstyle.tspan_line_start){ ps = p1 + Geom::Point(2*step, 0.0); - i = 15 & (i + 2); - } - else { ps = p1; } */ /* snap to nearest step in X */ -ps = Geom::Point(step * round(p1[Geom::X]/step),p1[Geom::Y]); -pf = Geom::Point(step * round(p2[Geom::X]/step),p2[Geom::Y]); + Geom::Point ps = Geom::Point(step * round(p1[Geom::X]/step),p1[Geom::Y]); + Geom::Point pf = Geom::Point(step * round(p2[Geom::X]/step),p2[Geom::Y]); + Geom::Point poff = Geom::Point(0,thickness/2.0); if(_nrstyle.text_decoration_style & TEXT_DECORATION_STYLE_ISDOUBLE){ ps -= Geom::Point(0, vextent/12.0); pf -= Geom::Point(0, vextent/12.0); - dc.moveTo(ps); - dc.lineTo(pf); + dc.rectangle( Geom::Rect(ps + poff, pf - poff)); ps += Geom::Point(0, vextent/6.0); pf += Geom::Point(0, vextent/6.0); - dc.moveTo(ps); - dc.lineTo(pf); + dc.rectangle( Geom::Rect(ps + poff, pf - poff)); } /* The next three have a problem in that they are phase dependent. The bits of a line are not necessarily passing through this routine in order, so we have to use the xphase information @@ -248,43 +274,52 @@ pf = Geom::Point(step * round(p2[Geom::X]/step),p2[Geom::Y]); Huge possitive offset should keep the phase calculation from ever being negative. */ else if(_nrstyle.text_decoration_style & TEXT_DECORATION_STYLE_DOTTED){ + // FIXME: Per spec, this should produce round dots. + Geom::Point pv = ps; while(1){ + Geom::Point pvlast = pv; if(dots[i]>0){ - if(ps[Geom::X]> pf[Geom::X])break; - dc.moveTo(ps); - ps += Geom::Point(step * (double)dots[i], 0.0); - if(ps[Geom::X]>= pf[Geom::X]){ - dc.lineTo(pf); + if(pv[Geom::X] > pf[Geom::X]) break; + + pv += Geom::Point(step * (double)dots[i], 0.0); + + if(pv[Geom::X]>= pf[Geom::X]){ + // Last dot + dc.rectangle( Geom::Rect(pvlast + poff, pf - poff)); break; + } else { + dc.rectangle( Geom::Rect(pvlast + poff, pv - poff)); } - else { - dc.lineTo(ps); - } - ps += Geom::Point(step * 4.0, 0.0); - } - else { - ps += Geom::Point(step * -(double)dots[i], 0.0); + + pv += Geom::Point(step * 4.0, 0.0); + + } else { + pv += Geom::Point(step * -(double)dots[i], 0.0); } i = 0; // once in phase, it stays in phase } } else if(_nrstyle.text_decoration_style & TEXT_DECORATION_STYLE_DASHED){ + Geom::Point pv = ps; while(1){ + Geom::Point pvlast = pv; if(dashes[i]>0){ - if(ps[Geom::X]> pf[Geom::X])break; - dc.moveTo(ps); - ps += Geom::Point(step * (double)dashes[i], 0.0); - if(ps[Geom::X]>= pf[Geom::X]){ - dc.lineTo(pf); + if(pv[Geom::X]> pf[Geom::X]) break; + + pv += Geom::Point(step * (double)dashes[i], 0.0); + + if(pv[Geom::X]>= pf[Geom::X]){ + // Last dash + dc.rectangle( Geom::Rect(pvlast + poff, pf - poff)); break; + } else { + dc.rectangle( Geom::Rect(pvlast + poff, pv - poff)); } - else { - dc.lineTo(ps); - } - ps += Geom::Point(step * 8.0, 0.0); - } - else { - ps += Geom::Point(step * -(double)dashes[i], 0.0); + + pv += Geom::Point(step * 8.0, 0.0); + + } else { + pv += Geom::Point(step * -(double)dashes[i], 0.0); } i = 0; // once in phase, it stays in phase } @@ -292,7 +327,7 @@ pf = Geom::Point(step * round(p2[Geom::X]/step),p2[Geom::Y]); else if(_nrstyle.text_decoration_style & TEXT_DECORATION_STYLE_WAVY){ double amp = vextent/10.0; double x = ps[Geom::X]; - double y = ps[Geom::Y]; + double y = ps[Geom::Y] + poff[Geom::Y]; dc.moveTo(Geom::Point(x, y + amp * wave[i])); while(1){ i = ((i + 1) & 15); @@ -300,17 +335,25 @@ pf = Geom::Point(step * round(p2[Geom::X]/step),p2[Geom::Y]); dc.lineTo(Geom::Point(x, y + amp * wave[i])); if(x >= pf[Geom::X])break; } - } + y = ps[Geom::Y] - poff[Geom::Y]; + dc.lineTo(Geom::Point(x, y + amp * wave[i])); + while(1){ + i = ((i - 1) & 15); + x -= step; + dc.lineTo(Geom::Point(x, y + amp * wave[i])); + if(x <= ps[Geom::X])break; + } + dc.closePath(); + } else { // TEXT_DECORATION_STYLE_SOLID, also default in case it was not set for some reason - dc.moveTo(ps); - dc.lineTo(pf); -// dc.revrectangle(Geom::Rect(ps,pf)); + dc.rectangle( Geom::Rect(ps + poff, pf - poff)); } } /* returns scaled line thickness */ -double DrawingText::decorateItem(DrawingContext &dc, Geom::Affine const &aff, double phase_length) +void DrawingText::decorateItem(DrawingContext &dc, double phase_length, bool under) { + if (_nrstyle.font_size < 1.0e-32)return; // would cause a divide by zero and nothing would be visible anyway double tsp_width_adj = _nrstyle.tspan_width / _nrstyle.font_size; double tsp_asc_adj = _nrstyle.ascender / _nrstyle.font_size; double tsp_size_adj = (_nrstyle.ascender + _nrstyle.descender) / _nrstyle.font_size; @@ -318,49 +361,54 @@ double DrawingText::decorateItem(DrawingContext &dc, Geom::Affine const &aff, do double final_underline_thickness = CLAMP(_nrstyle.underline_thickness, tsp_size_adj/30.0, tsp_size_adj/10.0); double final_line_through_thickness = CLAMP(_nrstyle.line_through_thickness, tsp_size_adj/30.0, tsp_size_adj/10.0); - double scale = aff.descrim(); double xphase = phase_length/ _nrstyle.font_size; // used to figure out phase of patterns - Inkscape::DrawingContext::Save save(dc); - dc.transform(aff); // must be leftmost affine in span - Geom::Point p1; Geom::Point p2; // All lines must be the same thickness, in combinations, line_through trumps underline double thickness = final_underline_thickness; - if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_UNDERLINE){ - p1 = Geom::Point(0.0, -_nrstyle.underline_position); - p2 = Geom::Point(tsp_width_adj,-_nrstyle.underline_position); - decorateStyle(dc, tsp_size_adj, xphase, p1, p2); - } - if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_OVERLINE){ - p1 = Geom::Point(0.0, tsp_asc_adj -_nrstyle.underline_position + 1 * final_underline_thickness); - p2 = Geom::Point(tsp_width_adj,tsp_asc_adj -_nrstyle.underline_position + 1 * final_underline_thickness); - decorateStyle(dc, tsp_size_adj, xphase, p1, p2); - } - if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_LINETHROUGH){ - thickness = final_line_through_thickness; - p1 = Geom::Point(0.0, _nrstyle.line_through_position); - p2 = Geom::Point(tsp_width_adj,_nrstyle.line_through_position); - decorateStyle(dc, tsp_size_adj, xphase, p1, p2); - } - // Obviously this does not blink, but it does indicate which text has been set with that attribute - if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_BLINK){ - thickness = final_line_through_thickness; - p1 = Geom::Point(0.0, _nrstyle.line_through_position - 2*final_line_through_thickness); - p2 = Geom::Point(tsp_width_adj,_nrstyle.line_through_position - 2*final_line_through_thickness); - decorateStyle(dc, tsp_size_adj, xphase, p1, p2); - p1 = Geom::Point(0.0, _nrstyle.line_through_position + 2*final_line_through_thickness); - p2 = Geom::Point(tsp_width_adj,_nrstyle.line_through_position + 2*final_line_through_thickness); - decorateStyle(dc, tsp_size_adj, xphase, p1, p2); + dc.setTolerance(0.5); // Is this really necessary... could effect dots. + + if( under ) { + + if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_UNDERLINE){ + p1 = Geom::Point(0.0, -_nrstyle.underline_position); + p2 = Geom::Point(tsp_width_adj,-_nrstyle.underline_position); + decorateStyle(dc, tsp_size_adj, xphase, p1, p2, thickness); + } + + if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_OVERLINE){ + p1 = Geom::Point(0.0, tsp_asc_adj -_nrstyle.underline_position + 1 * final_underline_thickness); + p2 = Geom::Point(tsp_width_adj,tsp_asc_adj -_nrstyle.underline_position + 1 * final_underline_thickness); + decorateStyle(dc, tsp_size_adj, xphase, p1, p2, thickness); + } + + } else { + // Over + + if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_LINETHROUGH){ + thickness = final_line_through_thickness; + p1 = Geom::Point(0.0, _nrstyle.line_through_position); + p2 = Geom::Point(tsp_width_adj,_nrstyle.line_through_position); + decorateStyle(dc, tsp_size_adj, xphase, p1, p2, thickness); + } + + // Obviously this does not blink, but it does indicate which text has been set with that attribute + if(_nrstyle.text_decoration_line & TEXT_DECORATION_LINE_BLINK){ + thickness = final_line_through_thickness; + p1 = Geom::Point(0.0, _nrstyle.line_through_position - 2*final_line_through_thickness); + p2 = Geom::Point(tsp_width_adj,_nrstyle.line_through_position - 2*final_line_through_thickness); + decorateStyle(dc, tsp_size_adj, xphase, p1, p2, thickness); + p1 = Geom::Point(0.0, _nrstyle.line_through_position + 2*final_line_through_thickness); + p2 = Geom::Point(tsp_width_adj,_nrstyle.line_through_position + 2*final_line_through_thickness); + decorateStyle(dc, tsp_size_adj, xphase, p1, p2, thickness); + } } - thickness *= scale; - return(thickness); } unsigned DrawingText::_renderItem(DrawingContext &dc, Geom::IntRect const &/*area*/, unsigned /*flags*/, DrawingItem * /*stop_at*/) { - if (_drawing.outline()) { + if (_drawing.outline()) { guint32 rgba = _drawing.outlinecolor; Inkscape::DrawingContext::Save save(dc); dc.setSource(rgba); @@ -382,127 +430,187 @@ unsigned DrawingText::_renderItem(DrawingContext &dc, Geom::IntRect const &/*are return RENDER_OK; } - // NOTE: this is very similar to drawing-shape.cpp; the only difference is in path feeding - double leftmost = DBL_MAX; - double phase_length = 0.0; - bool firsty = true; - bool decorate = true; - double starty = 0.0; - Geom::Affine aff; - using Geom::X; - using Geom::Y; - - // NOTE: + // NOTE: This is very similar to drawing-shape.cpp; the only differences are in path feeding + // and in applying text decorations. + + + // Do we have text decorations? + bool decorate = (_nrstyle.text_decoration_line != TEXT_DECORATION_LINE_CLEAR ); + // prepareFill / prepareStroke need to be called with _ctm in effect. // However, we might need to apply a different ctm for glyphs. // Therefore, only apply this ctm temporarily. - bool has_stroke, has_fill; + bool has_stroke = false; + bool has_fill = false; + bool has_td_fill = false; + bool has_td_stroke = false; { Inkscape::DrawingContext::Save save(dc); dc.transform(_ctm); - has_fill = _nrstyle.prepareFill( dc, _item_bbox); - has_stroke = _nrstyle.prepareStroke(dc, _item_bbox); + has_fill = _nrstyle.prepareFill( dc, _item_bbox, _fill_pattern); + has_stroke = _nrstyle.prepareStroke( dc, _item_bbox, _stroke_pattern); + + // Avoid creating patterns if not needed + if( decorate ) { + has_td_fill = _nrstyle.prepareTextDecorationFill( dc, _item_bbox, _fill_pattern); + has_td_stroke = _nrstyle.prepareTextDecorationStroke(dc, _item_bbox, _stroke_pattern); + } } - if (has_fill || has_stroke) { - Geom::Affine rotinv; - bool invset = false; + if (has_fill || has_stroke || has_td_fill || has_td_stroke) { - // accumulate the path that represents the glyphs - for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { - DrawingGlyphs *g = dynamic_cast<DrawingGlyphs *>(&*i); - if (!g) throw InvalidItemException(); - if (!invset) { - rotinv = g->_ctm.withoutTranslation().inverse(); - invset = true; - } + // Determine order for fill and stroke. + // Text doesn't have markers, we can do paint-order quick and dirty. + bool fill_first = false; + if( _nrstyle.paint_order_layer[0] == NRStyle::PAINT_ORDER_NORMAL || + _nrstyle.paint_order_layer[0] == NRStyle::PAINT_ORDER_FILL || + _nrstyle.paint_order_layer[2] == NRStyle::PAINT_ORDER_STROKE ) { + fill_first = true; + } // Won't get "stroke fill stroke" but that isn't 'valid' + + + // Determine geometry of text decoration + double phase_length = 0.0; + Geom::Affine aff; + if( decorate ) { + + Geom::Affine rotinv; + bool invset = false; + double leftmost = DBL_MAX; + bool first_y = true; + double start_y = 0.0; + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + + DrawingGlyphs *g = dynamic_cast<DrawingGlyphs *>(&*i); + if (!g) throw InvalidItemException(); + + if (!invset) { + rotinv = g->_ctm.withoutTranslation().inverse(); + invset = true; + } - Inkscape::DrawingContext::Save save(dc); - if (g->_ctm.isSingular()) continue; - dc.transform(g->_ctm); - if (g->_drawable) { - dc.path(*g->_font->PathVector(g->_glyph)); - } - // get the leftmost affine transform (leftmost defined with respect to the x axis of the first transform). - // That way the decoration will work no matter what mix of L->R, R->L text is in the span. - if (_nrstyle.text_decoration_line != TEXT_DECORATION_LINE_CLEAR) { Geom::Point pt = g->_ctm.translation() * rotinv; - if (pt[X] < leftmost) { - leftmost = pt[X]; + if (pt[Geom::X] < leftmost) { + leftmost = pt[Geom::X]; aff = g->_ctm; phase_length = g->_pl; } - /* If the text has been mapped onto a path, which causes y to vary, drop the text decorations. - To handle that properly would need a conformal map - */ - if (firsty) { - firsty = false; - starty = pt[Y]; + + // Check for text on a path. FIXME: This needs better test (and probably not here). + if (first_y) { + first_y = false; + start_y = pt[Geom::Y]; } - else if (fabs(pt[Y] - starty) > 1.0e-6) { + else if (fabs(pt[Geom::Y] - start_y) > 1.0e-6) { + // If the text has been mapped onto a path, which causes y to vary, drop the + // text decorations. To handle that properly would need a conformal map. decorate = false; } } } - // draw the text itself - // we need to apply this object's ctm again - Inkscape::DrawingContext::Save save(dc); - dc.transform(_ctm); + // Draw text decorations that go UNDER the text (underline, over-line) + if( decorate ) { -#ifdef WITH_SVG2 - // Text doesn't have markers, we can do paint-order quick and dirty. - bool fill_first = false; - if( _nrstyle.paint_order_layer[0] == NRStyle::PAINT_ORDER_NORMAL || - _nrstyle.paint_order_layer[0] == NRStyle::PAINT_ORDER_FILL || - _nrstyle.paint_order_layer[2] == NRStyle::PAINT_ORDER_STROKE ) { - fill_first = true; - } // Won't get "stroke fill stroke" but that isn't 'valid' + { + Inkscape::DrawingContext::Save save(dc); + dc.transform(aff); // must be leftmost affine in span + decorateItem(dc, phase_length, true); + } + + { + Inkscape::DrawingContext::Save save(dc); + dc.transform(_ctm); // Needed so that fill pattern rotates with text + + if (has_td_fill && fill_first) { + _nrstyle.applyTextDecorationFill(dc); + dc.fillPreserve(); + } + + if (has_td_stroke) { + _nrstyle.applyTextDecorationStroke(dc); + dc.strokePreserve(); + } + + if (has_td_fill && !fill_first) { + _nrstyle.applyTextDecorationFill(dc); + dc.fillPreserve(); + } - if (has_fill && fill_first) { -#else - if (has_fill) { -#endif - _nrstyle.applyFill(dc); - dc.fillPreserve(); + } + + dc.newPath(); // Clear text-decoration path } - if (has_stroke) { - _nrstyle.applyStroke(dc); - dc.strokePreserve(); + + // accumulate the path that represents the glyphs + for (ChildrenList::iterator i = _children.begin(); i != _children.end(); ++i) { + DrawingGlyphs *g = dynamic_cast<DrawingGlyphs *>(&*i); + if (!g) throw InvalidItemException(); + + Inkscape::DrawingContext::Save save(dc); + if (g->_ctm.isSingular()) continue; + dc.transform(g->_ctm); + if (g->_drawable) { + dc.path(*g->_font->PathVector(g->_glyph)); + } } -#ifdef WITH_SVG2 - if (has_fill && !fill_first) { - _nrstyle.applyFill(dc); - dc.fillPreserve(); + + // Draw the glyphs. + { + Inkscape::DrawingContext::Save save(dc); + dc.transform(_ctm); + + if (has_fill && fill_first) { + _nrstyle.applyFill(dc); + dc.fillPreserve(); + } + + if (has_stroke) { + _nrstyle.applyStroke(dc); + dc.strokePreserve(); + } + + if (has_fill && !fill_first) { + _nrstyle.applyFill(dc); + dc.fillPreserve(); + } } -#endif - dc.newPath(); // clear path - - // draw text decoration - if (_nrstyle.text_decoration_line != TEXT_DECORATION_LINE_CLEAR && decorate) { - guint32 ergba; - if (_nrstyle.text_decoration_useColor) { // color different from the glyph - ergba = SP_RGBA32_F_COMPOSE( - _nrstyle.text_decoration_color.color.v.c[0], - _nrstyle.text_decoration_color.color.v.c[1], - _nrstyle.text_decoration_color.color.v.c[2], - 1.0); + dc.newPath(); // Clear glyphs path + + // Draw text decorations that go OVER the text (line through, blink) + if (decorate) { + + { + Inkscape::DrawingContext::Save save(dc); + dc.transform(aff); // must be leftmost affine in span + decorateItem(dc, phase_length, false); } - else { // whatever the current fill color is - ergba = SP_RGBA32_F_COMPOSE( - _nrstyle.fill.color.v.c[0], - _nrstyle.fill.color.v.c[1], - _nrstyle.fill.color.v.c[2], - 1.0); + + { + Inkscape::DrawingContext::Save save(dc); + dc.transform(_ctm); // Needed so that fill pattern rotates with text + + if (has_td_fill && fill_first) { + _nrstyle.applyTextDecorationFill(dc); + dc.fillPreserve(); + } + + if (has_td_stroke) { + _nrstyle.applyTextDecorationStroke(dc); + dc.strokePreserve(); + } + + if (has_td_fill && !fill_first) { + _nrstyle.applyTextDecorationFill(dc); + dc.fillPreserve(); + } + } - dc.setSource(ergba); - dc.setTolerance(0.5); - double thickness = decorateItem(dc, aff, phase_length); - dc.setLineWidth(thickness); - dc.strokePreserve(); - dc.newPath(); // clear path + + dc.newPath(); // Clear text-decoration path } + } return RENDER_OK; } diff --git a/src/display/drawing-text.h b/src/display/drawing-text.h index b863ca2a4..4453a3db4 100644 --- a/src/display/drawing-text.h +++ b/src/display/drawing-text.h @@ -15,7 +15,7 @@ #include "display/drawing-group.h" #include "display/nr-style.h" -struct SPStyle; +class SPStyle; class font_instance; namespace Inkscape { @@ -68,8 +68,8 @@ protected: virtual DrawingItem *_pickItem(Geom::Point const &p, double delta, unsigned flags); virtual bool _canClip(); - double decorateItem(DrawingContext &dc, Geom::Affine const &aff, double phase_length); - void decorateStyle(DrawingContext &dc, double vextent, double xphase, Geom::Point const &p1, Geom::Point const &p2); + void decorateItem(DrawingContext &dc, double phase_length, bool under); + void decorateStyle(DrawingContext &dc, double vextent, double xphase, Geom::Point const &p1, Geom::Point const &p2, double thickness); NRStyle _nrstyle; friend class DrawingGlyphs; diff --git a/src/display/drawing.h b/src/display/drawing.h index cc74833ba..0c12b1510 100644 --- a/src/display/drawing.h +++ b/src/display/drawing.h @@ -12,18 +12,18 @@ #ifndef SEEN_INKSCAPE_DISPLAY_DRAWING_H #define SEEN_INKSCAPE_DISPLAY_DRAWING_H -#include <set> -#include <glib.h> +#include <2geom/rect.h> #include <boost/operators.hpp> #include <boost/utility.hpp> +#include <set> #include <sigc++/sigc++.h> -#include <2geom/rect.h> + #include "display/drawing-item.h" #include "display/rendermode.h" #include "nr-filter-colormatrix.h" typedef struct _SPCanvasArena SPCanvasArena; - +typedef unsigned int guint32; namespace Inkscape { @@ -65,7 +65,7 @@ public: OutlineColors const &colors() const { return _colors; } - void setGrayscaleMatrix(gdouble value_matrix[20]); + void setGrayscaleMatrix(double value_matrix[20]); void update(Geom::IntRect const &area = Geom::IntRect::infinite(), UpdateContext const &ctx = UpdateContext(), unsigned flags = DrawingItem::STATE_ALL, unsigned reset = 0); void render(DrawingContext &dc, Geom::IntRect const &area, unsigned flags = 0); @@ -100,7 +100,7 @@ private: OutlineColors _colors; Filters::FilterColorMatrix::ColorMatrixMatrix _grayscale_colormatrix; - SPCanvasArena *_canvasarena; // may be NULL is this arena is not the screen + SPCanvasArena *_canvasarena; // may be NULL if this arena is not the screen // but used for export etc. friend class DrawingItem; diff --git a/src/display/gnome-canvas-acetate.cpp b/src/display/gnome-canvas-acetate.cpp index 2cd0f296d..9147a1bbf 100644 --- a/src/display/gnome-canvas-acetate.cpp +++ b/src/display/gnome-canvas-acetate.cpp @@ -15,40 +15,17 @@ #include "gnome-canvas-acetate.h" -static void sp_canvas_acetate_class_init (SPCanvasAcetateClass *klass); -static void sp_canvas_acetate_init (SPCanvasAcetate *acetate); static void sp_canvas_acetate_destroy(SPCanvasItem *object); static void sp_canvas_acetate_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); static double sp_canvas_acetate_point (SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_item); -static SPCanvasItemClass *parent_class; - -GType sp_canvas_acetate_get_type (void) -{ - static GType acetate_type = 0; - if (!acetate_type) { - GTypeInfo acetate_info = { - sizeof (SPCanvasAcetateClass), - NULL, NULL, - (GClassInitFunc) sp_canvas_acetate_class_init, - NULL, NULL, - sizeof (SPCanvasAcetate), - 0, - (GInstanceInitFunc) sp_canvas_acetate_init, - NULL - }; - acetate_type = g_type_register_static(SPCanvasItem::getType(), "SPCanvasAcetate", &acetate_info, GTypeFlags(0)); - } - return acetate_type; -} +G_DEFINE_TYPE(SPCanvasAcetate, sp_canvas_acetate, SP_TYPE_CANVAS_ITEM); static void sp_canvas_acetate_class_init (SPCanvasAcetateClass *klass) { SPCanvasItemClass *item_class = (SPCanvasItemClass *) klass; - parent_class = (SPCanvasItemClass*)g_type_class_peek_parent (klass); - item_class->destroy = sp_canvas_acetate_destroy; item_class->update = sp_canvas_acetate_update; item_class->point = sp_canvas_acetate_point; @@ -64,8 +41,8 @@ static void sp_canvas_acetate_destroy(SPCanvasItem *object) g_return_if_fail (object != NULL); g_return_if_fail (GNOME_IS_CANVAS_ACETATE (object)); - if (SP_CANVAS_ITEM_CLASS(parent_class)->destroy) - (* SP_CANVAS_ITEM_CLASS(parent_class)->destroy) (object); + if (SP_CANVAS_ITEM_CLASS(sp_canvas_acetate_parent_class)->destroy) + SP_CANVAS_ITEM_CLASS(sp_canvas_acetate_parent_class)->destroy(object); } static void sp_canvas_acetate_update( SPCanvasItem *item, Geom::Affine const &/*affine*/, unsigned int /*flags*/ ) diff --git a/src/display/gnome-canvas-acetate.h b/src/display/gnome-canvas-acetate.h index 447c3a9c4..3e1ba7661 100644 --- a/src/display/gnome-canvas-acetate.h +++ b/src/display/gnome-canvas-acetate.h @@ -15,10 +15,8 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include <glib.h> #include "display/sp-canvas-item.h" - #define GNOME_TYPE_CANVAS_ACETATE (sp_canvas_acetate_get_type ()) #define SP_CANVAS_ACETATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_TYPE_CANVAS_ACETATE, SPCanvasAcetate)) #define SP_CANVAS_ACETATE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNOME_TYPE_CANVAS_ACETATE, SPCanvasAcetateClass)) @@ -27,17 +25,15 @@ struct SPCanvasAcetate { - SPCanvasItem item; + SPCanvasItem item; }; struct SPCanvasAcetateClass { - SPCanvasItemClass parent_class; + SPCanvasItemClass parent_class; }; GType sp_canvas_acetate_get_type (void); - - #endif // SEEN_SP_CANVAS_ACETATE_H /* diff --git a/src/display/grayscale.cpp b/src/display/grayscale.cpp index f59cf6d23..3c0031e87 100644 --- a/src/display/grayscale.cpp +++ b/src/display/grayscale.cpp @@ -36,7 +36,7 @@ guint32 process(guint32 rgba) { return process(SP_RGBA32_R_U(rgba), SP_RGBA32_G_U(rgba), SP_RGBA32_B_U(rgba), SP_RGBA32_A_U(rgba)); } -guint32 process(guchar r, guchar g, guchar b, guchar a) { +guint32 process(unsigned char r, unsigned char g, unsigned char b, unsigned char a) { /** To reduce banding in gradients, this calculation is tweaked a bit * by outputing blue+1 or red+1 or both. The luminance is calculated @@ -62,7 +62,7 @@ guint32 process(guchar r, guchar g, guchar b, guchar a) { } } -guchar luminance(guchar r, guchar g, guchar b) { +unsigned char luminance(unsigned char r, unsigned char g, unsigned char b) { guint32 luminance = ( red_factor * r + green_factor * g + blue_factor * b ); diff --git a/src/display/grayscale.h b/src/display/grayscale.h index 18162e1f3..0ffe727da 100644 --- a/src/display/grayscale.h +++ b/src/display/grayscale.h @@ -10,15 +10,15 @@ * Released under GNU GPL */ -#include <gdk/gdk.h> +typedef unsigned int guint32; /** * Provide methods to calculate grayscale values (e.g. convert rgba value to grayscale rgba value). */ namespace Grayscale { guint32 process(guint32 rgba); - guint32 process(guchar r, guchar g, guchar b, guchar a); - guchar luminance(guchar r, guchar g, guchar b); + guint32 process(unsigned char r, unsigned char g, unsigned char b, unsigned char a); + unsigned char luminance(unsigned char r, unsigned char g, unsigned char b); bool activeDesktopIsGrayscale(); }; diff --git a/src/display/guideline.cpp b/src/display/guideline.cpp index 55c1ee495..44bbd14bd 100644 --- a/src/display/guideline.cpp +++ b/src/display/guideline.cpp @@ -29,8 +29,6 @@ using Inkscape::ControlManager; -static void sp_guideline_class_init(SPGuideLineClass *c); -static void sp_guideline_init(SPGuideLine *guideline); static void sp_guideline_destroy(SPCanvasItem *object); static void sp_guideline_update(SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); @@ -40,34 +38,10 @@ static double sp_guideline_point(SPCanvasItem *item, Geom::Point p, SPCanvasItem static void sp_guideline_drawline (SPCanvasBuf *buf, gint x0, gint y0, gint x1, gint y1, guint32 rgba); -static SPCanvasItemClass *parent_class; - -GType sp_guideline_get_type() -{ - static GType guideline_type = 0; - - if (!guideline_type) { - static GTypeInfo const guideline_info = { - sizeof (SPGuideLineClass), - NULL, NULL, - (GClassInitFunc) sp_guideline_class_init, - NULL, NULL, - sizeof (SPGuideLine), - 16, - (GInstanceInitFunc) sp_guideline_init, - NULL, - }; - - guideline_type = g_type_register_static(SP_TYPE_CANVAS_ITEM, "SPGuideLine", &guideline_info, (GTypeFlags) 0); - } - - return guideline_type; -} +G_DEFINE_TYPE(SPGuideLine, sp_guideline, SP_TYPE_CANVAS_ITEM); static void sp_guideline_class_init(SPGuideLineClass *c) { - parent_class = SP_CANVAS_ITEM_CLASS(g_type_class_peek_parent(c)); - SPCanvasItemClass *item_class = SP_CANVAS_ITEM_CLASS(c); item_class->destroy = sp_guideline_destroy; item_class->update = sp_guideline_update; @@ -108,7 +82,7 @@ static void sp_guideline_destroy(SPCanvasItem *object) g_free(gl->label); } - SP_CANVAS_ITEM_CLASS(parent_class)->destroy(object); + SP_CANVAS_ITEM_CLASS(sp_guideline_parent_class)->destroy(object); } static void sp_guideline_render(SPCanvasItem *item, SPCanvasBuf *buf) @@ -197,8 +171,8 @@ static void sp_guideline_update(SPCanvasItem *item, Geom::Affine const &affine, { SPGuideLine *gl = SP_GUIDELINE(item); - if ((SP_CANVAS_ITEM_CLASS(parent_class))->update) { - (SP_CANVAS_ITEM_CLASS(parent_class))->update(item, affine, flags); + if ((SP_CANVAS_ITEM_CLASS(sp_guideline_parent_class))->update) { + (SP_CANVAS_ITEM_CLASS(sp_guideline_parent_class))->update(item, affine, flags); } gl->affine = affine; diff --git a/src/display/nr-3dutils.h b/src/display/nr-3dutils.h index c278c81c6..eb773a9ad 100644 --- a/src/display/nr-3dutils.h +++ b/src/display/nr-3dutils.h @@ -1,5 +1,5 @@ -#ifndef __NR_3DUTILS_H__ -#define __NR_3DUTILS_H__ +#ifndef SEEN_NR_3DUTILS_H +#define SEEN_NR_3DUTILS_H /* * 3D utils. Definition of gdouble vectors of dimension 3 and of some basic @@ -14,7 +14,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include <gdk/gdk.h> #include <2geom/forward.h> namespace NR { @@ -51,7 +50,7 @@ const static Fvector EYE_VECTOR(0, 0, 1); * \param v a reference to a vector with double components * \return the euclidian norm of v */ -gdouble norm(const Fvector &v); +double norm(const Fvector &v); /** * Normalizes a vector @@ -67,7 +66,7 @@ void normalize_vector(Fvector &v); * \param b a Fvector reference * \return the scalar product of a and b */ -gdouble scalar_product(const Fvector &a, const Fvector &b); +double scalar_product(const Fvector &a, const Fvector &b); /** * Computes the normalized sum of two Fvectors @@ -88,7 +87,7 @@ void normalized_sum(Fvector &r, const Fvector &a, const Fvector &b); * \param z a reference to a z coordinate * \param z a reference to a transformation matrix */ -void convert_coord(gdouble &x, gdouble &y, gdouble &z, Geom::Affine const &trans); +void convert_coord(double &x, double &y, double &z, Geom::Affine const &trans); } /* namespace NR */ diff --git a/src/display/nr-filter-blend.cpp b/src/display/nr-filter-blend.cpp index 099816bce..d0db6b42e 100644 --- a/src/display/nr-filter-blend.cpp +++ b/src/display/nr-filter-blend.cpp @@ -20,6 +20,7 @@ #include "config.h" #endif +#include <glibmm.h> #include "display/cairo-templates.h" #include "display/cairo-utils.h" #include "display/nr-filter-blend.h" @@ -83,8 +84,7 @@ void FilterBlend::render_cairo(FilterSlot &slot) case BLEND_LIGHTEN: cairo_set_operator(out_ct, CAIRO_OPERATOR_LIGHTEN); break; -#ifdef WITH_CSSBLEND - // NEW + // New in CSS Compositing and Blending Level 1 case BLEND_OVERLAY: cairo_set_operator(out_ct, CAIRO_OPERATOR_OVERLAY); break; @@ -118,7 +118,6 @@ void FilterBlend::render_cairo(FilterSlot &slot) case BLEND_LUMINOSITY: cairo_set_operator(out_ct, CAIRO_OPERATOR_HSL_LUMINOSITY); break; -#endif case BLEND_NORMAL: default: @@ -167,15 +166,12 @@ void FilterBlend::set_input(int input, int slot) { void FilterBlend::set_mode(FilterBlendMode mode) { if (mode == BLEND_NORMAL || mode == BLEND_MULTIPLY || mode == BLEND_SCREEN || mode == BLEND_DARKEN || - mode == BLEND_LIGHTEN -#ifdef WITH_CSSBLEND - || mode == BLEND_OVERLAY || + mode == BLEND_LIGHTEN || mode == BLEND_OVERLAY || mode == BLEND_COLORDODGE || mode == BLEND_COLORBURN || mode == BLEND_HARDLIGHT || mode == BLEND_SOFTLIGHT || mode == BLEND_DIFFERENCE || mode == BLEND_EXCLUSION || mode == BLEND_HUE || mode == BLEND_SATURATION || mode == BLEND_COLOR || mode == BLEND_LUMINOSITY -#endif ) { _blend_mode = mode; diff --git a/src/display/nr-filter-blend.h b/src/display/nr-filter-blend.h index 0a2927d87..30c9d6725 100644 --- a/src/display/nr-filter-blend.h +++ b/src/display/nr-filter-blend.h @@ -1,5 +1,5 @@ -#ifndef __NR_FILTER_BLEND_H__ -#define __NR_FILTER_BLEND_H__ +#ifndef SEEN_NR_FILTER_BLEND_H +#define SEEN_NR_FILTER_BLEND_H /* * SVG feBlend renderer @@ -28,7 +28,6 @@ enum FilterBlendMode { BLEND_SCREEN, BLEND_DARKEN, BLEND_LIGHTEN, -#ifdef WITH_CSSBLEND // New in CSS Compositing and Blending Level 1 BLEND_OVERLAY, BLEND_COLORDODGE, @@ -41,7 +40,6 @@ enum FilterBlendMode { BLEND_SATURATION, BLEND_COLOR, BLEND_LUMINOSITY, -#endif BLEND_ENDMODE, }; diff --git a/src/display/nr-filter-colormatrix.h b/src/display/nr-filter-colormatrix.h index c7e5e91d9..cc43f4914 100644 --- a/src/display/nr-filter-colormatrix.h +++ b/src/display/nr-filter-colormatrix.h @@ -1,5 +1,5 @@ -#ifndef __NR_FILTER_COLOR_MATRIX_H__ -#define __NR_FILTER_COLOR_MATRIX_H__ +#ifndef SEEN_NR_FILTER_COLOR_MATRIX_H +#define SEEN_NR_FILTER_COLOR_MATRIX_H /* * feColorMatrix filter primitive renderer @@ -16,6 +16,9 @@ #include <2geom/forward.h> #include "display/nr-filter-primitive.h" +typedef unsigned int guint32; +typedef signed int gint32; + namespace Inkscape { namespace Filters { @@ -40,8 +43,8 @@ public: virtual double complexity(Geom::Affine const &ctm); virtual void set_type(FilterColorMatrixType type); - virtual void set_value(gdouble value); - virtual void set_values(std::vector<gdouble> const &values); + virtual void set_value(double value); + virtual void set_values(std::vector<double> const &values); public: struct ColorMatrixMatrix { @@ -52,8 +55,8 @@ public: }; private: - std::vector<gdouble> values; - gdouble value; + std::vector<double> values; + double value; FilterColorMatrixType type; }; diff --git a/src/display/nr-filter-component-transfer.h b/src/display/nr-filter-component-transfer.h index 558d097a8..7019dde37 100644 --- a/src/display/nr-filter-component-transfer.h +++ b/src/display/nr-filter-component-transfer.h @@ -1,5 +1,5 @@ -#ifndef __NR_FILTER_COMPONENT_TRANSFER_H__ -#define __NR_FILTER_COMPONENT_TRANSFER_H__ +#ifndef SEEN_NR_FILTER_COMPONENT_TRANSFER_H +#define SEEN_NR_FILTER_COMPONENT_TRANSFER_H /* * feComponentTransfer filter primitive renderer @@ -40,7 +40,7 @@ public: virtual double complexity(Geom::Affine const &ctm); FilterComponentTransferType type[4]; - std::vector<gdouble> tableValues[4]; + std::vector<double> tableValues[4]; double slope[4]; double intercept[4]; double amplitude[4]; diff --git a/src/display/nr-filter-composite.h b/src/display/nr-filter-composite.h index 95579cc0e..35756383b 100644 --- a/src/display/nr-filter-composite.h +++ b/src/display/nr-filter-composite.h @@ -1,5 +1,5 @@ -#ifndef __NR_FILTER_COMPOSITE_H__ -#define __NR_FILTER_COMPOSITE_H__ +#ifndef SEEN_NR_FILTER_COMPOSITE_H +#define SEEN_NR_FILTER_COMPOSITE_H /* * feComposite filter effect renderer diff --git a/src/display/nr-filter-convolve-matrix.h b/src/display/nr-filter-convolve-matrix.h index 4041ff96f..d2e38eb95 100644 --- a/src/display/nr-filter-convolve-matrix.h +++ b/src/display/nr-filter-convolve-matrix.h @@ -1,5 +1,5 @@ -#ifndef __NR_FILTER_CONVOLVE_MATRIX_H__ -#define __NR_FILTER_CONVOLVE_MATRIX_H__ +#ifndef SEEN_NR_FILTER_CONVOLVE_MATRIX_H +#define SEEN_NR_FILTER_CONVOLVE_MATRIX_H /* * feConvolveMatrix filter primitive renderer @@ -48,10 +48,10 @@ public: void set_preserveAlpha(bool pa); private: - std::vector<gdouble> kernelMatrix; + std::vector<double> kernelMatrix; int targetX, targetY; int orderX, orderY; - gdouble divisor, bias; + double divisor, bias; int dx, dy, kernelUnitLength; FilterConvolveMatrixEdgeMode edgeMode; bool preserveAlpha; diff --git a/src/display/nr-filter-diffuselighting.h b/src/display/nr-filter-diffuselighting.h index 043a5eb39..7739b3ea6 100644 --- a/src/display/nr-filter-diffuselighting.h +++ b/src/display/nr-filter-diffuselighting.h @@ -1,5 +1,5 @@ -#ifndef __NR_FILTER_DIFFUSELIGHTING_H__ -#define __NR_FILTER_DIFFUSELIGHTING_H__ +#ifndef SEEN_NR_FILTER_DIFFUSELIGHTING_H +#define SEEN_NR_FILTER_DIFFUSELIGHTING_H /* * feDiffuseLighting renderer @@ -13,7 +13,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include <gdk/gdk.h> #include "display/nr-light-types.h" #include "display/nr-filter-primitive.h" #include "display/nr-filter-slot.h" @@ -23,6 +22,7 @@ class SPFeDistantLight; class SPFePointLight; class SPFeSpotLight; struct SVGICCColor; +typedef unsigned int guint32; namespace Inkscape { namespace Filters { @@ -43,8 +43,8 @@ public: SPFeSpotLight *spot; } light; LightType light_type; - gdouble diffuseConstant; - gdouble surfaceScale; + double diffuseConstant; + double surfaceScale; guint32 lighting_color; private: diff --git a/src/display/nr-filter-displacement-map.h b/src/display/nr-filter-displacement-map.h index a01930045..c4e2400fe 100644 --- a/src/display/nr-filter-displacement-map.h +++ b/src/display/nr-filter-displacement-map.h @@ -1,5 +1,5 @@ -#ifndef __NR_FILTER_DISPLACEMENT_MAP_H__ -#define __NR_FILTER_DISPLACEMENT_MAP_H__ +#ifndef SEEN_NR_FILTER_DISPLACEMENT_MAP_H +#define SEEN_NR_FILTER_DISPLACEMENT_MAP_H /* * feDisplacementMap filter primitive renderer diff --git a/src/display/nr-filter-flood.h b/src/display/nr-filter-flood.h index 9a968047d..826aa981a 100644 --- a/src/display/nr-filter-flood.h +++ b/src/display/nr-filter-flood.h @@ -1,5 +1,5 @@ -#ifndef __NR_FILTER_FLOOD_H__ -#define __NR_FILTER_FLOOD_H__ +#ifndef SEEN_NR_FILTER_FLOOD_H +#define SEEN_NR_FILTER_FLOOD_H /* * feFlood filter primitive renderer @@ -15,6 +15,7 @@ #include "display/nr-filter-primitive.h" struct SVGICCColor; +typedef unsigned int guint32; namespace Inkscape { namespace Filters { diff --git a/src/display/nr-filter-gaussian.h b/src/display/nr-filter-gaussian.h index 1c35a0f1d..88c38247f 100644 --- a/src/display/nr-filter-gaussian.h +++ b/src/display/nr-filter-gaussian.h @@ -1,5 +1,5 @@ -#ifndef __NR_FILTER_GAUSSIAN_H__ -#define __NR_FILTER_GAUSSIAN_H__ +#ifndef SEEN_NR_FILTER_GAUSSIAN_H +#define SEEN_NR_FILTER_GAUSSIAN_H /* * Gaussian blur renderer diff --git a/src/display/nr-filter-image.h b/src/display/nr-filter-image.h index 69691ac99..147a8ba6c 100644 --- a/src/display/nr-filter-image.h +++ b/src/display/nr-filter-image.h @@ -1,5 +1,5 @@ -#ifndef __NR_FILTER_IMAGE_H__ -#define __NR_FILTER_IMAGE_H__ +#ifndef SEEN_NR_FILTER_IMAGE_H +#define SEEN_NR_FILTER_IMAGE_H /* * feImage filter primitive renderer @@ -34,7 +34,7 @@ public: virtual double complexity(Geom::Affine const &ctm); void set_document( SPDocument *document ); - void set_href(const gchar *href); + void set_href(char const *href); void set_align( unsigned int align ); void set_clip( unsigned int clip ); bool from_element; @@ -42,7 +42,7 @@ public: private: SPDocument *document; - gchar *feImageHref; + char *feImageHref; Inkscape::Pixbuf *image; float feImageX, feImageY, feImageWidth, feImageHeight; unsigned int aspect_align, aspect_clip; diff --git a/src/display/nr-filter-merge.h b/src/display/nr-filter-merge.h index 238f9a3e7..b20d663ab 100644 --- a/src/display/nr-filter-merge.h +++ b/src/display/nr-filter-merge.h @@ -1,5 +1,5 @@ -#ifndef __NR_FILTER_MERGE_H__ -#define __NR_FILTER_MERGE_H__ +#ifndef SEEN_NR_FILTER_MERGE_H +#define SEEN_NR_FILTER_MERGE_H /* * feMerge filter effect renderer diff --git a/src/display/nr-filter-morphology.h b/src/display/nr-filter-morphology.h index 0574ff4ad..cd7dfe775 100644 --- a/src/display/nr-filter-morphology.h +++ b/src/display/nr-filter-morphology.h @@ -1,5 +1,5 @@ -#ifndef __NR_FILTER_MORPHOLOGY_H__ -#define __NR_FILTER_MORPHOLOGY_H__ +#ifndef SEEN_NR_FILTER_MORPHOLOGY_H +#define SEEN_NR_FILTER_MORPHOLOGY_H /* * feMorphology filter primitive renderer diff --git a/src/display/nr-filter-offset.h b/src/display/nr-filter-offset.h index 1ecc1621e..c1ee1d82a 100644 --- a/src/display/nr-filter-offset.h +++ b/src/display/nr-filter-offset.h @@ -1,5 +1,5 @@ -#ifndef __NR_FILTER_OFFSET_H__ -#define __NR_FILTER_OFFSET_H__ +#ifndef SEEN_NR_FILTER_OFFSET_H +#define SEEN_NR_FILTER_OFFSET_H /* * feOffset filter primitive renderer diff --git a/src/display/nr-filter-primitive.h b/src/display/nr-filter-primitive.h index 94bd6abb0..4b7577159 100644 --- a/src/display/nr-filter-primitive.h +++ b/src/display/nr-filter-primitive.h @@ -13,10 +13,11 @@ #include <2geom/forward.h> #include <2geom/rect.h> + #include "display/nr-filter-types.h" #include "svg/svg-length.h" -struct SPStyle; +class SPStyle; namespace Inkscape { namespace Filters { @@ -30,7 +31,7 @@ public: virtual ~FilterPrimitive(); virtual void render_cairo(FilterSlot &slot); - virtual int render(FilterSlot & /*slot*/, FilterUnits const & /*units*/) { return 0; } + virtual int render(FilterSlot & /*slot*/, FilterUnits const & /*units*/) { return 0; } // pure virtual? virtual void area_enlarge(Geom::IntRect &area, Geom::Affine const &m); /** diff --git a/src/display/nr-filter-skeleton.h b/src/display/nr-filter-skeleton.h index 049c0df80..e17c244c1 100644 --- a/src/display/nr-filter-skeleton.h +++ b/src/display/nr-filter-skeleton.h @@ -1,5 +1,5 @@ -#ifndef __NR_FILTER_SKELETON_H__ -#define __NR_FILTER_SKELETON_H__ +#ifndef SEEN_NR_FILTER_SKELETON_H +#define SEEN_NR_FILTER_SKELETON_H /* * Filter primitive renderer skeleton class diff --git a/src/display/nr-filter-slot.h b/src/display/nr-filter-slot.h index f3c98b8d9..987dedfd1 100644 --- a/src/display/nr-filter-slot.h +++ b/src/display/nr-filter-slot.h @@ -1,5 +1,5 @@ -#ifndef __NR_FILTER_SLOT_H__ -#define __NR_FILTER_SLOT_H__ +#ifndef SEEN_NR_FILTER_SLOT_H +#define SEEN_NR_FILTER_SLOT_H /* * A container class for filter slots. Allows for simple getting and @@ -15,10 +15,14 @@ */ #include <map> -#include <cairo.h> #include "display/nr-filter-types.h" #include "display/nr-filter-units.h" +extern "C" { +typedef struct _cairo cairo_t; +typedef struct _cairo_surface cairo_surface_t; +} + namespace Inkscape { class DrawingContext; class DrawingItem; diff --git a/src/display/nr-filter-specularlighting.h b/src/display/nr-filter-specularlighting.h index c57e3a9ff..ff9cda450 100644 --- a/src/display/nr-filter-specularlighting.h +++ b/src/display/nr-filter-specularlighting.h @@ -1,5 +1,5 @@ -#ifndef __NR_FILTER_SPECULARLIGHTING_H__ -#define __NR_FILTER_SPECULARLIGHTING_H__ +#ifndef SEEN_NR_FILTER_SPECULARLIGHTING_H +#define SEEN_NR_FILTER_SPECULARLIGHTING_H /* * feSpecularLighting renderer @@ -13,7 +13,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include <gdk/gdk.h> #include "display/nr-light-types.h" #include "display/nr-filter-primitive.h" @@ -21,6 +20,7 @@ class SPFeDistantLight; class SPFePointLight; class SPFeSpotLight; struct SVGICCColor; +typedef unsigned int guint32; namespace Inkscape { namespace Filters { @@ -44,9 +44,9 @@ public: SPFeSpotLight *spot; } light; LightType light_type; - gdouble surfaceScale; - gdouble specularConstant; - gdouble specularExponent; + double surfaceScale; + double specularConstant; + double specularExponent; guint32 lighting_color; private: diff --git a/src/display/nr-filter-tile.h b/src/display/nr-filter-tile.h index dc5b99a42..29087f2d6 100644 --- a/src/display/nr-filter-tile.h +++ b/src/display/nr-filter-tile.h @@ -1,5 +1,5 @@ -#ifndef __NR_FILTER_TILE_H__ -#define __NR_FILTER_TILE_H__ +#ifndef SEEN_NR_FILTER_TILE_H +#define SEEN_NR_FILTER_TILE_H /* * feTile filter primitive renderer diff --git a/src/display/nr-filter-turbulence.h b/src/display/nr-filter-turbulence.h index 360853364..ee8079133 100644 --- a/src/display/nr-filter-turbulence.h +++ b/src/display/nr-filter-turbulence.h @@ -1,5 +1,5 @@ -#ifndef __NR_FILTER_TURBULENCE_H__ -#define __NR_FILTER_TURBULENCE_H__ +#ifndef SEEN_NR_FILTER_TURBULENCE_H +#define SEEN_NR_FILTER_TURBULENCE_H /* * feTurbulence filter primitive renderer @@ -22,6 +22,7 @@ */ #include <2geom/point.h> + #include "display/nr-filter-primitive.h" #include "display/nr-filter-slot.h" #include "display/nr-filter-units.h" diff --git a/src/display/nr-filter-types.h b/src/display/nr-filter-types.h index 502bfe348..2e35d6da8 100644 --- a/src/display/nr-filter-types.h +++ b/src/display/nr-filter-types.h @@ -1,5 +1,5 @@ -#ifndef __NR_FILTER_TYPES_H__ -#define __NR_FILTER_TYPES_H__ +#ifndef SEEN_NR_FILTER_TYPES_H +#define SEEN_NR_FILTER_TYPES_H namespace Inkscape { namespace Filters { diff --git a/src/display/nr-filter-units.h b/src/display/nr-filter-units.h index f918cf12e..0ee6c3707 100644 --- a/src/display/nr-filter-units.h +++ b/src/display/nr-filter-units.h @@ -1,5 +1,5 @@ -#ifndef __NR_FILTER_UNITS_H__ -#define __NR_FILTER_UNITS_H__ +#ifndef SEEN_NR_FILTER_UNITS_H +#define SEEN_NR_FILTER_UNITS_H /* * Utilities for handling coordinate system transformations in filters diff --git a/src/display/nr-filter-utils.h b/src/display/nr-filter-utils.h index 7e073168f..35a74d7c1 100644 --- a/src/display/nr-filter-utils.h +++ b/src/display/nr-filter-utils.h @@ -1,5 +1,5 @@ -#ifndef __NR_FILTER_UTILS_H__ -#define __NR_FILTER_UTILS_H__ +#ifndef SEEN_NR_FILTER_UTILS_H +#define SEEN_NR_FILTER_UTILS_H /** * @file @@ -26,7 +26,6 @@ namespace Filters { * \return 0 if the value is smaller than 0, 255 if it is greater 255, else v * \param v the value to clamp */ -__attribute__ ((const)) inline int clamp(int const val) { if (val < 0) return 0; if (val > 255) return 255; @@ -39,7 +38,6 @@ inline int clamp(int const val) { * \return 0 if the value is smaller than 0, 255^3 (16581375) if it is greater than 255^3, else v * \param v the value to clamp */ -__attribute__ ((const)) inline int clamp3(int const val) { if (val < 0) return 0; if (val > 16581375) return 16581375; @@ -59,7 +57,6 @@ inline int clamp3(int const val) { * \param val the value to clamp * \param alpha the maximum value to clamp to */ -__attribute__ ((const)) inline int clamp_alpha(int const val, int const alpha) { if (val < 0) return 0; if (val > alpha) return alpha; diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp index 90b233fbc..dec5b1f57 100644 --- a/src/display/nr-filter.cpp +++ b/src/display/nr-filter.cpp @@ -9,7 +9,6 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include "display/nr-filter-image.h" #include <glib.h> #include <cmath> #include <cstring> @@ -29,6 +28,7 @@ #include "display/nr-filter-component-transfer.h" #include "display/nr-filter-diffuselighting.h" #include "display/nr-filter-displacement-map.h" +#include "display/nr-filter-image.h" #include "display/nr-filter-flood.h" #include "display/nr-filter-gaussian.h" #include "display/nr-filter-merge.h" diff --git a/src/display/nr-filter.h b/src/display/nr-filter.h index f9dcf1d84..9a30efabd 100644 --- a/src/display/nr-filter.h +++ b/src/display/nr-filter.h @@ -1,5 +1,5 @@ -#ifndef __NR_FILTER_H__ -#define __NR_FILTER_H__ +#ifndef SEEN_NR_FILTER_H +#define SEEN_NR_FILTER_H /* * SVG filters rendering diff --git a/src/display/nr-light-types.h b/src/display/nr-light-types.h index 5c9acb324..8cc92db77 100644 --- a/src/display/nr-light-types.h +++ b/src/display/nr-light-types.h @@ -1,5 +1,5 @@ -#ifndef __NR_LIGHT_TYPES_H__ -#define __NR_LIGHT_TYPES_H__ +#ifndef SEEN_NR_LIGHT_TYPES_H +#define SEEN_NR_LIGHT_TYPES_H namespace Inkscape { namespace Filters { diff --git a/src/display/nr-light.cpp b/src/display/nr-light.cpp index 6331d1546..0e9a55a9f 100644 --- a/src/display/nr-light.cpp +++ b/src/display/nr-light.cpp @@ -51,7 +51,7 @@ PointLight::PointLight(SPFePointLight *light, guint32 lighting_color, const Geom PointLight::~PointLight() {} -void PointLight::light_vector(NR::Fvector &v, gdouble x, gdouble y, gdouble z) { +void PointLight::light_vector(NR::Fvector &v, double x, double y, double z) { v[X_3D] = l_x - x; v[Y_3D] = l_y - y; v[Z_3D] = l_z - z; @@ -65,7 +65,7 @@ void PointLight::light_components(NR::Fvector &lc) { } SpotLight::SpotLight(SPFeSpotLight *light, guint32 lighting_color, const Geom::Affine &trans) { - gdouble p_x, p_y, p_z; + double p_x, p_y, p_z; color = lighting_color; l_x = light->x; l_y = light->y; @@ -86,7 +86,7 @@ SpotLight::SpotLight(SPFeSpotLight *light, guint32 lighting_color, const Geom::A SpotLight::~SpotLight() {} -void SpotLight::light_vector(NR::Fvector &v, gdouble x, gdouble y, gdouble z) { +void SpotLight::light_vector(NR::Fvector &v, double x, double y, double z) { v[X_3D] = l_x - x; v[Y_3D] = l_y - y; v[Z_3D] = l_z - z; @@ -94,7 +94,7 @@ void SpotLight::light_vector(NR::Fvector &v, gdouble x, gdouble y, gdouble z) { } void SpotLight::light_components(NR::Fvector &lc, const NR::Fvector &L) { - gdouble spmod = (-1) * NR::scalar_product(L, S); + double spmod = (-1) * NR::scalar_product(L, S); if (spmod <= cos_lca) spmod = 0; else diff --git a/src/display/nr-light.h b/src/display/nr-light.h index 0c1235483..94b573761 100644 --- a/src/display/nr-light.h +++ b/src/display/nr-light.h @@ -1,5 +1,6 @@ -#ifndef __NR_LIGHT_H__ -#define __NR_LIGHT_H__ +#ifndef SEEN_NR_LIGHT_H +#define SEEN_NR_LIGHT_H + /** \file * These classes provide tools to compute interesting objects relative to light * sources. Each class provides a constructor converting information contained @@ -8,14 +9,15 @@ * light color components (at a given point). */ -#include <gdk/gdk.h> +#include <2geom/forward.h> + #include "display/nr-3dutils.h" #include "display/nr-light-types.h" -#include <2geom/forward.h> class SPFeDistantLight; class SPFePointLight; class SPFeSpotLight; +typedef unsigned int guint32; namespace Inkscape { namespace Filters { @@ -53,8 +55,8 @@ class DistantLight { private: guint32 color; - gdouble azimuth; //azimuth in rad - gdouble elevation; //elevation in rad + double azimuth; //azimuth in rad + double elevation; //elevation in rad }; class PointLight { @@ -80,7 +82,7 @@ class PointLight { * \param y y coordinate of the current point * \param z z coordinate of the current point */ - void light_vector(NR::Fvector &v, gdouble x, gdouble y, gdouble z); + void light_vector(NR::Fvector &v, double x, double y, double z); /** * Computes the light components of the distant light @@ -92,9 +94,9 @@ class PointLight { private: guint32 color; //light position coordinates in render setting - gdouble l_x; - gdouble l_y; - gdouble l_z; + double l_x; + double l_y; + double l_z; }; class SpotLight { @@ -121,7 +123,7 @@ class SpotLight { * \param y y coordinate of the current point * \param z z coordinate of the current point */ - void light_vector(NR::Fvector &v, gdouble x, gdouble y, gdouble z); + void light_vector(NR::Fvector &v, double x, double y, double z); /** * Computes the light components of the distant light at the current @@ -135,11 +137,11 @@ class SpotLight { private: guint32 color; //light position coordinates in render setting - gdouble l_x; - gdouble l_y; - gdouble l_z; - gdouble cos_lca; //cos of the limiting cone angle - gdouble speExp; //specular exponent; + double l_x; + double l_y; + double l_z; + double cos_lca; //cos of the limiting cone angle + double speExp; //specular exponent; NR::Fvector S; //unit vector from light position in the direction //the spot point at }; diff --git a/src/display/nr-style.cpp b/src/display/nr-style.cpp index 125d0c6d6..96d16bf06 100644 --- a/src/display/nr-style.cpp +++ b/src/display/nr-style.cpp @@ -14,6 +14,7 @@ #include "sp-paint-server.h" #include "display/canvas-bpath.h" // contains SPStrokeJoinType, SPStrokeCapType etc. (WTF!) #include "display/drawing-context.h" +#include "display/drawing-pattern.h" void NRStyle::Paint::clear() { @@ -54,8 +55,13 @@ NRStyle::NRStyle() , line_join(CAIRO_LINE_JOIN_MITER) , fill_pattern(NULL) , stroke_pattern(NULL) + , text_decoration_fill_pattern(NULL) + , text_decoration_stroke_pattern(NULL) , text_decoration_line(TEXT_DECORATION_LINE_CLEAR) , text_decoration_style(TEXT_DECORATION_STYLE_CLEAR) + , text_decoration_fill() + , text_decoration_stroke() + , text_decoration_stroke_width(0.0) , phase_length(0.0) , tspan_line_start(false) , tspan_line_end(false) @@ -69,26 +75,35 @@ NRStyle::NRStyle() , line_through_position(0) , font_size(0) { -#ifdef WITH_SVG2 paint_order_layer[0] = PAINT_ORDER_NORMAL; -#endif } NRStyle::~NRStyle() { if (fill_pattern) cairo_pattern_destroy(fill_pattern); if (stroke_pattern) cairo_pattern_destroy(stroke_pattern); + if (text_decoration_fill_pattern) cairo_pattern_destroy(text_decoration_fill_pattern); + if (text_decoration_stroke_pattern) cairo_pattern_destroy(text_decoration_stroke_pattern); if (dash){ delete [] dash; } fill.clear(); stroke.clear(); + text_decoration_fill.clear(); + text_decoration_stroke.clear(); } void NRStyle::set(SPStyle *style) { if ( style->fill.isPaintserver() ) { - fill.set(style->getFillPaintServer()); + SPPaintServer* server = style->getFillPaintServer(); + if ( server && server->isValid() ) { + fill.set(server); + } else if ( style->fill.colorSet ) { + fill.set(style->fill.value.color); + } else { + fill.clear(); + } } else if ( style->fill.isColor() ) { fill.set(style->fill.value.color); } else if ( style->fill.isNone() ) { @@ -110,7 +125,14 @@ void NRStyle::set(SPStyle *style) } if ( style->stroke.isPaintserver() ) { - stroke.set(style->getStrokePaintServer()); + SPPaintServer* server = style->getStrokePaintServer(); + if ( server && server->isValid() ) { + stroke.set(server); + } else if ( style->stroke.isColor() ) { + stroke.set(style->stroke.colorSet); + } else { + stroke.clear(); + } } else if ( style->stroke.isColor() ) { stroke.set(style->stroke.value.color); } else if ( style->stroke.isNone() ) { @@ -165,7 +187,6 @@ void NRStyle::set(SPStyle *style) } -#ifdef WITH_SVG2 for( unsigned i = 0; i < PAINT_ORDER_LAYERS; ++i) { switch (style->paint_order.layer[i]) { case SP_CSS_PAINT_ORDER_NORMAL: @@ -182,7 +203,6 @@ void NRStyle::set(SPStyle *style) break; } } -#endif text_decoration_line = TEXT_DECORATION_LINE_CLEAR; if(style->text_decoration_line.inherit ){ text_decoration_line |= TEXT_DECORATION_LINE_INHERIT; } @@ -199,16 +219,65 @@ void NRStyle::set(SPStyle *style) if(style->text_decoration_style.dashed ){ text_decoration_style |= TEXT_DECORATION_STYLE_DASHED + TEXT_DECORATION_STYLE_SET; } if(style->text_decoration_style.wavy ){ text_decoration_style |= TEXT_DECORATION_STYLE_WAVY + TEXT_DECORATION_STYLE_SET; } + /* FIXME + The meaning of text-decoration-color in CSS3 for SVG is ambiguous (2014-05-06). Set + it for fill, for stroke, for both? Both would seem like the obvious choice but what happens + is that for text which is just fill (very common) it makes the lines fatter because it + enables stroke on the decorations when it wasn't present on the text. That contradicts the + usual behavior where the text and decorations by default have the same fill/stroke. + + The behavior here is that if color is defined it is applied to text_decoration_fill/stroke + ONLY if the corresponding fill/stroke is also present. + + Hopefully the standard will be clarified to resolve this issue. + */ + + SPStyle* style_td = style; + if ( style->text_decoration.style_td ) style_td = style->text_decoration.style_td; + text_decoration_stroke.opacity = SP_SCALE24_TO_FLOAT(style_td->stroke_opacity.value); + text_decoration_stroke_width = style_td->stroke_width.computed; + if( style->text_decoration_color.set || style->text_decoration_color.inherit || - style->text_decoration_color.currentcolor || - style->text_decoration_color.colorSet){ - text_decoration_color.set(style->text_decoration_color.value.color); - text_decoration_useColor = true; - } - else { - text_decoration_color.clear(); - text_decoration_useColor = false; + style->text_decoration_color.currentcolor ) { + + if(style->fill.isPaintserver() || style->fill.isColor()) { + // SVG sets color specifically + text_decoration_fill.set(style->text_decoration_color.value.color); + } else { + // No decoration fill because no text fill + text_decoration_fill.clear(); + } + + if(style->stroke.isPaintserver() || style->stroke.isColor()) { + // SVG sets color specifically + text_decoration_stroke.set(style->text_decoration_color.value.color); + } else { + // No decoration stroke because no text stroke + text_decoration_stroke.clear(); + } + + } else { + // Pick color/pattern from text + if ( style_td->fill.isPaintserver() ) { + text_decoration_fill.set(style_td->getFillPaintServer()); + } else if ( style_td->fill.isColor() ) { + text_decoration_fill.set(style_td->fill.value.color); + } else if ( style_td->fill.isNone() ) { + text_decoration_fill.clear(); + } else { + g_assert_not_reached(); + } + + if ( style_td->stroke.isPaintserver() ) { + text_decoration_stroke.set(style_td->getStrokePaintServer()); + } else if ( style_td->stroke.isColor() ) { + text_decoration_stroke.set(style_td->stroke.value.color); + } else if ( style_td->stroke.isNone() ) { + text_decoration_stroke.clear(); + } else { + g_assert_not_reached(); + } } if(text_decoration_line != TEXT_DECORATION_LINE_CLEAR){ @@ -231,16 +300,17 @@ void NRStyle::set(SPStyle *style) update(); } -bool NRStyle::prepareFill(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox) +bool NRStyle::prepareFill(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox, Inkscape::DrawingPattern *pattern) { // update fill pattern if (!fill_pattern) { switch (fill.type) { - case PAINT_SERVER: { - //fill_pattern = sp_paint_server_create_pattern(fill.server, dc.raw(), paintbox, fill.opacity); - fill_pattern = fill.server->pattern_new(dc.raw(), paintbox, fill.opacity); - - } break; + case PAINT_SERVER: + if (pattern) { + fill_pattern = pattern->renderPattern(fill.opacity); + } else { + fill_pattern = fill.server->pattern_new(dc.raw(), paintbox, fill.opacity); + } break; case PAINT_COLOR: { SPColor const &c = fill.color; fill_pattern = cairo_pattern_create_rgba( @@ -259,21 +329,57 @@ void NRStyle::applyFill(Inkscape::DrawingContext &dc) dc.setFillRule(fill_rule); } -bool NRStyle::prepareStroke(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox) +bool NRStyle::prepareTextDecorationFill(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox, Inkscape::DrawingPattern *pattern) +{ + // update text decoration pattern + if (!text_decoration_fill_pattern) { + switch (text_decoration_fill.type) { + case PAINT_SERVER: + if (pattern) { + text_decoration_fill_pattern = pattern->renderPattern( + text_decoration_fill.opacity); + } else { + text_decoration_fill_pattern = text_decoration_fill.server->pattern_new(dc.raw(), + paintbox, text_decoration_fill.opacity); + } + break; + case PAINT_COLOR: { + SPColor const &c = text_decoration_fill.color; + text_decoration_fill_pattern = cairo_pattern_create_rgba( + c.v.c[0], c.v.c[1], c.v.c[2], text_decoration_fill.opacity); + } break; + default: break; + } + } + if (!text_decoration_fill_pattern) return false; + return true; +} + +void NRStyle::applyTextDecorationFill(Inkscape::DrawingContext &dc) +{ + dc.setSource(text_decoration_fill_pattern); + // Fill rule does not matter, no intersections. +} + +bool NRStyle::prepareStroke(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox, Inkscape::DrawingPattern *pattern) { if (!stroke_pattern) { switch (stroke.type) { - case PAINT_SERVER: { - //stroke_pattern = sp_paint_server_create_pattern(stroke.server, dc.raw(), paintbox, stroke.opacity); - stroke_pattern = stroke.server->pattern_new(dc.raw(), paintbox, stroke.opacity); - - } break; + case PAINT_SERVER: + if (pattern) { + stroke_pattern = pattern->renderPattern(stroke.opacity); + } else { + stroke_pattern = stroke.server->pattern_new(dc.raw(), paintbox, stroke.opacity); + } + break; case PAINT_COLOR: { SPColor const &c = stroke.color; - stroke_pattern = cairo_pattern_create_rgba( - c.v.c[0], c.v.c[1], c.v.c[2], stroke.opacity); - } break; - default: break; + stroke_pattern = cairo_pattern_create_rgba(c.v.c[0], c.v.c[1], c.v.c[2], + stroke.opacity); + } + break; + default: + break; } } if (!stroke_pattern) return false; @@ -290,13 +396,52 @@ void NRStyle::applyStroke(Inkscape::DrawingContext &dc) cairo_set_dash(dc.raw(), dash, n_dash, dash_offset); // fixme } +bool NRStyle::prepareTextDecorationStroke(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox, Inkscape::DrawingPattern *pattern) +{ + if (!text_decoration_stroke_pattern) { + switch (text_decoration_stroke.type) { + case PAINT_SERVER: + if (pattern) { + text_decoration_stroke_pattern = pattern->renderPattern( + text_decoration_stroke.opacity); + } else { + text_decoration_stroke_pattern = text_decoration_stroke.server->pattern_new( + dc.raw(), paintbox, text_decoration_stroke.opacity); + } + break; + case PAINT_COLOR: { + SPColor const &c = text_decoration_stroke.color; + text_decoration_stroke_pattern = cairo_pattern_create_rgba( + c.v.c[0], c.v.c[1], c.v.c[2], text_decoration_stroke.opacity); + } break; + default: break; + } + } + if (!text_decoration_stroke_pattern) return false; + return true; +} + +void NRStyle::applyTextDecorationStroke(Inkscape::DrawingContext &dc) +{ + dc.setSource(text_decoration_stroke_pattern); + dc.setLineWidth(text_decoration_stroke_width); + dc.setLineCap(CAIRO_LINE_CAP_BUTT); + dc.setLineJoin(CAIRO_LINE_JOIN_MITER); + dc.setMiterLimit(miter_limit); + cairo_set_dash(dc.raw(), 0, 0, 0.0); // fixme (no dash) +} + void NRStyle::update() { // force pattern update if (fill_pattern) cairo_pattern_destroy(fill_pattern); if (stroke_pattern) cairo_pattern_destroy(stroke_pattern); + if (text_decoration_fill_pattern) cairo_pattern_destroy(text_decoration_fill_pattern); + if (text_decoration_stroke_pattern) cairo_pattern_destroy(text_decoration_stroke_pattern); fill_pattern = NULL; stroke_pattern = NULL; + text_decoration_fill_pattern = NULL; + text_decoration_stroke_pattern = NULL; } /* diff --git a/src/display/nr-style.h b/src/display/nr-style.h index 717cda899..f324fdb56 100644 --- a/src/display/nr-style.h +++ b/src/display/nr-style.h @@ -17,10 +17,11 @@ #include "color.h" class SPPaintServer; -struct SPStyle; +class SPStyle; namespace Inkscape { class DrawingContext; +class DrawingPattern; } struct NRStyle { @@ -28,10 +29,14 @@ struct NRStyle { ~NRStyle(); void set(SPStyle *); - bool prepareFill(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox); - bool prepareStroke(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox); + bool prepareFill(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox, Inkscape::DrawingPattern *pattern); + bool prepareStroke(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox, Inkscape::DrawingPattern *pattern); + bool prepareTextDecorationFill(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox, Inkscape::DrawingPattern *pattern); + bool prepareTextDecorationStroke(Inkscape::DrawingContext &dc, Geom::OptRect const &paintbox, Inkscape::DrawingPattern *pattern); void applyFill(Inkscape::DrawingContext &dc); void applyStroke(Inkscape::DrawingContext &dc); + void applyTextDecorationFill(Inkscape::DrawingContext &dc); + void applyTextDecorationStroke(Inkscape::DrawingContext &dc); void update(); enum PaintType { @@ -67,8 +72,9 @@ struct NRStyle { cairo_pattern_t *fill_pattern; cairo_pattern_t *stroke_pattern; + cairo_pattern_t *text_decoration_fill_pattern; + cairo_pattern_t *text_decoration_stroke_pattern; -#ifdef WITH_SVG2 enum PaintOrderType { PAINT_ORDER_NORMAL, PAINT_ORDER_FILL, @@ -78,7 +84,6 @@ struct NRStyle { static const size_t PAINT_ORDER_LAYERS = 3; PaintOrderType paint_order_layer[PAINT_ORDER_LAYERS]; -#endif #define TEXT_DECORATION_LINE_CLEAR 0x00 #define TEXT_DECORATION_LINE_SET 0x01 @@ -99,8 +104,9 @@ struct NRStyle { int text_decoration_line; int text_decoration_style; - Paint text_decoration_color; - bool text_decoration_useColor; // if false, use whatever the glyph color was + Paint text_decoration_fill; + Paint text_decoration_stroke; + float text_decoration_stroke_width; // These are the same as in style.h float phase_length; bool tspan_line_start; diff --git a/src/display/nr-svgfonts.cpp b/src/display/nr-svgfonts.cpp index 84b4bd080..011f51977 100644 --- a/src/display/nr-svgfonts.cpp +++ b/src/display/nr-svgfonts.cpp @@ -4,6 +4,7 @@ * * Authors: * Felipe C. da S. Sanches <juca@members.fsf.org> + * Jon A. Cruz <jon@joncruz.org> * * Copyright (C) 2008 Felipe C. da S. Sanches * @@ -32,9 +33,9 @@ #include "sp-font.h" #include "sp-glyph-kerning.h" -//*************************// +// ************************// // UserFont Implementation // -//*************************// +// ************************// // I wrote this binding code because Cairomm does not yet support userfonts. I have moved this code to cairomm and sent them a patch. // Once Cairomm incorporate the UserFonts binding, this code should be removed from inkscape and Cairomm API should be used. @@ -111,16 +112,38 @@ unsigned int size_of_substring(const char* substring, gchar* str){ return 0; } -//TODO: in these macros, verify what happens when using unicode strings. -#define Match_VKerning_Rule ((SP_VKERN(node))->u1->contains(previous_unicode[0])\ - || (SP_VKERN(node))->g1->contains(previous_glyph_name)) &&\ - ((SP_VKERN(node))->u2->contains(this->glyphs[i]->unicode[0])\ - || (SP_VKERN(node))->g2->contains(this->glyphs[i]->glyph_name.c_str())) -#define Match_HKerning_Rule ((SP_HKERN(node))->u1->contains(previous_unicode[0])\ - || (SP_HKERN(node))->g1->contains(previous_glyph_name)) &&\ - ((SP_HKERN(node))->u2->contains(this->glyphs[i]->unicode[0])\ - || (SP_HKERN(node))->g2->contains(this->glyphs[i]->glyph_name.c_str())) +namespace { + +//TODO: in these functions, verify what happens when using unicode strings. + +bool MatchVKerningRule(SPVkern const *vkern, + SPGlyph *glyph, + char const *previous_unicode, + gchar const *previous_glyph_name) +{ + bool value = (vkern->u1->contains(previous_unicode[0]) + || vkern->g1->contains(previous_glyph_name)) + && (vkern->u2->contains(glyph->unicode[0]) + || vkern->g2->contains(glyph->glyph_name.c_str())); + + return value; +} + +bool MatchHKerningRule(SPHkern const *hkern, + SPGlyph *glyph, + char const *previous_unicode, + gchar const *previous_glyph_name) +{ + bool value = (hkern->u1->contains(previous_unicode[0]) + || hkern->g1->contains(previous_glyph_name)) + && (hkern->u2->contains(glyph->unicode[0]) + || hkern->g2->contains(glyph->glyph_name.c_str())); + + return value; +} + +} // namespace cairo_status_t SvgFont::scaled_font_text_to_glyphs (cairo_scaled_font_t */*scaled_font*/, @@ -182,11 +205,13 @@ SvgFont::scaled_font_text_to_glyphs (cairo_scaled_font_t */*scaled_font*/, if ( (len = size_of_substring(this->glyphs[i]->unicode.c_str(), _utf8)) ){ for(SPObject* node = this->font->children;previous_unicode && node;node=node->next){ //apply glyph kerning if appropriate - if (SP_IS_HKERN(node) && is_horizontal_text && Match_HKerning_Rule ){ - x -= ((SP_HKERN(node))->k / 1000.0);//TODO: use here the height of the font + SPHkern *hkern = dynamic_cast<SPHkern *>(node); + if (hkern && is_horizontal_text && MatchHKerningRule(hkern, this->glyphs[i], previous_unicode, previous_glyph_name) ){ + x -= (hkern->k / 1000.0);//TODO: use here the height of the font } - if (SP_IS_VKERN(node) && !is_horizontal_text && Match_VKerning_Rule ){ - y -= ((SP_VKERN(node))->k / 1000.0);//TODO: use here the "height" of the font + SPVkern *vkern = dynamic_cast<SPVkern *>(node); + if (vkern && !is_horizontal_text && MatchVKerningRule(vkern, this->glyphs[i], previous_unicode, previous_glyph_name) ){ + y -= (vkern->k / 1000.0);//TODO: use here the "height" of the font } } previous_unicode = const_cast<char*>(this->glyphs[i]->unicode.c_str());//used for kerning checking @@ -246,9 +271,8 @@ SvgFont::glyph_modified(SPObject* /* blah */, unsigned int /* bleh */){ Geom::PathVector SvgFont::flip_coordinate_system(SPFont* spfont, Geom::PathVector pathv){ double units_per_em = 1000; - SPObject* obj; - for (obj = (SP_OBJECT(spfont))->children; obj; obj=obj->next){ - if (SP_IS_FONTFACE(obj)){ + for (SPObject *obj = spfont->children; obj; obj = obj->next){ + if (dynamic_cast<SPFontFace *>(obj)) { //XML Tree being directly used here while it shouldn't be. sp_repr_get_double(obj->getRepr(), "units_per_em", &units_per_em); } @@ -275,19 +299,21 @@ SvgFont::scaled_font_render_glyph (cairo_scaled_font_t */*scaled_font*/, if (glyph > this->glyphs.size()) return CAIRO_STATUS_SUCCESS;//TODO: this is an error! - SPObject* node; - if (glyph == this->glyphs.size()){ - if (!this->missingglyph) return CAIRO_STATUS_SUCCESS; - node = SP_OBJECT(this->missingglyph); + SPObject *node = NULL; + if (glyph == glyphs.size()){ + if (!missingglyph) { + return CAIRO_STATUS_SUCCESS; + } + node = missingglyph; } else { - node = SP_OBJECT(this->glyphs[glyph]); + node = glyphs[glyph]; } - if (!SP_IS_GLYPH(node) && !SP_IS_MISSING_GLYPH(node)) { + if (!dynamic_cast<SPGlyph *>(node) && !dynamic_cast<SPMissingGlyph *>(node)) { return CAIRO_STATUS_SUCCESS; // FIXME: is this the right code to return? } - SPFont* spfont = SP_FONT(node->parent); + SPFont* spfont = dynamic_cast<SPFont *>(node->parent); if (!spfont) { return CAIRO_STATUS_SUCCESS; // FIXME: is this the right code to return? } @@ -296,36 +322,48 @@ SvgFont::scaled_font_render_glyph (cairo_scaled_font_t */*scaled_font*/, // or using the d attribute of a glyph node. // pathv stores the path description from the d attribute: Geom::PathVector pathv; - if (SP_IS_GLYPH(node) && (SP_GLYPH(node))->d) { - pathv = sp_svg_read_pathv((SP_GLYPH(node))->d); - pathv = flip_coordinate_system(spfont, pathv); - this->render_glyph_path(cr, &pathv); - } else if (SP_IS_MISSING_GLYPH(node) && (SP_MISSING_GLYPH(node))->d) { - pathv = sp_svg_read_pathv((SP_MISSING_GLYPH(node))->d); + + SPGlyph *glyphNode = dynamic_cast<SPGlyph *>(node); + if (glyphNode && glyphNode->d) { + pathv = sp_svg_read_pathv(glyphNode->d); pathv = flip_coordinate_system(spfont, pathv); - this->render_glyph_path(cr, &pathv); + render_glyph_path(cr, &pathv); + } else { + SPMissingGlyph *missing = dynamic_cast<SPMissingGlyph *>(node); + if (missing && missing->d) { + pathv = sp_svg_read_pathv(missing->d); + pathv = flip_coordinate_system(spfont, pathv); + render_glyph_path(cr, &pathv); + } } if (node->hasChildren()){ //render the SVG described on this glyph's child nodes. for(node = node->children; node; node=node->next){ - if (SP_IS_PATH(node)){ - pathv = (SP_SHAPE(node))->_curve->get_pathvector(); - pathv = flip_coordinate_system(spfont, pathv); - this->render_glyph_path(cr, &pathv); + { + SPPath *path = dynamic_cast<SPPath *>(node); + if (path) { + pathv = path->_curve->get_pathvector(); + pathv = flip_coordinate_system(spfont, pathv); + render_glyph_path(cr, &pathv); + } } - if (SP_IS_OBJECTGROUP(node)){ + if (dynamic_cast<SPObjectGroup *>(node)) { g_warning("TODO: svgfonts: render OBJECTGROUP"); } - if (SP_IS_USE(node)){ - SPItem* item = SP_USE(node)->ref->getObject(); - if (SP_IS_PATH(item)){ - pathv = (SP_SHAPE(item))->_curve->get_pathvector(); + SPUse *use = dynamic_cast<SPUse *>(node); + if (use) { + SPItem* item = use->ref->getObject(); + SPPath *path = dynamic_cast<SPPath *>(item); + if (path) { + SPShape *shape = dynamic_cast<SPShape *>(item); + g_assert(shape != NULL); + pathv = shape->_curve->get_pathvector(); pathv = flip_coordinate_system(spfont, pathv); this->render_glyph_path(cr, &pathv); } - glyph_modified_connection = (SP_OBJECT(item))->connectModified(sigc::mem_fun(*this, &SvgFont::glyph_modified)); + glyph_modified_connection = item->connectModified(sigc::mem_fun(*this, &SvgFont::glyph_modified)); } } } @@ -337,11 +375,13 @@ cairo_font_face_t* SvgFont::get_font_face(){ if (!this->userfont) { for(SPObject* node = this->font->children;node;node=node->next){ - if (SP_IS_GLYPH(node)){ - this->glyphs.push_back(SP_GLYPH(node)); + SPGlyph *glyph = dynamic_cast<SPGlyph *>(node); + if (glyph) { + glyphs.push_back(glyph); } - if (SP_IS_MISSING_GLYPH(node)){ - this->missingglyph=SP_MISSING_GLYPH(node); + SPMissingGlyph *missing = dynamic_cast<SPMissingGlyph *>(node); + if (missing) { + missingglyph = missing; } } this->userfont = new UserFont(this); diff --git a/src/display/nr-svgfonts.h b/src/display/nr-svgfonts.h index e1bb047bb..21ab3ed02 100644 --- a/src/display/nr-svgfonts.h +++ b/src/display/nr-svgfonts.h @@ -1,4 +1,3 @@ -#include "config.h" #ifndef NR_SVGFONTS_H_SEEN #define NR_SVGFONTS_H_SEEN /* @@ -13,7 +12,7 @@ * Read the file 'COPYING' for more information. */ -#include "cairo.h" +#include <cairo.h> #include <sigc++/connection.h> class SvgFont; @@ -21,40 +20,50 @@ class SPFont; class SPGlyph; class SPMissingGlyph; -struct _GdkEventExpose; -typedef _GdkEventExpose GdkEventExpose; +extern "C" { typedef struct _GdkEventExpose GdkEventExpose; } namespace Gtk { class Widget; } -class UserFont{ +class UserFont { public: -UserFont(SvgFont* instance); -cairo_font_face_t* face; + UserFont(SvgFont* instance); + cairo_font_face_t* face; }; -class SvgFont{ +class SvgFont { public: -SvgFont(SPFont* spfont); -void refresh(); -cairo_font_face_t* get_font_face(); -cairo_status_t scaled_font_init (cairo_scaled_font_t *scaled_font, cairo_font_extents_t *metrics); -cairo_status_t scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font, const char *utf8, int utf8_len, cairo_glyph_t **glyphs, int *num_glyphs, cairo_text_cluster_t **clusters, int *num_clusters, cairo_text_cluster_flags_t *flags); -cairo_status_t scaled_font_render_glyph (cairo_scaled_font_t *scaled_font, unsigned long glyph, cairo_t *cr, cairo_text_extents_t *metrics); + SvgFont(SPFont* spfont); + void refresh(); + cairo_font_face_t* get_font_face(); + cairo_status_t scaled_font_init (cairo_scaled_font_t *scaled_font, cairo_font_extents_t *metrics); + cairo_status_t scaled_font_text_to_glyphs (cairo_scaled_font_t *scaled_font, const char *utf8, int utf8_len, cairo_glyph_t **glyphs, int *num_glyphs, cairo_text_cluster_t **clusters, int *num_clusters, cairo_text_cluster_flags_t *flags); + cairo_status_t scaled_font_render_glyph (cairo_scaled_font_t *scaled_font, unsigned long glyph, cairo_t *cr, cairo_text_extents_t *metrics); -Geom::PathVector flip_coordinate_system(SPFont* spfont, Geom::PathVector pathv); -void render_glyph_path(cairo_t* cr, Geom::PathVector* pathv); -void glyph_modified(SPObject *, unsigned int); + Geom::PathVector flip_coordinate_system(SPFont* spfont, Geom::PathVector pathv); + void render_glyph_path(cairo_t* cr, Geom::PathVector* pathv); + void glyph_modified(SPObject *, unsigned int); private: -SPFont* font; -UserFont* userfont; -std::vector<SPGlyph*> glyphs; -SPMissingGlyph* missingglyph; -sigc::connection glyph_modified_connection; + SPFont* font; + UserFont* userfont; + std::vector<SPGlyph*> glyphs; + SPMissingGlyph* missingglyph; + sigc::connection glyph_modified_connection; -bool drawing_expose_cb (Gtk::Widget *widget, GdkEventExpose *event, gpointer data); + bool drawing_expose_cb (Gtk::Widget *widget, GdkEventExpose *event, void* data); }; #endif //#ifndef NR_SVGFONTS_H_SEEN + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8 : diff --git a/src/display/snap-indicator.cpp b/src/display/snap-indicator.cpp index 627bfb2ab..2632d69db 100644 --- a/src/display/snap-indicator.cpp +++ b/src/display/snap-indicator.cpp @@ -22,7 +22,7 @@ #include "knot.h" #include "preferences.h" #include <glibmm/i18n.h> -#include "tools-switch.h" +#include "ui/tools-switch.h" #include "enums.h" namespace Inkscape { @@ -73,6 +73,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap switch (p.getTarget()) { case SNAPTARGET_UNDEFINED: target_name = _("UNDEFINED"); + g_warning("Snap target has not been specified"); break; case SNAPTARGET_GRID: target_name = _("grid line"); @@ -172,7 +173,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap target_name = _("constraint"); break; default: - g_warning("Snap target has not yet been defined!"); + g_warning("Snap target not in SnapTargetType enum"); break; } @@ -180,6 +181,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap switch (p.getSource()) { case SNAPSOURCE_UNDEFINED: source_name = _("UNDEFINED"); + g_warning("Snap source has not been specified"); break; case SNAPSOURCE_BBOX_CORNER: source_name = _("Bounding box corner"); @@ -235,7 +237,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap source_name = _("Multiple of grid spacing"); break; default: - g_warning("Snap source has not yet been defined!"); + g_warning("Snap source not in SnapSourceType enum"); break; } //std::cout << "Snapped " << source_name << " to " << target_name << std::endl; diff --git a/src/display/sodipodi-ctrl.cpp b/src/display/sodipodi-ctrl.cpp index 3636319df..327fbce1f 100644 --- a/src/display/sodipodi-ctrl.cpp +++ b/src/display/sodipodi-ctrl.cpp @@ -25,9 +25,6 @@ enum { ARG_PIXBUF }; - -static void sp_ctrl_class_init (SPCtrlClass *klass); -static void sp_ctrl_init (SPCtrl *ctrl); static void sp_ctrl_destroy(SPCanvasItem *object); static void sp_ctrl_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); static void sp_ctrl_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); @@ -36,29 +33,7 @@ static void sp_ctrl_render (SPCanvasItem *item, SPCanvasBuf *buf); static double sp_ctrl_point (SPCanvasItem *item, Geom::Point p, SPCanvasItem **actual_item); -static SPCanvasItemClass *parent_class; - -GType -sp_ctrl_get_type (void) -{ - static GType ctrl_type = 0; - if (!ctrl_type) { - static GTypeInfo const ctrl_info = { - sizeof (SPCtrlClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) sp_ctrl_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (SPCtrl), - 0, /* n_preallocs */ - (GInstanceInitFunc) sp_ctrl_init, - NULL - }; - ctrl_type = g_type_register_static (SP_TYPE_CANVAS_ITEM, "SPCtrl", &ctrl_info, (GTypeFlags)0); - } - return ctrl_type; -} +G_DEFINE_TYPE(SPCtrl, sp_ctrl, SP_TYPE_CANVAS_ITEM); static void sp_ctrl_class_init (SPCtrlClass *klass) @@ -66,8 +41,6 @@ sp_ctrl_class_init (SPCtrlClass *klass) SPCanvasItemClass *item_class = SP_CANVAS_ITEM_CLASS(klass); GObjectClass *g_object_class = (GObjectClass *) klass; - parent_class = SP_CANVAS_ITEM_CLASS(g_type_class_peek_parent (klass)); - g_object_class->set_property = sp_ctrl_set_property; g_object_class->get_property = sp_ctrl_get_property; @@ -239,8 +212,8 @@ static void sp_ctrl_destroy(SPCanvasItem *object) ctrl->cache = NULL; } - if (SP_CANVAS_ITEM_CLASS(parent_class)->destroy) - (* SP_CANVAS_ITEM_CLASS(parent_class)->destroy) (object); + if (SP_CANVAS_ITEM_CLASS(sp_ctrl_parent_class)->destroy) + SP_CANVAS_ITEM_CLASS(sp_ctrl_parent_class)->destroy(object); } static void @@ -251,8 +224,8 @@ sp_ctrl_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int fla ctrl = SP_CTRL (item); - if ((SP_CANVAS_ITEM_CLASS(parent_class))->update) - (* (SP_CANVAS_ITEM_CLASS(parent_class))->update) (item, affine, flags); + if (SP_CANVAS_ITEM_CLASS(sp_ctrl_parent_class)->update) + SP_CANVAS_ITEM_CLASS(sp_ctrl_parent_class)->update(item, affine, flags); sp_canvas_item_reset_bounds (item); diff --git a/src/display/sodipodi-ctrlrect.cpp b/src/display/sodipodi-ctrlrect.cpp index e6e427047..75789ff50 100644 --- a/src/display/sodipodi-ctrlrect.cpp +++ b/src/display/sodipodi-ctrlrect.cpp @@ -26,45 +26,19 @@ * Corner coords can be in any order - i.e. x1 < x0 is allowed */ -static void sp_ctrlrect_class_init(SPCtrlRectClass *c); -static void sp_ctrlrect_init(CtrlRect *ctrlrect); static void sp_ctrlrect_destroy(SPCanvasItem *object); static void sp_ctrlrect_update(SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); static void sp_ctrlrect_render(SPCanvasItem *item, SPCanvasBuf *buf); -static SPCanvasItemClass *parent_class; - static const guint DASH_LENGTH = 4; -GType sp_ctrlrect_get_type() -{ - static GType type = 0; - - if (!type) { - GTypeInfo info = { - sizeof(SPCtrlRectClass), - 0, // base_init - 0, // base_finalize - (GClassInitFunc)sp_ctrlrect_class_init, - 0, // class_finalize - 0, // class_data - sizeof(CtrlRect), - 0, // n_preallocs - (GInstanceInitFunc)sp_ctrlrect_init, - 0 // value_table - }; - type = g_type_register_static(SP_TYPE_CANVAS_ITEM, "SPCtrlRect", &info, static_cast<GTypeFlags>(0)); - } - return type; -} +G_DEFINE_TYPE(CtrlRect, sp_ctrlrect, SP_TYPE_CANVAS_ITEM); -static void sp_ctrlrect_class_init(SPCtrlRectClass *c) +static void sp_ctrlrect_class_init(CtrlRectClass *c) { SPCanvasItemClass *item_class = SP_CANVAS_ITEM_CLASS(c); - parent_class = SP_CANVAS_ITEM_CLASS(g_type_class_peek_parent(c)); - item_class->destroy = sp_ctrlrect_destroy; item_class->update = sp_ctrlrect_update; item_class->render = sp_ctrlrect_render; @@ -77,8 +51,8 @@ static void sp_ctrlrect_init(CtrlRect *cr) static void sp_ctrlrect_destroy(SPCanvasItem *object) { - if (SP_CANVAS_ITEM_CLASS(parent_class)->destroy) { - (* SP_CANVAS_ITEM_CLASS(parent_class)->destroy)(object); + if (SP_CANVAS_ITEM_CLASS(sp_ctrlrect_parent_class)->destroy) { + (* SP_CANVAS_ITEM_CLASS(sp_ctrlrect_parent_class)->destroy)(object); } } @@ -171,8 +145,8 @@ void CtrlRect::update(Geom::Affine const &affine, unsigned int flags) using Geom::X; using Geom::Y; - if ((SP_CANVAS_ITEM_CLASS(parent_class))->update) { - (SP_CANVAS_ITEM_CLASS(parent_class))->update(this, affine, flags); + if ((SP_CANVAS_ITEM_CLASS(sp_ctrlrect_parent_class))->update) { + (SP_CANVAS_ITEM_CLASS(sp_ctrlrect_parent_class))->update(this, affine, flags); } sp_canvas_item_reset_bounds(this); diff --git a/src/display/sodipodi-ctrlrect.h b/src/display/sodipodi-ctrlrect.h index 65a40a850..ff6c55b06 100644 --- a/src/display/sodipodi-ctrlrect.h +++ b/src/display/sodipodi-ctrlrect.h @@ -26,7 +26,7 @@ struct SPCanvasBuf; #define SP_TYPE_CTRLRECT (sp_ctrlrect_get_type ()) #define SP_CTRLRECT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_CTRLRECT, CtrlRect)) -#define SP_CTRLRECT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST((c), SP_TYPE_CTRLRECT, SPCtrlRectClass)) +#define SP_CTRLRECT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST((c), SP_TYPE_CTRLRECT, CtrlRectClass)) #define SP_IS_CTRLRECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_CTRLRECT)) #define SP_IS_CTRLRECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_CTRLRECT)) @@ -57,7 +57,7 @@ private: int _shadow; }; -struct SPCtrlRectClass : public SPCanvasItemClass {}; +struct CtrlRectClass : public SPCanvasItemClass {}; GType sp_ctrlrect_get_type(); diff --git a/src/display/sp-canvas-item.h b/src/display/sp-canvas-item.h index f34ec453c..3b7b7bd4f 100644 --- a/src/display/sp-canvas-item.h +++ b/src/display/sp-canvas-item.h @@ -23,10 +23,9 @@ # include "config.h" #endif -#include <glib-object.h> -#include <gtk/gtk.h> -#include <gdk/gdk.h> #include <2geom/rect.h> +#include <glib-object.h> + #include "ui/control-types.h" G_BEGIN_DECLS @@ -36,8 +35,10 @@ struct SPCanvasBuf; struct SPCanvasGroup; typedef struct _SPCanvasItemClass SPCanvasItemClass; +typedef union _GdkEvent GdkEvent; +typedef struct _GdkCursor GdkCursor; -#define SP_TYPE_CANVAS_ITEM (SPCanvasItem::getType()) +#define SP_TYPE_CANVAS_ITEM (sp_canvas_item_get_type()) #define SP_CANVAS_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SP_TYPE_CANVAS_ITEM, SPCanvasItem)) #define SP_CANVAS_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SP_TYPE_CANVAS_ITEM, SPCanvasItemClass)) #define SP_IS_CANVAS_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), SP_TYPE_CANVAS_ITEM)) @@ -50,7 +51,6 @@ typedef struct _SPCanvasItemClass SPCanvasItemClass; */ struct SPCanvasItem { GInitiallyUnowned parent_instance; - static GType getType(); SPCanvas *canvas; SPCanvasItem *parent; @@ -73,6 +73,8 @@ struct SPCanvasItem { bool in_destruction; }; +GType sp_canvas_item_get_type(); + /** * The vtable of an SPCanvasItem. */ diff --git a/src/display/sp-canvas-util.h b/src/display/sp-canvas-util.h index 07323f31a..73135ed79 100644 --- a/src/display/sp-canvas-util.h +++ b/src/display/sp-canvas-util.h @@ -1,5 +1,5 @@ -#ifndef __SP_CANVAS_UTILS_H__ -#define __SP_CANVAS_UTILS_H__ +#ifndef SEEN_SP_CANVAS_UTILS_H +#define SEEN_SP_CANVAS_UTILS_H /* * Helper stuff for SPCanvas @@ -19,7 +19,7 @@ struct SPCanvasItem; struct SPCanvasBuf; namespace Geom { - class Affine; + class Affine; } /* Miscellaneous utility & convenience functions for general canvas objects */ diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp index 6d903867b..305b0950a 100644 --- a/src/display/sp-canvas.cpp +++ b/src/display/sp-canvas.cpp @@ -61,8 +61,6 @@ struct SPCanvasGroupClass { * A group of Items. */ struct SPCanvasGroup { - static GType getType(); - /** * Adds an item to a canvas group. */ @@ -113,17 +111,8 @@ struct SPCanvasGroup { GList *items; GList *last; - - static SPCanvasItemClass *parentClass; }; -SPCanvasItemClass *SPCanvasGroup::parentClass; - -GType sp_canvas_group_get_type() -{ - return SPCanvasGroup::getType(); -} - /** * The SPCanvas vtable. */ @@ -161,19 +150,6 @@ enum { LAST_SIGNAL }; -void sp_canvas_item_base_class_init(SPCanvasItemClass *klass); -void sp_canvas_item_base_class_finalize(SPCanvasItemClass *klass); - -/** - * Initializes the SPCanvasItem vtable and the "event" signal. - */ -void sp_canvas_item_class_init(SPCanvasItemClass *klass); - -/** - * Callback for initialization of SPCanvasItem. - */ -void sp_canvas_item_init(SPCanvasItem *item, SPCanvasItemClass *klass); - /** * Callback that removes item from all referers and destroys it. */ @@ -181,7 +157,6 @@ void sp_canvas_item_dispose(GObject *object); void sp_canvas_item_finalize(GObject *object); void sp_canvas_item_real_destroy(SPCanvasItem *object); -static gpointer parent_class = NULL; static guint object_signals[LAST_SIGNAL] = { 0 }; /** @@ -358,45 +333,12 @@ public: static void requestCanvasUpdate(SPCanvas *canvas); }; -GType SPCanvasItem::getType() -{ - static GType object_type = 0; - - if (!object_type) { - static GTypeInfo const object_info = { - sizeof(SPCanvasItemClass), - reinterpret_cast<GBaseInitFunc>(sp_canvas_item_base_class_init), - reinterpret_cast<GBaseFinalizeFunc>(sp_canvas_item_base_class_finalize), - reinterpret_cast<GClassInitFunc>(sp_canvas_item_class_init), - NULL, // class_finalize - NULL, // class_data - sizeof(SPCanvasItem), - 16, // n_preallocs - reinterpret_cast<GInstanceInitFunc>(sp_canvas_item_init), - NULL // value_table - }; +G_DEFINE_TYPE(SPCanvasItem, sp_canvas_item, G_TYPE_INITIALLY_UNOWNED); - object_type = g_type_register_static(G_TYPE_INITIALLY_UNOWNED, - "SPCanvasItem", &object_info, GTypeFlags(0)); - } - - return object_type; -} - -namespace { - -void sp_canvas_item_base_class_init(SPCanvasItemClass * /*klass*/) -{ -} - -void sp_canvas_item_base_class_finalize(SPCanvasItemClass * /*klass*/) -{ -} - -void sp_canvas_item_class_init(SPCanvasItemClass *klass) +static void +sp_canvas_item_class_init(SPCanvasItemClass *klass) { GObjectClass *gobject_class = (GObjectClass *) klass; - parent_class = g_type_class_ref (G_TYPE_OBJECT); item_signals[ITEM_EVENT] = g_signal_new ("event", G_TYPE_FROM_CLASS (klass), @@ -421,7 +363,8 @@ void sp_canvas_item_class_init(SPCanvasItemClass *klass) G_TYPE_NONE, 0); } -void sp_canvas_item_init(SPCanvasItem *item, SPCanvasItemClass * /*klass*/) +static void +sp_canvas_item_init(SPCanvasItem *item) { item->xform = Geom::Affine(Geom::identity()); item->ctrlType = Inkscape::CTRL_TYPE_UNKNOWN; @@ -434,15 +377,13 @@ void sp_canvas_item_init(SPCanvasItem *item, SPCanvasItemClass * /*klass*/) item->in_destruction = false; } -} // namespace - SPCanvasItem *sp_canvas_item_new(SPCanvasGroup *parent, GType type, gchar const *first_arg_name, ...) { va_list args; g_return_val_if_fail(parent != NULL, NULL); g_return_val_if_fail(SP_IS_CANVAS_GROUP(parent), NULL); - g_return_val_if_fail(g_type_is_a(type, SPCanvasItem::getType()), NULL); + g_return_val_if_fail(g_type_is_a(type, SP_TYPE_CANVAS_ITEM), NULL); SPCanvasItem *item = SP_CANVAS_ITEM(g_object_new(type, NULL)); @@ -554,7 +495,7 @@ void sp_canvas_item_dispose(GObject *object) item->in_destruction = false; } - G_OBJECT_CLASS(parent_class)->dispose(object); + G_OBJECT_CLASS(sp_canvas_item_parent_class)->dispose(object); } void sp_canvas_item_real_destroy(SPCanvasItem *object) @@ -574,7 +515,7 @@ void sp_canvas_item_finalize(GObject *gobject) "and must be removed with g_object_ref_sink()."); } - G_OBJECT_CLASS (parent_class)->finalize (gobject); + G_OBJECT_CLASS (sp_canvas_item_parent_class)->finalize (gobject); } } // namespace @@ -982,37 +923,12 @@ gint sp_canvas_item_order (SPCanvasItem * item) } // SPCanvasGroup +G_DEFINE_TYPE(SPCanvasGroup, sp_canvas_group, SP_TYPE_CANVAS_ITEM); -/** - * Registers SPCanvasGroup class with Gtk and returns its type number. - */ -GType SPCanvasGroup::getType(void) -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof(SPCanvasGroupClass), - 0, // base_init - 0, // base_finalize - reinterpret_cast<GClassInitFunc>(SPCanvasGroup::classInit), - 0, // class_finalize - 0, // class_data - sizeof(SPCanvasGroup), - 0, // n_preallocs - reinterpret_cast<GInstanceInitFunc>(SPCanvasGroup::init), - 0 // value_table - }; - type = g_type_register_static(SPCanvasItem::getType(), "SPCanvasGroup", &info, static_cast<GTypeFlags>(0)); - } - return type; -} - -void SPCanvasGroup::classInit(SPCanvasGroupClass *klass) +static void sp_canvas_group_class_init(SPCanvasGroupClass *klass) { SPCanvasItemClass *item_class = reinterpret_cast<SPCanvasItemClass *>(klass); - parentClass = reinterpret_cast<SPCanvasItemClass*>(g_type_class_peek_parent(klass)); - item_class->destroy = SPCanvasGroup::destroy; item_class->update = SPCanvasGroup::update; item_class->render = SPCanvasGroup::render; @@ -1020,7 +936,7 @@ void SPCanvasGroup::classInit(SPCanvasGroupClass *klass) item_class->viewbox_changed = SPCanvasGroup::viewboxChanged; } -void SPCanvasGroup::init(SPCanvasGroup * /*group*/) +static void sp_canvas_group_init(SPCanvasGroup * /*group*/) { // Nothing here } @@ -1040,8 +956,8 @@ void SPCanvasGroup::destroy(SPCanvasItem *object) sp_canvas_item_destroy(child); } - if (SP_CANVAS_ITEM_CLASS(parentClass)->destroy) { - (* SP_CANVAS_ITEM_CLASS(parentClass)->destroy)(object); + if (SP_CANVAS_ITEM_CLASS(sp_canvas_group_parent_class)->destroy) { + (* SP_CANVAS_ITEM_CLASS(sp_canvas_group_parent_class)->destroy)(object); } } @@ -1238,7 +1154,7 @@ sp_canvas_init(SPCanvas *canvas) canvas->pick_event.crossing.y = 0; // Create the root item as a special case - canvas->root = SP_CANVAS_ITEM(g_object_new(SPCanvasGroup::getType(), NULL)); + canvas->root = SP_CANVAS_ITEM(g_object_new(SP_TYPE_CANVAS_GROUP, NULL)); canvas->root->canvas = canvas; g_object_ref (canvas->root); @@ -2153,6 +2069,8 @@ gboolean SPCanvasImpl::handleDraw(GtkWidget *widget, cairo_t *cr) { canvas->requestRedraw(r.left(), r.top(), r.right(), r.bottom()); } + cairo_rectangle_list_destroy(rects); + return FALSE; } #else diff --git a/src/display/sp-canvas.h b/src/display/sp-canvas.h index 72ae4b6bc..48c3de2fc 100644 --- a/src/display/sp-canvas.h +++ b/src/display/sp-canvas.h @@ -22,16 +22,6 @@ # include "config.h" #endif -#ifdef HAVE_INTTYPES_H -# include <inttypes.h> -#else -# ifdef HAVE_STDINT_H -# include <stdint.h> -# endif -#endif - -#include <glib.h> -#include <gdk/gdk.h> #include <gtk/gtk.h> #include <glibmm/ustring.h> #include <2geom/affine.h> diff --git a/src/display/sp-ctrlcurve.cpp b/src/display/sp-ctrlcurve.cpp index d9b687f2e..2e0e8105b 100644 --- a/src/display/sp-ctrlcurve.cpp +++ b/src/display/sp-ctrlcurve.cpp @@ -23,42 +23,18 @@ namespace { -static void sp_ctrlcurve_class_init(SPCtrlCurveClass *klass, gpointer data); -static void sp_ctrlcurve_init(SPCtrlCurve *ctrlcurve, gpointer g_class); static void sp_ctrlcurve_destroy(SPCanvasItem *object); static void sp_ctrlcurve_update(SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); static void sp_ctrlcurve_render(SPCanvasItem *item, SPCanvasBuf *buf); -static SPCanvasItemClass *parent_class; - } // namespace -GType SPCtrlCurve::getType() -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof(SPCtrlCurveClass), - NULL, NULL, - reinterpret_cast<GClassInitFunc>(sp_ctrlcurve_class_init), - NULL, NULL, - sizeof(SPCtrlCurve), - 0, - reinterpret_cast<GInstanceInitFunc>(sp_ctrlcurve_init), - NULL - }; - type = g_type_register_static(SP_TYPE_CANVAS_ITEM, "SPCtrlCurve", &info, static_cast<GTypeFlags>(0)); - } - return type; -} +G_DEFINE_TYPE(SPCtrlCurve, sp_ctrlcurve, SP_TYPE_CANVAS_ITEM); -namespace { - -void sp_ctrlcurve_class_init(SPCtrlCurveClass *klass, gpointer /*g_class*/) +static void +sp_ctrlcurve_class_init(SPCtrlCurveClass *klass) { - parent_class = reinterpret_cast<SPCanvasItemClass*>(g_type_class_peek_parent(klass)); - klass->destroy = sp_ctrlcurve_destroy; klass->update = sp_ctrlcurve_update; @@ -66,13 +42,14 @@ void sp_ctrlcurve_class_init(SPCtrlCurveClass *klass, gpointer /*g_class*/) } static void -sp_ctrlcurve_init(SPCtrlCurve *ctrlcurve, gpointer /*g_class*/) +sp_ctrlcurve_init(SPCtrlCurve *ctrlcurve) { // Points are initialized to 0,0 ctrlcurve->rgba = 0x0000ff7f; ctrlcurve->item=NULL; } +namespace { static void sp_ctrlcurve_destroy(SPCanvasItem *object) { @@ -83,8 +60,8 @@ sp_ctrlcurve_destroy(SPCanvasItem *object) ctrlcurve->item=NULL; - if (SP_CANVAS_ITEM_CLASS (parent_class)->destroy) - (* SP_CANVAS_ITEM_CLASS (parent_class)->destroy) (object); + if (SP_CANVAS_ITEM_CLASS(sp_ctrlcurve_parent_class)->destroy) + SP_CANVAS_ITEM_CLASS(sp_ctrlcurve_parent_class)->destroy(object); } static void @@ -125,8 +102,8 @@ sp_ctrlcurve_update(SPCanvasItem *item, Geom::Affine const &affine, unsigned int item->canvas->requestRedraw(item->x1, item->y1, item->x2, item->y2); - if (parent_class->update) - (* parent_class->update) (item, affine, flags); + if (SP_CANVAS_ITEM_CLASS(sp_ctrlcurve_parent_class)->update) + SP_CANVAS_ITEM_CLASS(sp_ctrlcurve_parent_class)->update(item, affine, flags); sp_canvas_item_reset_bounds (item); diff --git a/src/display/sp-ctrlcurve.h b/src/display/sp-ctrlcurve.h index 90936185c..847944f38 100644 --- a/src/display/sp-ctrlcurve.h +++ b/src/display/sp-ctrlcurve.h @@ -19,14 +19,11 @@ class SPItem; -#define SP_TYPE_CTRLCURVE (SPCtrlCurve::getType()) +#define SP_TYPE_CTRLCURVE (sp_ctrlcurve_get_type()) #define SP_CTRLCURVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_CTRLCURVE, SPCtrlCurve)) #define SP_IS_CTRLCURVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_CTRLCURVE)) struct SPCtrlCurve : public SPCtrlLine { - - static GType getType(); - void setCoords( gdouble x0, gdouble y0, gdouble x1, gdouble y1, gdouble x2, gdouble y2, gdouble x3, gdouble y3 ); @@ -36,9 +33,9 @@ struct SPCtrlCurve : public SPCtrlLine { Geom::Point p0, p1, p2, p3; }; -struct SPCtrlCurveClass : public SPCtrlLineClass{}; - +GType sp_ctrlcurve_get_type(); +struct SPCtrlCurveClass : public SPCtrlLineClass{}; #endif // SEEN_INKSCAPE_CTRLCURVE_H diff --git a/src/display/sp-ctrlline.cpp b/src/display/sp-ctrlline.cpp index aef284c1a..1bde540c0 100644 --- a/src/display/sp-ctrlline.cpp +++ b/src/display/sp-ctrlline.cpp @@ -30,55 +30,31 @@ namespace { -void sp_ctrlline_class_init(SPCtrlLineClass *klass, gpointer data); -void sp_ctrlline_init(SPCtrlLine *ctrlline, gpointer g_class); void sp_ctrlline_destroy(SPCanvasItem *object); void sp_ctrlline_update(SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); void sp_ctrlline_render(SPCanvasItem *item, SPCanvasBuf *buf); -SPCanvasItemClass *parent_class = 0; - } // namespace -GType SPCtrlLine::getType() -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof(SPCtrlLineClass), - NULL, NULL, - reinterpret_cast<GClassInitFunc>(sp_ctrlline_class_init), - NULL, NULL, - sizeof(SPCtrlLine), - 0, - reinterpret_cast<GInstanceInitFunc>(sp_ctrlline_init), - NULL - }; - type = g_type_register_static(SP_TYPE_CANVAS_ITEM, "SPCtrlLine", &info, static_cast<GTypeFlags>(0)); - } - return type; -} - -namespace { +G_DEFINE_TYPE(SPCtrlLine, sp_ctrlline, SP_TYPE_CANVAS_ITEM); -void sp_ctrlline_class_init(SPCtrlLineClass *klass, gpointer /*data*/) +static void sp_ctrlline_class_init(SPCtrlLineClass *klass) { - parent_class = reinterpret_cast<SPCanvasItemClass*>(g_type_class_peek_parent(klass)); - klass->destroy = sp_ctrlline_destroy; klass->update = sp_ctrlline_update; klass->render = sp_ctrlline_render; } -void sp_ctrlline_init(SPCtrlLine *ctrlline, gpointer /*g_class*/) +static void sp_ctrlline_init(SPCtrlLine *ctrlline) { ctrlline->rgba = 0x0000ff7f; ctrlline->s[Geom::X] = ctrlline->s[Geom::Y] = ctrlline->e[Geom::X] = ctrlline->e[Geom::Y] = 0.0; ctrlline->item=NULL; } +namespace { void sp_ctrlline_destroy(SPCanvasItem *object) { g_return_if_fail(object != NULL); @@ -88,8 +64,8 @@ void sp_ctrlline_destroy(SPCanvasItem *object) ctrlline->item = NULL; - if(SP_CANVAS_ITEM_CLASS (parent_class)->destroy) { - (* SP_CANVAS_ITEM_CLASS (parent_class)->destroy)(object); + if(SP_CANVAS_ITEM_CLASS (sp_ctrlline_parent_class)->destroy) { + SP_CANVAS_ITEM_CLASS (sp_ctrlline_parent_class)->destroy(object); } } @@ -134,8 +110,8 @@ void sp_ctrlline_update(SPCanvasItem *item, Geom::Affine const &affine, unsigned item->canvas->requestRedraw(item->x1, item->y1, item->x2, item->y2); - if (parent_class->update) { - (* parent_class->update)(item, affine, flags); + if (SP_CANVAS_ITEM_CLASS(sp_ctrlline_parent_class)->update) { + SP_CANVAS_ITEM_CLASS(sp_ctrlline_parent_class)->update(item, affine, flags); } sp_canvas_item_reset_bounds(item); diff --git a/src/display/sp-ctrlline.h b/src/display/sp-ctrlline.h index 12be03ca5..b2e222437 100644 --- a/src/display/sp-ctrlline.h +++ b/src/display/sp-ctrlline.h @@ -20,13 +20,11 @@ class SPItem; -#define SP_TYPE_CTRLLINE (SPCtrlLine::getType()) +#define SP_TYPE_CTRLLINE (sp_ctrlline_get_type()) #define SP_CTRLLINE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_CTRLLINE, SPCtrlLine)) #define SP_IS_CTRLLINE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_CTRLLINE)) struct SPCtrlLine : public SPCanvasItem { - static GType getType(); - void setRgba32(guint32 rgba); void setCoords(gdouble x0, gdouble y0, gdouble x1, gdouble y1); @@ -41,6 +39,8 @@ struct SPCtrlLine : public SPCanvasItem { Geom::Affine affine; }; +GType sp_ctrlline_get_type(); + struct SPCtrlLineClass : public SPCanvasItemClass{}; diff --git a/src/display/sp-ctrlpoint.cpp b/src/display/sp-ctrlpoint.cpp index 026cc7589..1082cb1b3 100644 --- a/src/display/sp-ctrlpoint.cpp +++ b/src/display/sp-ctrlpoint.cpp @@ -20,42 +20,17 @@ #include "display/cairo-utils.h" #include "display/sp-canvas.h" - -static void sp_ctrlpoint_class_init (SPCtrlPointClass *klass); -static void sp_ctrlpoint_init (SPCtrlPoint *ctrlpoint); static void sp_ctrlpoint_destroy(SPCanvasItem *object); static void sp_ctrlpoint_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); static void sp_ctrlpoint_render (SPCanvasItem *item, SPCanvasBuf *buf); -static SPCanvasItemClass *parent_class; - -GType -sp_ctrlpoint_get_type (void) -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof(SPCtrlPointClass), - NULL, NULL, - (GClassInitFunc) sp_ctrlpoint_class_init, - NULL, NULL, - sizeof(SPCtrlPoint), - 0, - (GInstanceInitFunc) sp_ctrlpoint_init, - NULL - }; - type = g_type_register_static(SP_TYPE_CANVAS_ITEM, "SPCtrlPoint", &info, (GTypeFlags)0); - } - return type; -} +G_DEFINE_TYPE(SPCtrlPoint, sp_ctrlpoint, SP_TYPE_CANVAS_ITEM); static void sp_ctrlpoint_class_init(SPCtrlPointClass *klass) { SPCanvasItemClass *item_class = SP_CANVAS_ITEM_CLASS(klass); - parent_class = SP_CANVAS_ITEM_CLASS(g_type_class_peek_parent(klass)); - item_class->destroy = sp_ctrlpoint_destroy; item_class->update = sp_ctrlpoint_update; item_class->render = sp_ctrlpoint_render; @@ -79,8 +54,8 @@ static void sp_ctrlpoint_destroy(SPCanvasItem *object) ctrlpoint->item=NULL; - if (SP_CANVAS_ITEM_CLASS(parent_class)->destroy) - (* SP_CANVAS_ITEM_CLASS(parent_class)->destroy) (object); + if (SP_CANVAS_ITEM_CLASS(sp_ctrlpoint_parent_class)->destroy) + SP_CANVAS_ITEM_CLASS(sp_ctrlpoint_parent_class)->destroy(object); } static void @@ -111,8 +86,8 @@ static void sp_ctrlpoint_update(SPCanvasItem *item, Geom::Affine const &affine, item->canvas->requestRedraw((int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); - if (parent_class->update) { - (* parent_class->update) (item, affine, flags); + if (SP_CANVAS_ITEM_CLASS(sp_ctrlpoint_parent_class)->update) { + SP_CANVAS_ITEM_CLASS(sp_ctrlpoint_parent_class)->update(item, affine, flags); } sp_canvas_item_reset_bounds (item); diff --git a/src/display/sp-ctrlquadr.cpp b/src/display/sp-ctrlquadr.cpp index b6a0da109..760e93a6d 100644 --- a/src/display/sp-ctrlquadr.cpp +++ b/src/display/sp-ctrlquadr.cpp @@ -29,42 +29,18 @@ struct SPCtrlQuadr : public SPCanvasItem{ struct SPCtrlQuadrClass : public SPCanvasItemClass{}; -static void sp_ctrlquadr_class_init (SPCtrlQuadrClass *klass); -static void sp_ctrlquadr_init (SPCtrlQuadr *ctrlquadr); static void sp_ctrlquadr_destroy(SPCanvasItem *object); static void sp_ctrlquadr_update (SPCanvasItem *item, Geom::Affine const &affine, unsigned int flags); static void sp_ctrlquadr_render (SPCanvasItem *item, SPCanvasBuf *buf); -static SPCanvasItemClass *parent_class; - -GType -sp_ctrlquadr_get_type (void) -{ - static GType type = 0; - if (!type) { - GTypeInfo info = { - sizeof(SPCtrlQuadrClass), - NULL, NULL, - (GClassInitFunc) sp_ctrlquadr_class_init, - NULL, NULL, - sizeof(SPCtrlQuadr), - 0, - (GInstanceInitFunc) sp_ctrlquadr_init, - NULL - }; - type = g_type_register_static(SP_TYPE_CANVAS_ITEM, "SPCtrlQuadr", &info, (GTypeFlags)0); - } - return type; -} +G_DEFINE_TYPE(SPCtrlQuadr, sp_ctrlquadr, SP_TYPE_CANVAS_ITEM); static void sp_ctrlquadr_class_init (SPCtrlQuadrClass *klass) { SPCanvasItemClass *item_class = SP_CANVAS_ITEM_CLASS(klass); - parent_class = SP_CANVAS_ITEM_CLASS(g_type_class_peek_parent(klass)); - item_class->destroy = sp_ctrlquadr_destroy; item_class->update = sp_ctrlquadr_update; item_class->render = sp_ctrlquadr_render; @@ -85,8 +61,8 @@ static void sp_ctrlquadr_destroy(SPCanvasItem *object) g_return_if_fail (object != NULL); g_return_if_fail (SP_IS_CTRLQUADR (object)); - if (SP_CANVAS_ITEM_CLASS(parent_class)->destroy) - (* SP_CANVAS_ITEM_CLASS(parent_class)->destroy) (object); + if (SP_CANVAS_ITEM_CLASS(sp_ctrlquadr_parent_class)->destroy) + (* SP_CANVAS_ITEM_CLASS(sp_ctrlquadr_parent_class)->destroy) (object); } static void @@ -139,8 +115,8 @@ static void sp_ctrlquadr_update(SPCanvasItem *item, Geom::Affine const &affine, item->canvas->requestRedraw((int)item->x1, (int)item->y1, (int)item->x2, (int)item->y2); - if (parent_class->update) { - (* parent_class->update)(item, affine, flags); + if (SP_CANVAS_ITEM_CLASS(sp_ctrlquadr_parent_class)->update) { + SP_CANVAS_ITEM_CLASS(sp_ctrlquadr_parent_class)->update(item, affine, flags); } sp_canvas_item_reset_bounds (item); |
