mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-27 20:25:44 +00:00
1cdb518fb7
The new clip from bug 1364007 can cause us to clip to a rectangle that's not aligned to device pixels. With the current rect inflation, we didn't notice, but if we want to remove the inflation then we need to make sure to round out the rect that we clip to. MozReview-Commit-ID: BO9zds8fiKI --HG-- extra : rebase_source : f71f283ef73cf58dbc2cc05d06ea9bc864fd5084
93 lines
2.9 KiB
C++
93 lines
2.9 KiB
C++
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "gfxQuartzNativeDrawing.h"
|
|
#include "gfxPlatform.h"
|
|
#include "mozilla/gfx/Helpers.h"
|
|
|
|
using namespace mozilla::gfx;
|
|
using namespace mozilla;
|
|
|
|
gfxQuartzNativeDrawing::gfxQuartzNativeDrawing(DrawTarget& aDrawTarget,
|
|
const Rect& nativeRect)
|
|
: mDrawTarget(&aDrawTarget)
|
|
, mNativeRect(nativeRect)
|
|
, mCGContext(nullptr)
|
|
{
|
|
}
|
|
|
|
CGContextRef
|
|
gfxQuartzNativeDrawing::BeginNativeDrawing()
|
|
{
|
|
NS_ASSERTION(!mCGContext, "BeginNativeDrawing called when drawing already in progress");
|
|
|
|
DrawTarget *dt = mDrawTarget;
|
|
if (dt->IsDualDrawTarget() || dt->IsTiledDrawTarget() ||
|
|
dt->GetBackendType() != BackendType::SKIA || dt->IsRecording()) {
|
|
// We need a DrawTarget that we can get a CGContextRef from:
|
|
Matrix transform = dt->GetTransform();
|
|
|
|
mNativeRect = transform.TransformBounds(mNativeRect);
|
|
mNativeRect.RoundOut();
|
|
if (mNativeRect.IsEmpty()) {
|
|
return nullptr;
|
|
}
|
|
|
|
mTempDrawTarget =
|
|
Factory::CreateDrawTarget(BackendType::SKIA,
|
|
IntSize::Truncate(mNativeRect.width, mNativeRect.height),
|
|
SurfaceFormat::B8G8R8A8);
|
|
if (!mTempDrawTarget) {
|
|
return nullptr;
|
|
}
|
|
|
|
transform.PostTranslate(-mNativeRect.x, -mNativeRect.y);
|
|
mTempDrawTarget->SetTransform(transform);
|
|
|
|
dt = mTempDrawTarget;
|
|
} else {
|
|
// Clip the DT in case BorrowedCGContext needs to create a new layer.
|
|
// This prevents it from creating a new layer the size of the window.
|
|
// But make sure that this clip is device pixel aligned.
|
|
Matrix transform = dt->GetTransform();
|
|
|
|
Rect deviceRect = transform.TransformBounds(mNativeRect);
|
|
deviceRect.RoundOut();
|
|
mNativeRect = transform.Inverse().TransformBounds(deviceRect);
|
|
mDrawTarget->PushClipRect(mNativeRect);
|
|
}
|
|
|
|
MOZ_ASSERT(dt->GetBackendType() == BackendType::SKIA);
|
|
mCGContext = mBorrowedContext.Init(dt);
|
|
|
|
if (NS_WARN_IF(!mCGContext)) {
|
|
// Failed borrowing CG context, so we need to clean up.
|
|
if (!mTempDrawTarget) {
|
|
mDrawTarget->PopClip();
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
return mCGContext;
|
|
}
|
|
|
|
void
|
|
gfxQuartzNativeDrawing::EndNativeDrawing()
|
|
{
|
|
NS_ASSERTION(mCGContext, "EndNativeDrawing called without BeginNativeDrawing");
|
|
|
|
mBorrowedContext.Finish();
|
|
if (mTempDrawTarget) {
|
|
RefPtr<SourceSurface> source = mTempDrawTarget->Snapshot();
|
|
|
|
AutoRestoreTransform autoRestore(mDrawTarget);
|
|
mDrawTarget->SetTransform(Matrix());
|
|
mDrawTarget->DrawSurface(source, mNativeRect,
|
|
Rect(0, 0, mNativeRect.width, mNativeRect.height));
|
|
} else {
|
|
mDrawTarget->PopClip();
|
|
}
|
|
}
|