summaryrefslogtreecommitdiffstats
path: root/skia/ext/vector_platform_device_emf_win.h
blob: 1a2704129fc11838348fa8209685ce52273a9e28 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SKIA_EXT_VECTOR_PLATFORM_DEVICE_EMF_WIN_H_
#define SKIA_EXT_VECTOR_PLATFORM_DEVICE_EMF_WIN_H_
#pragma once

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "skia/ext/platform_device.h"
#include "third_party/skia/include/core/SkMatrix.h"
#include "third_party/skia/include/core/SkRegion.h"

namespace skia {

class SK_API VectorPlatformDeviceEmfFactory : public SkDeviceFactory {
 public:
  virtual SkDevice* newDevice(SkCanvas* ignored, SkBitmap::Config config,
                              int width, int height,
                              bool isOpaque, bool isForLayer) OVERRIDE;
  static PlatformDevice* CreateDevice(int width, int height, bool isOpaque,
                                      HANDLE shared_section);
};

// A device is basically a wrapper around SkBitmap that provides a surface for
// SkCanvas to draw into. This specific device is not not backed by a surface
// and is thus unreadable. This is because the backend is completely vectorial.
// This device is a simple wrapper over a Windows device context (HDC) handle.
class VectorPlatformDeviceEmf : public PlatformDevice {
 public:
  // Factory function. The DC is kept as the output context.
  static VectorPlatformDeviceEmf* create(HDC dc, int width, int height);

  VectorPlatformDeviceEmf(HDC dc, const SkBitmap& bitmap);
  virtual ~VectorPlatformDeviceEmf();

  virtual PlatformSurface BeginPlatformPaint();

  virtual void drawPaint(const SkDraw& draw, const SkPaint& paint) OVERRIDE;
  virtual void drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
                          size_t count, const SkPoint[],
                          const SkPaint& paint) OVERRIDE;
  virtual void drawRect(const SkDraw& draw, const SkRect& r,
                        const SkPaint& paint) OVERRIDE;
  virtual void drawPath(const SkDraw& draw, const SkPath& path,
                        const SkPaint& paint,
                        const SkMatrix* prePathMatrix = NULL,
                        bool pathIsMutable = false) OVERRIDE;
  virtual void drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
                          const SkIRect* srcRectOrNull,
                          const SkMatrix& matrix,
                          const SkPaint& paint) OVERRIDE;
  virtual void drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
                          int x, int y, const SkPaint& paint) OVERRIDE;
  virtual void drawText(const SkDraw& draw, const void* text, size_t len,
                        SkScalar x, SkScalar y, const SkPaint& paint) OVERRIDE;
  virtual void drawPosText(const SkDraw& draw, const void* text, size_t len,
                           const SkScalar pos[], SkScalar constY,
                           int scalarsPerPos, const SkPaint& paint) OVERRIDE;
  virtual void drawTextOnPath(const SkDraw& draw, const void* text, size_t len,
                              const SkPath& path, const SkMatrix* matrix,
                              const SkPaint& paint) OVERRIDE;
  virtual void drawVertices(const SkDraw& draw, SkCanvas::VertexMode,
                            int vertexCount,
                            const SkPoint verts[], const SkPoint texs[],
                            const SkColor colors[], SkXfermode* xmode,
                            const uint16_t indices[], int indexCount,
                            const SkPaint& paint) OVERRIDE;
  virtual void drawDevice(const SkDraw& draw, SkDevice*, int x, int y,
                          const SkPaint&) OVERRIDE;


  virtual void setMatrixClip(const SkMatrix& transform, const SkRegion& region,
                             const SkClipStack&);
  virtual void DrawToNativeContext(HDC dc, int x, int y, const RECT* src_rect);
  virtual bool IsVectorial() { return true; }

  void LoadClipRegion();
  bool alpha_blend_used() const { return alpha_blend_used_; }

 protected:
  // Override from SkDevice (through PlatformDevice).
  virtual SkDeviceFactory* onNewDeviceFactory();

 private:
  // Applies the SkPaint's painting properties in the current GDI context, if
  // possible. If GDI can't support all paint's properties, returns false. It
  // doesn't execute the "commands" in SkPaint.
  bool ApplyPaint(const SkPaint& paint);

  // Selects a new object in the device context. It can be a pen, a brush, a
  // clipping region, a bitmap or a font. Returns the old selected object.
  HGDIOBJ SelectObject(HGDIOBJ object);

  // Creates a brush according to SkPaint's properties.
  bool CreateBrush(bool use_brush, const SkPaint& paint);

  // Creates a pen according to SkPaint's properties.
  bool CreatePen(bool use_pen, const SkPaint& paint);

  // Restores back the previous objects (pen, brush, etc) after a paint command.
  void Cleanup();

  // Creates a brush according to SkPaint's properties.
  bool CreateBrush(bool use_brush, COLORREF color);

  // Creates a pen according to SkPaint's properties.
  bool CreatePen(bool use_pen, COLORREF color, int stroke_width,
                 float stroke_miter, DWORD pen_style);

  // Draws a bitmap in the the device, using the currently loaded matrix.
  void InternalDrawBitmap(const SkBitmap& bitmap, int x, int y,
                          const SkPaint& paint);

  // The Windows Device Context handle. It is the backend used with GDI drawing.
  // This backend is write-only and vectorial.
  HDC hdc_;

  // Translation assigned to the DC: we need to keep track of this separately
  // so it can be updated even if the DC isn't created yet.
  SkMatrix transform_;

  // The current clipping
  SkRegion clip_region_;

  // Previously selected brush before the current drawing.
  HGDIOBJ previous_brush_;

  // Previously selected pen before the current drawing.
  HGDIOBJ previous_pen_;

  // True if AlphaBlend() was called during this print.
  bool alpha_blend_used_;

  DISALLOW_COPY_AND_ASSIGN(VectorPlatformDeviceEmf);
};

}  // namespace skia

#endif  // SKIA_EXT_VECTOR_PLATFORM_DEVICE_EMF_WIN_H_