1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #include "gfxQuartzNativeDrawing.h"
7 #include "gfxPlatform.h"
8 #include "mozilla/gfx/Helpers.h"
9
10 using namespace mozilla::gfx;
11 using namespace mozilla;
12
gfxQuartzNativeDrawing(DrawTarget & aDrawTarget,const Rect & nativeRect)13 gfxQuartzNativeDrawing::gfxQuartzNativeDrawing(DrawTarget& aDrawTarget,
14 const Rect& nativeRect)
15 : mDrawTarget(&aDrawTarget)
16 , mNativeRect(nativeRect)
17 , mCGContext(nullptr)
18 {
19 }
20
21 CGContextRef
BeginNativeDrawing()22 gfxQuartzNativeDrawing::BeginNativeDrawing()
23 {
24 NS_ASSERTION(!mCGContext, "BeginNativeDrawing called when drawing already in progress");
25
26 DrawTarget *dt = mDrawTarget;
27 if (dt->IsDualDrawTarget() || dt->IsTiledDrawTarget() ||
28 dt->GetBackendType() != BackendType::SKIA) {
29 // We need a DrawTarget that we can get a CGContextRef from:
30 Matrix transform = dt->GetTransform();
31
32 mNativeRect = transform.TransformBounds(mNativeRect);
33 mNativeRect.RoundOut();
34 // Quartz theme drawing often adjusts drawing rects, so make
35 // sure our surface is big enough for that.
36 mNativeRect.Inflate(5);
37 if (mNativeRect.IsEmpty()) {
38 return nullptr;
39 }
40
41 mTempDrawTarget =
42 Factory::CreateDrawTarget(BackendType::SKIA,
43 IntSize::Truncate(mNativeRect.width, mNativeRect.height),
44 SurfaceFormat::B8G8R8A8);
45
46 if (mTempDrawTarget) {
47 transform.PostTranslate(-mNativeRect.x, -mNativeRect.y);
48 mTempDrawTarget->SetTransform(transform);
49 }
50 dt = mTempDrawTarget;
51 }
52 if (dt) {
53 MOZ_ASSERT(dt->GetBackendType() == BackendType::SKIA);
54 mCGContext = mBorrowedContext.Init(dt);
55 MOZ_ASSERT(mCGContext);
56 }
57 return mCGContext;
58 }
59
60 void
EndNativeDrawing()61 gfxQuartzNativeDrawing::EndNativeDrawing()
62 {
63 NS_ASSERTION(mCGContext, "EndNativeDrawing called without BeginNativeDrawing");
64
65 mBorrowedContext.Finish();
66 if (mTempDrawTarget) {
67 RefPtr<SourceSurface> source = mTempDrawTarget->Snapshot();
68
69 AutoRestoreTransform autoRestore(mDrawTarget);
70 mDrawTarget->SetTransform(Matrix());
71 mDrawTarget->DrawSurface(source, mNativeRect,
72 Rect(0, 0, mNativeRect.width, mNativeRect.height));
73 }
74 }
75