void CCameraBlurFilter::draw(float amount, bool clearDepth) { if (amount <= 0.f) return; SClipScreenRect clipRect(g_Viewport); CGraphics::ResolveSpareTexture(clipRect, 0, clearDepth); float aspect = CGraphics::g_CroppedViewport.xc_width / float(CGraphics::g_CroppedViewport.x10_height); float xFac = CGraphics::g_CroppedViewport.xc_width / float(g_Viewport.x8_width); float yFac = CGraphics::g_CroppedViewport.x10_height / float(g_Viewport.xc_height); float xBias = CGraphics::g_CroppedViewport.x4_left / float(g_Viewport.x8_width); float yBias = CGraphics::g_CroppedViewport.x8_top / float(g_Viewport.xc_height); Vert verts[4] = { {{-1.0, -1.0}, {xBias, yBias}}, {{-1.0, 1.0}, {xBias, yBias + yFac}}, {{1.0, -1.0}, {xBias + xFac, yBias}}, {{1.0, 1.0}, {xBias + xFac, yBias + yFac}}, }; m_vbo->load(verts, sizeof(verts)); for (int i = 0; i < 6; ++i) { float tmp = i; tmp *= 2.f * M_PIF; tmp /= 6.f; float amtX = std::cos(tmp); amtX *= amount / 448.f / aspect; float amtY = std::sin(tmp); amtY *= amount / 448.f; m_uniform.m_uv[i][0] = amtX * xFac; m_uniform.m_uv[i][1] = amtY * yFac; } m_uniform.m_opacity = std::min(amount / 2.f, 1.f); m_uniBuf->load(&m_uniform, sizeof(m_uniform)); CGraphics::SetShaderDataBinding(m_dataBind); CGraphics::DrawArray(0, 4); }
void CanvasRenderingContext2D::putImageData(ImageData* data, float dx, float dy, float dirtyX, float dirtyY, float dirtyWidth, float dirtyHeight, ExceptionCode& ec) { if (!data) { ec = TYPE_MISMATCH_ERR; return; } if (!isfinite(dx) || !isfinite(dy) || !isfinite(dirtyX) || !isfinite(dirtyY) || !isfinite(dirtyWidth) || !isfinite(dirtyHeight)) { ec = INDEX_SIZE_ERR; return; } ImageBuffer* buffer = m_canvas ? m_canvas->buffer() : 0; if (!buffer) return; if (dirtyWidth < 0) { dirtyX += dirtyWidth; dirtyWidth = -dirtyWidth; } if (dirtyHeight < 0) { dirtyY += dirtyHeight; dirtyHeight = -dirtyHeight; } FloatRect clipRect(dirtyX, dirtyY, dirtyWidth, dirtyHeight); clipRect.intersect(IntRect(0, 0, data->width(), data->height())); IntSize destOffset(static_cast<int>(dx), static_cast<int>(dy)); IntRect sourceRect = enclosingIntRect(clipRect); sourceRect.move(destOffset); sourceRect.intersect(IntRect(IntPoint(), buffer->size())); if (sourceRect.isEmpty()) return; willDraw(sourceRect); sourceRect.move(-destOffset); IntPoint destPoint(destOffset.width(), destOffset.height()); buffer->putImageData(data, sourceRect, destPoint); }
void PaintedLayerComposite::RenderLayer(const nsIntRect& aClipRect) { if (!mBuffer || !mBuffer->IsAttached()) { return; } PROFILER_LABEL("PaintedLayerComposite", "RenderLayer", js::ProfileEntry::Category::GRAPHICS); MOZ_ASSERT(mBuffer->GetCompositor() == mCompositeManager->GetCompositor() && mBuffer->GetLayer() == this, "buffer is corrupted"); const nsIntRegion& visibleRegion = GetEffectiveVisibleRegion(); gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height); #ifdef MOZ_DUMP_PAINTING if (gfxUtils::sDumpPainting) { RefPtr<gfx::DataSourceSurface> surf = mBuffer->GetAsSurface(); if (surf) { WriteSnapshotToDumpFile(this, surf); } } #endif EffectChain effectChain(this); LayerManagerComposite::AutoAddMaskEffect autoMaskEffect(mMaskLayer, effectChain); AddBlendModeEffect(effectChain); mBuffer->SetPaintWillResample(MayResample()); mBuffer->Composite(effectChain, GetEffectiveOpacity(), GetEffectiveTransform(), GetEffectFilter(), clipRect, &visibleRegion); mBuffer->BumpFlashCounter(); mCompositeManager->GetCompositor()->MakeCurrent(); }
void ossimQtRoiRectAnnotator::paintAnnotation( QPainter* p, int clipx, int clipy, int clipw, int cliph ) { if ( !p || (thePoints.size() != 2) ) { return; } ossimIrect clipRect(clipx, clipy, clipx + (clipw - 1), clipy + (cliph - 1)); if (clipRect.intersects(getRoiRect())) { QRect r; r.setCoords(thePoints[0].x, thePoints[0].y, thePoints[1].x, thePoints[1].y); p->setPen(thePenColor); p->drawRect(r); } }
ClipRect PaintLayerClipper::applyOverflowClipToBackgroundRectWithGeometryMapper( const ClipRectsContext& context, const ClipRect& clip) const { const LayoutObject& layoutObject = *m_layer.layoutObject(); FloatRect clipRect(clip.rect()); if (shouldClipOverflow(context)) { LayoutRect layerBoundsWithVisualOverflow = layoutObject.isLayoutView() ? toLayoutView(layoutObject).viewRect() : toLayoutBox(layoutObject).visualOverflowRect(); toLayoutBox(layoutObject) .flipForWritingMode( // PaintLayer are in physical coordinates, so the overflow has to be // flipped. layerBoundsWithVisualOverflow); mapLocalToRootWithGeometryMapper(context, layerBoundsWithVisualOverflow); clipRect.intersect(FloatRect(layerBoundsWithVisualOverflow)); } return ClipRect(LayoutRect(clipRect)); }
void EllipsisBox::paintSelection(GraphicsContext* context, const FloatPoint& boxOrigin, RenderStyle* style, const Font& font) { Color textColor = renderer().resolveColor(style, CSSPropertyColor); Color c = renderer().selectionBackgroundColor(); if (!c.alpha()) return; // If the text color ends up being the same as the selection background, invert the selection // background. if (textColor == c) c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue()); GraphicsContextStateSaver stateSaver(*context); LayoutUnit top = root().selectionTop(); LayoutUnit h = root().selectionHeight(); const int deltaY = roundToInt(logicalTop() - top); const FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY); FloatRect clipRect(localOrigin, FloatSize(m_logicalWidth, h.toFloat())); context->clip(clipRect); context->drawHighlightForText(font, constructTextRun(&renderer(), font, m_str, style, TextRun::AllowTrailingExpansion), localOrigin, h, c); }
void EllipsisBox::paintSelection(GraphicsContext* context, const LayoutPoint& paintOffset, RenderStyle* style, const Font& font) { Color textColor = style->visitedDependentColor(CSSPropertyColor); Color c = m_renderer->selectionBackgroundColor(); if (!c.isValid() || !c.alpha()) return; // If the text color ends up being the same as the selection background, invert the selection // background. if (textColor == c) c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue()); GraphicsContextStateSaver stateSaver(*context); LayoutUnit top = root()->selectionTop(); LayoutUnit h = root()->selectionHeight(); FloatRect clipRect(x() + paintOffset.x(), top + paintOffset.y(), m_logicalWidth, h); alignSelectionRectToDevicePixels(clipRect); context->clip(clipRect); // FIXME: Why is this always LTR? Fix by passing correct text run flags below. context->drawHighlightForText(font, RenderBlock::constructTextRun(renderer(), font, m_str, style, TextRun::AllowTrailingExpansion), roundedIntPoint(LayoutPoint(x() + paintOffset.x(), y() + paintOffset.y() + top)), h, c, style->colorSpace()); }
void PlatformContextSkia::beginLayerClippedToImage(const FloatRect& rect, const ImageBuffer* imageBuffer) { SkRect bounds = { SkFloatToScalar(rect.x()), SkFloatToScalar(rect.y()), SkFloatToScalar(rect.maxX()), SkFloatToScalar(rect.maxY()) }; if (imageBuffer->internalSize().isEmpty()) { clipRect(bounds); return; } // Skia doesn't support clipping to an image, so we create a layer. The next // time restore is invoked the layer and |imageBuffer| are combined to // create the resulting image. m_state->m_clip = bounds; // Get the absolute coordinates of the stored clipping rectangle to make it // independent of any transform changes. getTotalMatrix().mapRect(&m_state->m_clip); SkCanvas::SaveFlags saveFlags = static_cast<SkCanvas::SaveFlags>(SkCanvas::kHasAlphaLayer_SaveFlag | SkCanvas::kFullColorLayer_SaveFlag); saveLayer(&bounds, 0, saveFlags); const SkBitmap* bitmap = imageBuffer->context()->platformContext()->bitmap(); if (m_trackOpaqueRegion) { SkRect opaqueRect = bitmap->isOpaque() ? m_state->m_clip : SkRect::MakeEmpty(); m_opaqueRegion.setImageMask(opaqueRect); } // Copy off the image as |imageBuffer| may be deleted before restore is invoked. if (bitmap->isImmutable()) m_state->m_imageBufferClip = *bitmap; else { // We need to make a deep-copy of the pixels themselves, so they don't // change on us between now and when we want to apply them in restore() bitmap->copyTo(&m_state->m_imageBufferClip, SkBitmap::kARGB_8888_Config); } }
void PlatformContextCairo::clipForPatternFilling(const GraphicsContextState& state) { ASSERT(state.fillPattern); // Hold current cairo path in a variable for restoring it after configuring the pattern clip rectangle. auto currentPath = cairo_copy_path(m_cr.get()); cairo_new_path(m_cr.get()); // Initialize clipping extent from current cairo clip extents, then shrink if needed according to pattern. // Inspired by GraphicsContextQt::drawRepeatPattern. double x1, y1, x2, y2; cairo_clip_extents(m_cr.get(), &x1, &y1, &x2, &y2); FloatRect clipRect(x1, y1, x2 - x1, y2 - y1); Image* patternImage = state.fillPattern->tileImage(); ASSERT(patternImage); const AffineTransform& patternTransform = state.fillPattern->getPatternSpaceTransform(); FloatRect patternRect = patternTransform.mapRect(FloatRect(0, 0, patternImage->width(), patternImage->height())); bool repeatX = state.fillPattern->repeatX(); bool repeatY = state.fillPattern->repeatY(); if (!repeatX) { clipRect.setX(patternRect.x()); clipRect.setWidth(patternRect.width()); } if (!repeatY) { clipRect.setY(patternRect.y()); clipRect.setHeight(patternRect.height()); } if (!repeatX || !repeatY) { cairo_rectangle(m_cr.get(), clipRect.x(), clipRect.y(), clipRect.width(), clipRect.height()); cairo_clip(m_cr.get()); } // Restoring cairo path. cairo_append_path(m_cr.get(), currentPath); cairo_path_destroy(currentPath); }
void TableCellPainter::paintBackgroundsBehindCell(const PaintInfo& paintInfo, const LayoutPoint& paintOffset, const LayoutObject* backgroundObject, DisplayItem::Type type) { if (!backgroundObject) return; if (m_layoutTableCell.style()->visibility() != VISIBLE) return; LayoutTable* tableElt = m_layoutTableCell.table(); if (!tableElt->collapseBorders() && m_layoutTableCell.style()->emptyCells() == EmptyCellsHide && !m_layoutTableCell.firstChild()) return; LayoutRect paintRect = paintBounds(paintOffset, backgroundObject != &m_layoutTableCell ? AddOffsetFromParent : DoNotAddOffsetFromParent); // Record drawing only if the cell is painting background from containers. Optional<LayoutObjectDrawingRecorder> recorder; if (backgroundObject != &m_layoutTableCell) { if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(paintInfo.context, m_layoutTableCell, type)) return; recorder.emplace(paintInfo.context, m_layoutTableCell, type, paintRect); } else { ASSERT(paintRect.location() == paintOffset); } Color c = backgroundObject->resolveColor(CSSPropertyBackgroundColor); const FillLayer& bgLayer = backgroundObject->style()->backgroundLayers(); if (bgLayer.hasImage() || c.alpha()) { // We have to clip here because the background would paint // on top of the borders otherwise. This only matters for cells and rows. bool shouldClip = backgroundObject->hasLayer() && (backgroundObject == &m_layoutTableCell || backgroundObject == m_layoutTableCell.parent()) && tableElt->collapseBorders(); GraphicsContextStateSaver stateSaver(paintInfo.context, shouldClip); if (shouldClip) { LayoutRect clipRect(paintRect.location(), m_layoutTableCell.size()); clipRect.expand(m_layoutTableCell.borderInsets()); paintInfo.context.clip(pixelSnappedIntRect(clipRect)); } BoxPainter(m_layoutTableCell).paintFillLayers(paintInfo, c, bgLayer, paintRect, BackgroundBleedNone, SkXfermode::kSrcOver_Mode, backgroundObject); } }
void EllipsisBoxPainter::paintSelection(GraphicsContext& context, const LayoutPoint& boxOrigin, const ComputedStyle& style, const Font& font) { Color textColor = m_ellipsisBox.getLineLayoutItem().resolveColor(style, CSSPropertyColor); Color c = m_ellipsisBox.getLineLayoutItem().selectionBackgroundColor(); if (!c.alpha()) return; // If the text color ends up being the same as the selection background, invert the selection // background. if (textColor == c) c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue()); GraphicsContextStateSaver stateSaver(context); LayoutUnit selectionBottom = m_ellipsisBox.root().selectionBottom(); LayoutUnit top = m_ellipsisBox.root().selectionTop(); LayoutUnit h = m_ellipsisBox.root().selectionHeight(); const int deltaY = roundToInt(m_ellipsisBox.getLineLayoutItem().styleRef().isFlippedLinesWritingMode() ? selectionBottom - m_ellipsisBox.logicalBottom() : m_ellipsisBox.logicalTop() - top); const FloatPoint localOrigin(LayoutPoint(boxOrigin.x(), boxOrigin.y() - deltaY)); FloatRect clipRect(localOrigin, FloatSize(LayoutSize(m_ellipsisBox.logicalWidth(), h))); context.clip(clipRect); context.drawHighlightForText(font, constructTextRun(font, m_ellipsisBox.ellipsisStr(), style, TextRun::AllowTrailingExpansion), localOrigin, h, c); }
void ThreadedCompositor::renderLayerTree() { if (!m_scene) return; if (!ensureGLContext()) return; FloatRect clipRect(0, 0, m_viewportSize.width(), m_viewportSize.height()); TransformationMatrix viewportTransform; FloatPoint scrollPostion = viewportController()->visibleContentsRect().location(); viewportTransform.scale(viewportController()->pageScaleFactor()); viewportTransform.translate(-scrollPostion.x(), -scrollPostion.y()); m_scene->paintToCurrentGLContext(viewportTransform, 1, clipRect, Color::white, false, scrollPostion); #if PLATFORM(BCM_RPI) auto bufferExport = m_surface->lockFrontBuffer(); m_compositingManager.commitBCMBuffer(bufferExport); #endif #if PLATFORM(BCM_NEXUS) auto bufferExport = m_surface->lockFrontBuffer(); m_compositingManager.commitBCMNexusBuffer(bufferExport); #endif #if PLATFORM(INTEL_CE) auto bufferExport = m_surface->lockFrontBuffer(); m_compositingManager.commitIntelCEBuffer(bufferExport); #endif glContext()->swapBuffers(); #if PLATFORM(GBM) auto bufferExport = m_surface->lockFrontBuffer(); m_compositingManager.commitPrimeBuffer(bufferExport); #endif }
virtual void frameRectsChanged() { if (!platformWidget()) return; IntRect windowRect = convertToContainingWindow(IntRect(0, 0, frameRect().width(), frameRect().height())); platformWidget()->setGeometry(windowRect); ScrollView* parentScrollView = parent(); if (!parentScrollView) return; ASSERT(parentScrollView->isFrameView()); IntRect clipRect(static_cast<FrameView*>(parentScrollView)->windowClipRect()); clipRect.move(-windowRect.x(), -windowRect.y()); clipRect.intersect(platformWidget()->rect()); QRegion clipRegion = QRegion(clipRect); platformWidget()->setMask(clipRegion); handleVisibility(); }
// Ensure that the 'getConservativeBounds' calls are returning bounds clamped // to the render target DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrClipBounds, reporter, ctxInfo) { static const int kXSize = 100; static const int kYSize = 100; const SkIRect intScreen = SkIRect::MakeWH(kXSize, kYSize); const SkRect screen = SkRect::Make(intScreen); SkRect clipRect(screen); clipRect.outset(10, 10); // create a clip stack that will (trivially) reduce to a single rect that // is larger than the screen SkClipStack stack; stack.clipRect(clipRect, SkMatrix::I(), kReplace_SkClipOp, false); bool isIntersectionOfRects = true; SkRect devStackBounds; stack.getConservativeBounds(0, 0, kXSize, kYSize, &devStackBounds, &isIntersectionOfRects); // make sure that the SkClipStack is behaving itself REPORTER_ASSERT(reporter, screen == devStackBounds); REPORTER_ASSERT(reporter, isIntersectionOfRects); // wrap the SkClipStack in a GrClip GrClipStackClip clipData(&stack); SkIRect devGrClipBound; clipData.getConservativeBounds(kXSize, kYSize, &devGrClipBound, &isIntersectionOfRects); // make sure that GrClip is behaving itself REPORTER_ASSERT(reporter, intScreen == devGrClipBound); REPORTER_ASSERT(reporter, isIntersectionOfRects); }
Rect2I GUIInputCaret::getSpriteClipRect(const Rect2I& parentClipRect) const { Vector2I offset(mElement->_getLayoutData().area.x, mElement->_getLayoutData().area.y); Vector2I clipOffset = getSpriteOffset() - offset - Vector2I(mElement->_getTextInputRect().x, mElement->_getTextInputRect().y); Rect2I clipRect(-clipOffset.x, -clipOffset.y, mTextDesc.width, mTextDesc.height); Rect2I localParentCliprect = parentClipRect; // Move parent rect to our space localParentCliprect.x += mElement->_getTextInputOffset().x + clipRect.x; localParentCliprect.y += mElement->_getTextInputOffset().y + clipRect.y; // Clip our rectangle so its not larger then the parent clipRect.clip(localParentCliprect); // Increase clip size by 1, so we can fit the caret in case it is fully at the end of the text clipRect.width += 1; return clipRect; }
NS_IMETHODIMP nsFileControlFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, const nsDisplayListSet& aLists) { // Our background is inherited to the text input, and we don't really want to // paint it or out padding and borders (which we never have anyway, per // styles in forms.css) -- doing it just makes us look ugly in some cases and // has no effect in others. nsDisplayListCollection tempList; nsresult rv = nsAreaFrame::BuildDisplayList(aBuilder, aDirtyRect, tempList); if (NS_FAILED(rv)) return rv; tempList.BorderBackground()->DeleteAll(); // Clip height only nsRect clipRect(aBuilder->ToReferenceFrame(this), GetSize()); clipRect.width = GetOverflowRect().XMost(); rv = OverflowClip(aBuilder, tempList, aLists, clipRect); NS_ENSURE_SUCCESS(rv, rv); // Disabled file controls don't pass mouse events to their children, so we // put an invisible item in the display list above the children // just to catch events // REVIEW: I'm not sure why we do this, but that's what nsFileControlFrame:: // GetFrameForPoint was doing if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::disabled) && IsVisibleForPainting(aBuilder)) { nsDisplayItem* item = new (aBuilder) nsDisplayEventReceiver(this); if (!item) return NS_ERROR_OUT_OF_MEMORY; aLists.Content()->AppendToTop(item); } return DisplaySelectionOverlay(aBuilder, aLists); }
bool GiGraphics::setClipBox(const RECT_2D& rc) { if (!isDrawing() || isStopping()) return false; bool ret = false; Box2d rect; if (!rect.intersectWith(Box2d(rc), Box2d(m_impl->clipBox0)).isEmpty()) { if (rect != Box2d(m_impl->clipBox)) { rect.get(m_impl->clipBox); m_impl->rectDraw.set(Box2d(rc)); m_impl->rectDraw.inflate(GiGraphicsImpl::CLIP_INFLATE); m_impl->rectDrawM = m_impl->rectDraw * xf().displayToModel(); m_impl->rectDrawW = m_impl->rectDrawM * xf().modelToWorld(); SafeCall(m_impl->canvas, clipRect(m_impl->clipBox.left, m_impl->clipBox.top, m_impl->clipBox.width(), m_impl->clipBox.height())); } ret = true; } return ret; }
void EllipsisBox::paintSelection(GraphicsContext* context, const FloatPoint& boxOrigin, RenderStyle* style, const Font& font) { Color textColor = m_renderer->resolveColor(style, CSSPropertyColor); Color c = m_renderer->selectionBackgroundColor(); if (!c.isValid() || !c.alpha()) return; // If the text color ends up being the same as the selection background, invert the selection // background. if (textColor == c) c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue()); GraphicsContextStateSaver stateSaver(*context); LayoutUnit selectionBottom = root()->selectionBottom(); LayoutUnit top = root()->selectionTop(); LayoutUnit h = root()->selectionHeight(); const int deltaY = roundToInt(renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom - logicalBottom() : logicalTop() - top); const FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY); FloatRect clipRect(localOrigin, FloatSize(m_logicalWidth, h)); alignSelectionRectToDevicePixels(clipRect); context->clip(clipRect); // FIXME: Why is this always LTR? Fix by passing correct text run flags below. context->drawHighlightForText(font, RenderBlockFlow::constructTextRun(renderer(), font, m_str, style, TextRun::AllowTrailingExpansion), localOrigin, h, c); }
ossimAnnotationObject* ossimAnnotationMultiLineObject::getNewClippedObject(const ossimDrect& rect)const { ossimAnnotationMultiLineObject* result = (ossimAnnotationMultiLineObject*)NULL; if(intersects(rect)) { vector<ossimPolyLine> lineList; vector<ossimPolyLine> tempResult; ossimDrect clipRect(rect.ul().x - 10, rect.ul().y - 10, rect.lr().x + 10, rect.lr().y + 10); for(ossim_uint32 i =0; i< thePolyLineList.size();++i) { if(thePolyLineList[i].clipToRect(tempResult, clipRect)) { lineList.insert(lineList.end(), tempResult.begin(), tempResult.end()); } } if(lineList.size() > 0) { result = new ossimAnnotationMultiLineObject(lineList, theRed, theGreen, theBlue, theThickness); } } return result; }
void TransparencyWin::computeLayerSize() { if (m_transformMode == Untransform) { // The meaning of the "transformed" source rect is a little ambigous // here. The rest of the code doesn't care about it in the Untransform // case since we're using our own happy coordinate system. So we set it // to be the source rect since that matches how the code below actually // uses the variable: to determine how to translate things to account // for the offset of the layer. m_transformedSourceRect = m_sourceRect; } else if (m_transformMode == KeepTransform && m_layerMode != TextComposite) { // FIXME: support clipping for other modes IntRect clippedSourceRect = m_sourceRect; SkRect clipBounds; if (m_destContext->getClipBounds(&clipBounds)) { FloatRect clipRect(clipBounds.left(), clipBounds.top(), clipBounds.width(), clipBounds.height()); clippedSourceRect.intersect(enclosingIntRect(clipRect)); } m_transformedSourceRect = m_orgTransform.mapRect(clippedSourceRect); } else m_transformedSourceRect = m_orgTransform.mapRect(m_sourceRect); m_layerSize = IntSize(m_transformedSourceRect.width(), m_transformedSourceRect.height()); }
virtual void frameRectsChanged() { if (!platformWidget()) return; IntRect windowRect = convertToContainingWindow(IntRect(0, 0, frameRect().width(), frameRect().height())); platformWidget()->setGeometry(windowRect); ScrollView* parentScrollView = parent(); if (!parentScrollView) return; ASSERT(parentScrollView->isFrameView()); IntRect clipRect(static_cast<FrameView*>(parentScrollView)->windowClipRect()); clipRect.move(-windowRect.x(), -windowRect.y()); clipRect.intersect(platformWidget()->rect()); QRegion clipRegion = QRegion(clipRect); platformWidget()->setMask(clipRegion); // if setMask is set with an empty QRegion, no clipping will // be performed, so in that case we hide the platformWidget platformWidget()->setVisible(!clipRegion.isEmpty()); }
void ImageLayerComposite::RenderLayer(const nsIntPoint& aOffset, const nsIntRect& aClipRect) { if (!mImageHost) { return; } mCompositor->MakeCurrent(); EffectChain effectChain; LayerManagerComposite::AddMaskEffect(mMaskLayer, effectChain); gfx::Matrix4x4 transform; ToMatrix4x4(GetEffectiveTransform(), transform); gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height); mImageHost->SetCompositor(mCompositor); mImageHost->Composite(effectChain, GetEffectiveOpacity(), transform, gfx::Point(aOffset.x, aOffset.y), gfx::ToFilter(mFilter), clipRect); }
testStep->assertMessage()); \ } \ TEST_STEP(NAME, NAME##TestStep ) /////////////////////////////////////////////////////////////////////////////// // Basic test steps for most virtual methods in SkCanvas that draw or affect // the state of the canvas. SIMPLE_TEST_STEP(Translate, translate(SkIntToScalar(1), SkIntToScalar(2))); SIMPLE_TEST_STEP(Scale, scale(SkIntToScalar(1), SkIntToScalar(2))); SIMPLE_TEST_STEP(Rotate, rotate(SkIntToScalar(1))); SIMPLE_TEST_STEP(Skew, skew(SkIntToScalar(1), SkIntToScalar(2))); SIMPLE_TEST_STEP(Concat, concat(d.fMatrix)); SIMPLE_TEST_STEP(SetMatrix, setMatrix(d.fMatrix)); SIMPLE_TEST_STEP(ClipRect, clipRect(d.fRect)); SIMPLE_TEST_STEP(ClipPath, clipPath(d.fPath)); SIMPLE_TEST_STEP(ClipRegion, clipRegion(d.fRegion, SkRegion::kReplace_Op)); SIMPLE_TEST_STEP(Clear, clear(d.fColor)); /////////////////////////////////////////////////////////////////////////////// // Complex test steps static void SaveMatrixClipStep(SkCanvas* canvas, const TestData& d, skiatest::Reporter* reporter, CanvasTestStep* testStep) { int saveCount = canvas->getSaveCount(); canvas->save(); canvas->translate(SkIntToScalar(1), SkIntToScalar(2)); canvas->clipRegion(d.fRegion); canvas->restore(); REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount,
///////////////////////////////////////////////////////////////////////////// // RenderAllShadows : render all shadow instances ///////////////////////////////////////////////////////////////////////////// void VBlobShadowManager::RenderAllShadows() { // if enabled, a 2D bounding box is additionally used for clipping, which saves a lot of fillrate! // TODO: PSP2 - fix 2d clipping #if defined(_VISION_PSP2) static bool bClipScissor = false; #else static bool bClipScissor = true; #endif VisFrustum_cl viewFrustum; IVisVisibilityCollector_cl *pVisColl = VisRenderContext_cl::GetCurrentContext()->GetVisibilityCollector(); if (pVisColl==NULL || pVisColl->GetBaseFrustum()==NULL) return; viewFrustum.CopyFrom((VisFrustum_cl&)*pVisColl->GetBaseFrustum()); // render all shadows VISION_PROFILE_FUNCTION(PROFILING_BS_OVERALL); // get the collection of visible (opaque) primitives. For each shadow instance determine // the primitives in this list, which intersect with the shadow box // (we do not want to render primitives that are not visible) const VisStaticGeometryInstanceCollection_cl *pVisibleGeom = pVisColl->GetVisibleStaticGeometryInstancesForPass(VPT_PrimaryOpaquePass); VRectanglef clipRect(false); VRectanglef screenRect(0.f,0.f,(float)Vision::Video.GetXRes(),(float)Vision::Video.GetYRes()); hkvVec3 vBoxCorner[8]; hkvVec2 vCorner2D(false); // now render the shadows: FOR_ALL_SHADOWS if (pShadow->GetOwner()) pShadow->SetBoundingBoxFromOwnerProperties(); // shadow box visible? if (!viewFrustum.Overlaps(pShadow->m_ShadowBox)) continue; // build 2D bounding box for scissor clipping if (bClipScissor) { VISION_PROFILE_FUNCTION(PROFILING_BS_SCISSORRECT); clipRect.Reset(); pShadow->m_ShadowBox.getCorners(vBoxCorner); for (int i=0; i<8; i++) { // if one vertex is behind camera, do not use clipping if (!Vision::Contexts.GetCurrentContext()->Project2D(vBoxCorner[i],vCorner2D.x,vCorner2D.y)) { Vision::RenderLoopHelper.SetScissorRect(NULL); goto render_shadow; } clipRect.Add(vCorner2D); } VASSERT(clipRect.IsValid()); clipRect = clipRect.GetIntersection(screenRect); if (!clipRect.IsValid()) continue; // do not render shadows at all if rect is outside the screen Vision::RenderLoopHelper.SetScissorRect(&clipRect); } render_shadow: // get the visible primitives in the shadow bounding box { VISION_PROFILE_FUNCTION(PROFILING_BS_DETERMINE_PRIMS); // affected static geometry: shadowGeom.Clear(); pVisibleGeom->DetermineEntriesTouchingBox(pShadow->m_ShadowBox,shadowGeom); } // split into geometry types: if (!shadowGeom.GetNumEntries()) continue; const VisStaticGeometryType_e relevantTypes[2] = {STATIC_GEOMETRY_TYPE_MESHINSTANCE,STATIC_GEOMETRY_TYPE_TERRAIN}; // two relevant geometry types: for (int iType=0; iType<2; iType++) { shadowGeomOfType.Clear(); shadowGeom.GetEntriesOfType(shadowGeomOfType,relevantTypes[iType]); VCompiledTechnique *pFX = GetDefaultTechnique(relevantTypes[iType]); if (shadowGeomOfType.GetNumEntries()==0 || pFX==NULL) continue; // for all the shader in the projection effect (usually 1 shader), render the primitive collection const int iShaderCount = pFX->GetShaderCount(); for (int j=0; j<iShaderCount; j++) { VBlobShadowShader *pShader = (VBlobShadowShader *)pFX->GetShader(j); { // code block for easier profiling VISION_PROFILE_FUNCTION(PROFILING_BS_PREPARE_SHADER); // prepare the shader, i.e. setup shadow specific projection planes, colors etc. pShader->UpdateShadow(pShadow); } { // code block for easier profiling VISION_PROFILE_FUNCTION(PROFILING_BS_RENDER_PRIMS); Vision::RenderLoopHelper.RenderStaticGeometryWithShader(shadowGeomOfType,*pShader); } } } }
ossimAnnotationObject* ossimAnnotationMultiPolyObject::getNewClippedObject(const ossimDrect& rect)const { ossimAnnotationObject* result = (ossimAnnotationObject*)NULL; if(theBoundingRect.intersects(rect)) { ossimDrect clipRect(rect.ul().x - 10, rect.ul().y - 10, rect.lr().x + 10, rect.lr().y + 10); if(theFillEnabled) { vector<ossimPolygon> polyListResult; for(ossim_uint32 i = 0; i < theMultiPolygon.size(); ++i) { vector<ossimPolygon> tempList; if(theMultiPolygon[i].clipToRect(tempList, rect)) { polyListResult.insert(polyListResult.end(), tempList.begin(), tempList.end()); } } if(polyListResult.size()) { result = new ossimAnnotationMultiPolyObject(polyListResult, theFillEnabled, theRed, theGreen, theBlue, theThickness); } } else { vector<ossimPolyLine> lineListResult; vector<ossimPolyLine> tempResult; for(ossim_uint32 i = 0; i< theMultiPolygon.size(); ++i) { ossimPolyLine polyLine = theMultiPolygon[i]; if(polyLine.clipToRect(tempResult, clipRect)) { lineListResult.insert(lineListResult.end(), tempResult.begin(), tempResult.end()); } } if(lineListResult.size()) { result = new ossimAnnotationMultiLineObject(lineListResult, theRed, theGreen, theBlue, theThickness); } } } return result; }
void ossimAnnotationMultiPolyObject::draw(ossimRgbImage& anImage)const { if(theMultiPolygon.size()<1) return; if(theBoundingRect.hasNans()) return; anImage.setDrawColor(theRed, theGreen, theBlue); anImage.setThickness(theThickness); ossimDrect imageRect = anImage.getImageData()->getImageRectangle(); if(theBoundingRect.intersects(imageRect)) { // we need to extend it by a couple of pixels since // if a pixel lies on the edge and then another pixel is just off // the edge we will get a stair step and so for several pixels // the line might be inside the image rectangle but the clip // algorithm will only draw 1 pixel since it thinks the first // point is inside and the second point is outside and will // execute the clip algorithm keeping only the first // point. ossimDrect clipRect(imageRect.ul().x - 10, imageRect.ul().y - 10, imageRect.lr().x + 10, imageRect.lr().y + 10); int j = 0; for(ossim_uint32 i = 0; i < theMultiPolygon.size(); ++i) { const ossimPolygon& poly = theMultiPolygon[i]; int vertexCount = poly.getVertexCount(); if(!theFillEnabled) { if(poly.getNumberOfVertices() == 1) { ossimDpt start, end; start = poly[0]; end = poly[0]; if(clipRect.clip(start, end)) { anImage.drawLine(ossimIpt(start), ossimIpt(end)); } } else if(poly.getNumberOfVertices() == 2) { ossimDpt start, end; start = poly[0]; end = poly[1]; if(clipRect.clip(start, end)) { anImage.drawLine(ossimIpt(start), ossimIpt(end)); } } else if(vertexCount > 2) { ossimDpt start, end; j = 0; while(j<vertexCount) { start = poly[j]; end = poly[(j+1)%vertexCount]; if(clipRect.clip(start, end)) { anImage.drawLine(ossimIpt(start), ossimIpt(end)); } ++j; } #if 0 ossimDpt start, end; start = poly[vertexCount-1]; end = poly[0]; j = 0; do { if(clipRect.clip(start, end)) { anImage.drawLine(ossimIpt(start), ossimIpt(end)); } ++j; start = poly[j-1]; end = poly[j]; } while(j < vertexCount); #endif } } else { vector<ossimPolygon> result; if(poly.clipToRect(result, imageRect)) { for(j = 0; j < (int)result.size(); ++j) { anImage.drawFilledPolygon(result[j].getVertexList()); } } } } } }
LayoutState::LayoutState(std::unique_ptr<LayoutState> next, RenderBox* renderer, const LayoutSize& offset, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged, ColumnInfo* columnInfo) : m_columnInfo(columnInfo) , m_lineGrid(0) , m_next(std::move(next)) #if ENABLE(CSS_SHAPES) , m_shapeInsideInfo(0) #endif #ifndef NDEBUG , m_renderer(renderer) #endif { ASSERT(m_next); bool fixed = renderer->isOutOfFlowPositioned() && renderer->style().position() == FixedPosition; if (fixed) { // FIXME: This doesn't work correctly with transforms. FloatPoint fixedOffset = renderer->view().localToAbsolute(FloatPoint(), IsFixed); m_paintOffset = LayoutSize(fixedOffset.x(), fixedOffset.y()) + offset; } else m_paintOffset = m_next->m_paintOffset + offset; if (renderer->isOutOfFlowPositioned() && !fixed) { if (RenderElement* container = renderer->container()) { if (container->isInFlowPositioned() && container->isRenderInline()) m_paintOffset += toRenderInline(container)->offsetForInFlowPositionedInline(renderer); } } m_layoutOffset = m_paintOffset; if (renderer->isInFlowPositioned() && renderer->hasLayer()) m_paintOffset += renderer->layer()->offsetForInFlowPosition(); m_clipped = !fixed && m_next->m_clipped; if (m_clipped) m_clipRect = m_next->m_clipRect; if (renderer->hasOverflowClip()) { LayoutRect clipRect(toPoint(m_paintOffset) + renderer->view().layoutDelta(), renderer->cachedSizeForOverflowClip()); if (m_clipped) m_clipRect.intersect(clipRect); else { m_clipRect = clipRect; m_clipped = true; } m_paintOffset -= renderer->scrolledContentOffset(); } // If we establish a new page height, then cache the offset to the top of the first page. // We can compare this later on to figure out what part of the page we're actually on, if (pageLogicalHeight || m_columnInfo || renderer->isRenderFlowThread()) { m_pageLogicalHeight = pageLogicalHeight; bool isFlipped = renderer->style().isFlippedBlocksWritingMode(); m_pageOffset = LayoutSize(m_layoutOffset.width() + (!isFlipped ? renderer->borderLeft() + renderer->paddingLeft() : renderer->borderRight() + renderer->paddingRight()), m_layoutOffset.height() + (!isFlipped ? renderer->borderTop() + renderer->paddingTop() : renderer->borderBottom() + renderer->paddingBottom())); m_pageLogicalHeightChanged = pageLogicalHeightChanged; } else { // If we don't establish a new page height, then propagate the old page height and offset down. m_pageLogicalHeight = m_next->m_pageLogicalHeight; m_pageLogicalHeightChanged = m_next->m_pageLogicalHeightChanged; m_pageOffset = m_next->m_pageOffset; // Disable pagination for objects we don't support. For now this includes overflow:scroll/auto, inline blocks and // writing mode roots. if (renderer->isUnsplittableForPagination()) m_pageLogicalHeight = 0; } // Propagate line grid information. propagateLineGridInfo(renderer); if (!m_columnInfo) m_columnInfo = m_next->m_columnInfo; #if ENABLE(CSS_SHAPES) if (renderer->isRenderBlock()) { const RenderBlock* renderBlock = toRenderBlock(renderer); m_shapeInsideInfo = renderBlock->shapeInsideInfo(); if (!m_shapeInsideInfo && m_next->m_shapeInsideInfo && renderBlock->allowsShapeInsideInfoSharing()) m_shapeInsideInfo = m_next->m_shapeInsideInfo; } #endif m_layoutDelta = m_next->m_layoutDelta; #if !ASSERT_DISABLED && ENABLE(SATURATED_LAYOUT_ARITHMETIC) m_layoutDeltaXSaturated = m_next->m_layoutDeltaXSaturated; m_layoutDeltaYSaturated = m_next->m_layoutDeltaYSaturated; #endif m_isPaginated = m_pageLogicalHeight || m_columnInfo || renderer->isRenderFlowThread(); if (lineGrid() && renderer->hasColumns() && renderer->style().hasInlineColumnAxis()) computeLineGridPaginationOrigin(renderer); // If we have a new grid to track, then add it to our set. if (renderer->style().lineGrid() != RenderStyle::initialLineGrid() && renderer->isRenderBlockFlow()) establishLineGrid(toRenderBlockFlow(renderer)); // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip if present. }
PassOwnPtr<CCSharedQuadState> CCRenderSurface::createReplicaSharedQuadState() const { bool isOpaque = false; return CCSharedQuadState::create(replicaOriginTransform(), replicaDrawTransform(), contentRect(), clipRect(), drawOpacity(), isOpaque); }
template<class ContainerT> void ContainerRender(ContainerT* aContainer, const nsIntPoint& aOffset, LayerManagerComposite* aManager, const nsIntRect& aClipRect) { /** * Setup our temporary surface for rendering the contents of this container. */ RefPtr<CompositingRenderTarget> surface; Compositor* compositor = aManager->GetCompositor(); RefPtr<CompositingRenderTarget> previousTarget = compositor->GetCurrentRenderTarget(); nsIntPoint childOffset(aOffset); nsIntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds(); aContainer->mSupportsComponentAlphaChildren = false; float opacity = aContainer->GetEffectiveOpacity(); bool needsSurface = aContainer->UseIntermediateSurface(); if (needsSurface) { SurfaceInitMode mode = INIT_MODE_CLEAR; bool surfaceCopyNeeded = false; gfx::IntRect surfaceRect = gfx::IntRect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height); // we're about to create a framebuffer backed by textures to use as an intermediate // surface. What to do if its size (as given by framebufferRect) would exceed the // maximum texture size supported by the GL? The present code chooses the compromise // of just clamping the framebuffer's size to the max supported size. // This gives us a lower resolution rendering of the intermediate surface (children layers). // See bug 827170 for a discussion. int32_t maxTextureSize = compositor->GetMaxTextureSize(); surfaceRect.width = std::min(maxTextureSize, surfaceRect.width); surfaceRect.height = std::min(maxTextureSize, surfaceRect.height); if (aContainer->GetEffectiveVisibleRegion().GetNumRects() == 1 && (aContainer->GetContentFlags() & Layer::CONTENT_OPAQUE)) { // don't need a background, we're going to paint all opaque stuff aContainer->mSupportsComponentAlphaChildren = true; mode = INIT_MODE_NONE; } else { const gfx3DMatrix& transform3D = aContainer->GetEffectiveTransform(); gfxMatrix transform; // If we have an opaque ancestor layer, then we can be sure that // all the pixels we draw into are either opaque already or will be // covered by something opaque. Otherwise copying up the background is // not safe. if (HasOpaqueAncestorLayer(aContainer) && transform3D.Is2D(&transform) && !transform.HasNonIntegerTranslation()) { mode = gfxPlatform::GetPlatform()->UsesSubpixelAATextRendering() ? INIT_MODE_COPY : INIT_MODE_CLEAR; surfaceCopyNeeded = (mode == INIT_MODE_COPY); surfaceRect.x += transform.x0; surfaceRect.y += transform.y0; aContainer->mSupportsComponentAlphaChildren = gfxPlatform::GetPlatform()->UsesSubpixelAATextRendering(); } } surfaceRect -= gfx::IntPoint(aOffset.x, aOffset.y); if (surfaceCopyNeeded) { surface = compositor->CreateRenderTargetFromSource(surfaceRect, previousTarget); } else { surface = compositor->CreateRenderTarget(surfaceRect, mode); } compositor->SetRenderTarget(surface); childOffset.x = visibleRect.x; childOffset.y = visibleRect.y; } else { surface = previousTarget; aContainer->mSupportsComponentAlphaChildren = (aContainer->GetContentFlags() & Layer::CONTENT_OPAQUE) || (aContainer->GetParent() && aContainer->GetParent()->SupportsComponentAlphaChildren()); } nsAutoTArray<Layer*, 12> children; aContainer->SortChildrenBy3DZOrder(children); /** * Render this container's contents. */ for (uint32_t i = 0; i < children.Length(); i++) { LayerComposite* layerToRender = static_cast<LayerComposite*>(children.ElementAt(i)->ImplData()); if (layerToRender->GetLayer()->GetEffectiveVisibleRegion().IsEmpty() && !layerToRender->GetLayer()->AsContainerLayer()) { continue; } nsIntRect clipRect = layerToRender->GetLayer()-> CalculateScissorRect(aClipRect, &aManager->GetWorldTransform()); if (clipRect.IsEmpty()) { continue; } layerToRender->RenderLayer(childOffset, clipRect); // invariant: our GL context should be current here, I don't think we can // assert it though } if (needsSurface) { // Unbind the current surface and rebind the previous one. #ifdef MOZ_DUMP_PAINTING if (gfxUtils::sDumpPainting) { nsRefPtr<gfxImageSurface> surf = surface->Dump(aManager->GetCompositor()); WriteSnapshotToDumpFile(aContainer, surf); } #endif compositor->SetRenderTarget(previousTarget); EffectChain effectChain; LayerManagerComposite::AddMaskEffect(aContainer->GetMaskLayer(), effectChain, !aContainer->GetTransform().CanDraw2D()); effectChain.mPrimaryEffect = new EffectRenderTarget(surface); gfx::Matrix4x4 transform; ToMatrix4x4(aContainer->GetEffectiveTransform(), transform); gfx::Rect rect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height); gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height); aManager->GetCompositor()->DrawQuad(rect, clipRect, effectChain, opacity, transform, gfx::Point(aOffset.x, aOffset.y)); } if (aContainer->GetFrameMetrics().IsScrollable()) { gfx::Matrix4x4 transform; ToMatrix4x4(aContainer->GetEffectiveTransform(), transform); const FrameMetrics& frame = aContainer->GetFrameMetrics(); LayerRect layerViewport = frame.mViewport * frame.LayersPixelsPerCSSPixel(); gfx::Rect rect(layerViewport.x, layerViewport.y, layerViewport.width, layerViewport.height); gfx::Rect clipRect(aClipRect.x, aClipRect.y, aClipRect.width, aClipRect.height); aManager->GetCompositor()->DrawDiagnostics(gfx::Color(1.0, 0.0, 0.0, 1.0), rect, clipRect, transform, gfx::Point(aOffset.x, aOffset.y)); } }
const unsigned char* QgsSymbolV2::_getPolygon( QPolygonF& pts, QList<QPolygonF>& holes, QgsRenderContext& context, const unsigned char* wkb, bool clipToExtent ) { QgsConstWkbPtr wkbPtr( wkb + 1 ); unsigned int wkbType, numRings; wkbPtr >> wkbType >> numRings; if ( numRings == 0 ) // sanity check for zero rings in polygon return wkbPtr; bool hasZValue = QgsWKBTypes::hasZ( static_cast< QgsWKBTypes::Type >( wkbType ) ); bool hasMValue = QgsWKBTypes::hasM( static_cast< QgsWKBTypes::Type >( wkbType ) ); double x, y; holes.clear(); const QgsCoordinateTransform* ct = context.coordinateTransform(); const QgsMapToPixel& mtp = context.mapToPixel(); const QgsRectangle& e = context.extent(); double cw = e.width() / 10; double ch = e.height() / 10; QgsRectangle clipRect( e.xMinimum() - cw, e.yMinimum() - ch, e.xMaximum() + cw, e.yMaximum() + ch ); for ( unsigned int idx = 0; idx < numRings; idx++ ) { unsigned int nPoints; wkbPtr >> nPoints; QPolygonF poly( nPoints ); // Extract the points from the WKB and store in a pair of vectors. QPointF* ptr = poly.data(); for ( unsigned int jdx = 0; jdx < nPoints; ++jdx, ++ptr ) { wkbPtr >> x >> y; if ( hasZValue ) wkbPtr += sizeof( double ); if ( hasMValue ) wkbPtr += sizeof( double ); *ptr = QPointF( x, y ); } if ( nPoints < 1 ) continue; //clip close to view extent, if needed QRectF ptsRect = poly.boundingRect(); if ( clipToExtent && !context.extent().contains( ptsRect ) ) QgsClipper::trimPolygon( poly, clipRect ); //transform the QPolygonF to screen coordinates if ( ct ) { ct->transformPolygon( poly ); } ptr = poly.data(); for ( int i = 0; i < poly.size(); ++i, ++ptr ) { mtp.transformInPlace( ptr->rx(), ptr->ry() ); } if ( idx == 0 ) pts = poly; else holes.append( poly ); } return wkbPtr; }