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