void
gfxQuartzNativeDrawing::EndNativeDrawing()
{
  NS_ASSERTION(mCGContext, "EndNativeDrawing called without BeginNativeDrawing");
  MOZ_ASSERT(!mContext->IsCairo(), "BeginNativeDrawing succeeded with cairo context?");

  mBorrowedContext.Finish();
  if (mDrawTarget) {
    DrawTarget *dest = mContext->GetDrawTarget();
    RefPtr<SourceSurface> source = mDrawTarget->Snapshot();

    IntSize backingSize(NSToIntFloor(mNativeRect.width * mBackingScale),
                        NSToIntFloor(mNativeRect.height * mBackingScale));

    Matrix oldTransform = dest->GetTransform();
    Matrix newTransform = oldTransform;
    newTransform.Translate(mNativeRect.x, mNativeRect.y);
    newTransform.Scale(1.0f / mBackingScale, 1.0f / mBackingScale);

    dest->SetTransform(newTransform);

    dest->DrawSurface(source,
                      gfx::Rect(0, 0, backingSize.width, backingSize.height),
                      gfx::Rect(0, 0, backingSize.width, backingSize.height));


    dest->SetTransform(oldTransform);
  }
}
Example #2
0
void
DrawBlur(gfxContext* aDestinationCtx,
         SourceSurface* aBlur,
         const IntPoint& aTopLeft,
         const Rect* aDirtyRect)
{
    DrawTarget *dest = aDestinationCtx->GetDrawTarget();

    nsRefPtr<gfxPattern> thebesPat = aDestinationCtx->GetPattern();
    Pattern* pat = thebesPat->GetPattern(dest, nullptr);

    Matrix oldTransform = dest->GetTransform();
    Matrix newTransform = oldTransform;
    newTransform.Translate(aTopLeft.x, aTopLeft.y);

    // Avoid a semi-expensive clip operation if we can, otherwise
    // clip to the dirty rect
    if (aDirtyRect) {
        dest->PushClipRect(*aDirtyRect);
    }

    dest->SetTransform(newTransform);
    dest->MaskSurface(*pat, aBlur, Point(0, 0));
    dest->SetTransform(oldTransform);

    if (aDirtyRect) {
        dest->PopClip();
    }
}
void
ClientLayerManager::MakeSnapshotIfRequired()
{
  if (!mShadowTarget) {
    return;
  }
  if (mWidget) {
    if (CompositorBridgeChild* remoteRenderer = GetRemoteRenderer()) {
      // The compositor doesn't draw to a different sized surface
      // when there's a rotation. Instead we rotate the result
      // when drawing into dt
      LayoutDeviceIntRect outerBounds;
      mWidget->GetBounds(outerBounds);

      IntRect bounds = ToOutsideIntRect(mShadowTarget->GetClipExtents());
      if (mTargetRotation) {
        bounds =
          RotateRect(bounds, outerBounds.ToUnknownRect(), mTargetRotation);
      }

      SurfaceDescriptor inSnapshot;
      if (!bounds.IsEmpty() &&
          mForwarder->AllocSurfaceDescriptor(bounds.Size(),
                                             gfxContentType::COLOR_ALPHA,
                                             &inSnapshot)) {

        // Make a copy of |inSnapshot| because the call to send it over IPC
        // will call forget() on the Shmem inside, and zero it out.
        SurfaceDescriptor outSnapshot = inSnapshot;

        if (remoteRenderer->SendMakeSnapshot(inSnapshot, bounds)) {
          RefPtr<DataSourceSurface> surf = GetSurfaceForDescriptor(outSnapshot);
          DrawTarget* dt = mShadowTarget->GetDrawTarget();

          Rect dstRect(bounds.x, bounds.y, bounds.width, bounds.height);
          Rect srcRect(0, 0, bounds.width, bounds.height);

          gfx::Matrix rotate =
            ComputeTransformForUnRotation(outerBounds.ToUnknownRect(),
                                          mTargetRotation);

          gfx::Matrix oldMatrix = dt->GetTransform();
          dt->SetTransform(rotate * oldMatrix);
          dt->DrawSurface(surf, dstRect, srcRect,
                          DrawSurfaceOptions(),
                          DrawOptions(1.0f, CompositionOp::OP_OVER));
          dt->SetTransform(oldMatrix);
        }
        mForwarder->DestroySurfaceDescriptor(&outSnapshot);
      }
    }
  }
  mShadowTarget = nullptr;
}
Example #4
0
  virtual void ProcessReadback(gfx::DataSourceSurface *aSourceSurface)
  {
    SourceRotatedBuffer rotBuffer(aSourceSurface, nullptr, mBufferRect, mBufferRotation);

    for (uint32_t i = 0; i < mReadbackUpdates.Length(); ++i) {
      ReadbackProcessor::Update& update = mReadbackUpdates[i];
      nsIntPoint offset = update.mLayer->GetBackgroundLayerOffset();

      ReadbackSink* sink = update.mLayer->GetSink();

      if (!sink) {
        continue;
      }

      if (!aSourceSurface) {
        sink->SetUnknown(update.mSequenceCounter);
        continue;
      }

      nsRefPtr<gfxContext> ctx =
        sink->BeginUpdate(update.mUpdateRect + offset, update.mSequenceCounter);

      if (!ctx) {
        continue;
      }

      DrawTarget* dt = ctx->GetDrawTarget();
      dt->SetTransform(Matrix::Translation(offset.x, offset.y));

      rotBuffer.DrawBufferWithRotation(dt, RotatedBuffer::BUFFER_BLACK);

      update.mLayer->GetSink()->EndUpdate(ctx, update.mUpdateRect + offset);
    }
  }
