Open NaCl IRT file only once at startup
[chromium-blink-merge.git] / printing / printed_document.cc
blob28a70e9ac73f567d6ba8d9c5fae71c70eef4c89c
1 // Copyright (c) 2011 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.
5 #include "printing/printed_document.h"
7 #include <algorithm>
8 #include <set>
9 #include <string>
10 #include <vector>
12 #include "base/file_path.h"
13 #include "base/file_util.h"
14 #include "base/i18n/file_util_icu.h"
15 #include "base/lazy_instance.h"
16 #include "base/message_loop.h"
17 #include "base/stringprintf.h"
18 #include "base/string_util.h"
19 #include "base/utf_string_conversions.h"
20 #include "base/i18n/time_formatting.h"
21 #include "printing/page_number.h"
22 #include "printing/printed_pages_source.h"
23 #include "printing/printed_page.h"
24 #include "printing/units.h"
25 #include "skia/ext/platform_device.h"
26 #include "ui/base/text/text_elider.h"
27 #include "ui/gfx/font.h"
29 namespace {
31 struct PrintDebugDumpPath {
32 PrintDebugDumpPath()
33 : enabled(false) {
36 bool enabled;
37 FilePath debug_dump_path;
40 static base::LazyInstance<PrintDebugDumpPath> g_debug_dump_info =
41 LAZY_INSTANCE_INITIALIZER;
43 } // namespace
45 namespace printing {
47 PrintedDocument::PrintedDocument(const PrintSettings& settings,
48 PrintedPagesSource* source,
49 int cookie)
50 : mutable_(source),
51 immutable_(settings, source, cookie) {
53 // Records the expected page count if a range is setup.
54 if (!settings.ranges.empty()) {
55 // If there is a range, set the number of page
56 for (unsigned i = 0; i < settings.ranges.size(); ++i) {
57 const PageRange& range = settings.ranges[i];
58 mutable_.expected_page_count_ += range.to - range.from + 1;
63 PrintedDocument::~PrintedDocument() {
66 void PrintedDocument::SetPage(int page_number,
67 Metafile* metafile,
68 double shrink,
69 const gfx::Size& paper_size,
70 const gfx::Rect& page_rect) {
71 // Notice the page_number + 1, the reason is that this is the value that will
72 // be shown. Users dislike 0-based counting.
73 scoped_refptr<PrintedPage> page(
74 new PrintedPage(page_number + 1,
75 metafile,
76 paper_size,
77 page_rect));
79 base::AutoLock lock(lock_);
80 mutable_.pages_[page_number] = page;
82 #if defined(OS_POSIX) && !defined(OS_MACOSX)
83 if (page_number < mutable_.first_page)
84 mutable_.first_page = page_number;
85 #endif
87 if (mutable_.shrink_factor == 0) {
88 mutable_.shrink_factor = shrink;
89 } else {
90 DCHECK_EQ(mutable_.shrink_factor, shrink);
93 DebugDump(*page);
96 bool PrintedDocument::GetPage(int page_number,
97 scoped_refptr<PrintedPage>* page) {
98 base::AutoLock lock(lock_);
99 PrintedPages::const_iterator itr = mutable_.pages_.find(page_number);
100 if (itr != mutable_.pages_.end()) {
101 if (itr->second.get()) {
102 *page = itr->second;
103 return true;
106 return false;
109 bool PrintedDocument::IsComplete() const {
110 base::AutoLock lock(lock_);
111 if (!mutable_.page_count_)
112 return false;
113 PageNumber page(immutable_.settings_, mutable_.page_count_);
114 if (page == PageNumber::npos())
115 return false;
117 for (; page != PageNumber::npos(); ++page) {
118 #if defined(OS_WIN) || defined(OS_MACOSX)
119 const bool metafile_must_be_valid = true;
120 #elif defined(OS_POSIX)
121 const bool metafile_must_be_valid = (page.ToInt() == mutable_.first_page);
122 #endif
123 PrintedPages::const_iterator itr = mutable_.pages_.find(page.ToInt());
124 if (itr == mutable_.pages_.end() || !itr->second.get())
125 return false;
126 if (metafile_must_be_valid && !itr->second->metafile())
127 return false;
129 return true;
132 void PrintedDocument::DisconnectSource() {
133 base::AutoLock lock(lock_);
134 mutable_.source_ = NULL;
137 uint32 PrintedDocument::MemoryUsage() const {
138 std::vector< scoped_refptr<PrintedPage> > pages_copy;
140 base::AutoLock lock(lock_);
141 pages_copy.reserve(mutable_.pages_.size());
142 PrintedPages::const_iterator end = mutable_.pages_.end();
143 for (PrintedPages::const_iterator itr = mutable_.pages_.begin();
144 itr != end; ++itr) {
145 if (itr->second.get()) {
146 pages_copy.push_back(itr->second);
150 uint32 total = 0;
151 for (size_t i = 0; i < pages_copy.size(); ++i) {
152 total += pages_copy[i]->metafile()->GetDataSize();
154 return total;
157 void PrintedDocument::set_page_count(int max_page) {
158 base::AutoLock lock(lock_);
159 DCHECK_EQ(0, mutable_.page_count_);
160 mutable_.page_count_ = max_page;
161 if (immutable_.settings_.ranges.empty()) {
162 mutable_.expected_page_count_ = max_page;
163 } else {
164 // If there is a range, don't bother since expected_page_count_ is already
165 // initialized.
166 DCHECK_NE(mutable_.expected_page_count_, 0);
170 int PrintedDocument::page_count() const {
171 base::AutoLock lock(lock_);
172 return mutable_.page_count_;
175 int PrintedDocument::expected_page_count() const {
176 base::AutoLock lock(lock_);
177 return mutable_.expected_page_count_;
180 void PrintedDocument::DebugDump(const PrintedPage& page) {
181 if (!g_debug_dump_info.Get().enabled)
182 return;
184 string16 filename;
185 filename += name();
186 filename += ASCIIToUTF16("_");
187 filename += ASCIIToUTF16(StringPrintf("%02d", page.page_number()));
188 #if defined(OS_WIN)
189 filename += ASCIIToUTF16("_.emf");
190 page.metafile()->SaveTo(
191 g_debug_dump_info.Get().debug_dump_path.Append(filename));
192 #else // OS_WIN
193 filename += ASCIIToUTF16("_.pdf");
194 page.metafile()->SaveTo(
195 g_debug_dump_info.Get().debug_dump_path.Append(UTF16ToUTF8(filename)));
196 #endif // OS_WIN
199 void PrintedDocument::set_debug_dump_path(const FilePath& debug_dump_path) {
200 g_debug_dump_info.Get().enabled = !debug_dump_path.empty();
201 g_debug_dump_info.Get().debug_dump_path = debug_dump_path;
204 const FilePath& PrintedDocument::debug_dump_path() {
205 return g_debug_dump_info.Get().debug_dump_path;
208 PrintedDocument::Mutable::Mutable(PrintedPagesSource* source)
209 : source_(source),
210 expected_page_count_(0),
211 page_count_(0),
212 shrink_factor(0) {
213 #if defined(OS_POSIX) && !defined(OS_MACOSX)
214 first_page = INT_MAX;
215 #endif
218 PrintedDocument::Mutable::~Mutable() {
221 PrintedDocument::Immutable::Immutable(const PrintSettings& settings,
222 PrintedPagesSource* source,
223 int cookie)
224 : settings_(settings),
225 source_message_loop_(MessageLoop::current()),
226 name_(source->RenderSourceName()),
227 cookie_(cookie) {
230 PrintedDocument::Immutable::~Immutable() {
233 } // namespace printing