summaryrefslogtreecommitdiffstats
path: root/src/display
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2015-06-25 16:15:05 +0000
committerJabiertxof <jtx@jtx.marker.es>2015-06-25 16:15:05 +0000
commit5c2d982cc636ee4e2bc12703c01c86e245dd821f (patch)
tree6e6f22800c7d38314e14eccd486b65c3c4286d81 /src/display
parentupdate to trunk (diff)
parentFix for the bug 1468396 (diff)
downloadinkscape-5c2d982cc636ee4e2bc12703c01c86e245dd821f.tar.gz
inkscape-5c2d982cc636ee4e2bc12703c01c86e245dd821f.zip
update to trunk
(bzr r13645.1.94)
Diffstat (limited to 'src/display')
-rw-r--r--src/display/drawing-text.cpp28
-rw-r--r--src/display/snap-indicator.cpp15
-rw-r--r--src/display/sp-canvas-item.h7
-rw-r--r--src/display/sp-canvas.cpp30
-rw-r--r--src/display/sp-canvas.h1
5 files changed, 52 insertions, 29 deletions
diff --git a/src/display/drawing-text.cpp b/src/display/drawing-text.cpp
index e20a7ff2a..a3ca7173a 100644
--- a/src/display/drawing-text.cpp
+++ b/src/display/drawing-text.cpp
@@ -91,9 +91,24 @@ unsigned DrawingGlyphs::_updateItem(Geom::IntRect const &/*area*/, UpdateContext
if (_transform) {
scale_bigbox /= _transform->descrim();
}
+
- 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;
+ /* Because there can be text decorations the bounding box must correspond in Y to a little above the glyph's ascend
+ and a little below its descend. This leaves room for overline and underline. The left and right sides
+ come from the glyph's bounding box. Note that the initial direction of ascender is positive down in Y, and
+ this flips after the transform is applied. So change the sign on descender. 1.1 provides a little extra space
+ above and below the max/min y positions of the letters to place the text decorations.*/
+
+ Geom::Rect b;
+ if(_drawable){
+ Geom::OptRect tiltb = bounds_exact(*_font->PathVector(_glyph));
+ Geom::Rect bigbox(Geom::Point(tiltb->left(),-_dsc*scale_bigbox*1.1),Geom::Point(tiltb->right(),_asc*scale_bigbox*1.1));
+ b = bigbox * ctx.ctm;
+ }
+ else { // Fallback, spaces mostly
+ Geom::Rect bigbox(Geom::Point(0.0, -_dsc*scale_bigbox*1.1),Geom::Point(_width*scale_bigbox, _asc*scale_bigbox*1.1));
+ b = bigbox * ctx.ctm;
+ }
/*
The pick box matches the characters as best as it can, leaving no extra space above or below
@@ -108,11 +123,11 @@ unsigned DrawingGlyphs::_updateItem(Geom::IntRect const &/*area*/, UpdateContext
if(_drawable){
pb = bounds_exact_transformed(*_font->PathVector(_glyph), ctx.ctm);
}
- if(!pb){ // Fallback
+ if(!pb){ // Fallback, spaces mostly
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.
@@ -214,7 +229,7 @@ DrawingText::addComponent(font_instance *font, int glyph, Geom::Affine const &tr
ng->setGlyph(font, glyph, trans);
if(font->PathVector(glyph)){ ng->_drawable = true; }
else { ng->_drawable = false; }
- ng->_width = width; // only used when _drawable = false
+ ng->_width = width; // used especially when _drawable = false, otherwise, it is the advance of the font
ng->_asc = ascent; // of font, not of this one character
ng->_dsc = descent; // of font, not of this one character
ng->_pl = phase_length; // used for phase of dots, dashes, and wavy
@@ -367,7 +382,7 @@ void DrawingText::decorateStyle(DrawingContext &dc, double vextent, double xphas
/* returns scaled line thickness */
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
+ if ( _nrstyle.font_size <= 1.0e-32 )return; // might cause a divide by zero or overflow 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;
@@ -381,6 +396,7 @@ void DrawingText::decorateItem(DrawingContext &dc, double phase_length, bool und
Geom::Point p2;
// All lines must be the same thickness, in combinations, line_through trumps underline
double thickness = final_underline_thickness;
+ if ( thickness <= 1.0e-32 )return; // might cause a divide by zero or overflow and nothing would be visible anyway
dc.setTolerance(0.5); // Is this really necessary... could effect dots.
if( under ) {
diff --git a/src/display/snap-indicator.cpp b/src/display/snap-indicator.cpp
index 8c0c8163f..926b35599 100644
--- a/src/display/snap-indicator.cpp
+++ b/src/display/snap-indicator.cpp
@@ -258,6 +258,19 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap
const int timeout_val = 4000;
+ // The snap indicator will be deleted after some time-out, and sp_canvas_item_dispose
+ // will be called. This will set canvas->current_item to NULL if the snap indicator was
+ // the current item, after which any events will go to the root handler instead of any
+ // item handler. Dragging an object which has just snapped might therefore not be possible
+ // without selecting / repicking it again. To avoid this, we make sure here that the
+ // snap indicator will never be picked, and will therefore never be the current item.
+ // Reported bugs:
+ // - scrolling when hovering above a pre-snap indicator won't work (for example)
+ // (https://bugs.launchpad.net/inkscape/+bug/522335/comments/8)
+ // - dragging doesn't work without repicking
+ // (https://bugs.launchpad.net/inkscape/+bug/1420301/comments/15)
+ SP_CTRL(canvasitem)->pickable = false;
+
SP_CTRL(canvasitem)->moveto(p.getPoint());
_snaptarget = _desktop->add_temporary_canvasitem(canvasitem, timeout_val);
_snaptarget_is_presnap = pre_snap;
@@ -282,6 +295,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap
SPCanvasItem *canvas_tooltip = sp_canvastext_new(_desktop->getTempGroup(), _desktop, tooltip_pos, tooltip_str);
sp_canvastext_set_fontsize(SP_CANVASTEXT(canvas_tooltip), fontsize);
+ SP_CANVASTEXT(canvas_tooltip)->pickable = false; // See the extensive comment above
SP_CANVASTEXT(canvas_tooltip)->rgba = 0xffffffff;
SP_CANVASTEXT(canvas_tooltip)->outline = false;
SP_CANVASTEXT(canvas_tooltip)->background = true;
@@ -306,6 +320,7 @@ SnapIndicator::set_new_snaptarget(Inkscape::SnappedPoint const &p, bool pre_snap
SP_CTRLRECT(box)->setRectangle(*bbox);
SP_CTRLRECT(box)->setColor(pre_snap ? 0x7f7f7fff : 0xff0000ff, 0, 0);
SP_CTRLRECT(box)->setDashed(true);
+ SP_CTRLRECT(box)->pickable = false; // See the extensive comment above
sp_canvas_item_move_to_z(box, 0);
_snaptarget_bbox = _desktop->add_temporary_canvasitem(box, timeout_val);
}
diff --git a/src/display/sp-canvas-item.h b/src/display/sp-canvas-item.h
index 3b7b7bd4f..3e9e085a0 100644
--- a/src/display/sp-canvas-item.h
+++ b/src/display/sp-canvas-item.h
@@ -69,7 +69,12 @@ struct SPCanvasItem {
gboolean visible;
gboolean need_update;
gboolean need_affine;
-
+
+ // If true, then SPCanvasGroup::point() and sp_canvas_item_invoke_point() will calculate
+ // the distance to the pointer, such that this item can be picked in pickCurrentItem()
+ // Only if an item can be picked, then it can be set as current_item and receive events!
+ bool pickable;
+
bool in_destruction;
};
diff --git a/src/display/sp-canvas.cpp b/src/display/sp-canvas.cpp
index 305b0950a..5efc4ce86 100644
--- a/src/display/sp-canvas.cpp
+++ b/src/display/sp-canvas.cpp
@@ -375,6 +375,7 @@ sp_canvas_item_init(SPCanvasItem *item)
// used for rubberbanding, path outline, etc.
item->visible = TRUE;
item->in_destruction = false;
+ item->pickable = true;
}
SPCanvasItem *sp_canvas_item_new(SPCanvasGroup *parent, GType type, gchar const *first_arg_name, ...)
@@ -728,7 +729,6 @@ bool sp_canvas_item_is_visible(SPCanvasItem *item)
return item->visible;
}
-
/**
* Sets visible flag on item and requests a redraw.
*/
@@ -1009,21 +1009,21 @@ double SPCanvasGroup::point(SPCanvasItem *item, Geom::Point p, SPCanvasItem **ac
if ((child->x1 <= x2) && (child->y1 <= y2) && (child->x2 >= x1) && (child->y2 >= y1)) {
SPCanvasItem *point_item = NULL; // cater for incomplete item implementations
- int has_point;
- if (child->visible && SP_CANVAS_ITEM_GET_CLASS(child)->point) {
+ int pickable;
+ if (child->visible && child->pickable && SP_CANVAS_ITEM_GET_CLASS(child)->point) {
dist = sp_canvas_item_invoke_point(child, p, &point_item);
- has_point = TRUE;
+ pickable = TRUE;
} else {
- has_point = FALSE;
+ pickable = FALSE;
}
- // This metric should be improved, because in case of (partly) overlapping items we will now
+ // TODO: This metric should be improved, because in case of (partly) overlapping items we will now
// always select the last one that has been added to the group. We could instead select the one
// of which the center is the closest, for example. One can then move to the center
// of the item to be focused, and have that one selected. Of course this will only work if the
// centers are not coincident, but at least it's better than what we have now.
// See the extensive comment in Inkscape::SelTrans::_updateHandles()
- if (has_point && point_item && ((int) (dist + 0.5) <= item->canvas->close_enough)) {
+ if (pickable && point_item && ((int) (dist + 0.5) <= item->canvas->close_enough)) {
best = dist;
*actual_item = point_item;
}
@@ -1480,20 +1480,6 @@ int SPCanvasImpl::emitEvent(SPCanvas *canvas, GdkEvent *event)
if (canvas->grabbed_item && !is_descendant (canvas->current_item, canvas->grabbed_item)) {
item = canvas->grabbed_item;
} else {
- // Make sure that current_item is up-to-date. If a snap indicator was just deleted, then
- // sp_canvas_item_dispose has been called and there is no current_item specified. We need
- // that though because otherwise we don't know where to send this event to, leading to a
- // lost event. We can't wait for idle events to have current_item updated, we need it now!
- // Otherwise, scrolling when hovering above a pre-snap indicator won't work (for example)
- // See this bug report: https://bugs.launchpad.net/inkscape/+bug/522335/comments/8
- if (canvas->need_repick && !canvas->in_repick && event->type == GDK_SCROLL) {
- // To avoid side effects, we'll only do this for scroll events, because this is the
- // only thing we want to fix here. An example of a reported side effect is that
- // otherwise selection of nodes in the node editor by dragging a rectangle using a
- // tablet will break
- canvas->need_repick = FALSE;
- pickCurrentItem(canvas, reinterpret_cast<GdkEvent *>(event));
- }
item = canvas->current_item;
}
@@ -1527,7 +1513,7 @@ int SPCanvasImpl::pickCurrentItem(SPCanvas *canvas, GdkEvent *event)
{
int button_down = 0;
- if (!canvas->root) // canvas may have already be destroyed by closing desktop durring interrupted display!
+ if (!canvas->root) // canvas may have already be destroyed by closing desktop during interrupted display!
return FALSE;
int retval = FALSE;
diff --git a/src/display/sp-canvas.h b/src/display/sp-canvas.h
index 48c3de2fc..65b06ade8 100644
--- a/src/display/sp-canvas.h
+++ b/src/display/sp-canvas.h
@@ -23,6 +23,7 @@
#endif
#include <gtk/gtk.h>
+#include <stdint.h>
#include <glibmm/ustring.h>
#include <2geom/affine.h>
#include <2geom/rect.h>