1a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav/*
2a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * Copyright (C) 2014 The Android Open Source Project
3a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav *
4a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * Licensed under the Apache License, Version 2.0 (the "License");
5a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * you may not use this file except in compliance with the License.
6a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * You may obtain a copy of the License at
7a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav *
8a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav *      http://www.apache.org/licenses/LICENSE-2.0
9a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav *
10a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * Unless required by applicable law or agreed to in writing, software
11a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * distributed under the License is distributed on an "AS IS" BASIS,
12a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * See the License for the specific language governing permissions and
14a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * limitations under the License.
15a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav */
16a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
17a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavpackage com.android.printspooler.util;
18a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
19a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport android.print.PageRange;
20525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganovimport android.print.PrintDocumentInfo;
21a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
22a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport java.util.Arrays;
23a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavimport java.util.Comparator;
24a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
25a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav/**
26a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav * This class contains utility functions for working with page ranges.
27a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav */
28a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslavpublic final class PageRangeUtils {
29a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
30a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    private static final PageRange[] ALL_PAGES_RANGE = new PageRange[] {PageRange.ALL_PAGES};
31a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
32a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    private static final Comparator<PageRange> sComparator = new Comparator<PageRange>() {
33a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        @Override
34a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        public int compare(PageRange lhs, PageRange rhs) {
35a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            return lhs.getStart() - rhs.getStart();
36a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        }
37a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    };
38a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
39a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    private PageRangeUtils() {
40a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        /* do nothing - hide constructor */
41a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    }
42a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
43a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    /**
44525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov     * Gets whether page ranges contains a given page.
45525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov     *
46525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov     * @param pageRanges The page ranges.
47525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov     * @param pageIndex The page for which to check.
48525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov     * @return Whether the page is within the ranges.
49525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov     */
50525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov    public static boolean contains(PageRange[] pageRanges, int pageIndex) {
51525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        final int rangeCount = pageRanges.length;
52525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        for (int i = 0; i < rangeCount; i++) {
53525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            PageRange pageRange = pageRanges[i];
54525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            if (pageRange.contains(pageIndex)) {
55525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov                return true;
56525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            }
57525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        }
58525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        return false;
59525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov    }
60525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov
61525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov    /**
62a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav     * Checks whether one page range array contains another one.
63a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav     *
64a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav     * @param ourRanges The container page ranges.
65a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav     * @param otherRanges The contained page ranges.
66525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov     * @param pageCount The total number of pages.
67a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav     * @return Whether the container page ranges contains the contained ones.
68a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav     */
69525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov    public static boolean contains(PageRange[] ourRanges, PageRange[] otherRanges, int pageCount) {
70a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        if (ourRanges == null || otherRanges == null) {
71a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            return false;
72a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        }
73a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
74a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        if (Arrays.equals(ourRanges, ALL_PAGES_RANGE)) {
75a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            return true;
76a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        }
77a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
78525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        if (Arrays.equals(otherRanges, ALL_PAGES_RANGE)) {
79525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            otherRanges[0] = new PageRange(0, pageCount - 1);
80525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        }
81525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov
82a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        ourRanges = normalize(ourRanges);
83a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        otherRanges = normalize(otherRanges);
84a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
85a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        // Note that the code below relies on the ranges being normalized
86a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        // which is they contain monotonically increasing non-intersecting
87a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        // sub-ranges whose start is less that or equal to the end.
88a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        int otherRangeIdx = 0;
89a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        final int ourRangeCount = ourRanges.length;
90a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        final int otherRangeCount = otherRanges.length;
91a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        for (int ourRangeIdx = 0; ourRangeIdx < ourRangeCount; ourRangeIdx++) {
92a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            PageRange ourRange = ourRanges[ourRangeIdx];
93a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            for (; otherRangeIdx < otherRangeCount; otherRangeIdx++) {
94a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                PageRange otherRange = otherRanges[otherRangeIdx];
95a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                if (otherRange.getStart() > ourRange.getEnd()) {
96a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    break;
97a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                }
98a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                if (otherRange.getStart() < ourRange.getStart()
99a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                        || otherRange.getEnd() > ourRange.getEnd()) {
100a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                    return false;
101a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                }
102a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            }
103a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        }
104525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        return (otherRangeIdx >= otherRangeCount);
105a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    }
106a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
107a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    /**
108a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav     * Normalizes a page range, which is the resulting page ranges are
109a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav     * non-overlapping with the start lesser than or equal to the end
110a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav     * and ordered in an ascending order.
111a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav     *
112a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav     * @param pageRanges The page ranges to normalize.
113a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav     * @return The normalized page ranges.
114a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav     */
115a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    public static PageRange[] normalize(PageRange[] pageRanges) {
116a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        if (pageRanges == null) {
117a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            return null;
118a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        }
119525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov
120a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        final int oldRangeCount = pageRanges.length;
121a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        if (oldRangeCount <= 1) {
122a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            return pageRanges;
123a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        }
124525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov
125a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        Arrays.sort(pageRanges, sComparator);
126525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov
127a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        int newRangeCount = 1;
128a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        for (int i = 0; i < oldRangeCount - 1; i++) {
129a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            PageRange currentRange = pageRanges[i];
130a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            PageRange nextRange = pageRanges[i + 1];
131a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            if (currentRange.getEnd() + 1 >= nextRange.getStart()) {
132a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                pageRanges[i] = null;
133a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                pageRanges[i + 1] = new PageRange(currentRange.getStart(),
134a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav                        Math.max(currentRange.getEnd(), nextRange.getEnd()));
135525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            } else {
136525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov                newRangeCount++;
137a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            }
138a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        }
139525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov
140a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        if (newRangeCount == oldRangeCount) {
141a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            return pageRanges;
142a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        }
143525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov
144525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        int normalRangeIndex = 0;
145525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        PageRange[] normalRanges = new PageRange[newRangeCount];
146525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        for (int i = 0; i < oldRangeCount; i++) {
147525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            PageRange normalRange = pageRanges[i];
148525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            if (normalRange != null) {
149525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov                normalRanges[normalRangeIndex] = normalRange;
150525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov                normalRangeIndex++;
151525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            }
152525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        }
153525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov
154525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        return normalRanges;
155a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    }
156a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
157a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    /**
158a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav     * Offsets a the start and end of page ranges with the given value.
159a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav     *
160a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav     * @param pageRanges The page ranges to offset.
161a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav     * @param offset The offset value.
162a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav     */
163a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    public static void offset(PageRange[] pageRanges, int offset) {
164a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        if (offset == 0) {
165a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            return;
166a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        }
167a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        final int pageRangeCount = pageRanges.length;
168a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        for (int i = 0; i < pageRangeCount; i++) {
169a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            final int start = pageRanges[i].getStart() + offset;
170a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            final int end = pageRanges[i].getEnd() + offset;
171a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            pageRanges[i] = new PageRange(start, end);
172a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        }
173a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    }
174a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav
175a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    /**
176a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav     * Gets the number of pages in a normalized range array.
177a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav     *
178a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav     * @param pageRanges Normalized page ranges.
179a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav     * @param layoutPageCount Page count after reported after layout pass.
180a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav     * @return The page count in the ranges.
181a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav     */
182a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    public static int getNormalizedPageCount(PageRange[] pageRanges, int layoutPageCount) {
183a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        int pageCount = 0;
184525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        if (pageRanges != null) {
185525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            final int pageRangeCount = pageRanges.length;
186525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            for (int i = 0; i < pageRangeCount; i++) {
187525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov                PageRange pageRange = pageRanges[i];
188525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov                if (PageRange.ALL_PAGES.equals(pageRange)) {
189525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov                    return layoutPageCount;
190525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov                }
191525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov                pageCount += pageRange.getSize();
192525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            }
193525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        }
194525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        return pageCount;
195525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov    }
196525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov
197525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov    public static PageRange asAbsoluteRange(PageRange pageRange, int pageCount) {
198525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        if (PageRange.ALL_PAGES.equals(pageRange)) {
199525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            return new PageRange(0, pageCount - 1);
200525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        }
201525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        return pageRange;
202525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov    }
203525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov
204525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov    public static boolean isAllPages(PageRange[] pageRanges) {
205a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        final int pageRangeCount = pageRanges.length;
206a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        for (int i = 0; i < pageRangeCount; i++) {
207a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            PageRange pageRange = pageRanges[i];
208525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            if (isAllPages(pageRange)) {
209525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov                return true;
210a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav            }
211a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav        }
212525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        return false;
213525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov    }
214525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov
215525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov    public static boolean isAllPages(PageRange pageRange) {
216525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        return PageRange.ALL_PAGES.equals(pageRange);
217525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov    }
218525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov
219525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov    public static boolean isAllPages(PageRange[] pageRanges, int pageCount) {
220525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        final int pageRangeCount = pageRanges.length;
221525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        for (int i = 0; i < pageRangeCount; i++) {
222525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            PageRange pageRange = pageRanges[i];
223525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            if (isAllPages(pageRange, pageCount)) {
224525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov                return true;
225525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            }
226525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        }
227525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        return false;
228525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov    }
229525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov
230525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov    public static boolean isAllPages(PageRange pageRanges, int pageCount) {
231525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        return pageRanges.getStart() == 0 && pageRanges.getEnd() == pageCount - 1;
232525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov    }
233525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov
234525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov    public static PageRange[] computePrintedPages(PageRange[] requestedPages,
235525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            PageRange[] writtenPages, int pageCount) {
236525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        // Adjust the print job pages based on what was requested and written.
237525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        // The cases are ordered in the most expected to the least expected
238525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        // with a special case first where the app does not know the page count
239525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        // so we ask for all to be written.
240525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        if (Arrays.equals(requestedPages, ALL_PAGES_RANGE)
241525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov                && pageCount == PrintDocumentInfo.PAGE_COUNT_UNKNOWN) {
242525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            return ALL_PAGES_RANGE;
243525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        } else if (Arrays.equals(writtenPages, requestedPages)) {
244525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            // We got a document with exactly the pages we wanted. Hence,
245525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            // the printer has to print all pages in the data.
246525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            return ALL_PAGES_RANGE;
247525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        } else if (Arrays.equals(writtenPages, ALL_PAGES_RANGE)) {
248525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            // We requested specific pages but got all of them. Hence,
249525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            // the printer has to print only the requested pages.
250525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            return requestedPages;
251525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        } else if (PageRangeUtils.contains(writtenPages, requestedPages, pageCount)) {
252525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            // We requested specific pages and got more but not all pages.
253525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            // Hence, we have to offset appropriately the printed pages to
254525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            // be based off the start of the written ones instead of zero.
255525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            // The written pages are always non-null and not empty.
256525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            final int offset = -writtenPages[0].getStart();
257525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            PageRangeUtils.offset(requestedPages, offset);
258525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            return requestedPages;
259525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        } else if (Arrays.equals(requestedPages, ALL_PAGES_RANGE)
260525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov                && isAllPages(writtenPages, pageCount)) {
261525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            // We requested all pages via the special constant and got all
262525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            // of them as an explicit enumeration. Hence, the printer has
263525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            // to print only the requested pages.
264525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov            return ALL_PAGES_RANGE;
265525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        }
266525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov
267525a66b2bb5abf844aff2109bdc9ed819566beceSvet Ganov        return null;
268a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav    }
269a798c0a984f29f7180883a61839f68d2cbf0c6ceSvetoslav}
270