Upload upstream chromium 73.0.3683.0
[platform/framework/web/chromium-efl.git] / 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 <stddef.h>
9 #include <stdint.h>
10 #include <windows.h>
11
12 #include <memory>
13 #include <vector>
14
15 #include "base/compiler_specific.h"
16 #include "base/gtest_prod_util.h"
17 #include "base/macros.h"
18 #include "printing/metafile.h"
19
20 namespace base {
21 class FilePath;
22 }
23
24 namespace gfx {
25 class Rect;
26 class Size;
27 }
28
29 namespace printing {
30
31 // Simple wrapper class that manage an EMF data stream and its virtual HDC.
32 class PRINTING_EXPORT Emf : public Metafile {
33  public:
34   class Record;
35   class Enumerator;
36   struct EnumerationContext;
37
38   // Generates a virtual HDC that will record every GDI commands and compile
39   // it in a EMF data stream.
40   Emf();
41   ~Emf() override;
42
43   // Closes metafile.
44   void Close();
45
46   // Generates a new metafile that will record every GDI command, and will
47   // be saved to |metafile_path|.
48   bool InitToFile(const base::FilePath& metafile_path);
49
50   // Initializes the Emf with the data in |metafile_path|.
51   bool InitFromFile(const base::FilePath& metafile_path);
52
53   // Metafile methods.
54   bool Init() override;
55   bool InitFromData(const void* src_buffer, size_t src_buffer_size) override;
56
57   // Inserts a custom GDICOMMENT records indicating StartPage/EndPage calls
58   // (since StartPage and EndPage do not work in a metafile DC). Only valid
59   // when hdc_ is non-NULL. |page_size|, |content_area|, and |scale_factor| are
60   // ignored.
61   void StartPage(const gfx::Size& page_size,
62                  const gfx::Rect& content_area,
63                  const float& scale_factor) override;
64   bool FinishPage() override;
65   bool FinishDocument() override;
66
67   uint32_t GetDataSize() const override;
68   bool GetData(void* buffer, uint32_t size) const override;
69
70   // Should be passed to Playback to keep the exact same size.
71   gfx::Rect GetPageBounds(unsigned int page_number) const override;
72
73   unsigned int GetPageCount() const override;
74   HDC context() const override;
75   bool Playback(HDC hdc, const RECT* rect) const override;
76   bool SafePlayback(HDC hdc) const override;
77
78   HENHMETAFILE emf() const { return emf_; }
79
80  private:
81   FRIEND_TEST_ALL_PREFIXES(EmfTest, DC);
82   FRIEND_TEST_ALL_PREFIXES(EmfPrintingTest, PageBreak);
83   FRIEND_TEST_ALL_PREFIXES(EmfTest, FileBackedEmf);
84
85   // Playbacks safely one EMF record.
86   static int CALLBACK SafePlaybackProc(HDC hdc,
87                                        HANDLETABLE* handle_table,
88                                        const ENHMETARECORD* record,
89                                        int objects_count,
90                                        LPARAM param);
91
92   // Compiled EMF data handle.
93   HENHMETAFILE emf_;
94
95   // Valid when generating EMF data through a virtual HDC.
96   HDC hdc_;
97
98   DISALLOW_COPY_AND_ASSIGN(Emf);
99 };
100
101 struct Emf::EnumerationContext {
102   EnumerationContext();
103
104   HANDLETABLE* handle_table;
105   int objects_count;
106   HDC hdc;
107   const XFORM* base_matrix;
108   int dc_on_page_start;
109 };
110
111 // One EMF record. It keeps pointers to the EMF buffer held by Emf::emf_.
112 // The entries become invalid once Emf::CloseEmf() is called.
113 class PRINTING_EXPORT Emf::Record {
114  public:
115   // Plays the record.
116   bool Play(EnumerationContext* context) const;
117
118   // Plays the record working around quirks with SetLayout,
119   // SetWorldTransform and ModifyWorldTransform. See implementation for details.
120   bool SafePlayback(EnumerationContext* context) const;
121
122   // Access the underlying EMF record.
123   const ENHMETARECORD* record() const { return record_; }
124
125  protected:
126   explicit Record(const ENHMETARECORD* record);
127
128  private:
129   friend class Emf;
130   friend class Enumerator;
131   const ENHMETARECORD* record_;
132 };
133
134 // Retrieves individual records out of a Emf buffer. The main use is to skip
135 // over records that are unsupported on a specific printer or to play back
136 // only a part of an EMF buffer.
137 class PRINTING_EXPORT Emf::Enumerator {
138  public:
139   // Iterator type used for iterating the records.
140   typedef std::vector<Record>::const_iterator const_iterator;
141
142   // Enumerates the records at construction time. |hdc| and |rect| are
143   // both optional at the same time or must both be valid.
144   // Warning: |emf| must be kept valid for the time this object is alive.
145   Enumerator(const Emf& emf, HDC hdc, const RECT* rect);
146
147   ~Enumerator();
148
149   // Retrieves the first Record.
150   const_iterator begin() const;
151
152   // Retrieves the end of the array.
153   const_iterator end() const;
154
155  private:
156   FRIEND_TEST_ALL_PREFIXES(EmfPrintingTest, Enumerate);
157
158   // Processes one EMF record and saves it in the items_ array.
159   static int CALLBACK EnhMetaFileProc(HDC hdc,
160                                       HANDLETABLE* handle_table,
161                                       const ENHMETARECORD* record,
162                                       int objects_count,
163                                       LPARAM param);
164
165   // The collection of every EMF records in the currently loaded EMF buffer.
166   // Initialized by Enumerate(). It keeps pointers to the EMF buffer held by
167   // Emf::emf_. The entries become invalid once Emf::CloseEmf() is called.
168   std::vector<Record> items_;
169
170   EnumerationContext context_;
171
172   DISALLOW_COPY_AND_ASSIGN(Enumerator);
173 };
174
175 }  // namespace printing
176
177 #endif  // PRINTING_EMF_WIN_H_