| Index: gfx/canvas_direct2d.cc
|
| ===================================================================
|
| --- gfx/canvas_direct2d.cc (revision 53197)
|
| +++ gfx/canvas_direct2d.cc (working copy)
|
| @@ -36,10 +36,17 @@
|
| // CanvasDirect2D, public:
|
|
|
| CanvasDirect2D::CanvasDirect2D(ID2D1RenderTarget* rt) : rt_(rt) {
|
| + // A RenderState entry is pushed onto the stack to track the clip count prior
|
| + // to any calls to Save*().
|
| + state_.push(RenderState());
|
| rt_->BeginDraw();
|
| }
|
|
|
| CanvasDirect2D::~CanvasDirect2D() {
|
| + // Unwind any clips that were pushed outside of any Save*()/Restore() pairs.
|
| + int clip_count = state_.top().clip_count;
|
| + for (int i = 0; i < clip_count; ++i)
|
| + rt_->PopAxisAlignedClip();
|
| rt_->EndDraw();
|
| }
|
|
|
| @@ -54,10 +61,7 @@
|
| // CanvasDirect2D, Canvas implementation:
|
|
|
| void CanvasDirect2D::Save() {
|
| - if (!drawing_state_block_)
|
| - GetD2D1Factory()->CreateDrawingStateBlock(drawing_state_block_.Receive());
|
| - rt_->SaveDrawingState(drawing_state_block_.get());
|
| - layers_.push(NULL);
|
| + SaveInternal(NULL);
|
| }
|
|
|
| void CanvasDirect2D::SaveLayerAlpha(uint8 alpha) {
|
| @@ -81,35 +85,45 @@
|
| D2D1_LAYER_OPTIONS_NONE),
|
| layer);
|
| }
|
| - layers_.push(layer);
|
| + SaveInternal(layer);
|
| }
|
|
|
| void CanvasDirect2D::Restore() {
|
| - ID2D1Layer* layer = layers_.top();
|
| + ID2D1Layer* layer = state_.top().layer;
|
| if (layer) {
|
| rt_->PopLayer();
|
| layer->Release();
|
| }
|
| - layers_.pop();
|
| +
|
| + int clip_count = state_.top().clip_count;
|
| + for (int i = 0; i < clip_count; ++i)
|
| + rt_->PopAxisAlignedClip();
|
| +
|
| + state_.pop();
|
| + // The state_ stack should never be empty - we should always have at least one
|
| + // entry to hold a clip count when there is no active save/restore entry.
|
| + CHECK(!state_.empty()) << "Called Restore() once too often!";
|
| +
|
| rt_->RestoreDrawingState(drawing_state_block_);
|
| }
|
|
|
| -bool CanvasDirect2D::GetClipRect(gfx::Rect* clip_rect) {
|
| - return false;
|
| -}
|
| -
|
| bool CanvasDirect2D::ClipRectInt(int x, int y, int w, int h) {
|
| - return false;
|
| + rt_->PushAxisAlignedClip(RectToRectF(x, y, w, h),
|
| + D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
|
| + // Increment the clip count so the call to PushAxisAlignedClip() can be
|
| + // balanced with a call to PopAxisAlignedClip in the next Restore().
|
| + ++state_.top().clip_count;
|
| + return w > 0 && h > 0;
|
| }
|
|
|
| -bool CanvasDirect2D::IntersectsClipRectInt(int x, int y, int w, int h) {
|
| - return false;
|
| -}
|
| -
|
| void CanvasDirect2D::TranslateInt(int x, int y) {
|
| + rt_->SetTransform(D2D1::Matrix3x2F::Translation(static_cast<float>(x),
|
| + static_cast<float>(y)));
|
| }
|
|
|
| void CanvasDirect2D::ScaleInt(int x, int y) {
|
| + rt_->SetTransform(D2D1::Matrix3x2F::Scale(static_cast<float>(x),
|
| + static_cast<float>(y)));
|
| }
|
|
|
| void CanvasDirect2D::FillRectInt(int x, int y, int w, int h,
|
| @@ -216,4 +230,14 @@
|
| return NULL;
|
| }
|
|
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// CanvasDirect2D, private:
|
| +
|
| +void CanvasDirect2D::SaveInternal(ID2D1Layer* layer) {
|
| + if (!drawing_state_block_)
|
| + GetD2D1Factory()->CreateDrawingStateBlock(drawing_state_block_.Receive());
|
| + rt_->SaveDrawingState(drawing_state_block_.get());
|
| + state_.push(RenderState(layer));
|
| +}
|
| +
|
| } // namespace gfx
|
|
|