1 /* 2 * Copyright (C) 2024 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 17 package android.graphics.pdf.models.selection; 18 19 import android.annotation.FlaggedApi; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.graphics.Point; 23 import android.graphics.pdf.content.PdfPageTextContent; 24 import android.graphics.pdf.flags.Flags; 25 import android.graphics.pdf.utils.Preconditions; 26 import android.os.Parcel; 27 import android.os.Parcelable; 28 29 /** 30 * Represents one edge of the selected content. 31 */ 32 @FlaggedApi(Flags.FLAG_ENABLE_PDF_VIEWER) 33 public final class SelectionBoundary implements Parcelable { 34 @NonNull 35 public static final Creator<SelectionBoundary> CREATOR = new Creator<SelectionBoundary>() { 36 @Override 37 public SelectionBoundary createFromParcel(Parcel in) { 38 return new SelectionBoundary(in); 39 } 40 41 @Override 42 public SelectionBoundary[] newArray(int size) { 43 return new SelectionBoundary[size]; 44 } 45 }; 46 private final int mIndex; 47 private final Point mPoint; 48 49 private final boolean mIsRtl; 50 51 /** 52 * <p> 53 * Create a new instance of {@link SelectionBoundary} if index of boundary and isRtl is known. 54 * The text returned by {@link PdfPageTextContent#getText()} form a "stream" and inside this 55 * "stream" each character has an index. 56 * 57 * @param index index of the selection boundary 58 * @param isRtl Determines whether the direction of selection is right-to-left (rtl) or reverse 59 * @throws IllegalArgumentException If the index is negative 60 * @hide 61 */ SelectionBoundary(int index, boolean isRtl)62 public SelectionBoundary(int index, boolean isRtl) { 63 Preconditions.checkArgument(index >= 0, "Index cannot be negative"); 64 this.mIndex = index; 65 this.mPoint = null; 66 this.mIsRtl = isRtl; 67 } 68 69 /** 70 * <p> 71 * Create a new instance of {@link SelectionBoundary} if index of boundary is known. The text 72 * returned by {@link PdfPageTextContent#getText()} form a "stream" and inside this "stream" 73 * each character has an index. 74 * <strong>Note: </strong>Point defaults to {@code null} in this case. 75 * 76 * @param index index of the selection boundary. 77 * @throws IllegalArgumentException If the index is negative. 78 */ SelectionBoundary(int index)79 public SelectionBoundary(int index) { 80 Preconditions.checkArgument(index >= 0, "Index cannot be negative"); 81 this.mIndex = index; 82 this.mPoint = null; 83 this.mIsRtl = false; 84 } 85 86 /** 87 * Creates a new instance of {@link SelectionBoundary} if the boundary and isRTL is known. 88 * 89 * @param point The point of selection boundary. 90 * @param isRtl Determines whether the direction of selection is right-to-left (rtl) or reverse 91 * @throws NullPointerException If the point is null 92 * @hide 93 */ SelectionBoundary(@onNull Point point, boolean isRtl)94 public SelectionBoundary(@NonNull Point point, boolean isRtl) { 95 Preconditions.checkNotNull(point, "Point cannot be null"); 96 this.mIndex = -1; 97 this.mPoint = point; 98 this.mIsRtl = isRtl; 99 } 100 101 /** 102 * Create a new instance of {@link SelectionBoundary} if the boundary {@link Point} is known. 103 * Index defaults to -1. 104 * 105 * @param point The point of selection boundary. 106 * @throws NullPointerException If the point is null. 107 */ SelectionBoundary(@onNull Point point)108 public SelectionBoundary(@NonNull Point point) { 109 Preconditions.checkNotNull(point, "Point cannot be null"); 110 this.mIndex = -1; 111 this.mPoint = point; 112 this.mIsRtl = false; 113 } 114 SelectionBoundary(Parcel in)115 private SelectionBoundary(Parcel in) { 116 mIndex = in.readInt(); 117 mPoint = in.readParcelable(Point.class.getClassLoader()); 118 mIsRtl = in.readBoolean(); 119 } 120 121 /** 122 * Gets the index of the text as determined by the text stream processed. If the value is -1 123 * then the {@link #getPoint()} will determine the selection boundary. 124 * 125 * @return index of the selection boundary. 126 */ getIndex()127 public int getIndex() { 128 return mIndex; 129 } 130 131 /** 132 * Gets the x, y coordinates of the selection boundary in points (1/72"). These coordinates are 133 * represented by a {@link Point} . If the value is {@code null} then the {@link #getIndex()} 134 * will determine the selection boundary. 135 * <p><strong>Note:</strong> Point (0,0) represents the top-left corner of the page 136 * 137 * @return The point of the selection boundary. 138 */ 139 @Nullable getPoint()140 public Point getPoint() { 141 return mPoint; 142 } 143 144 @Override describeContents()145 public int describeContents() { 146 return 0; 147 } 148 149 @Override writeToParcel(@ndroidx.annotation.NonNull Parcel dest, int flags)150 public void writeToParcel(@androidx.annotation.NonNull Parcel dest, int flags) { 151 dest.writeInt(mIndex); 152 dest.writeParcelable(mPoint, flags); 153 dest.writeBoolean(mIsRtl); 154 } 155 156 /** 157 * Gets whether the direction of selection is right-to-left (rtl) or reverse. The value of isRtl 158 * is determined by the underlying native layer using the start and stop boundaries. 159 * 160 * @return The direction of selection 161 */ getIsRtl()162 public boolean getIsRtl() { 163 return mIsRtl; 164 } 165 } 166