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"
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"
31 struct PrintDebugDumpPath
{
37 FilePath debug_dump_path
;
40 base::LazyInstance
<PrintDebugDumpPath
> g_debug_dump_info
=
41 LAZY_INSTANCE_INITIALIZER
;
47 PrintedDocument::PrintedDocument(const PrintSettings
& settings
,
48 PrintedPagesSource
* 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
,
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,
80 base::AutoLock
lock(lock_
);
81 mutable_
.pages_
[page_number
] = page
;
83 #if defined(OS_POSIX) && !defined(OS_MACOSX)
84 if (page_number
< mutable_
.first_page
)
85 mutable_
.first_page
= page_number
;
91 bool PrintedDocument::GetPage(int page_number
,
92 scoped_refptr
<PrintedPage
>* page
) {
93 base::AutoLock
lock(lock_
);
94 PrintedPages::const_iterator itr
= mutable_
.pages_
.find(page_number
);
95 if (itr
!= mutable_
.pages_
.end()) {
96 if (itr
->second
.get()) {
104 bool PrintedDocument::IsComplete() const {
105 base::AutoLock
lock(lock_
);
106 if (!mutable_
.page_count_
)
108 PageNumber
page(immutable_
.settings_
, mutable_
.page_count_
);
109 if (page
== PageNumber::npos())
112 for (; page
!= PageNumber::npos(); ++page
) {
113 #if defined(OS_WIN) || defined(OS_MACOSX)
114 const bool metafile_must_be_valid
= true;
115 #elif defined(OS_POSIX)
116 const bool metafile_must_be_valid
= (page
.ToInt() == mutable_
.first_page
);
118 PrintedPages::const_iterator itr
= mutable_
.pages_
.find(page
.ToInt());
119 if (itr
== mutable_
.pages_
.end() || !itr
->second
.get())
121 if (metafile_must_be_valid
&& !itr
->second
->metafile())
127 void PrintedDocument::DisconnectSource() {
128 base::AutoLock
lock(lock_
);
129 mutable_
.source_
= NULL
;
132 uint32
PrintedDocument::MemoryUsage() const {
133 std::vector
< scoped_refptr
<PrintedPage
> > pages_copy
;
135 base::AutoLock
lock(lock_
);
136 pages_copy
.reserve(mutable_
.pages_
.size());
137 PrintedPages::const_iterator end
= mutable_
.pages_
.end();
138 for (PrintedPages::const_iterator itr
= mutable_
.pages_
.begin();
140 if (itr
->second
.get()) {
141 pages_copy
.push_back(itr
->second
);
146 for (size_t i
= 0; i
< pages_copy
.size(); ++i
) {
147 total
+= pages_copy
[i
]->metafile()->GetDataSize();
152 void PrintedDocument::set_page_count(int max_page
) {
153 base::AutoLock
lock(lock_
);
154 DCHECK_EQ(0, mutable_
.page_count_
);
155 mutable_
.page_count_
= max_page
;
156 if (immutable_
.settings_
.ranges
.empty()) {
157 mutable_
.expected_page_count_
= max_page
;
159 // If there is a range, don't bother since expected_page_count_ is already
161 DCHECK_NE(mutable_
.expected_page_count_
, 0);
165 int PrintedDocument::page_count() const {
166 base::AutoLock
lock(lock_
);
167 return mutable_
.page_count_
;
170 int PrintedDocument::expected_page_count() const {
171 base::AutoLock
lock(lock_
);
172 return mutable_
.expected_page_count_
;
175 void PrintedDocument::DebugDump(const PrintedPage
& page
) {
176 if (!g_debug_dump_info
.Get().enabled
)
181 filename
+= ASCIIToUTF16("_");
182 filename
+= ASCIIToUTF16(StringPrintf("%02d", page
.page_number()));
184 filename
+= ASCIIToUTF16("_.emf");
185 page
.metafile()->SaveTo(
186 g_debug_dump_info
.Get().debug_dump_path
.Append(filename
));
188 filename
+= ASCIIToUTF16("_.pdf");
189 page
.metafile()->SaveTo(
190 g_debug_dump_info
.Get().debug_dump_path
.Append(UTF16ToUTF8(filename
)));
194 void PrintedDocument::set_debug_dump_path(const FilePath
& debug_dump_path
) {
195 g_debug_dump_info
.Get().enabled
= !debug_dump_path
.empty();
196 g_debug_dump_info
.Get().debug_dump_path
= debug_dump_path
;
199 const FilePath
& PrintedDocument::debug_dump_path() {
200 return g_debug_dump_info
.Get().debug_dump_path
;
203 PrintedDocument::Mutable::Mutable(PrintedPagesSource
* source
)
205 expected_page_count_(0),
207 #if defined(OS_POSIX) && !defined(OS_MACOSX)
208 first_page
= INT_MAX
;
212 PrintedDocument::Mutable::~Mutable() {
215 PrintedDocument::Immutable::Immutable(const PrintSettings
& settings
,
216 PrintedPagesSource
* source
,
218 : settings_(settings
),
219 source_message_loop_(MessageLoop::current()),
220 name_(source
->RenderSourceName()),
224 PrintedDocument::Immutable::~Immutable() {
227 #if defined(OS_POSIX) && defined(USE_AURA)
228 // This function is not used on aura linux/chromeos.
229 void PrintedDocument::RenderPrintedPage(const PrintedPage
& page
,
230 PrintingContext
* context
) const {
234 } // namespace printing