Home | History | Annotate | Download | only in gfx
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "ui/gfx/canvas_paint_mac.h"
      6 #include "ui/gfx/size.h"
      7 
      8 namespace gfx {
      9 
     10 CanvasSkiaPaint::CanvasSkiaPaint(NSRect dirtyRect)
     11     : context_(NULL),
     12       rectangle_(dirtyRect),
     13       composite_alpha_(false) {
     14   Init(true);
     15 }
     16 
     17 CanvasSkiaPaint::CanvasSkiaPaint(NSRect dirtyRect, bool opaque)
     18     : context_(NULL),
     19       rectangle_(dirtyRect),
     20       composite_alpha_(false) {
     21   Init(opaque);
     22 }
     23 
     24 CanvasSkiaPaint::~CanvasSkiaPaint() {
     25   if (!is_empty()) {
     26     platform_canvas()->restoreToCount(1);
     27 
     28     // Blit the dirty rect to the current context.
     29     CGImageRef image = CGBitmapContextCreateImage(context_);
     30     CGRect dest_rect = NSRectToCGRect(rectangle_);
     31 
     32     CGContextRef destination_context =
     33         (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
     34     CGContextSaveGState(destination_context);
     35     CGContextSetBlendMode(
     36         destination_context,
     37         composite_alpha_ ? kCGBlendModeNormal : kCGBlendModeCopy);
     38 
     39     if ([[NSGraphicsContext currentContext] isFlipped]) {
     40       // Mirror context on the target's rect middle scanline.
     41       CGContextTranslateCTM(destination_context, 0.0, NSMidY(rectangle_));
     42       CGContextScaleCTM(destination_context, 1.0, -1.0);
     43       CGContextTranslateCTM(destination_context, 0.0, -NSMidY(rectangle_));
     44     }
     45 
     46     CGContextDrawImage(destination_context, dest_rect, image);
     47     CGContextRestoreGState(destination_context);
     48 
     49     CFRelease(image);
     50   }
     51 }
     52 
     53 void CanvasSkiaPaint::Init(bool opaque) {
     54   CGContextRef destination_context =
     55         (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
     56   CGRect scaled_unit_rect = CGContextConvertRectToDeviceSpace(
     57         destination_context, CGRectMake(0, 0, 1, 1));
     58     // Assume that the x scale and the y scale are the same.
     59   CGFloat scale = scaled_unit_rect.size.width;
     60 
     61   gfx::Size size(NSWidth(rectangle_), NSHeight(rectangle_));
     62   RecreateBackingCanvas(size, scale, opaque);
     63   skia::PlatformCanvas* canvas = platform_canvas();
     64   canvas->clear(SkColorSetARGB(0, 0, 0, 0));
     65 
     66     // Need to translate so that the dirty region appears at the origin of the
     67     // surface.
     68   canvas->translate(-SkDoubleToScalar(NSMinX(rectangle_)),
     69                     -SkDoubleToScalar(NSMinY(rectangle_)));
     70 
     71   context_ = skia::GetBitmapContext(skia::GetTopDevice(*canvas));
     72 }
     73 
     74 }  // namespace skia
     75 
     76 
     77