Upstream version 10.38.208.0
[platform/framework/web/crosswalk.git] / src / printing / emf_win.h
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 PRINTING_EMF_WIN_H_
6 #define PRINTING_EMF_WIN_H_
7
8 #include <windows.h>
9
10 #include <vector>
11
12 #include "base/basictypes.h"
13 #include "base/compiler_specific.h"
14 #include "base/gtest_prod_util.h"
15 #include "printing/metafile.h"
16
17 namespace base {
18 class FilePath;
19 }
20
21 namespace gfx {
22 class Rect;
23 class Size;
24 }
25
26 namespace printing {
27
28 // http://msdn2.microsoft.com/en-us/library/ms535522.aspx
29 // Windows 2000/XP: When a page in a spooled file exceeds approximately 350
30 // MB, it can fail to print and not send an error message.
31 const size_t kMetafileMaxSize = 350*1024*1024;
32
33 // Simple wrapper class that manage an EMF data stream and its virtual HDC.
34 class PRINTING_EXPORT Emf : public Metafile {
35  public:
36   class Record;
37   class Enumerator;
38   struct EnumerationContext;
39
40   // Generates a virtual HDC that will record every GDI commands and compile
41   // it in a EMF data stream.
42   Emf();
43   virtual ~Emf();
44
45   // Closes metafile.
46   void Close();
47
48   // Generates a new metafile that will record every GDI command, and will
49   // be saved to |metafile_path|.
50   virtual bool InitToFile(const base::FilePath& metafile_path);
51
52   // Initializes the Emf with the data in |metafile_path|.
53   virtual bool InitFromFile(const base::FilePath& metafile_path);
54
55   // Metafile methods.
56   virtual bool Init() OVERRIDE;
57   virtual bool InitFromData(const void* src_buffer,
58                             uint32 src_buffer_size) OVERRIDE;
59
60   virtual SkBaseDevice* StartPageForVectorCanvas(
61       const gfx::Size& page_size, const gfx::Rect& content_area,
62       const float& scale_factor) OVERRIDE;
63   // Inserts a custom GDICOMMENT records indicating StartPage/EndPage calls
64   // (since StartPage and EndPage do not work in a metafile DC). Only valid
65   // when hdc_ is non-NULL. |page_size|, |content_area|, and |scale_factor| are
66   // ignored.
67   virtual bool StartPage(const gfx::Size& page_size,
68                          const gfx::Rect& content_area,
69                          const float& scale_factor) OVERRIDE;
70   virtual bool FinishPage() OVERRIDE;
71   virtual bool FinishDocument() OVERRIDE;
72
73   virtual uint32 GetDataSize() const OVERRIDE;
74   virtual bool GetData(void* buffer, uint32 size) const OVERRIDE;
75
76   // Saves the EMF data to a file as-is. It is recommended to use the .emf file
77   // extension but it is not enforced. This function synchronously writes to the
78   // file. For testing only.
79   virtual bool SaveTo(const base::FilePath& file_path) const OVERRIDE;
80
81   // Should be passed to Playback to keep the exact same size.
82   virtual gfx::Rect GetPageBounds(unsigned int page_number) const OVERRIDE;
83
84   virtual unsigned int GetPageCount() const OVERRIDE {
85     return page_count_;
86   }
87
88   virtual HDC context() const OVERRIDE {
89     return hdc_;
90   }
91
92   virtual bool Playback(HDC hdc, const RECT* rect) const OVERRIDE;
93   virtual bool SafePlayback(HDC hdc) const OVERRIDE;
94
95   virtual HENHMETAFILE emf() const OVERRIDE {
96     return emf_;
97   }
98
99   // Returns true if metafile contains alpha blend.
100   bool IsAlphaBlendUsed() const;
101
102   // Returns new metafile with only bitmap created by playback of the current
103   // metafile. Returns NULL if fails.
104   Emf* RasterizeMetafile(int raster_area_in_pixels) const;
105
106   // Returns new metafile where AlphaBlend replaced by bitmaps. Returns NULL
107   // if fails.
108   Emf* RasterizeAlphaBlend() const;
109
110  private:
111   FRIEND_TEST_ALL_PREFIXES(EmfTest, DC);
112   FRIEND_TEST_ALL_PREFIXES(EmfPrintingTest, PageBreak);
113   FRIEND_TEST_ALL_PREFIXES(EmfTest, FileBackedEmf);
114
115   // Retrieves the underlying data stream. It is a helper function.
116   bool GetDataAsVector(std::vector<uint8>* buffer) const;
117
118   // Playbacks safely one EMF record.
119   static int CALLBACK SafePlaybackProc(HDC hdc,
120                                        HANDLETABLE* handle_table,
121                                        const ENHMETARECORD* record,
122                                        int objects_count,
123                                        LPARAM param);
124
125   // Compiled EMF data handle.
126   HENHMETAFILE emf_;
127
128   // Valid when generating EMF data through a virtual HDC.
129   HDC hdc_;
130
131   int page_count_;
132
133   DISALLOW_COPY_AND_ASSIGN(Emf);
134 };
135
136 struct Emf::EnumerationContext {
137   EnumerationContext();
138
139   HANDLETABLE* handle_table;
140   int objects_count;
141   HDC hdc;
142   const XFORM* base_matrix;
143   int dc_on_page_start;
144 };
145
146 // One EMF record. It keeps pointers to the EMF buffer held by Emf::emf_.
147 // The entries become invalid once Emf::CloseEmf() is called.
148 class PRINTING_EXPORT Emf::Record {
149  public:
150   // Plays the record.
151   bool Play(EnumerationContext* context) const;
152
153   // Plays the record working around quirks with SetLayout,
154   // SetWorldTransform and ModifyWorldTransform. See implementation for details.
155   bool SafePlayback(EnumerationContext* context) const;
156
157   // Access the underlying EMF record.
158   const ENHMETARECORD* record() const { return record_; }
159
160  protected:
161   explicit Record(const ENHMETARECORD* record);
162
163  private:
164   friend class Emf;
165   friend class Enumerator;
166   const ENHMETARECORD* record_;
167 };
168
169 // Retrieves individual records out of a Emf buffer. The main use is to skip
170 // over records that are unsupported on a specific printer or to play back
171 // only a part of an EMF buffer.
172 class PRINTING_EXPORT Emf::Enumerator {
173  public:
174   // Iterator type used for iterating the records.
175   typedef std::vector<Record>::const_iterator const_iterator;
176
177   // Enumerates the records at construction time. |hdc| and |rect| are
178   // both optional at the same time or must both be valid.
179   // Warning: |emf| must be kept valid for the time this object is alive.
180   Enumerator(const Emf& emf, HDC hdc, const RECT* rect);
181
182   // Retrieves the first Record.
183   const_iterator begin() const;
184
185   // Retrieves the end of the array.
186   const_iterator end() const;
187
188  private:
189   FRIEND_TEST_ALL_PREFIXES(EmfPrintingTest, Enumerate);
190
191   // Processes one EMF record and saves it in the items_ array.
192   static int CALLBACK EnhMetaFileProc(HDC hdc,
193                                       HANDLETABLE* handle_table,
194                                       const ENHMETARECORD* record,
195                                       int objects_count,
196                                       LPARAM param);
197
198   // The collection of every EMF records in the currently loaded EMF buffer.
199   // Initialized by Enumerate(). It keeps pointers to the EMF buffer held by
200   // Emf::emf_. The entries become invalid once Emf::CloseEmf() is called.
201   std::vector<Record> items_;
202
203   EnumerationContext context_;
204
205   DISALLOW_COPY_AND_ASSIGN(Enumerator);
206 };
207
208 }  // namespace printing
209
210 #endif  // PRINTING_EMF_WIN_H_