[email protected] | b5cf844c | 2012-06-18 21:49:20 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 8f87929 | 2011-04-08 00:21:20 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Wei Li | ab75477 | 2018-08-22 22:41:17 | [diff] [blame] | 5 | #ifndef PRINTING_METAFILE_SKIA_H_ |
| 6 | #define PRINTING_METAFILE_SKIA_H_ |
[email protected] | 8f87929 | 2011-04-08 00:21:20 | [diff] [blame] | 7 | |
avi | 126e93c | 2015-12-21 21:48:16 | [diff] [blame] | 8 | #include <stdint.h> |
| 9 | |
dcheng | c3df9ba | 2016-04-07 23:09:32 | [diff] [blame] | 10 | #include <memory> |
| 11 | |
Wei Li | 1d345bf | 2018-08-10 02:52:37 | [diff] [blame] | 12 | #include "base/gtest_prod_util.h" |
[email protected] | 8f87929 | 2011-04-08 00:21:20 | [diff] [blame] | 13 | #include "build/build_config.h" |
enne | 7b64edf3 | 2017-02-16 20:10:02 | [diff] [blame] | 14 | #include "cc/paint/paint_canvas.h" |
Wei Li | ab75477 | 2018-08-22 22:41:17 | [diff] [blame] | 15 | #include "printing/common/metafile_utils.h" |
[email protected] | 7d748990 | 2011-04-11 21:54:06 | [diff] [blame] | 16 | #include "printing/metafile.h" |
Julie Jeongeun Kim | e1abed9 | 2020-06-11 11:01:48 | [diff] [blame] | 17 | #include "printing/mojom/print.mojom-forward.h" |
vitalybuka | a73fc37 | 2015-02-06 18:40:37 | [diff] [blame] | 18 | #include "skia/ext/platform_canvas.h" |
Dominic Mazzoni | 0a39059c | 2020-01-08 19:30:45 | [diff] [blame] | 19 | #include "ui/accessibility/ax_tree_update.h" |
[email protected] | 8f87929 | 2011-04-08 00:21:20 | [diff] [blame] | 20 | |
| 21 | #if defined(OS_WIN) |
| 22 | #include <windows.h> |
| 23 | #endif |
| 24 | |
Gyuyoung Kim | 5f7f4c7 | 2020-07-14 13:09:03 | [diff] [blame] | 25 | namespace base { |
| 26 | class UnguessableToken; |
| 27 | } // namespace base |
| 28 | |
[email protected] | 8f87929 | 2011-04-08 00:21:20 | [diff] [blame] | 29 | namespace printing { |
| 30 | |
Wei Li | ab75477 | 2018-08-22 22:41:17 | [diff] [blame] | 31 | struct MetafileSkiaData; |
[email protected] | 8f87929 | 2011-04-08 00:21:20 | [diff] [blame] | 32 | |
Lei Zhang | 662e422 | 2017-12-14 20:18:34 | [diff] [blame] | 33 | // This class uses Skia graphics library to generate a PDF or MSKP document. |
Wei Li | ab75477 | 2018-08-22 22:41:17 | [diff] [blame] | 34 | class PRINTING_EXPORT MetafileSkia : public Metafile { |
[email protected] | 8f87929 | 2011-04-08 00:21:20 | [diff] [blame] | 35 | public: |
Julie Jeongeun Kim | e1abed9 | 2020-06-11 11:01:48 | [diff] [blame] | 36 | // Default constructor, for mojom::SkiaDocumentType::kPDF type only. |
Wei Li | e13ea64 | 2018-02-17 07:55:19 | [diff] [blame] | 37 | // TODO(weili): we should split up this use case into a different class, see |
| 38 | // comments before InitFromData()'s implementation. |
Wei Li | ab75477 | 2018-08-22 22:41:17 | [diff] [blame] | 39 | MetafileSkia(); |
Julie Jeongeun Kim | e1abed9 | 2020-06-11 11:01:48 | [diff] [blame] | 40 | MetafileSkia(mojom::SkiaDocumentType type, int document_cookie); |
Lei Zhang | dd3e9b0 | 2020-08-19 23:04:42 | [diff] [blame^] | 41 | MetafileSkia(const MetafileSkia&) = delete; |
| 42 | MetafileSkia& operator=(const MetafileSkia&) = delete; |
Wei Li | ab75477 | 2018-08-22 22:41:17 | [diff] [blame] | 43 | ~MetafileSkia() override; |
[email protected] | 8f87929 | 2011-04-08 00:21:20 | [diff] [blame] | 44 | |
[email protected] | 7d748990 | 2011-04-11 21:54:06 | [diff] [blame] | 45 | // Metafile methods. |
dcheng | d5a0f18 | 2014-10-22 00:04:34 | [diff] [blame] | 46 | bool Init() override; |
Lei Zhang | b4ef0d5d | 2020-03-27 23:18:29 | [diff] [blame] | 47 | bool InitFromData(base::span<const uint8_t> data) override; |
[email protected] | 8f87929 | 2011-04-08 00:21:20 | [diff] [blame] | 48 | |
thestig | 192677ec | 2016-06-09 07:43:17 | [diff] [blame] | 49 | void StartPage(const gfx::Size& page_size, |
dcheng | d5a0f18 | 2014-10-22 00:04:34 | [diff] [blame] | 50 | const gfx::Rect& content_area, |
Morten Stenshorne | eebf2db | 2020-05-25 09:00:05 | [diff] [blame] | 51 | float scale_factor, |
| 52 | mojom::PageOrientation page_orientation) override; |
dcheng | d5a0f18 | 2014-10-22 00:04:34 | [diff] [blame] | 53 | bool FinishPage() override; |
| 54 | bool FinishDocument() override; |
[email protected] | 8f87929 | 2011-04-08 00:21:20 | [diff] [blame] | 55 | |
thestig | 707a24b2 | 2015-09-14 18:16:33 | [diff] [blame] | 56 | uint32_t GetDataSize() const override; |
| 57 | bool GetData(void* dst_buffer, uint32_t dst_buffer_size) const override; |
[email protected] | 8f87929 | 2011-04-08 00:21:20 | [diff] [blame] | 58 | |
dcheng | d5a0f18 | 2014-10-22 00:04:34 | [diff] [blame] | 59 | gfx::Rect GetPageBounds(unsigned int page_number) const override; |
| 60 | unsigned int GetPageCount() const override; |
[email protected] | 8f87929 | 2011-04-08 00:21:20 | [diff] [blame] | 61 | |
Nico Weber | 8e55956 | 2017-10-03 01:25:26 | [diff] [blame] | 62 | printing::NativeDrawingContext context() const override; |
[email protected] | 8f87929 | 2011-04-08 00:21:20 | [diff] [blame] | 63 | |
| 64 | #if defined(OS_WIN) |
Nico Weber | 8e55956 | 2017-10-03 01:25:26 | [diff] [blame] | 65 | bool Playback(printing::NativeDrawingContext hdc, |
thestig | 3109df1 | 2017-04-26 21:57:25 | [diff] [blame] | 66 | const RECT* rect) const override; |
Nico Weber | 8e55956 | 2017-10-03 01:25:26 | [diff] [blame] | 67 | bool SafePlayback(printing::NativeDrawingContext hdc) const override; |
Avi Drissman | 578cd72 | 2020-07-29 17:21:15 | [diff] [blame] | 68 | #elif defined(OS_MAC) |
thestig | 99fc213 | 2017-04-27 03:37:54 | [diff] [blame] | 69 | bool RenderPage(unsigned int page_number, |
Nico Weber | 8e55956 | 2017-10-03 01:25:26 | [diff] [blame] | 70 | printing::NativeDrawingContext context, |
Lei Zhang | f69ea3b | 2020-03-24 17:53:48 | [diff] [blame] | 71 | const CGRect& rect, |
Daniel Hosseinian | 345ecfa | 2020-04-08 03:45:16 | [diff] [blame] | 72 | bool autorotate, |
| 73 | bool fit_to_page) const override; |
[email protected] | b8d85bc | 2011-06-22 13:34:57 | [diff] [blame] | 74 | #endif |
[email protected] | 8f87929 | 2011-04-08 00:21:20 | [diff] [blame] | 75 | |
Shimi Zhang | 5ccdf20 | 2020-02-13 01:13:19 | [diff] [blame] | 76 | #if defined(OS_ANDROID) |
| 77 | bool SaveToFileDescriptor(int fd) const override; |
| 78 | #else |
halcanary | 5be808e | 2014-11-10 22:20:05 | [diff] [blame] | 79 | bool SaveTo(base::File* file) const override; |
Shimi Zhang | 5ccdf20 | 2020-02-13 01:13:19 | [diff] [blame] | 80 | #endif // defined(OS_ANDROID) |
halcanary | 5be808e | 2014-11-10 22:20:05 | [diff] [blame] | 81 | |
Wei Li | 5bb65974 | 2018-02-14 03:07:58 | [diff] [blame] | 82 | // Unlike FinishPage() or FinishDocument(), this is for out-of-process |
| 83 | // subframe printing. It will just serialize the content into SkPicture |
| 84 | // format and store it as final data. |
| 85 | void FinishFrameContent(); |
| 86 | |
[email protected] | 59751637 | 2011-07-01 05:10:44 | [diff] [blame] | 87 | // Return a new metafile containing just the current page in draft mode. |
Wei Li | ab75477 | 2018-08-22 22:41:17 | [diff] [blame] | 88 | std::unique_ptr<MetafileSkia> GetMetafileForCurrentPage( |
Julie Jeongeun Kim | e1abed9 | 2020-06-11 11:01:48 | [diff] [blame] | 89 | mojom::SkiaDocumentType type); |
[email protected] | 59751637 | 2011-07-01 05:10:44 | [diff] [blame] | 90 | |
vitalybuka | 9de71ea | 2014-11-05 09:22:34 | [diff] [blame] | 91 | // This method calls StartPage and then returns an appropriate |
vitalybuka | a73fc37 | 2015-02-06 18:40:37 | [diff] [blame] | 92 | // PlatformCanvas implementation bound to the context created by |
enne | 7b64edf3 | 2017-02-16 20:10:02 | [diff] [blame] | 93 | // StartPage or NULL on error. The PaintCanvas pointer that |
Wei Li | ab75477 | 2018-08-22 22:41:17 | [diff] [blame] | 94 | // is returned is owned by this MetafileSkia object and does not |
halcanary | 5be808e | 2014-11-10 22:20:05 | [diff] [blame] | 95 | // need to be ref()ed or unref()ed. The canvas will remain valid |
| 96 | // until FinishPage() or FinishDocument() is called. |
Morten Stenshorne | eebf2db | 2020-05-25 09:00:05 | [diff] [blame] | 97 | cc::PaintCanvas* GetVectorCanvasForNewPage( |
| 98 | const gfx::Size& page_size, |
| 99 | const gfx::Rect& content_area, |
| 100 | float scale_factor, |
| 101 | mojom::PageOrientation page_orientation); |
halcanary | 5be808e | 2014-11-10 22:20:05 | [diff] [blame] | 102 | |
Wei Li | e13ea64 | 2018-02-17 07:55:19 | [diff] [blame] | 103 | // This is used for painting content of out-of-process subframes. |
| 104 | // For such a subframe, since the content is in another process, we create a |
| 105 | // place holder picture now, and replace it with actual content by pdf |
| 106 | // compositor service later. |
Gyuyoung Kim | 5f7f4c7 | 2020-07-14 13:09:03 | [diff] [blame] | 107 | uint32_t CreateContentForRemoteFrame( |
| 108 | const gfx::Rect& rect, |
| 109 | const base::UnguessableToken& render_proxy_token); |
Wei Li | e13ea64 | 2018-02-17 07:55:19 | [diff] [blame] | 110 | |
| 111 | int GetDocumentCookie() const; |
Gyuyoung Kim | 5f7f4c7 | 2020-07-14 13:09:03 | [diff] [blame] | 112 | const ContentToProxyTokenMap& GetSubframeContentInfo() const; |
Wei Li | e13ea64 | 2018-02-17 07:55:19 | [diff] [blame] | 113 | |
Alan Screen | 06d2016 | 2020-06-26 17:42:12 | [diff] [blame] | 114 | void UtilizeTypefaceContext(ContentProxySet* typeface_content_info); |
| 115 | |
Dominic Mazzoni | 0a39059c | 2020-01-08 19:30:45 | [diff] [blame] | 116 | const ui::AXTreeUpdate& accessibility_tree() const { |
| 117 | return accessibility_tree_; |
| 118 | } |
| 119 | ui::AXTreeUpdate& accessibility_tree() { return accessibility_tree_; } |
| 120 | |
[email protected] | 8f87929 | 2011-04-08 00:21:20 | [diff] [blame] | 121 | private: |
Wei Li | ab75477 | 2018-08-22 22:41:17 | [diff] [blame] | 122 | FRIEND_TEST_ALL_PREFIXES(MetafileSkiaTest, TestFrameContent); |
Alan Screen | 06d2016 | 2020-06-26 17:42:12 | [diff] [blame] | 123 | FRIEND_TEST_ALL_PREFIXES(MetafileSkiaTest, TestMultiPictureDocumentTypefaces); |
Wei Li | 1d345bf | 2018-08-10 02:52:37 | [diff] [blame] | 124 | |
| 125 | // The following three functions are used for tests only. |
| 126 | void AppendPage(const SkSize& page_size, sk_sp<cc::PaintRecord> record); |
| 127 | void AppendSubframeInfo(uint32_t content_id, |
Gyuyoung Kim | 5f7f4c7 | 2020-07-14 13:09:03 | [diff] [blame] | 128 | const base::UnguessableToken& proxy_token, |
Wei Li | 1d345bf | 2018-08-10 02:52:37 | [diff] [blame] | 129 | sk_sp<SkPicture> subframe_pic_holder); |
| 130 | SkStreamAsset* GetPdfData() const; |
| 131 | |
Wei Li | e13ea64 | 2018-02-17 07:55:19 | [diff] [blame] | 132 | // Callback function used during page content drawing to replace a custom |
| 133 | // data holder with corresponding place holder SkPicture. |
| 134 | void CustomDataToSkPictureCallback(SkCanvas* canvas, uint32_t content_id); |
| 135 | |
Wei Li | ab75477 | 2018-08-22 22:41:17 | [diff] [blame] | 136 | std::unique_ptr<MetafileSkiaData> data_; |
[email protected] | 8f87929 | 2011-04-08 00:21:20 | [diff] [blame] | 137 | |
Dominic Mazzoni | 0a39059c | 2020-01-08 19:30:45 | [diff] [blame] | 138 | ui::AXTreeUpdate accessibility_tree_; |
[email protected] | 8f87929 | 2011-04-08 00:21:20 | [diff] [blame] | 139 | }; |
| 140 | |
| 141 | } // namespace printing |
| 142 | |
Wei Li | ab75477 | 2018-08-22 22:41:17 | [diff] [blame] | 143 | #endif // PRINTING_METAFILE_SKIA_H_ |