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#ifndef SKIA_EXT_BITMAP_PLATFORM_DEVICE_MAC_H_
6#define SKIA_EXT_BITMAP_PLATFORM_DEVICE_MAC_H_
7
8#include "base/basictypes.h"
9#include "base/compiler_specific.h"
10#include "skia/ext/platform_device.h"
11#include "skia/ext/refptr.h"
12
13namespace skia {
14
15// A device is basically a wrapper around SkBitmap that provides a surface for
16// SkCanvas to draw into. Our device provides a surface CoreGraphics can also
17// write to. BitmapPlatformDevice creates a bitmap using
18// CGCreateBitmapContext() in a format that Skia supports and can then use this
19// to draw text into, etc. This pixel data is provided to the bitmap that the
20// device contains so that it can be shared.
21//
22// The device owns the pixel data, when the device goes away, the pixel data
23// also becomes invalid. THIS IS DIFFERENT THAN NORMAL SKIA which uses
24// reference counting for the pixel data. In normal Skia, you could assign
25// another bitmap to this device's bitmap and everything will work properly.
26// For us, that other bitmap will become invalid as soon as the device becomes
27// invalid, which may lead to subtle bugs. Therefore, DO NOT ASSIGN THE
28// DEVICE'S PIXEL DATA TO ANOTHER BITMAP, make sure you copy instead.
29class SK_API BitmapPlatformDevice : public SkBitmapDevice, public PlatformDevice {
30 public:
31  // Creates a BitmapPlatformDevice instance. |is_opaque| should be set if the
32  // caller knows the bitmap will be completely opaque and allows some
33  // optimizations.
34  // |context| may be NULL. If |context| is NULL, then the bitmap backing store
35  // is not initialized.
36  static BitmapPlatformDevice* Create(CGContextRef context,
37                                      int width, int height,
38                                      bool is_opaque);
39
40  // Creates a BitmapPlatformDevice instance.  If |is_opaque| is false,
41  // then the bitmap is initialzed to 0.
42  static BitmapPlatformDevice* CreateAndClear(int width, int height,
43                                              bool is_opaque);
44
45  // Creates a context for |data| and calls Create.
46  // If |data| is NULL, then the bitmap backing store is not initialized.
47  static BitmapPlatformDevice* CreateWithData(uint8_t* data,
48                                              int width, int height,
49                                              bool is_opaque);
50
51  virtual ~BitmapPlatformDevice();
52
53  // PlatformDevice overrides
54  virtual CGContextRef GetBitmapContext() OVERRIDE;
55  virtual void DrawToNativeContext(CGContextRef context, int x, int y,
56                                   const CGRect* src_rect) OVERRIDE;
57
58  // SkBaseDevice overrides
59  virtual void setMatrixClip(const SkMatrix& transform, const SkRegion& region,
60                             const SkClipStack&) OVERRIDE;
61
62 protected:
63  BitmapPlatformDevice(CGContextRef context,
64                       const SkBitmap& bitmap);
65
66  virtual SkBaseDevice* onCreateDevice(const SkImageInfo& info,
67                                       Usage usage) OVERRIDE;
68
69 private:
70  void ReleaseBitmapContext();
71
72  // Sets the transform and clip operations. This will not update the CGContext,
73  // but will mark the config as dirty. The next call of LoadConfig will
74  // pick up these changes.
75  void SetMatrixClip(const SkMatrix& transform, const SkRegion& region);
76
77  // Loads the current transform and clip into the context. Can be called even
78  // when |bitmap_context_| is NULL (will be a NOP).
79  void LoadConfig();
80
81  // Lazily-created graphics context used to draw into the bitmap.
82  CGContextRef bitmap_context_;
83
84  // True when there is a transform or clip that has not been set to the
85  // context.  The context is retrieved for every text operation, and the
86  // transform and clip do not change as much. We can save time by not loading
87  // the clip and transform for every one.
88  bool config_dirty_;
89
90  // Translation assigned to the context: we need to keep track of this
91  // separately so it can be updated even if the context isn't created yet.
92  SkMatrix transform_;
93
94  // The current clipping
95  SkRegion clip_region_;
96  DISALLOW_COPY_AND_ASSIGN(BitmapPlatformDevice);
97};
98
99}  // namespace skia
100
101#endif  // SKIA_EXT_BITMAP_PLATFORM_DEVICE_MAC_H_
102