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_PRINTED_DOCUMENT_H_ 6#define PRINTING_PRINTED_DOCUMENT_H_ 7 8#include <map> 9 10#include "base/files/file_path.h" 11#include "base/memory/ref_counted.h" 12#include "base/memory/scoped_ptr.h" 13#include "base/strings/string16.h" 14#include "base/synchronization/lock.h" 15#include "printing/print_settings.h" 16#include "ui/gfx/native_widget_types.h" 17 18namespace base { 19class RefCountedMemory; 20class TaskRunner; 21} 22 23namespace printing { 24 25class MetafilePlayer; 26class PrintedPage; 27class PrintedPagesSource; 28class PrintingContext; 29 30// A collection of rendered pages. The settings are immutable. If the print 31// settings are changed, a new PrintedDocument must be created. 32// Warning: May be accessed from many threads at the same time. Only one thread 33// will have write access. Sensible functions are protected by a lock. 34// Warning: Once a page is loaded, it cannot be replaced. Pages may be discarded 35// under low memory conditions. 36class PRINTING_EXPORT PrintedDocument 37 : public base::RefCountedThreadSafe<PrintedDocument> { 38 public: 39 // The cookie shall be unique and has a specific relationship with its 40 // originating source and settings. 41 PrintedDocument(const PrintSettings& settings, 42 PrintedPagesSource* source, 43 int cookie, 44 base::TaskRunner* blocking_runner); 45 46 // Sets a page's data. 0-based. Takes metafile ownership. 47 // Note: locks for a short amount of time. 48 void SetPage(int page_number, 49 scoped_ptr<MetafilePlayer> metafile, 50#if defined(OS_WIN) 51 double shrink, 52#endif // OS_WIN 53 const gfx::Size& paper_size, 54 const gfx::Rect& page_rect); 55 56 // Retrieves a page. If the page is not available right now, it 57 // requests to have this page be rendered and returns NULL. 58 // Note: locks for a short amount of time. 59 scoped_refptr<PrintedPage> GetPage(int page_number); 60 61 // Draws the page in the context. 62 // Note: locks for a short amount of time in debug only. 63#if defined(OS_WIN) || defined(OS_MACOSX) && !defined(USE_AURA) 64 void RenderPrintedPage(const PrintedPage& page, 65 gfx::NativeDrawingContext context) const; 66#elif defined(OS_POSIX) 67 void RenderPrintedPage(const PrintedPage& page, 68 PrintingContext* context) const; 69#endif 70 71 // Returns true if all the necessary pages for the settings are already 72 // rendered. 73 // Note: locks while parsing the whole tree. 74 bool IsComplete() const; 75 76 // Disconnects the PrintedPage source (PrintedPagesSource). It is done when 77 // the source is being destroyed. 78 void DisconnectSource(); 79 80 // Sets the number of pages in the document to be rendered. Can only be set 81 // once. 82 // Note: locks for a short amount of time. 83 void set_page_count(int max_page); 84 85 // Number of pages in the document. Used for headers/footers. 86 // Note: locks for a short amount of time. 87 int page_count() const; 88 89 // Returns the number of expected pages to be rendered. It is a non-linear 90 // series if settings().ranges is not empty. It is the same value as 91 // document_page_count() otherwise. 92 // Note: locks for a short amount of time. 93 int expected_page_count() const; 94 95 // Getters. All these items are immutable hence thread-safe. 96 const PrintSettings& settings() const { return immutable_.settings_; } 97 const base::string16& name() const { return immutable_.name_; } 98 int cookie() const { return immutable_.cookie_; } 99 100 // Sets a path where to dump printing output files for debugging. If never set 101 // no files are generated. 102 static void set_debug_dump_path(const base::FilePath& debug_dump_path); 103 104 // Creates debug file name from given |document_name| and |extension|. 105 // |extension| should include '.', example ".pdf" 106 // Returns empty |base::FilePath| if debug dumps is not enabled. 107 static base::FilePath CreateDebugDumpPath( 108 const base::string16& document_name, 109 const base::FilePath::StringType& extension); 110 111 // Dump data on blocking task runner if debug dumps enabled. 112 void DebugDumpData(const base::RefCountedMemory* data, 113 const base::FilePath::StringType& extension); 114 115 private: 116 friend class base::RefCountedThreadSafe<PrintedDocument>; 117 118 virtual ~PrintedDocument(); 119 120 // Array of data for each print previewed page. 121 typedef std::map<int, scoped_refptr<PrintedPage> > PrintedPages; 122 123 // Contains all the mutable stuff. All this stuff MUST be accessed with the 124 // lock held. 125 struct Mutable { 126 explicit Mutable(PrintedPagesSource* source); 127 ~Mutable(); 128 129 // Source that generates the PrintedPage's (i.e. a TabContents). It will be 130 // set back to NULL if the source is deleted before this object. 131 PrintedPagesSource* source_; 132 133 // Contains the pages' representation. This is a collection of PrintedPage. 134 // Warning: Lock must be held when accessing this member. 135 PrintedPages pages_; 136 137 // Number of expected pages to be rendered. 138 // Warning: Lock must be held when accessing this member. 139 int expected_page_count_; 140 141 // The total number of pages in the document. 142 int page_count_; 143 144#if defined(OS_POSIX) && !defined(OS_MACOSX) 145 // Page number of the first page. 146 int first_page; 147#endif 148 }; 149 150 // Contains all the immutable stuff. All this stuff can be accessed without 151 // any lock held. This is because it can't be changed after the object's 152 // construction. 153 struct Immutable { 154 Immutable(const PrintSettings& settings, 155 PrintedPagesSource* source, 156 int cookie, 157 base::TaskRunner* blocking_runner); 158 ~Immutable(); 159 160 // Print settings used to generate this document. Immutable. 161 PrintSettings settings_; 162 163 // Document name. Immutable. 164 base::string16 name_; 165 166 // Cookie to uniquely identify this document. It is used to make sure that a 167 // PrintedPage is correctly belonging to the PrintedDocument. Since 168 // PrintedPage generation is completely asynchronous, it could be easy to 169 // mess up and send the page to the wrong document. It can be viewed as a 170 // simpler hash of PrintSettings since a new document is made each time the 171 // print settings change. 172 int cookie_; 173 174 // Native thread for blocking operations, like file access. 175 scoped_refptr<base::TaskRunner> blocking_runner_; 176 }; 177 178 // All writable data member access must be guarded by this lock. Needs to be 179 // mutable since it can be acquired from const member functions. 180 mutable base::Lock lock_; 181 182 // All the mutable members. 183 Mutable mutable_; 184 185 // All the immutable members. 186 const Immutable immutable_; 187 188 DISALLOW_COPY_AND_ASSIGN(PrintedDocument); 189}; 190 191} // namespace printing 192 193#endif // PRINTING_PRINTED_DOCUMENT_H_ 194