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 static 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,
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
;
87 if (mutable_
.shrink_factor
== 0) {
88 mutable_
.shrink_factor
= shrink
;
90 DCHECK_EQ(mutable_
.shrink_factor
, shrink
);
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()) {
109 bool PrintedDocument::IsComplete() const {
110 base::AutoLock
lock(lock_
);
111 if (!mutable_
.page_count_
)
113 PageNumber
page(immutable_
.settings_
, mutable_
.page_count_
);
114 if (page
== PageNumber::npos())
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
);
123 PrintedPages::const_iterator itr
= mutable_
.pages_
.find(page
.ToInt());
124 if (itr
== mutable_
.pages_
.end() || !itr
->second
.get())
126 if (metafile_must_be_valid
&& !itr
->second
->metafile())
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();
145 if (itr
->second
.get()) {
146 pages_copy
.push_back(itr
->second
);
151 for (size_t i
= 0; i
< pages_copy
.size(); ++i
) {
152 total
+= pages_copy
[i
]->metafile()->GetDataSize();
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
;
164 // If there is a range, don't bother since expected_page_count_ is already
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
)
186 filename
+= ASCIIToUTF16("_");
187 filename
+= ASCIIToUTF16(StringPrintf("%02d", page
.page_number()));
189 filename
+= ASCIIToUTF16("_.emf");
190 page
.metafile()->SaveTo(
191 g_debug_dump_info
.Get().debug_dump_path
.Append(filename
));
193 filename
+= ASCIIToUTF16("_.pdf");
194 page
.metafile()->SaveTo(
195 g_debug_dump_info
.Get().debug_dump_path
.Append(UTF16ToUTF8(filename
)));
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
)
210 expected_page_count_(0),
213 #if defined(OS_POSIX) && !defined(OS_MACOSX)
214 first_page
= INT_MAX
;
218 PrintedDocument::Mutable::~Mutable() {
221 PrintedDocument::Immutable::Immutable(const PrintSettings
& settings
,
222 PrintedPagesSource
* source
,
224 : settings_(settings
),
225 source_message_loop_(MessageLoop::current()),
226 name_(source
->RenderSourceName()),
230 PrintedDocument::Immutable::~Immutable() {
233 } // namespace printing