| /* |
| * Copyright (C) 2006 Apple Computer, Inc. |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Library General Public |
| * License as published by the Free Software Foundation; either |
| * version 2 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Library General Public License for more details. |
| * |
| * You should have received a copy of the GNU Library General Public License |
| * along with this library; see the file COPYING.LIB. If not, write to |
| * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| * Boston, MA 02110-1301, USA. |
| */ |
| |
| #include "platform/mac/LocalCurrentGraphicsContext.h" |
| |
| #include <AppKit/NSGraphicsContext.h> |
| #include "platform/graphics/GraphicsContext.h" |
| #include "platform/graphics/paint/PaintCanvas.h" |
| #include "platform/mac/ThemeMac.h" |
| #include "platform_canvas.h" |
| |
| namespace blink { |
| |
| LocalCurrentGraphicsContext::LocalCurrentGraphicsContext( |
| GraphicsContext& graphics_context, |
| const IntRect& dirty_rect) |
| : LocalCurrentGraphicsContext(graphics_context.Canvas(), |
| graphics_context.DeviceScaleFactor(), |
| dirty_rect) {} |
| |
| static IntRect ClampRect(int size, const IntRect& rect) { |
| IntRect clamped_rect(rect); |
| clamped_rect.SetSize(IntSize(std::min(size, clamped_rect.Width()), |
| std::min(size, clamped_rect.Height()))); |
| return clamped_rect; |
| } |
| |
| static const int kMaxDirtyRectPixelSize = 10000; |
| |
| LocalCurrentGraphicsContext::LocalCurrentGraphicsContext( |
| PaintCanvas* canvas, |
| float device_scale_factor, |
| const IntRect& dirty_rect) |
| : did_set_graphics_context_(false), |
| inflated_dirty_rect_(ThemeMac::InflateRectForAA(dirty_rect)), |
| graphics_context_canvas_(canvas, |
| inflated_dirty_rect_, |
| device_scale_factor) { |
| saved_canvas_ = canvas; |
| canvas->save(); |
| |
| // Constrain the maximum size of what we paint to something reasonable. This |
| // accordingly means we will not paint the entirety of truly huge native form |
| // elements, which is deemed an acceptable tradeoff for this simple approach |
| // to manage such an edge case. |
| if (dirty_rect.Width() > kMaxDirtyRectPixelSize || |
| dirty_rect.Height() > kMaxDirtyRectPixelSize) |
| canvas->clipRect(ClampRect(kMaxDirtyRectPixelSize, dirty_rect), |
| SkRegion::kIntersect_Op); |
| |
| CGContextRef cg_context = this->CgContext(); |
| if (cg_context == [[NSGraphicsContext currentContext] graphicsPort]) { |
| saved_ns_graphics_context_ = 0; |
| return; |
| } |
| |
| saved_ns_graphics_context_ = [[NSGraphicsContext currentContext] retain]; |
| NSGraphicsContext* new_context = |
| [NSGraphicsContext graphicsContextWithGraphicsPort:cg_context |
| flipped:YES]; |
| [NSGraphicsContext setCurrentContext:new_context]; |
| did_set_graphics_context_ = true; |
| } |
| |
| LocalCurrentGraphicsContext::~LocalCurrentGraphicsContext() { |
| if (did_set_graphics_context_) { |
| [NSGraphicsContext setCurrentContext:saved_ns_graphics_context_]; |
| [saved_ns_graphics_context_ release]; |
| } |
| |
| saved_canvas_->restore(); |
| } |
| |
| CGContextRef LocalCurrentGraphicsContext::CgContext() { |
| // This synchronizes the CGContext to reflect the current SkCanvas state. |
| // The implementation may not return the same CGContext each time. |
| CGContextRef cg_context = graphics_context_canvas_.CgContext(); |
| |
| return cg_context; |
| } |
| } |