/** * Merges any clipping rectangles that overlap to try and reduce * the total number of clip rectangles. */ void MergeClipRect() { if (s_rectList.size() <= 1) return; RectList::iterator rOuter, rInner; for (rOuter = s_rectList.begin(); rOuter != s_rectList.end(); ++rOuter) { rInner = rOuter; while (++rInner != s_rectList.end()) { if (LooseIntersectRectangle(*rOuter, *rInner)) { // these two rectangles overlap or // are next to each other - merge them UnionRectangle(*rOuter, *rOuter, *rInner); // remove the inner rect from the list s_rectList.erase(rInner); // move back to beginning of list rInner = rOuter; } } } }
void NUIRenderHandler::OnImeCompositionRangeChanged(CefRefPtr<CefBrowser> browser, const CefRange& selected_range, const RectList& character_bounds) { if (g_imeHandler) { // Convert from view coordinates to device coordinates. CefRenderHandler::RectList device_bounds; CefRenderHandler::RectList::const_iterator it = character_bounds.begin(); for (; it != character_bounds.end(); ++it) { device_bounds.push_back(*it); } g_imeHandler->ChangeCompositionRange(selected_range, device_bounds); } }
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); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void SrcCefOSRRenderer::OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type, const RectList& dirtyRects, const void* buffer, int width, int height) { if( !m_pBrowser || !m_pBrowser->GetPanel() ) { Warning("SrcCefOSRRenderer::OnPaint: No browser or vgui panel yet\n"); return; } int channels = 4; if( type != PET_VIEW ) { Warning("SrcCefOSRRenderer::OnPaint: Unsupported paint type\n"); return; } Assert( dirtyRects.size() > 0 ); int dirtyx, dirtyy, dirtyxend, dirtyyend; dirtyx = width; dirtyy = height; dirtyxend = 0; dirtyyend = 0; //AUTO_LOCK( s_BufferMutex ); // Update image buffer size if needed if( m_iWidth != width || m_iHeight != height ) { if( m_pTextureBuffer != NULL ) { free( m_pTextureBuffer ); m_pTextureBuffer = NULL; } DevMsg("Texture buffer size changed from %dh %dw to %dw %dh\n", m_iWidth, m_iHeight, width, height ); m_iWidth = width; m_iHeight = height; m_pTextureBuffer = (unsigned char*) malloc( m_iWidth * m_iHeight * channels ); // Full dirty dirtyx = 0; dirtyy = 0; dirtyxend = m_iWidth; dirtyyend = m_iHeight; } const unsigned char *imagebuffer = (const unsigned char *)buffer; // Update dirty rects CefRenderHandler::RectList::const_iterator i = dirtyRects.begin(); for (; i != dirtyRects.end(); ++i) { const CefRect& rect = *i; for( int y = rect.y; y < rect.y + rect.height; y++ ) { memcpy( m_pTextureBuffer + (y * m_iWidth * channels) + (rect.x * channels), // Our current row + x offset imagebuffer + (y * m_iWidth * channels) + (rect.x * channels), // Source offset rect.width * channels // size of row we want to copy ); } // Update max dirty area dirtyx = Min( rect.x, dirtyx ); dirtyy = Min( rect.y, dirtyy ); dirtyxend = Max( rect.x + rect.width, dirtyxend ); dirtyyend = Max( rect.y + rect.height, dirtyyend ); } m_pBrowser->GetPanel()->MarkTextureDirty( dirtyx, dirtyy, dirtyxend, dirtyyend ); }