View Raw SPL
#include 

static ucu = "";

/* clip a series to drawn lines or rectangles */
clipline(h, s, mode, rloc)
{
        local idx, t, len, line, y, yv, xoff, seg, clip;

        if (argc < 4)
        {
                if (argc < 3)
                {
                        if (argc < 2)
                        {
                                if (argc < 1) return(s);
                                
                                s = refseries(w0);
                        }
                        
                        mode = 0;
                }
                
                rloc = 0;
        }

        ucu = getconf("units_convert_hunits");
        setconf("units_convert_hunits", "0");

        /* coordinates of edit line */
        if (h.shape == "Rectangle")
        {
                line = cliprectcoords(h, s, rloc);
        }
        else
        {
                line = cliplinecoords(h, s);
        }

        /* convert x values to indices */
        idx  = xtoidx(s, xvals(line));
        xoff = xoffset(s);

        if ((len = length(idx)) > 1)
        {
                yv = yvals(s);

                seg  = extract(yv, idx[1], idx[len] - idx[1] + 1);
                
                if (mode)
                {
                        clip = (seg < line) ? line : seg;
                }
                else
                {
                        clip = (seg > line) ? line : seg;
                }

                /* insert */
                y = concat(extract(yv, 1, idx[1] - 1), clip, extract(yv, idx[len] + 1, -1));

                if (ISXYSERIES(s))
                {
                        y = xy(xvals(s), yvals(y));
                }

                /* update units, etc. */
                setvunits(y, getvunits(s));
                sethunits(y, gethunits(s));
                setxoffset(y, xoff);
                setyoffset(y, yoffset(s));
                setplotstyle(y, getplotstyle(s));
        }
        else
        {
                y = refseries(s);
        }

        setconf("units_convert_hunits", ucu);

        return(y);
}


cliprectcoords(h, s, mode)
{
        local x, xl, xr, idx, coords, y, line;

        if (argc < 3)
        {
                if (argc < 2)
                {
                        if (argc < 1) error("cliprectcoords - handle required");
                        
                        s = refseries(w0);
                }
                
                mode = 0;
        }

        coords = h.coords;

        xl = min(xvals(coords));
        xr = max(xvals(coords));

        switch (mode)
        {
                case 0:
                default:
                        /* bottom */
                        y = min(yvals(coords));
                        break;

                case 1:
                        /* middle */
                        y = (min(yvals(coords)) + max(yvals(coords))) / 2;
                        break;

                case 2:
                        /* top */
                        y = max(yvals(coords));
                        break;
        }

        if (not(ISXYSERIES(s)))
        {
                line = xy( {xl, xr}, {y, y});
                line = xyinterp(line, deltax(s));
        }
        else
        {
                idx  = xtoidx(s, {xl, xr});
                x    = extract(xvals(s), idx[1], idx[2] - idx[1] + 1);
                line = xy(x, ones(length(x), 1) * y);
        }

        return(line);
}


cliplinecoords(h, s)
{
        local x, xl, xr, coords, line;

        if (argc < 2)
        {
                s = refseries(w0);
        }

        coords = h.coords;

        if (ISXYSERIES(s))
        {
                xl = min(xvals(coords));
                xr = max(xvals(coords));

                idx  = xtoidx(s, {xl, xr});
                x    = extract(xvals(s), idx[1], idx[2] - idx[1] + 1);
                line = xylookup(coords, x);
        }
        else
        {
                line = xyinterp(coords, deltax(s));
        }
        
        return(line);
}


clipline_error(errnum, errmes)
{
        if (strlen(ucu) > 0)
        {
                setconf("units_convert_hunits", ucu);
        }
        
        error(sprintf("[clipline] %s", errmes));
}