1 /* 2 * Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 /* 27 * (C) Copyright Taligent, Inc. 1996 - 1997, All Rights Reserved 28 * (C) Copyright IBM Corp. 1996 - 1998, All Rights Reserved 29 * 30 * The original version of this source code and documentation is 31 * copyrighted and owned by Taligent, Inc., a wholly-owned subsidiary 32 * of IBM. These materials are provided under terms of a License 33 * Agreement between Taligent and Sun. This technology is protected 34 * by multiple US and International patents. 35 * 36 * This notice and attribution to Taligent may not be removed. 37 * Taligent is a registered trademark of Taligent, Inc. 38 * 39 */ 40 41 package java.awt.font; 42 import java.lang.String; 43 44 /** 45 * The <code>TextHitInfo</code> class represents a character position in a 46 * text model, and a <b>bias</b>, or "side," of the character. Biases are 47 * either <EM>leading</EM> (the left edge, for a left-to-right character) 48 * or <EM>trailing</EM> (the right edge, for a left-to-right character). 49 * Instances of <code>TextHitInfo</code> are used to specify caret and 50 * insertion positions within text. 51 * <p> 52 * For example, consider the text "abc". TextHitInfo.trailing(1) 53 * corresponds to the right side of the 'b' in the text. 54 * <p> 55 * <code>TextHitInfo</code> is used primarily by {@link TextLayout} and 56 * clients of <code>TextLayout</code>. Clients of <code>TextLayout</code> 57 * query <code>TextHitInfo</code> instances for an insertion offset, where 58 * new text is inserted into the text model. The insertion offset is equal 59 * to the character position in the <code>TextHitInfo</code> if the bias 60 * is leading, and one character after if the bias is trailing. The 61 * insertion offset for TextHitInfo.trailing(1) is 2. 62 * <p> 63 * Sometimes it is convenient to construct a <code>TextHitInfo</code> with 64 * the same insertion offset as an existing one, but on the opposite 65 * character. The <code>getOtherHit</code> method constructs a new 66 * <code>TextHitInfo</code> with the same insertion offset as an existing 67 * one, with a hit on the character on the other side of the insertion offset. 68 * Calling <code>getOtherHit</code> on trailing(1) would return leading(2). 69 * In general, <code>getOtherHit</code> for trailing(n) returns 70 * leading(n+1) and <code>getOtherHit</code> for leading(n) 71 * returns trailing(n-1). 72 * <p> 73 * <strong>Example</strong>:<p> 74 * Converting a graphical point to an insertion point within a text 75 * model 76 * <blockquote><pre> 77 * TextLayout layout = ...; 78 * Point2D.Float hitPoint = ...; 79 * TextHitInfo hitInfo = layout.hitTestChar(hitPoint.x, hitPoint.y); 80 * int insPoint = hitInfo.getInsertionIndex(); 81 * // insPoint is relative to layout; may need to adjust for use 82 * // in a text model 83 * </pre></blockquote> 84 * 85 * @see TextLayout 86 */ 87 88 public final class TextHitInfo { 89 private int charIndex; 90 private boolean isLeadingEdge; 91 92 /** 93 * Constructs a new <code>TextHitInfo</code>. 94 * @param charIndex the index of the character hit 95 * @param isLeadingEdge <code>true</code> if the leading edge of the 96 * character was hit 97 */ 98 private TextHitInfo(int charIndex, boolean isLeadingEdge) { 99 this.charIndex = charIndex; 100 this.isLeadingEdge = isLeadingEdge; 101 } 102 103 /** 104 * Returns the index of the character hit. 105 * @return the index of the character hit. 106 */ 107 public int getCharIndex() { 108 return charIndex; 109 } 110 111 /** 112 * Returns <code>true</code> if the leading edge of the character was 113 * hit. 114 * @return <code>true</code> if the leading edge of the character was 115 * hit; <code>false</code> otherwise. 116 */ 117 public boolean isLeadingEdge() { 118 return isLeadingEdge; 119 } 120 121 /** 122 * Returns the insertion index. This is the character index if 123 * the leading edge of the character was hit, and one greater 124 * than the character index if the trailing edge was hit. 125 * @return the insertion index. 126 */ 127 public int getInsertionIndex() { 128 return isLeadingEdge ? charIndex : charIndex + 1; 129 } 130 131 /** 132 * Returns the hash code. 133 * @return the hash code of this <code>TextHitInfo</code>, which is 134 * also the <code>charIndex</code> of this <code>TextHitInfo</code>. 135 */ 136 public int hashCode() { 137 return charIndex; 138 } 139 140 /** 141 * Returns <code>true</code> if the specified <code>Object</code> is a 142 * <code>TextHitInfo</code> and equals this <code>TextHitInfo</code>. 143 * @param obj the <code>Object</code> to test for equality 144 * @return <code>true</code> if the specified <code>Object</code> 145 * equals this <code>TextHitInfo</code>; <code>false</code> otherwise. 146 */ 147 public boolean equals(Object obj) { 148 return (obj instanceof TextHitInfo) && equals((TextHitInfo)obj); 149 } 150 151 /** 152 * Returns <code>true</code> if the specified <code>TextHitInfo</code> 153 * has the same <code>charIndex</code> and <code>isLeadingEdge</code> 154 * as this <code>TextHitInfo</code>. This is not the same as having 155 * the same insertion offset. 156 * @param hitInfo a specified <code>TextHitInfo</code> 157 * @return <code>true</code> if the specified <code>TextHitInfo</code> 158 * has the same <code>charIndex</code> and <code>isLeadingEdge</code> 159 * as this <code>TextHitInfo</code>. 160 */ 161 public boolean equals(TextHitInfo hitInfo) { 162 return hitInfo != null && charIndex == hitInfo.charIndex && 163 isLeadingEdge == hitInfo.isLeadingEdge; 164 } 165 166 /** 167 * Returns a <code>String</code> representing the hit for debugging 168 * use only. 169 * @return a <code>String</code> representing this 170 * <code>TextHitInfo</code>. 171 */ 172 public String toString() { 173 return "TextHitInfo[" + charIndex + (isLeadingEdge ? "L" : "T")+"]"; 174 } 175 176 /** 177 * Creates a <code>TextHitInfo</code> on the leading edge of the 178 * character at the specified <code>charIndex</code>. 179 * @param charIndex the index of the character hit 180 * @return a <code>TextHitInfo</code> on the leading edge of the 181 * character at the specified <code>charIndex</code>. 182 */ 183 public static TextHitInfo leading(int charIndex) { 184 return new TextHitInfo(charIndex, true); 185 } 186 187 /** 188 * Creates a hit on the trailing edge of the character at 189 * the specified <code>charIndex</code>. 190 * @param charIndex the index of the character hit 191 * @return a <code>TextHitInfo</code> on the trailing edge of the 192 * character at the specified <code>charIndex</code>. 193 */ 194 public static TextHitInfo trailing(int charIndex) { 195 return new TextHitInfo(charIndex, false); 196 } 197 198 /** 199 * Creates a <code>TextHitInfo</code> at the specified offset, 200 * associated with the character before the offset. 201 * @param offset an offset associated with the character before 202 * the offset 203 * @return a <code>TextHitInfo</code> at the specified offset. 204 */ 205 public static TextHitInfo beforeOffset(int offset) { 206 return new TextHitInfo(offset-1, false); 207 } 208 209 /** 210 * Creates a <code>TextHitInfo</code> at the specified offset, 211 * associated with the character after the offset. 212 * @param offset an offset associated with the character after 213 * the offset 214 * @return a <code>TextHitInfo</code> at the specified offset. 215 */ 216 public static TextHitInfo afterOffset(int offset) { 217 return new TextHitInfo(offset, true); 218 } 219 220 /** 221 * Creates a <code>TextHitInfo</code> on the other side of the 222 * insertion point. This <code>TextHitInfo</code> remains unchanged. 223 * @return a <code>TextHitInfo</code> on the other side of the 224 * insertion point. 225 */ 226 public TextHitInfo getOtherHit() { 227 if (isLeadingEdge) { 228 return trailing(charIndex - 1); 229 } else { 230 return leading(charIndex + 1); 231 } 232 } 233 234 /** 235 * Creates a <code>TextHitInfo</code> whose character index is offset 236 * by <code>delta</code> from the <code>charIndex</code> of this 237 * <code>TextHitInfo</code>. This <code>TextHitInfo</code> remains 238 * unchanged. 239 * @param delta the value to offset this <code>charIndex</code> 240 * @return a <code>TextHitInfo</code> whose <code>charIndex</code> is 241 * offset by <code>delta</code> from the <code>charIndex</code> of 242 * this <code>TextHitInfo</code>. 243 */ 244 public TextHitInfo getOffsetHit(int delta) { 245 return new TextHitInfo(charIndex + delta, isLeadingEdge); 246 } 247 }