Layout::iterator Layout::getLetterAt(double x, double y) const { Geom::Point point(x, y); double rotation; for (iterator it = begin() ; it != end() ; it.nextCharacter()) { Geom::Rect box = characterBoundingBox(it, &rotation); // todo: rotation if (box.contains(point)) return it; } return end(); }
/** * Get the item under the specified point. * Searches the tree for the first item in the Z-order which is closer than * @a delta to the given point. The pick should be visual - for example * an object with a thick stroke should pick on the entire area of the stroke. * @param p Search point * @param delta Maximum allowed distance from the point * @param sticky Whether the pick should ignore visibility and sensitivity. * When false, only visible and sensitive objects are considered. * When true, invisible and insensitive objects can also be picked. */ DrawingItem * DrawingItem::pick(Geom::Point const &p, double delta, unsigned flags) { // Sometimes there's no BBOX in state, reason unknown (bug 992817) // I made this not an assert to remove the warning if (!(_state & STATE_BBOX) || !(_state & STATE_PICK)) { g_warning("Invalid state when picking: STATE_BBOX = %d, STATE_PICK = %d", _state & STATE_BBOX, _state & STATE_PICK); return NULL; } // ignore invisible and insensitive items unless sticky if (!(flags & PICK_STICKY) && !(_visible && _sensitive)) return NULL; bool outline = _drawing.outline(); if (!_drawing.outline()) { // pick inside clipping path; if NULL, it means the object is clipped away there if (_clip) { DrawingItem *cpick = _clip->pick(p, delta, flags | PICK_AS_CLIP); if (!cpick) return NULL; } // same for mask if (_mask) { DrawingItem *mpick = _mask->pick(p, delta, flags); if (!mpick) return NULL; } } Geom::OptIntRect box = (outline || (flags & PICK_AS_CLIP)) ? _bbox : _drawbox; if (!box) { return NULL; } Geom::Rect expanded = *box; expanded.expandBy(delta); if (expanded.contains(p)) { return _pickItem(p, delta, flags); } return NULL; }
static bool is_within(Geom::Rect const &area, Geom::Rect const &box) { return area.contains(box); }