- add sources.
[platform/framework/web/crosswalk.git] / src / win8 / metro_driver / print_document_source.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 CHROME_BROWSER_UI_METRO_DRIVER_PRINT_DOCUMENT_SOURCE_H_
6 #define CHROME_BROWSER_UI_METRO_DRIVER_PRINT_DOCUMENT_SOURCE_H_
7
8 #include <documentsource.h>
9 #include <printpreview.h>
10 #include <windows.graphics.printing.h>
11
12 #include <vector>
13
14 #include "base/basictypes.h"
15 #include "base/memory/ref_counted.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "base/synchronization/condition_variable.h"
18 #include "base/synchronization/waitable_event.h"
19 #include "win8/metro_driver/winrt_utils.h"
20
21 // Hack to be removed once we don't need to build with an SDK earlier than
22 // 8441 where the name of the interface has been changed.
23 // TODO(mad): remove once we don't run mixed SDK/OS anymore.
24 #ifndef __IPrintPreviewDxgiPackageTarget_FWD_DEFINED__
25 typedef IPrintPreviewDXGIPackageTarget IPrintPreviewDxgiPackageTarget;
26 #endif
27
28
29 namespace base {
30 class Lock;
31 };  // namespace base
32
33 namespace metro_driver {
34
35 // This class is given to Metro as a source for print documents.
36 // The methodless IPrintDocumentSource interface is used to identify it as such.
37 // Then, the other interfaces are used to generate preview and print documents.
38 // It also exposes a few methods for the print handler to control the document.
39 class PrintDocumentSource
40     : public mswr::RuntimeClass<
41           mswr::RuntimeClassFlags<mswr::WinRtClassicComMix>,
42           wingfx::Printing::IPrintDocumentSource,
43           IPrintDocumentPageSource,
44           IPrintPreviewPageCollection> {
45  public:
46   // A set of interfaces for the DirectX context that our parent owns
47   // and that don't need to change from document to document.
48   struct DirectXContext {
49     DirectXContext() {}
50     DirectXContext(ID3D11Device1* device_3d,
51                    ID2D1Factory1* factory_2d,
52                    ID2D1Device* device_2d,
53                    ID2D1DeviceContext* context_2d,
54                    IWICImagingFactory2* factory_wic)
55         : d3d_device(device_3d),
56           d2d_factory(factory_2d),
57           d2d_device(device_2d),
58           d2d_context(context_2d),
59           wic_factory(factory_wic) {
60     }
61     DirectXContext(const DirectXContext& other)
62         : d3d_device(other.d3d_device),
63           d2d_factory(other.d2d_factory),
64           d2d_device(other.d2d_device),
65           d2d_context(other.d2d_context),
66           wic_factory(other.wic_factory) {
67     }
68     mswr::ComPtr<ID3D11Device1> d3d_device;
69     mswr::ComPtr<ID2D1Factory1> d2d_factory;
70     mswr::ComPtr<ID2D1Device> d2d_device;
71     mswr::ComPtr<ID2D1DeviceContext> d2d_context;
72     mswr::ComPtr<IWICImagingFactory2> wic_factory;
73   };
74
75   // Construction / Initialization.
76   explicit PrintDocumentSource();
77   HRESULT RuntimeClassInitialize(const DirectXContext& directx_context,
78                                  base::Lock* parent_lock);
79   // Aborts any pending asynchronous operation.
80   void Abort();
81
82   // classic COM interface IPrintDocumentPageSource methods
83   STDMETHOD(GetPreviewPageCollection) (
84       IPrintDocumentPackageTarget* package_target,
85       IPrintPreviewPageCollection** page_collection);
86   STDMETHOD(MakeDocument)(IInspectable* options,
87                           IPrintDocumentPackageTarget* package_target);
88
89   // classic COM interface IPrintPreviewPageCollection methods
90   STDMETHOD(Paginate)(uint32 page, IInspectable* options);
91   STDMETHOD(MakePage)(uint32 desired_page, float width, float height);
92
93   // If the screen DPI changes, we must be warned here.
94   void ResetDpi(float dpi);
95
96   // When the page count is known, this is called and we can setup our data.
97   void SetPageCount(size_t page_count);
98
99   // Every time a page is ready, this is called and we can read the data if
100   // we were waiting for it, or store it for later use.
101   void AddPage(size_t page_number, IStream* metafile_stream);
102
103  private:
104   // Print the page given in the metafile stream to the given print control.
105   HRESULT PrintPage(ID2D1PrintControl* print_control,
106                     ID2D1GdiMetafile* metafile_stream,
107                     D2D1_SIZE_F pageSize);
108
109   // Helper function to wait for the page count to be ready.
110   // Returns 0 when aborted.
111   size_t WaitAndGetPageCount();
112
113   // Helper function to wait for a given page to be ready.
114   // Returns S_FALSE when aborted.
115   HRESULT WaitAndGetPage(size_t page_number,
116                          ID2D1GdiMetafile** metafile_stream);
117
118   DirectXContext directx_context_;
119
120   // Once page data is available, it's added to this vector.
121   std::vector<mswr::ComPtr<IStream>> pages_;
122
123   // When page count is set, the size of this vector is set to that number.
124   // Then, every time page data is added to pages_, the associated condition
125   // variable in this vector is signaled. This is only filled when we receive
126   // the page count, so we must wait on page_count_ready_ before accessing
127   // the content of this vector.
128   std::vector<scoped_ptr<base::ConditionVariable> > pages_ready_state_;
129
130   // This event is signaled when we receive a page count from Chrome. We should
131   // not receive any page data before the count, so we can check this event
132   // while waiting for pages too, in case we ask for page data before we got
133   // the count, so before we properly initialized pages_ready_state_.
134   base::WaitableEvent page_count_ready_;
135
136   // The preview target interface set from within GetPreviewPageCollection
137   // but used from within MakePage.
138   mswr::ComPtr<IPrintPreviewDxgiPackageTarget> dxgi_preview_target_;
139
140   // Our parent's lock (to make sure it is initialized and destroyed early
141   // enough), which we use to protect access to our data members.
142   base::Lock* parent_lock_;
143
144   // The width/height requested in Paginate and used in MakePage.
145   // TODO(mad): Height is currently not used, and width is only used for
146   // scaling. We need to add a way to specify width and height when we request
147   // pages from Chrome.
148   float height_;
149   float width_;
150
151   // The DPI is set by Windows and we need to give it to DirectX.
152   float dpi_;
153
154   // A flag identiying that we have been aborted. Needed to properly handle
155   // asynchronous callbacks.
156   bool aborted_;
157
158   // TODO(mad): remove once we don't run mixed SDK/OS anymore.
159   bool using_old_preview_interface_;
160 };
161
162 }  // namespace metro_driver
163
164 #endif  // CHROME_BROWSER_UI_METRO_DRIVER_PRINT_DOCUMENT_SOURCE_H_