Example #5
0
void
gfxAlphaBoxBlur::Paint(gfxContext* aDestinationCtx)
{
    if (!mContext)
        return;

    mBlur->Blur(mData);

    mozilla::gfx::Rect* dirtyRect = mBlur->GetDirtyRect();

    DrawTarget *dest = aDestinationCtx->GetDrawTarget();
    if (!dest) {
      NS_ERROR("Blurring not supported for Thebes contexts!");
      return;
    }

    mozilla::RefPtr<SourceSurface> mask
      = dest->CreateSourceSurfaceFromData(mData,
                                          mBlur->GetSize(),
                                          mBlur->GetStride(),
                                          FORMAT_A8);
    if (!mask) {
      NS_ERROR("Failed to create mask!");
      return;
    }

    nsRefPtr<gfxPattern> thebesPat = aDestinationCtx->GetPattern();
    Pattern* pat = thebesPat->GetPattern(dest, nullptr);

    Matrix oldTransform = dest->GetTransform();
    Matrix newTransform = oldTransform;
    newTransform.Translate(mBlur->GetRect().x, mBlur->GetRect().y);

    // Avoid a semi-expensive clip operation if we can, otherwise
    // clip to the dirty rect
    if (dirtyRect) {
        dest->PushClipRect(*dirtyRect);
    }

    dest->SetTransform(newTransform);
    dest->MaskSurface(*pat, mask, Point(0, 0));
    dest->SetTransform(oldTransform);

    if (dirtyRect) {
        dest->PopClip();
    }
}
Example #6
0
void
gfxAlphaBoxBlur::Paint(gfxContext* aDestinationCtx)
{
  if (!mAccelerated && !mData) {
    return;
  }

  DrawTarget *dest = aDestinationCtx->GetDrawTarget();
  if (!dest) {
    NS_WARNING("Blurring not supported for Thebes contexts!");
    return;
  }

  RefPtr<gfxPattern> thebesPat = aDestinationCtx->GetPattern();
  Pattern* pat = thebesPat->GetPattern(dest, nullptr);
  if (!pat) {
    NS_WARNING("Failed to get pattern for blur!");
    return;
  }

  IntPoint topLeft;
  RefPtr<SourceSurface> mask = DoBlur(nullptr, &topLeft);
  if (!mask) {
    NS_ERROR("Failed to create mask!");
    return;
  }

  // Avoid a semi-expensive clip operation if we can, otherwise
  // clip to the dirty rect
  Rect* dirtyRect = mBlur.GetDirtyRect();
  if (dirtyRect) {
    dest->PushClipRect(*dirtyRect);
  }

  Matrix oldTransform = dest->GetTransform();
  Matrix newTransform = oldTransform;
  newTransform.PreTranslate(topLeft);
  dest->SetTransform(newTransform);

  dest->MaskSurface(*pat, mask, Point(0, 0));

  dest->SetTransform(oldTransform);

  if (dirtyRect) {
    dest->PopClip();
  }
}
void
ClientLayerManager::MakeSnapshotIfRequired()
{
  if (!mShadowTarget) {
    return;
  }
  if (mWidget) {
    if (CompositorChild* remoteRenderer = GetRemoteRenderer()) {
      // The compositor doesn't draw to a different sized surface
      // when there's a rotation. Instead we rotate the result
      // when drawing into dt
      nsIntRect outerBounds;
      mWidget->GetBounds(outerBounds);

      nsIntRect bounds = ToOutsideIntRect(mShadowTarget->GetClipExtents());
      if (mTargetRotation) {
        bounds = RotateRect(bounds, outerBounds, mTargetRotation);
      }

      SurfaceDescriptor inSnapshot;
      if (!bounds.IsEmpty() &&
          mForwarder->AllocSurfaceDescriptor(bounds.Size().ToIntSize(),
                                             gfxContentType::COLOR_ALPHA,
                                             &inSnapshot) &&
          remoteRenderer->SendMakeSnapshot(inSnapshot, bounds)) {
        RefPtr<DataSourceSurface> surf = GetSurfaceForDescriptor(inSnapshot);
        DrawTarget* dt = mShadowTarget->GetDrawTarget();

        Rect dstRect(bounds.x, bounds.y, bounds.width, bounds.height);
        Rect srcRect(0, 0, bounds.width, bounds.height);

        gfx::Matrix rotate = ComputeTransformForUnRotation(outerBounds, mTargetRotation);

        gfx::Matrix oldMatrix = dt->GetTransform();
        dt->SetTransform(oldMatrix * rotate);
        dt->DrawSurface(surf, dstRect, srcRect,
                        DrawSurfaceOptions(),
                        DrawOptions(1.0f, CompositionOp::OP_OVER));
        dt->SetTransform(oldMatrix);
      }
      mForwarder->DestroySharedSurface(&inSnapshot);
    }
  }
  mShadowTarget = nullptr;
}
Example #8
0
DrawTarget*
ContentClientIncremental::BorrowDrawTargetForPainting(const PaintState& aPaintState,
        RotatedContentBuffer::DrawIterator* aIter)
{
    if (aPaintState.mMode == SurfaceMode::SURFACE_NONE) {
        return nullptr;
    }

    if (aIter) {
        if (aIter->mCount++ > 0) {
            return nullptr;
        }
        aIter->mDrawRegion = aPaintState.mRegionToDraw;
    }

    DrawTarget* result = nullptr;

    nsIntRect drawBounds = aPaintState.mRegionToDraw.GetBounds();
    MOZ_ASSERT(!mLoanedDrawTarget);

    // BeginUpdate is allowed to modify the given region,
    // if it wants more to be repainted than we request.
    if (aPaintState.mMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
        nsIntRegion drawRegionCopy = aPaintState.mRegionToDraw;
        RefPtr<DrawTarget> onBlack = GetUpdateSurface(BUFFER_BLACK, drawRegionCopy);
        RefPtr<DrawTarget> onWhite = GetUpdateSurface(BUFFER_WHITE, aPaintState.mRegionToDraw);
        if (onBlack && onWhite) {
            NS_ASSERTION(aPaintState.mRegionToDraw == drawRegionCopy,
                         "BeginUpdate should always modify the draw region in the same way!");
            FillSurface(onBlack, aPaintState.mRegionToDraw, nsIntPoint(drawBounds.x, drawBounds.y), gfxRGBA(0.0, 0.0, 0.0, 1.0));
            FillSurface(onWhite, aPaintState.mRegionToDraw, nsIntPoint(drawBounds.x, drawBounds.y), gfxRGBA(1.0, 1.0, 1.0, 1.0));
            mLoanedDrawTarget = Factory::CreateDualDrawTarget(onBlack, onWhite);
        } else {
            mLoanedDrawTarget = nullptr;
        }
    } else {
        mLoanedDrawTarget = GetUpdateSurface(BUFFER_BLACK, aPaintState.mRegionToDraw);
    }
    if (!mLoanedDrawTarget) {
        NS_WARNING("unable to get context for update");
        return nullptr;
    }

    result = mLoanedDrawTarget;
    mLoanedTransform = mLoanedDrawTarget->GetTransform();
    mLoanedTransform.Translate(-drawBounds.x, -drawBounds.y);
    result->SetTransform(mLoanedTransform);
    mLoanedTransform.Translate(drawBounds.x, drawBounds.y);

    if (mContentType == gfxContentType::COLOR_ALPHA) {
        gfxUtils::ClipToRegion(result, aPaintState.mRegionToDraw);
        nsIntRect bounds = aPaintState.mRegionToDraw.GetBounds();
        result->ClearRect(Rect(bounds.x, bounds.y, bounds.width, bounds.height));
    }

    return result;
}
void
gfxQuartzNativeDrawing::EndNativeDrawing()
{
    NS_ASSERTION(mCGContext, "EndNativeDrawing called without BeginNativeDrawing");

    if (mBorrowedContext.cg) {
        MOZ_ASSERT(!mContext->IsCairo());
        mBorrowedContext.Finish();
        if (mDrawTarget) {
          DrawTarget *dest = mContext->GetDrawTarget();
          RefPtr<SourceSurface> source = mDrawTarget->Snapshot();

          IntSize backingSize(NSToIntFloor(mNativeRect.width * mBackingScale),
                              NSToIntFloor(mNativeRect.height * mBackingScale));

          Matrix oldTransform = dest->GetTransform();
          Matrix newTransform = oldTransform;
          newTransform.Translate(mNativeRect.x, mNativeRect.y);
          newTransform.Scale(1.0f / mBackingScale, 1.0f / mBackingScale);

          dest->SetTransform(newTransform);

          dest->DrawSurface(source,
                            gfx::Rect(0, 0, backingSize.width, backingSize.height),
                            gfx::Rect(0, 0, backingSize.width, backingSize.height));


          dest->SetTransform(oldTransform);
        }
        return;
    }

    cairo_quartz_finish_cg_context_with_clip(mSurfaceContext->GetCairo());
    mQuartzSurface->MarkDirty();
    if (mSurfaceContext != mContext) {
        gfxContextMatrixAutoSaveRestore save(mContext);

        // Copy back to destination
        mContext->Translate(mNativeRect.TopLeft());
        mContext->Scale(1.0f / mBackingScale, 1.0f / mBackingScale);
        mContext->DrawSurface(mQuartzSurface, mQuartzSurface->GetSize());
    }
}
void
gfxWindowsNativeDrawing::PaintToContext()
{
    if (mRenderState == RENDER_STATE_NATIVE_DRAWING_DONE) {
        // nothing to do, it already went to the context
        mRenderState = RENDER_STATE_DONE;
    } else if (mRenderState == RENDER_STATE_ALPHA_RECOVERY_WHITE_DONE) {
        RefPtr<gfxImageSurface> black = mBlackSurface->GetAsImageSurface();
        RefPtr<gfxImageSurface> white = mWhiteSurface->GetAsImageSurface();
        if (!gfxAlphaRecovery::RecoverAlpha(black, white)) {
            NS_ERROR("Alpha recovery failure");
            return;
        }
        RefPtr<DataSourceSurface> source =
            Factory::CreateWrappingDataSourceSurface(black->Data(),
                                                     black->Stride(),
                                                     black->GetSize(),
                                                     SurfaceFormat::B8G8R8A8);
        {
            DrawTarget* dt = mContext->GetDrawTarget();
            AutoRestoreTransform autoRestoreTransform(dt);

            Matrix newTransform = dt->GetTransform();
            newTransform.PreTranslate(ToPoint(mNativeRect.TopLeft()));
            dt->SetTransform(newTransform);

            Rect rect(Point(0.0, 0.0), ToSize(mNativeRect.Size()));
            Matrix m = Matrix::Scaling(1.0 / mScale.width, 1.0 / mScale.height);
            Filter filter = (mNativeDrawFlags & DO_NEAREST_NEIGHBOR_FILTERING)
                          ? Filter::LINEAR
                          : Filter::GOOD;
            SurfacePattern pat(source, ExtendMode::CLAMP, m, filter);
            dt->FillRect(rect, pat);
        }

        mRenderState = RENDER_STATE_DONE;
    } else {
        NS_ERROR("Invalid RenderState in gfxWindowsNativeDrawing::PaintToContext");
    }
}
Example #11
0
void
nsTableCellFrame::DecorateForSelection(nsRenderingContext& aRenderingContext,
                                       nsPoint aPt)
{
  NS_ASSERTION(IsSelected(), "Should only be called for selected cells");
  int16_t displaySelection;
  nsPresContext* presContext = PresContext();
  displaySelection = DisplaySelection(presContext);
  if (displaySelection) {
    RefPtr<nsFrameSelection> frameSelection =
      presContext->PresShell()->FrameSelection();

    if (frameSelection->GetTableCellSelection()) {
      nscolor       bordercolor;
      if (displaySelection == nsISelectionController::SELECTION_DISABLED) {
        bordercolor = NS_RGB(176,176,176);// disabled color
      }
      else {
        bordercolor =
          LookAndFeel::GetColor(LookAndFeel::eColorID_TextSelectBackground);
      }
      nscoord threePx = nsPresContext::CSSPixelsToAppUnits(3);
      if ((mRect.width > threePx) && (mRect.height > threePx))
      {
        //compare bordercolor to ((nsStyleColor *)myColor)->mBackgroundColor)
        bordercolor = EnsureDifferentColors(bordercolor,
                                            StyleBackground()->mBackgroundColor);

        int32_t appUnitsPerDevPixel = PresContext()->AppUnitsPerDevPixel();
        Point devPixelOffset = NSPointToPoint(aPt, appUnitsPerDevPixel);

        DrawTarget* drawTarget = aRenderingContext.GetDrawTarget();
        AutoRestoreTransform autoRestoreTransform(drawTarget);
        drawTarget->SetTransform(
          drawTarget->GetTransform().PreTranslate(devPixelOffset));

        ColorPattern color(ToDeviceColor(bordercolor));

        nscoord onePixel = nsPresContext::CSSPixelsToAppUnits(1);

        StrokeLineWithSnapping(nsPoint(onePixel, 0), nsPoint(mRect.width, 0),
                               appUnitsPerDevPixel, *drawTarget, color);
        StrokeLineWithSnapping(nsPoint(0, onePixel), nsPoint(0, mRect.height),
                               appUnitsPerDevPixel, *drawTarget, color);
        StrokeLineWithSnapping(nsPoint(onePixel, mRect.height),
                               nsPoint(mRect.width, mRect.height),
                               appUnitsPerDevPixel, *drawTarget, color);
        StrokeLineWithSnapping(nsPoint(mRect.width, onePixel),
                               nsPoint(mRect.width, mRect.height),
                               appUnitsPerDevPixel, *drawTarget, color);
        //middle
        nsRect r(onePixel, onePixel,
                 mRect.width - onePixel, mRect.height - onePixel);
        Rect devPixelRect =
          NSRectToSnappedRect(r, appUnitsPerDevPixel, *drawTarget);
        drawTarget->StrokeRect(devPixelRect, color);
        //shading
        StrokeLineWithSnapping(nsPoint(2*onePixel, mRect.height-2*onePixel),
                               nsPoint(mRect.width-onePixel, mRect.height- (2*onePixel)),
                               appUnitsPerDevPixel, *drawTarget, color);
        StrokeLineWithSnapping(nsPoint(mRect.width - (2*onePixel), 2*onePixel),
                               nsPoint(mRect.width - (2*onePixel), mRect.height-onePixel),
                               appUnitsPerDevPixel, *drawTarget, color);
      }
    }
  }
}