/** * 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; } } } }
RectList DDClipper::GetRectangles(const RectList &rect_list) const { RectList rects; for( int i=0; i!=rect_list.size(); ++i) { RectList rcs = GetRectangles( rect_list[i] ); for( int k=0; k!=rcs.size(); ++k ) rects.push_back( rcs[k] ); } return rects; }
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 ViewManager::restore(int x1, int y1, int x2, int y2) { RectList *rl = new RectList(); Common::Rect redrawBounds(x1, y1, x2, y2); rl->addRect(x1, y1, x2, y2); for (ListIterator i = _views.begin(); i != _views.end(); ++i) { View *v = *i; if (v->isVisible() && v->bounds().intersects(redrawBounds)) v->onRefresh(rl, _vm->_screen); } _vm->_screen->update(); }
RectList* RectList::unpack(void *buffer, int bufferSize, int *bufferPos) { int size; RectList* rectList; Rectangle* rect; MPI_Unpack(buffer, bufferSize, bufferPos, &size, 1, MPI_INT, MPI_COMM_WORLD); // size rectList = new RectList(); // sestaveni for (int i = 0; i < size; i++) { rect = Rectangle::unpack(buffer, bufferSize, bufferPos); rectList->append(rect); // headItem, tailItem, rectItems } rectList->toUnpositioned(); // currentItem je vzdy prvni bez pozice return rectList; }
DDClipper::DDClipper(const RectList &rect_list): _dd_clipper(NULL) { int i,j,num,size =num= rect_list.size(); for ( j=0; j!=size; ++j ) { if (!rect_list[j]) --num; } if (num > 0) { DDraw7Ptr dd = DDCreator::GetDirectDraw(); dd->CreateClipper(0, &_dd_clipper, NULL); MemBlock region_buffer( sizeof(RGNDATAHEADER) + sizeof(RECT)*num ); LPRGNDATA regn = (LPRGNDATA)( region_buffer.GetPtr() ); regn->rdh.dwSize = sizeof(RGNDATAHEADER); regn->rdh.iType = RDH_RECTANGLES; regn->rdh.nCount = num; regn->rdh.nRgnSize = sizeof(RECT); LPRECT rc = (LPRECT)(regn->Buffer); Rect bound( rect_list[0] ); g_SizeLastRegion = 0; for(j=0, i=0; j!=size; ++j) { if (!rect_list[j]) { continue; } rc[i].left = rect_list[j].GetX1(); rc[i].top = rect_list[j].GetY1(); rc[i].right = rect_list[j].GetX2(); rc[i].bottom= rect_list[j].GetY2(); #ifdef DEBUG_REGION g_LastRegion[ g_SizeLastRegion++ ] = rc[i]; #endif bound |= rect_list[j]; ++i; } assert( i == num ); regn->rdh.rcBound.left = bound.GetX1(); regn->rdh.rcBound.top = bound.GetY1(); regn->rdh.rcBound.right = bound.GetX2(); regn->rdh.rcBound.bottom= bound.GetY2(); #ifdef DEBUG_REGION g_LastRegion[ g_SizeLastRegion++ ] = regn->rdh.rcBound; #endif if ( _dd_clipper->SetClipList(regn,0) != DD_OK ) { DDClipper_ERROR( Useless::Error("DDClipper::DDClipper() :SetClipList() failed") ); } } }
void BrowserClient::OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type, const RectList &dirtyRects, const void *buffer, int width, int height) { if (type == PET_VIEW && dirtyRects.size() > 0) { _image->setImage( width, height, 1, 4, GL_BGRA, GL_UNSIGNED_BYTE, (unsigned char*)(buffer), osg::Image::NO_DELETE ); } else if (type == PET_POPUP) { _popupImage->setImage( width, height, 1, 4, GL_BGRA, GL_UNSIGNED_BYTE, (unsigned char*)(buffer), osg::Image::NO_DELETE ); } }
RectList calc_bboxes(cv::Mat &mat ) { RectList boxes; std::vector<std::vector<cv::Point> > contours; /* Do edge detection?? */ /* Find contours */ cv::findContours(mat, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE); /* For each contour: */ for (int i = 0; i < contours.size(); i++) { //TODO: Iterator? /* Check area */ if (cv::contourArea(contours[i]) < MIN_AREA) continue; /* Get bounding box */ //TODO: Maybe poly approx first? cv::Rect bbox = cv::boundingRect(contours[i]); /* Add to list */ boxes.push_back(bbox); } return boxes; }
void BrowserClient::OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type, const RectList &dirtyRects, const void *buffer, int width, int height) { if (type == PET_VIEW && dirtyRects.size() > 0) { if (_width != width || _height != height) { OE_DEBUG << LC << "[OnPaint] Dimensions do not match: " << width << " x " << height << " vs. " << _width << " x " << _height << std::endl; return; } _image->setImage( width, height, 1, 4, GL_BGRA, GL_UNSIGNED_BYTE, (unsigned char*)(buffer), osg::Image::NO_DELETE ); } else if (type == PET_POPUP) { _popupImage->setImage( width, height, 1, 4, GL_BGRA, GL_UNSIGNED_BYTE, (unsigned char*)(buffer), osg::Image::NO_DELETE ); } }
void RenderHandler::OnPaint(CefRefPtr<CefBrowser> browser, PaintElementType type, const RectList &dirtyRects, const void *buffer, int width, int height) { FUpdateTextureRegion2D * updateRegions = static_cast<FUpdateTextureRegion2D*>(FMemory::Malloc(sizeof(FUpdateTextureRegion2D) * dirtyRects.size())); int current = 0; for (auto dirtyRect : dirtyRects) { updateRegions[current].DestX = updateRegions[current].SrcX = dirtyRect.x; updateRegions[current].DestY = updateRegions[current].SrcY = dirtyRect.y; updateRegions[current].Height = dirtyRect.height; updateRegions[current].Width = dirtyRect.width; current++; } // Trigger our parent UIs Texture to update parentUI->TextureUpdate(buffer, updateRegions, dirtyRects.size()); }
void Surface::MultiBlit ( const Surface &surf, const PointList &p, const RectList &r, const Surf::BlitFX &fx ) { int ir, rsize = r.size(); int ip, psize = p.size(); for( ir=0, ip=0; ir!=rsize && ip!=psize; ++ir, ++ip ) { if (!r[ir]) continue; Pos ps = p[ip]; Rect rc = r[ir]; Blit( ps.x, ps.y , surf, rc, fx ); } }
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 ); }
namespace Tinsel { /** list of all clip rectangles */ static RectList s_rectList; /** * Resets the clipping rectangle allocator. */ void ResetClipRect(void) { s_rectList.clear(); } /** * Allocate a clipping rectangle from the free list. * @param pClip clip rectangle dimensions to allocate */ void AddClipRect(const Common::Rect &pClip) { s_rectList.push_back(pClip); } const RectList &GetClipRects() { return s_rectList; } /** * Creates the intersection of two rectangles. * Returns True if there is a intersection. * @param pDest Pointer to destination rectangle that is to receive the intersection * @param pSrc1 Pointer to a source rectangle * @param pSrc2 Pointer to a source rectangle */ bool IntersectRectangle(Common::Rect &pDest, const Common::Rect &pSrc1, const Common::Rect &pSrc2) { pDest.left = MAX(pSrc1.left, pSrc2.left); pDest.top = MAX(pSrc1.top, pSrc2.top); pDest.right = MIN(pSrc1.right, pSrc2.right); pDest.bottom = MIN(pSrc1.bottom, pSrc2.bottom); return !pDest.isEmpty(); } /** * Creates the union of two rectangles. * Returns True if there is a union. * @param pDest destination rectangle that is to receive the new union * @param pSrc1 a source rectangle * @param pSrc2 a source rectangle */ bool UnionRectangle(Common::Rect &pDest, const Common::Rect &pSrc1, const Common::Rect &pSrc2) { pDest.left = MIN(pSrc1.left, pSrc2.left); pDest.top = MIN(pSrc1.top, pSrc2.top); pDest.right = MAX(pSrc1.right, pSrc2.right); pDest.bottom = MAX(pSrc1.bottom, pSrc2.bottom); return !pDest.isEmpty(); } /** * Check if the two rectangles are next to each other. * @param pSrc1 a source rectangle * @param pSrc2 a source rectangle */ static bool LooseIntersectRectangle(const Common::Rect &pSrc1, const Common::Rect &pSrc2) { Common::Rect pDest; pDest.left = MAX(pSrc1.left, pSrc2.left); pDest.top = MAX(pSrc1.top, pSrc2.top); pDest.right = MIN(pSrc1.right, pSrc2.right); pDest.bottom = MIN(pSrc1.bottom, pSrc2.bottom); return pDest.isValidRect(); } /** * Adds velocities and creates clipping rectangles for all the * objects that have moved on the specified object list. * @param pObjList Playfield display list to draw * @param pWin Playfield window top left position * @param pClip Playfield clipping rectangle * @param bNoVelocity When reset, objects pos is updated with velocity * @param bScrolled) When set, playfield has scrolled */ void FindMovingObjects(OBJECT *pObjList, Common::Point *pWin, Common::Rect *pClip, bool bNoVelocity, bool bScrolled) { OBJECT *pObj; // object list traversal pointer for (pObj = pObjList->pNext; pObj != NULL; pObj = pObj->pNext) { if (!bNoVelocity) { // we want to add velocities to objects position if (bScrolled) { // this playfield has scrolled // indicate change pObj->flags |= DMA_CHANGED; } } if ((pObj->flags & DMA_CHANGED) || // object changed HasPalMoved(pObj->pPal)) { // or palette moved // object has changed in some way Common::Rect rcClip; // objects clipped bounding rectangle Common::Rect rcObj; // objects bounding rectangle // calc intersection of objects previous bounding rectangle // NOTE: previous position is in screen co-ords if (IntersectRectangle(rcClip, pObj->rcPrev, *pClip)) { // previous position is within clipping rect AddClipRect(rcClip); } // calc objects current bounding rectangle if (pObj->flags & DMA_ABS) { // object position is absolute rcObj.left = fracToInt(pObj->xPos); rcObj.top = fracToInt(pObj->yPos); } else { // object position is relative to window rcObj.left = fracToInt(pObj->xPos) - pWin->x; rcObj.top = fracToInt(pObj->yPos) - pWin->y; } rcObj.right = rcObj.left + pObj->width; rcObj.bottom = rcObj.top + pObj->height; // calc intersection of object with clipping rect if (IntersectRectangle(rcClip, rcObj, *pClip)) { // current position is within clipping rect AddClipRect(rcClip); // update previous position pObj->rcPrev = rcClip; } else { // clear previous position pObj->rcPrev = Common::Rect(); } // clear changed flag pObj->flags &= ~DMA_CHANGED; } } } /** * 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; } } } } /** * Redraws all objects within this clipping rectangle. * @param pObjList Object list to draw * @param pWin Window top left position * @param pClip Pointer to clip rectangle */ void UpdateClipRect(OBJECT *pObjList, Common::Point *pWin, Common::Rect *pClip) { int x, y, right, bottom; // object corners int hclip, vclip; // total size of object clipping DRAWOBJECT currentObj; // filled in to draw the current object in list OBJECT *pObj; // object list iterator // Initialise the fields of the drawing object to empty memset(¤tObj, 0, sizeof(DRAWOBJECT)); for (pObj = pObjList->pNext; pObj != NULL; pObj = pObj->pNext) { if (pObj->flags & DMA_ABS) { // object position is absolute x = fracToInt(pObj->xPos); y = fracToInt(pObj->yPos); } else { // object position is relative to window x = fracToInt(pObj->xPos) - pWin->x; y = fracToInt(pObj->yPos) - pWin->y; } // calc object right right = x + pObj->width; if (right < 0) // totally clipped if negative continue; // calc object bottom bottom = y + pObj->height; if (bottom < 0) // totally clipped if negative continue; // bottom clip = low right y - clip low right y currentObj.botClip = bottom - pClip->bottom; if (currentObj.botClip < 0) { // negative - object is not clipped currentObj.botClip = 0; } // right clip = low right x - clip low right x currentObj.rightClip = right - pClip->right; if (currentObj.rightClip < 0) { // negative - object is not clipped currentObj.rightClip = 0; } // top clip = clip top left y - top left y currentObj.topClip = pClip->top - y; if (currentObj.topClip < 0) { // negative - object is not clipped currentObj.topClip = 0; } else { // clipped - adjust start position to top of clip rect y = pClip->top; } // left clip = clip top left x - top left x currentObj.leftClip = pClip->left - x; if (currentObj.leftClip < 0) { // negative - object is not clipped currentObj.leftClip = 0; } else // NOTE: This else statement is disabled in tinsel v1 { // clipped - adjust start position to left of clip rect x = pClip->left; } // calc object total horizontal clipping hclip = currentObj.leftClip + currentObj.rightClip; // calc object total vertical clipping vclip = currentObj.topClip + currentObj.botClip; if (hclip + vclip != 0) { // object is clipped in some way if (pObj->width <= hclip) // object totally clipped horizontally - ignore continue; if (pObj->height <= vclip) // object totally clipped vertically - ignore continue; // set clip bit in objects flags currentObj.flags = pObj->flags | DMA_CLIP; } else { // object is not clipped - copy flags currentObj.flags = pObj->flags; } // copy objects properties to local object currentObj.width = pObj->width; currentObj.height = pObj->height; currentObj.xPos = (short)x; currentObj.yPos = (short)y; currentObj.pPal = pObj->pPal; currentObj.constant = pObj->constant; currentObj.hBits = pObj->hBits; // draw the object DrawObject(¤tObj); } } } // end of namespace Tinsel
/** * Resets the clipping rectangle allocator. */ void ResetClipRect(void) { s_rectList.clear(); }
/** * Allocate a clipping rectangle from the free list. * @param pClip clip rectangle dimensions to allocate */ void AddClipRect(const Common::Rect &pClip) { s_rectList.push_back(pClip); }