PageRangeUtils.java revision a798c0a984f29f7180883a61839f68d2cbf0c6ce
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.printspooler.util; 18 19import android.print.PageRange; 20 21import java.util.Arrays; 22import java.util.Comparator; 23 24/** 25 * This class contains utility functions for working with page ranges. 26 */ 27public final class PageRangeUtils { 28 29 private static final PageRange[] ALL_PAGES_RANGE = new PageRange[] {PageRange.ALL_PAGES}; 30 31 private static final Comparator<PageRange> sComparator = new Comparator<PageRange>() { 32 @Override 33 public int compare(PageRange lhs, PageRange rhs) { 34 return lhs.getStart() - rhs.getStart(); 35 } 36 }; 37 38 private PageRangeUtils() { 39 /* do nothing - hide constructor */ 40 } 41 42 /** 43 * Checks whether one page range array contains another one. 44 * 45 * @param ourRanges The container page ranges. 46 * @param otherRanges The contained page ranges. 47 * @return Whether the container page ranges contains the contained ones. 48 */ 49 public static boolean contains(PageRange[] ourRanges, PageRange[] otherRanges) { 50 if (ourRanges == null || otherRanges == null) { 51 return false; 52 } 53 54 if (Arrays.equals(ourRanges, ALL_PAGES_RANGE)) { 55 return true; 56 } 57 58 ourRanges = normalize(ourRanges); 59 otherRanges = normalize(otherRanges); 60 61 // Note that the code below relies on the ranges being normalized 62 // which is they contain monotonically increasing non-intersecting 63 // sub-ranges whose start is less that or equal to the end. 64 int otherRangeIdx = 0; 65 final int ourRangeCount = ourRanges.length; 66 final int otherRangeCount = otherRanges.length; 67 for (int ourRangeIdx = 0; ourRangeIdx < ourRangeCount; ourRangeIdx++) { 68 PageRange ourRange = ourRanges[ourRangeIdx]; 69 for (; otherRangeIdx < otherRangeCount; otherRangeIdx++) { 70 PageRange otherRange = otherRanges[otherRangeIdx]; 71 if (otherRange.getStart() > ourRange.getEnd()) { 72 break; 73 } 74 if (otherRange.getStart() < ourRange.getStart() 75 || otherRange.getEnd() > ourRange.getEnd()) { 76 return false; 77 } 78 } 79 } 80 if (otherRangeIdx < otherRangeCount) { 81 return false; 82 } 83 return true; 84 } 85 86 /** 87 * Normalizes a page range, which is the resulting page ranges are 88 * non-overlapping with the start lesser than or equal to the end 89 * and ordered in an ascending order. 90 * 91 * @param pageRanges The page ranges to normalize. 92 * @return The normalized page ranges. 93 */ 94 public static PageRange[] normalize(PageRange[] pageRanges) { 95 if (pageRanges == null) { 96 return null; 97 } 98 final int oldRangeCount = pageRanges.length; 99 if (oldRangeCount <= 1) { 100 return pageRanges; 101 } 102 Arrays.sort(pageRanges, sComparator); 103 int newRangeCount = 1; 104 for (int i = 0; i < oldRangeCount - 1; i++) { 105 newRangeCount++; 106 PageRange currentRange = pageRanges[i]; 107 PageRange nextRange = pageRanges[i + 1]; 108 if (currentRange.getEnd() + 1 >= nextRange.getStart()) { 109 newRangeCount--; 110 pageRanges[i] = null; 111 pageRanges[i + 1] = new PageRange(currentRange.getStart(), 112 Math.max(currentRange.getEnd(), nextRange.getEnd())); 113 } 114 } 115 if (newRangeCount == oldRangeCount) { 116 return pageRanges; 117 } 118 return Arrays.copyOfRange(pageRanges, oldRangeCount - newRangeCount, 119 oldRangeCount); 120 } 121 122 /** 123 * Offsets a the start and end of page ranges with the given value. 124 * 125 * @param pageRanges The page ranges to offset. 126 * @param offset The offset value. 127 */ 128 public static void offset(PageRange[] pageRanges, int offset) { 129 if (offset == 0) { 130 return; 131 } 132 final int pageRangeCount = pageRanges.length; 133 for (int i = 0; i < pageRangeCount; i++) { 134 final int start = pageRanges[i].getStart() + offset; 135 final int end = pageRanges[i].getEnd() + offset; 136 pageRanges[i] = new PageRange(start, end); 137 } 138 } 139 140 /** 141 * Gets the number of pages in a normalized range array. 142 * 143 * @param pageRanges Normalized page ranges. 144 * @param layoutPageCount Page count after reported after layout pass. 145 * @return The page count in the ranges. 146 */ 147 public static int getNormalizedPageCount(PageRange[] pageRanges, int layoutPageCount) { 148 int pageCount = 0; 149 final int pageRangeCount = pageRanges.length; 150 for (int i = 0; i < pageRangeCount; i++) { 151 PageRange pageRange = pageRanges[i]; 152 if (PageRange.ALL_PAGES.equals(pageRange)) { 153 return layoutPageCount; 154 } 155 pageCount += pageRange.getEnd() - pageRange.getStart() + 1; 156 } 157 return pageCount; 158 } 159} 160