void RemoteDrawingEngine::FillRegion(BRegion& region) { BRegion clippedRegion = region; clippedRegion.IntersectWith(&fClippingRegion); if (clippedRegion.CountRects() == 0) return; RemoteMessage message(NULL, fHWInterface->SendBuffer()); message.Start(RP_FILL_REGION); message.Add(fToken); message.AddRegion(clippedRegion.CountRects() < region.CountRects() ? clippedRegion : region); }
void View::AddTokensForViewsInRegion(BPrivate::PortLink& link, BRegion& region, BRegion* windowContentClipping) { if (!fVisible) return; { // NOTE: use scope in order to reduce stack space requirements // This check will prevent descending the view hierarchy // any further than necessary IntRect screenBounds(Bounds()); ConvertToScreen(&screenBounds); if (!region.Intersects((clipping_rect)screenBounds)) return; // Unfortunately, we intersecting another region, but otherwise // we couldn't provide the exact update rect to the client BRegion localDirty = _ScreenClipping(windowContentClipping); localDirty.IntersectWith(®ion); if (localDirty.CountRects() > 0) { link.Attach<int32>(fToken); link.Attach<BRect>(localDirty.Frame()); } } for (View* child = FirstChild(); child; child = child->NextSibling()) child->AddTokensForViewsInRegion(link, region, windowContentClipping); }
void TStageMovieCue::InvalidateSelectionRect() { // Create a region containing selection rect BRegion theRegion; BRect selectRect; // Top selectRect.Set(Bounds().left, Bounds().top, Bounds().right, Bounds().top +kBorder); theRegion.Include(selectRect); // Right selectRect.Set(Bounds().right-kBorder, Bounds().top, Bounds().right, Bounds().bottom); theRegion.Include(selectRect); // Bottom selectRect.Set(Bounds().left, Bounds().bottom-kBorder, Bounds().right, Bounds().bottom); theRegion.Include(selectRect); // Left selectRect.Set(Bounds().left, Bounds().top, Bounds().left+kBorder, Bounds().bottom); theRegion.Include(selectRect); // Now invalidate for(int32 index = 0; index < theRegion.CountRects(); index++) { Invalidate( theRegion.RectAt(index)); } }
void TStageMovieCue::UpdatePictureCueRegion(double theTime) { // Determine channelID int32 cueChannelID = m_ChannelCue->GetChannelID(); // Get total channels int32 totalChannels = static_cast<MuseumApp *>(be_app)->GetCueSheet()->GetCueSheetView()->GetTotalChannels(); // Determine cue layer. Iterate through all higher layers and determine // the area to be invalidated. Construct a region to do this. Exlude all // other area rects in higher channels than us. We wil then break // the region down into rects and invalidate them. BRegion invalRegion; invalRegion.Include(m_ChannelCue->GetArea()); for(int32 index = cueChannelID+1; index <= totalChannels; index++) { TStageCue *stageCue = ((TStageView *)Parent())->GetStageCueAtTimeandChannel(theTime, index); if (stageCue) invalRegion.Exclude( stageCue->GetChannelCue()->GetArea()); } // Now call our custom invalidation routine for(int32 index = 0; index < invalRegion.CountRects(); index++) { Parent()->Invalidate( invalRegion.RectAt(index)); //((TStageView *)Parent())->StageDraw( invalRegion.RectAt(index), theTime); } }
void BGLView::DirectConnected(direct_buffer_info *info) { if (!fClipInfo/* && m_direct_connection_disabled*/) { fClipInfo = new glview_direct_info(); } glview_direct_info *glviewDirectInfo = (glview_direct_info *)fClipInfo; direct_buffer_info *localInfo = glviewDirectInfo->direct_info; switch(info->buffer_state & B_DIRECT_MODE_MASK) { case B_DIRECT_START: glviewDirectInfo->direct_connected = true; _UnlockDraw(); case B_DIRECT_MODIFY: { _LockDraw(); localInfo->buffer_state = info->buffer_state; localInfo->driver_state = info->driver_state; localInfo->bits = info->bits; localInfo->pci_bits = info->pci_bits; localInfo->bytes_per_row = info->bytes_per_row; localInfo->bits_per_pixel = info->bits_per_pixel; localInfo->pixel_format = info->pixel_format; localInfo->layout = info->layout; localInfo->orientation = info->orientation; //memcpy(&localInfo->_reserved, info->_reserved, sizeof(info->_reserved)); //localInfo->_dd_type_ = info->_dd_type_; //localInfo->_dd_token_ = info->_dd_token_; // Collect the rects into a BRegion, then clip to the view's bounds BRegion region; for (uint32 c = 0; c < info->clip_list_count; c++) region.Include(info->clip_list[c]); BRegion boundsRegion = fBounds.OffsetByCopy(info->window_bounds.left, info->window_bounds.top); localInfo->window_bounds = boundsRegion.RectAtInt(0); // window_bounds are now view bounds region.IntersectWith(&boundsRegion); localInfo->clip_list_count = region.CountRects(); localInfo->clip_bounds = region.FrameInt(); for (uint32 c = 0; c < localInfo->clip_list_count; c++) localInfo->clip_list[c] = region.RectAtInt(c); _UnlockDraw(); break; } case B_DIRECT_STOP: glviewDirectInfo->direct_connected = false; _LockDraw(); break; } if (fRenderer) fRenderer->DirectConnected(localInfo); }
virtual void Draw(BRect updateRect) { BRegion region; GetClippingRegion(®ion); BMessage message(MSG_REDRAW); int32 count = region.CountRects(); for (int32 i = 0; i < count; i++) message.AddRect("rect", region.RectAt(i)); be_app->PostMessage(&message); }
status_t PictureDataWriter::WriteSetClipping(const BRegion ®ion) { // TODO: I don't know if it's compatible with R5's BPicture version try { const int32 numRects = region.CountRects(); if (numRects > 0 && region.Frame().IsValid()) { BeginOp(B_PIC_SET_CLIPPING_RECTS); Write<uint32>(numRects); for (int32 i = 0; i < numRects; i++) { Write<BRect>(region.RectAt(i)); } EndOp(); } else WriteClearClipping(); } catch (status_t &status) { return status; } return B_OK; }
void AccelerantHWInterface::_CopyBackToFront(/*const*/ BRegion& region) { if (fOffscreenBackBuffer) { int32 xOffset = 0; int32 yOffset = -(int32)fFrontBuffer->Height(); int32 count = region.CountRects(); clipping_rect rects[count]; for (int32 i = 0; i < count; i++) { rects[i] = region.RectAtInt(i); rects[i].top -= yOffset; rects[i].bottom -= yOffset; } _CopyRegion(rects, count, xOffset, yOffset, false); return; } return HWInterface::_CopyBackToFront(region); }
status_t DirectWindowInfo::SetState(direct_buffer_state bufferState, direct_driver_state driverState, RenderingBuffer* buffer, const BRect& windowFrame, const BRegion& clipRegion) { if ((fBufferInfo->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_STOP && (bufferState & B_DIRECT_MODE_MASK) != B_DIRECT_START) return B_OK; fBufferInfo->buffer_state = bufferState; if (driverState != -1) fBufferInfo->driver_state = driverState; if ((bufferState & B_DIRECT_MODE_MASK) != B_DIRECT_STOP) { fBufferInfo->bits = buffer->Bits(); fBufferInfo->pci_bits = NULL; // TODO fBufferInfo->bytes_per_row = buffer->BytesPerRow(); switch (buffer->ColorSpace()) { case B_RGB32: case B_RGBA32: case B_RGB32_BIG: case B_RGBA32_BIG: fBufferInfo->bits_per_pixel = 32; break; case B_RGB24: case B_RGB24_BIG: fBufferInfo->bits_per_pixel = 24; break; case B_RGB16: case B_RGB16_BIG: case B_RGB15: case B_RGB15_BIG: fBufferInfo->bits_per_pixel = 16; break; case B_CMAP8: case B_GRAY8: fBufferInfo->bits_per_pixel = 8; break; default: syslog(LOG_ERR, "unknown colorspace in DirectWindowInfo::SetState()!\n"); fBufferInfo->bits_per_pixel = 0; break; } fBufferInfo->pixel_format = buffer->ColorSpace(); fBufferInfo->layout = B_BUFFER_NONINTERLEAVED; fBufferInfo->orientation = B_BUFFER_TOP_TO_BOTTOM; // TODO fBufferInfo->window_bounds = to_clipping_rect(windowFrame); const int32 kMaxClipRectsCount = (DIRECT_BUFFER_INFO_AREA_SIZE - sizeof(direct_buffer_info)) / sizeof(clipping_rect); fBufferInfo->clip_list_count = min_c(clipRegion.CountRects(), kMaxClipRectsCount); fBufferInfo->clip_bounds = clipRegion.FrameInt(); for (uint32 i = 0; i < fBufferInfo->clip_list_count; i++) fBufferInfo->clip_list[i] = clipRegion.RectAtInt(i); } return _SyncronizeWithClient(); }
void MediaNodePanel::arrangeIOJacks() { D_METHOD(("MediaNodePanel::arrangeIOJacks()\n")); SortItems(DiagramItem::M_ENDPOINT, &compareTypeAndID); switch (dynamic_cast<MediaRoutingView *>(view())->getLayout()) { case MediaRoutingView::M_ICON_VIEW: { BRegion updateRegion; float align = 1.0; view()->GetItemAlignment(0, &align); // adjust this panel's size int32 numInputs = 0, numOutputs = 0; for (uint32 i = 0; i < CountItems(); i++) { MediaJack *jack = dynamic_cast<MediaJack *>(ItemAt(i)); if (jack) { if (jack->isInput()) { numInputs++; } if (jack->isOutput()) { numOutputs++; } } } float minHeight = MediaJack::M_DEFAULT_HEIGHT + MediaJack::M_DEFAULT_GAP; minHeight *= numInputs > numOutputs ? numInputs : numOutputs; minHeight += m_labelRect.Height(); minHeight += 2 * MediaJack::M_DEFAULT_GAP; minHeight = ((int)minHeight / (int)align) * align + align; if ((Frame().Height() < minHeight) || ((Frame().Height() > minHeight) && (minHeight >= MediaNodePanel::M_DEFAULT_HEIGHT))) { updateRegion.Include(Frame()); resizeTo(Frame().Width(), minHeight); updateRegion.Include(Frame()); _prepareLabel(); } // adjust the placement of the jacks BRect r = m_bodyRect; r.bottom -= M_BODY_V_MARGIN; float inputOffset = 0.0, outputOffset = 0.0; float center = Frame().top + r.top + (r.Height() / 2.0); center += MediaJack::M_DEFAULT_GAP - (MediaJack::M_DEFAULT_HEIGHT / 2.0); center = ((int)center / (int)align) * align; if (numInputs) { if (numInputs % 2) // odd number of inputs { inputOffset = center - (numInputs / 2) * (MediaJack::M_DEFAULT_HEIGHT + MediaJack::M_DEFAULT_GAP); } else // even number of inputs { inputOffset = center - ((numInputs + 1) / 2) * (MediaJack::M_DEFAULT_HEIGHT + MediaJack::M_DEFAULT_GAP); } } if (numOutputs) { if (numOutputs % 2) // odd number of outputs { outputOffset = center - (numOutputs / 2) * (MediaJack::M_DEFAULT_HEIGHT + MediaJack::M_DEFAULT_GAP); } else // even number of outputs { outputOffset = center - ((numOutputs + 1) / 2) * (MediaJack::M_DEFAULT_HEIGHT + MediaJack::M_DEFAULT_GAP); } } for (uint32 i = 0; i < CountItems(); i++) { MediaJack *jack = dynamic_cast<MediaJack *>(ItemAt(i)); if (jack) { if (jack->isInput()) { jack->setPosition(inputOffset, Frame().left, Frame().right, &updateRegion); inputOffset += jack->Frame().Height() + MediaJack::M_DEFAULT_GAP; } if (jack->isOutput()) { jack->setPosition(outputOffset, Frame().left, Frame().right, &updateRegion); outputOffset += jack->Frame().Height() + MediaJack::M_DEFAULT_GAP; } } } for (int32 i = 0; i < updateRegion.CountRects(); i++) { view()->Invalidate(updateRegion.RectAt(i)); } break; } case MediaRoutingView::M_MINI_ICON_VIEW: { BRegion updateRegion; float align = 1.0; view()->GetItemAlignment(&align, 0); // adjust this panel's size int32 numInputs = 0, numOutputs = 0; for (uint32 i = 0; i < CountItems(); i++) { MediaJack *jack = dynamic_cast<MediaJack *>(ItemAt(i)); if (jack) { if (jack->isInput()) { numInputs++; } if (jack->isOutput()) { numOutputs++; } } } float minWidth = MediaJack::M_DEFAULT_WIDTH + MediaJack::M_DEFAULT_GAP; minWidth *= numInputs > numOutputs ? numInputs : numOutputs; minWidth += m_bodyRect.Width(); minWidth += 2 * MediaJack::M_DEFAULT_GAP; minWidth = ((int)minWidth / (int)align) * align + align; if ((Frame().Width() < minWidth) || ((Frame().Width() > minWidth) && (minWidth >= MediaNodePanel::M_DEFAULT_WIDTH))) { updateRegion.Include(Frame()); resizeTo(minWidth, Frame().Height()); updateRegion.Include(Frame()); _prepareLabel(); } // adjust the placement of the jacks float inputOffset = 0.0, outputOffset = 0.0; float center = Frame().left + m_labelRect.left + (m_labelRect.Width() / 2.0); center += MediaJack::M_DEFAULT_GAP - (MediaJack::M_DEFAULT_WIDTH / 2.0); center = ((int)center / (int)align) * align; if (numInputs) { if (numInputs % 2) // odd number of inputs { inputOffset = center - (numInputs / 2) * (MediaJack::M_DEFAULT_WIDTH + MediaJack::M_DEFAULT_GAP); } else // even number of inputs { inputOffset = center - ((numInputs + 1) / 2) * (MediaJack::M_DEFAULT_WIDTH + MediaJack::M_DEFAULT_GAP); } } if (numOutputs) { if (numOutputs % 2) // odd number of outputs { outputOffset = center - (numOutputs / 2) * (MediaJack::M_DEFAULT_WIDTH + MediaJack::M_DEFAULT_GAP); } else // even number of outputs { outputOffset = center - ((numOutputs + 1) / 2) * (MediaJack::M_DEFAULT_WIDTH + MediaJack::M_DEFAULT_GAP); } } for (uint32 i = 0; i < CountItems(); i++) { MediaJack *jack = dynamic_cast<MediaJack *>(ItemAt(i)); if (jack) { if (jack->isInput()) { jack->setPosition(inputOffset, Frame().top, Frame().bottom, &updateRegion); inputOffset += jack->Frame().Width() + MediaJack::M_DEFAULT_GAP; } if (jack->isOutput()) { jack->setPosition(outputOffset, Frame().top, Frame().bottom, &updateRegion); outputOffset += jack->Frame().Width() + MediaJack::M_DEFAULT_GAP; } } } for (int32 i = 0; i < updateRegion.CountRects(); i++) { view()->Invalidate(updateRegion.RectAt(i)); } break; } } _updateBitmap(); }
void View::ResizeBy(int32 x, int32 y, BRegion* dirtyRegion) { if (x == 0 && y == 0) return; fFrame.right += x; fFrame.bottom += y; if (fVisible && dirtyRegion) { IntRect oldBounds(Bounds()); oldBounds.right -= x; oldBounds.bottom -= y; BRegion* dirty = fWindow->GetRegion(); if (!dirty) return; dirty->Set((clipping_rect)Bounds()); dirty->Include((clipping_rect)oldBounds); if (!(fFlags & B_FULL_UPDATE_ON_RESIZE)) { // the dirty region is just the difference of // old and new bounds dirty->Exclude((clipping_rect)(oldBounds & Bounds())); } InvalidateScreenClipping(); if (dirty->CountRects() > 0) { if ((fFlags & B_DRAW_ON_CHILDREN) == 0) { // exclude children, they are expected to // include their own dirty regions in ParentResized() for (View* child = FirstChild(); child; child = child->NextSibling()) { if (!child->IsVisible()) continue; IntRect previousChildVisible( child->Frame() & oldBounds & Bounds()); if (dirty->Frame().Intersects(previousChildVisible)) { dirty->Exclude((clipping_rect)previousChildVisible); } } } ConvertToScreen(dirty); dirtyRegion->Include(dirty); } fWindow->RecycleRegion(dirty); } // layout the children for (View* child = FirstChild(); child; child = child->NextSibling()) child->ParentResized(x, y, dirtyRegion); // view bitmap resize_frame(fBitmapDestination, fBitmapResizingMode, x, y); // at this point, children are at their new locations, // so we can rebuild the clipping // TODO: when the implementation of Hide() and Show() is // complete, see if this should be avoided RebuildClipping(false); }