Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(84)

Side by Side Diff: pdf/range_set.cc

Issue 2349753003: Improve linearized pdf load/show time. (Closed)
Patch Set: remove useless code. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2016 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 #include "pdf/range_set.h"
6
7 #include <algorithm>
8 #include <list>
9 #include <sstream>
10
11 namespace chrome_pdf {
12
13 namespace {
14
15 gfx::Range FixDirection(const gfx::Range& range) {
16 if (!range.IsValid() || !range.is_reversed())
17 return range;
18 return gfx::Range(range.end() + 1, range.start() + 1);
19 }
20
21 } // namespace
22
23 RangeSet::RangeSet() {}
24
25 RangeSet::RangeSet(const gfx::Range& range) {
26 Union(range);
27 }
28
29 RangeSet::~RangeSet() {}
30
31 void RangeSet::Union(const gfx::Range& range) {
32 if (range.is_empty())
33 return;
34 gfx::Range fixed_range = FixDirection(range);
35 if (IsEmpty()) {
36 ranges_.insert(fixed_range);
37 return;
38 }
39
40 auto start = ranges_.upper_bound(fixed_range);
41 if (start != ranges_.begin())
42 --start; // start now points to the key equal or lower than offset.
43 if (start->end() < fixed_range.start())
44 ++start; // start element is entirely before current range, skip it.
45
46 auto end = ranges_.upper_bound(gfx::Range(fixed_range.end()));
47 if (start == end) { // No ranges to merge.
48 ranges_.insert(fixed_range);
49 return;
50 }
51
52 --end;
53
54 int new_start = std::min<size_t>(start->start(), fixed_range.start());
55 int new_end = std::max(end->end(), fixed_range.end());
56
57 ranges_.erase(start, ++end);
58 ranges_.insert(gfx::Range(new_start, new_end));
59 }
60
61 void RangeSet::Union(const RangeSet& range_set) {
62 if (&range_set == this)
63 return;
64 for (const auto& it : range_set.ranges()) {
65 Union(it);
66 }
67 }
68
69 bool RangeSet::Contains(uint32_t point) const {
70 return Contains(gfx::Range(point, point + 1));
71 }
72
73 bool RangeSet::Contains(const gfx::Range& range) const {
74 if (range.is_empty())
75 return false;
76 const gfx::Range fixed_range = FixDirection(range);
77 auto it = ranges().upper_bound(fixed_range);
78 if (it == ranges().begin())
79 return false; // No ranges includes range.start().
80
81 --it; // Now it starts equal or before range.start().
82 return it->end() >= fixed_range.end();
83 }
84
85 bool RangeSet::Contains(const RangeSet& range_set) const {
86 for (const auto& it : range_set.ranges()) {
87 if (!Contains(it))
88 return false;
89 }
90 return true;
91 }
92
93 bool RangeSet::Intersects(const gfx::Range& range) const {
94 if (IsEmpty() || range.is_empty())
95 return false;
96 const gfx::Range fixed_range = FixDirection(range);
97 auto start = ranges_.upper_bound(fixed_range);
98 if (start != ranges_.begin())
99 --start; // start now points to the key equal or lower than
100 // range.start().
101 if (start->end() < range.start())
102 ++start; // start element is entirely before current range, skip it.
103 auto end = ranges_.upper_bound(gfx::Range(fixed_range.end()));
104 for (auto it = start; it != end; ++it) {
105 if (fixed_range.end() > it->start() && fixed_range.start() < it->end())
106 return true;
107 }
108 return false;
109 }
110
111 bool RangeSet::Intersects(const RangeSet& range_set) const {
112 for (const auto& it : range_set.ranges()) {
113 if (Intersects(it))
114 return true;
115 }
116 return false;
117 }
118
119 void RangeSet::Intersect(const gfx::Range& range) {
120 Intersect(RangeSet(range));
121 }
122
123 void RangeSet::Intersect(const RangeSet& range_set) {
124 if (IsEmpty())
125 return;
126 RangesContainer new_ranges;
127 for (const auto& range : range_set.ranges()) {
128 auto start = ranges_.upper_bound(range);
129 if (start != ranges_.begin())
130 --start; // start now points to the key equal or lower than
131 // range.start().
132 if (start->end() < range.start())
133 ++start; // start element is entirely before current range, skip it.
134 auto end = ranges_.upper_bound(gfx::Range(range.end()));
135 if (start == end) { // No data in the current range available.
136 continue;
137 }
138 for (auto it = start; it != end; ++it) {
139 const gfx::Range new_range = range.Intersect(*it);
140 if (!new_range.is_empty()) {
141 new_ranges.insert(new_range);
142 }
143 }
144 }
145 new_ranges.swap(ranges_);
146 }
147
148 void RangeSet::Subtract(const gfx::Range& range) {
149 if (range.is_empty() || IsEmpty())
150 return;
151 const gfx::Range fixed_range = FixDirection(range);
152 auto start = ranges_.upper_bound(fixed_range);
153 if (start != ranges_.begin())
154 --start; // start now points to the key equal or lower than
155 // range.start().
156 if (start->end() < fixed_range.start())
157 ++start; // start element is entirely before current range, skip it.
158 auto end = ranges_.upper_bound(gfx::Range(fixed_range.end()));
159 if (start == end) { // No data in the current range available.
160 return;
161 }
162 std::list<gfx::Range> new_ranges;
163 for (auto it = start; it != end; ++it) {
164 const gfx::Range left(it->start(),
165 std::min(it->end(), fixed_range.start()));
166 const gfx::Range right(std::max(it->start(), fixed_range.end()), it->end());
167 if (!left.is_empty() && !left.is_reversed()) {
168 new_ranges.push_back(left);
169 }
170 if (!right.is_empty() && !right.is_reversed() && right != left) {
171 new_ranges.push_back(right);
172 }
173 }
174 ranges_.erase(start, end);
175 for (const auto& it : new_ranges) {
176 ranges_.insert(it);
177 }
178 }
179
180 void RangeSet::Subtract(const RangeSet& range_set) {
181 if (&range_set == this) {
182 ranges_.clear();
183 return;
184 }
185 for (const auto& range : range_set.ranges()) {
186 Subtract(range);
187 }
188 }
189
190 void RangeSet::Diff(const gfx::Range& range) {
191 Diff(RangeSet(range));
192 }
193
194 void RangeSet::Diff(const RangeSet& range_set) {
195 RangeSet tmp = *this;
196 tmp.Intersect(range_set);
197 Union(range_set);
198 Subtract(tmp);
199 }
200
201 bool RangeSet::IsEmpty() const {
202 return ranges().empty();
203 }
204
205 void RangeSet::Clear() {
206 ranges_.clear();
207 }
208
209 gfx::Range RangeSet::First() const {
210 return *ranges().begin();
211 }
212
213 gfx::Range RangeSet::Last() const {
214 return *ranges().rbegin();
215 }
216
217 std::string RangeSet::ToString() const {
218 std::stringstream ss;
219 ss << "{";
220 for (const auto& it : ranges()) {
221 ss << "[" << it.start() << "," << it.end() << ")";
222 }
223 ss << "}";
224 return ss.str();
225 }
226
227 } // namespace chrome_pdf
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698