2 * Copyright (c) 2001-2015, Haiku, Inc.
3 * Distributed under the terms of the MIT license.
6 * DarkWyrm <bpmagic@columbus.rr.com>
7 * Adi Oanca <adioanca@gmail.com>
8 * Axel Dörfler, axeld@pinc-software.de
9 * Stephan Aßmus <superstippi@gmx.de>
10 * Marcus Overhagen <marcus@overhagen.de>
11 * Adrien Destugues <pulkomandy@pulkomandy.tk
12 * Julian Harnath <julian.harnath@rwth-aachen.de>
22 #include "AlphaMask.h"
23 #include "DrawingEngine.h"
24 #include "DrawState.h"
30 // GCC >= 3.1 doesn't need it anymore
32 # define GCC_2_NRV(x) return x;
33 // GCC 2 named return value syntax
34 // see http://gcc.gnu.org/onlinedocs/gcc-2.95.2/gcc_5.html#SEC106
40 fDrawState(new(std::nothrow
) DrawState())
45 Canvas::Canvas(const DrawState
& state
)
47 fDrawState(new(std::nothrow
) DrawState(state
))
58 Canvas::InitCheck() const
60 if (fDrawState
== NULL
)
70 DrawState
* newState
= fDrawState
->PushState();
72 fDrawState
= newState
;
79 if (fDrawState
->PreviousState() == NULL
)
82 bool rebuildClipping
= fDrawState
->HasAdditionalClipping();
84 fDrawState
= fDrawState
->PopState();
87 // (the clipping from the popped state is not effective anymore)
89 RebuildClipping(false);
94 Canvas::SetDrawState(DrawState
* newState
)
96 fDrawState
= newState
;
101 Canvas::SetDrawingOrigin(BPoint origin
)
103 fDrawState
->SetOrigin(origin
);
106 if (fDrawState
->HasClipping())
107 RebuildClipping(false);
112 Canvas::DrawingOrigin() const
114 BPoint
origin(fDrawState
->Origin());
115 float scale
= Scale();
125 Canvas::SetScale(float scale
)
127 fDrawState
->SetScale(scale
);
130 if (fDrawState
->HasClipping())
131 RebuildClipping(false);
136 Canvas::Scale() const
138 return fDrawState
->Scale();
143 Canvas::SetUserClipping(const BRegion
* region
)
145 fDrawState
->SetClippingRegion(region
);
147 // rebuild clipping (for just this canvas)
148 RebuildClipping(false);
153 Canvas::ClipToRect(BRect rect
, bool inverse
)
155 bool needDrawStateUpdate
= fDrawState
->ClipToRect(rect
, inverse
);
156 RebuildClipping(false);
157 return needDrawStateUpdate
;
162 Canvas::ClipToShape(shape_data
* shape
, bool inverse
)
164 fDrawState
->ClipToShape(shape
, inverse
);
169 Canvas::SetAlphaMask(AlphaMask
* mask
)
171 fDrawState
->SetAlphaMask(mask
);
176 Canvas::GetAlphaMask() const
178 return fDrawState
->GetAlphaMask();
183 Canvas::LocalToScreenTransform() const GCC_2_NRV(transform
)
186 SimpleTransform transform
;
188 _LocalToScreenTransform(transform
);
194 Canvas::ScreenToLocalTransform() const GCC_2_NRV(transform
)
197 SimpleTransform transform
;
199 _ScreenToLocalTransform(transform
);
205 Canvas::PenToScreenTransform() const GCC_2_NRV(transform
)
208 SimpleTransform transform
;
210 fDrawState
->Transform(transform
);
211 _LocalToScreenTransform(transform
);
217 Canvas::PenToLocalTransform() const GCC_2_NRV(transform
)
220 SimpleTransform transform
;
222 fDrawState
->Transform(transform
);
228 Canvas::ScreenToPenTransform() const GCC_2_NRV(transform
)
231 SimpleTransform transform
;
233 _ScreenToLocalTransform(transform
);
234 fDrawState
->InverseTransform(transform
);
240 Canvas::BlendLayer(Layer
* layer
)
242 if (layer
->Opacity() == 255) {
244 layer
->ReleaseReference();
248 UtilityBitmap
* layerBitmap
= layer
->RenderToBitmap(this);
249 if (layerBitmap
== NULL
)
252 BRect destination
= layerBitmap
->Bounds();
253 destination
.OffsetBy(layer
->LeftTopOffset());
254 LocalToScreenTransform().Apply(&destination
);
258 fDrawState
->SetDrawingMode(B_OP_ALPHA
);
259 fDrawState
->SetBlendingMode(B_PIXEL_ALPHA
, B_ALPHA_COMPOSITE
);
260 fDrawState
->SetTransformEnabled(false);
262 AlphaMask
* mask
= new(std::nothrow
) UniformAlphaMask(layer
->Opacity());
264 layerBitmap
->ReleaseReference();
265 layer
->ReleaseReference();
270 mask
->ReleaseReference();
273 GetDrawingEngine()->DrawBitmap(layerBitmap
, layerBitmap
->Bounds(),
276 fDrawState
->SetTransformEnabled(true);
281 layerBitmap
->ReleaseReference();
282 layer
->ReleaseReference();
286 // #pragma mark - OffscreenCanvas
289 OffscreenCanvas::OffscreenCanvas(DrawingEngine
* engine
,
290 const DrawState
& state
, const IntRect
& bounds
)
293 fDrawingEngine(engine
),
300 OffscreenCanvas::~OffscreenCanvas()
307 OffscreenCanvas::ResyncDrawState()
309 fDrawingEngine
->SetDrawState(fDrawState
);
314 OffscreenCanvas::UpdateCurrentDrawingRegion()
316 if (fDrawState
->HasClipping()) {
317 fDrawState
->GetCombinedClippingRegion(&fCurrentDrawingRegion
);
318 fDrawingEngine
->ConstrainClippingRegion(&fCurrentDrawingRegion
);
324 OffscreenCanvas::Bounds() const