void NotationPreview::makeNotationPreviewRects(QPoint basePoint,
        const Segment* segment, const QRect& clipRect, RectRanges* npRects)
{
    Profiler profiler("NotationPreview::makeNotationPreviewRects");

    RectList* cachedNPData = getNotationPreviewData(segment);

    if (cachedNPData->empty())
        return ;

    RectList::iterator npEnd = cachedNPData->end();

    // Find the first preview rect that *starts within* the clipRect.
    // Probably not the right thing to do as this means any event that starts
    // prior to the clipRect but stretches through the clipRect will be
    // dropped.  And this explains why long notes disappear from the segment
    // previews.
    // Note that RectList is a std::vector, so this call will take increasing
    // amounts of time as the number of events to the left of the clipRect
    // increases.  This is probably at least a small part of the "CPU usage
    // increasing over time" issue.
    // If cachedNPData is sorted by start time, we could at least do a binary
    // search.
    RectList::iterator npi = std::lower_bound(cachedNPData->begin(), npEnd, clipRect, RectCompare());

    // If no preview rects were within the clipRect, bail.
    if (npi == npEnd)
        return ;

    // ??? Go back one event if we aren't already at the beginning.  Why?
    // Hilariously, this partially "fixes" the "missing event in preview"
    // problem.  However, it only "fixes" the problem for a single event.
    // Is that why this is here?
    // When testing, to get around the fact that the segments are drawn on a
    // segment layer in CompositionView, just disable then re-enable segment
    // previews in the menu and the "missing event in preview" problem is easy
    // to see.
    if (npi != cachedNPData->begin())
        --npi;

    // Compute the interval within the Notation Preview for this segment.

    RectRange interval;
    interval.range.first = npi;

    // Compute the rightmost x coord (xLim)
    int segEndX = int(nearbyint(m_grid.getRulerScale()->getXForTime(segment->getEndMarkerTime())));
    int xLim = std::min(clipRect.right(), segEndX);

    //RG_DEBUG << "NotationPreview::makeNotationPreviewRects : basePoint.x : "
    //         << basePoint.x();

    // Search sequentially for the last preview rect in the segment.
    while (npi != npEnd  &&  npi->x() < xLim)
        ++npi;

    interval.range.second = npi;
    interval.basePoint.setX(0);
    interval.basePoint.setY(basePoint.y());
    interval.color = segment->getPreviewColour();

    // Add the interval to the caller's interval list.
    npRects->push_back(interval);
}
void NotationPreview::makeNotationPreviewRectsMovingSegment(QPoint basePoint,
        const Segment* segment, const QRect& currentSR, RectRanges* npRects)
{
    CompositionRect unmovedSR =
            m_compositionModelImpl.computeSegmentRect(*segment);

    RectList* cachedNPData = getNotationPreviewData(segment);

    if (cachedNPData->empty())
        return ;

    RectList::iterator npBegin = cachedNPData->begin();
    RectList::iterator npEnd = cachedNPData->end();

    RectList::iterator npi;

    if (m_compositionModelImpl.getChangeType() ==
            CompositionModelImpl::ChangeResizeFromStart)
        npi = std::lower_bound(npBegin, npEnd, currentSR, RectCompare());
    else
        npi = std::lower_bound(npBegin, npEnd, unmovedSR, RectCompare());

    if (npi == npEnd)
        return ;

    // ??? Bump iterator back one to try and pick up the previous event
    //     rectangle which might be needed.
    if (npi != npBegin  &&
            m_compositionModelImpl.getChangeType() !=
                    CompositionModelImpl::ChangeResizeFromStart) {
        --npi;
    }

    // Compute the interval within the Notation Preview for this segment.

    RectRange interval;
    interval.range.first = npi;

    // Compute the rightmost x coord (xLim)
    int xLim = m_compositionModelImpl.getChangeType() ==
            CompositionModelImpl::ChangeMove ?
                    unmovedSR.right() : currentSR.right();

    //RG_DEBUG << "NotationPreview::makeNotationPreviewRectsMovingSegment : basePoint.x : "
    //         << basePoint.x();

    // Search sequentially for the last preview rect in the segment.
    while (npi != npEnd  &&  npi->x() < xLim)
        ++npi;

    interval.range.second = npi;
    interval.basePoint.setY(basePoint.y());

    if (m_compositionModelImpl.getChangeType() ==
            CompositionModelImpl::ChangeMove)
        interval.basePoint.setX(basePoint.x() - unmovedSR.x());
    else
        interval.basePoint.setX(0);

    interval.color = segment->getPreviewColour();

    npRects->push_back(interval);
}