1. /*
  2. * @(#)TextHitInfo.java 1.32 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. /*
  8. * (C) Copyright Taligent, Inc. 1996 - 1997, All Rights Reserved
  9. * (C) Copyright IBM Corp. 1996 - 1998, All Rights Reserved
  10. *
  11. * The original version of this source code and documentation is
  12. * copyrighted and owned by Taligent, Inc., a wholly-owned subsidiary
  13. * of IBM. These materials are provided under terms of a License
  14. * Agreement between Taligent and Sun. This technology is protected
  15. * by multiple US and International patents.
  16. *
  17. * This notice and attribution to Taligent may not be removed.
  18. * Taligent is a registered trademark of Taligent, Inc.
  19. *
  20. */
  21. package java.awt.font;
  22. import java.lang.String;
  23. /**
  24. * The <code>TextHitInfo</code> class represents a character position in a
  25. * text model, and a <b>bias</b>, or "side," of the character. Biases are
  26. * either <EM>leading</EM> (the left edge, for a left-to-right character)
  27. * or <EM>trailing</EM> (the right edge, for a left-to-right character).
  28. * Instances of <code>TextHitInfo</code> are used to specify caret and
  29. * insertion positions within text.
  30. * <p>
  31. * For example, consider the text "abc". TextHitInfo.trailing(1)
  32. * corresponds to the right side of the 'b' in the text.
  33. * <p>
  34. * <code>TextHitInfo</code> is used primarily by {@link TextLayout} and
  35. * clients of <code>TextLayout</code>. Clients of <code>TextLayout</code>
  36. * query <code>TextHitInfo</code> instances for an insertion offset, where
  37. * new text is inserted into the text model. The insertion offset is equal
  38. * to the character position in the <code>TextHitInfo</code> if the bias
  39. * is leading, and one character after if the bias is trailing. The
  40. * insertion offset for TextHitInfo.trailing(1) is 2.
  41. * <p>
  42. * Sometimes it is convenient to construct a <code>TextHitInfo</code> with
  43. * the same insertion offset as an existing one, but on the opposite
  44. * character. The <code>getOtherHit</code> method constructs a new
  45. * <code>TextHitInfo</code> with the same insertion offset as an existing
  46. * one, with a hit on the character on the other side of the insertion offset.
  47. * Calling <code>getOtherHit</code> on trailing(1) would return leading(2).
  48. * In general, <code>getOtherHit</code> for trailing(n) returns
  49. * leading(n+1) and <code>getOtherHit</code> for leading(n)
  50. * returns trailing(n-1).
  51. * <p>
  52. * <strong>Example</strong>:<p>
  53. * Converting a graphical point to an insertion point within a text
  54. * model
  55. * <blockquote><pre>
  56. * TextLayout layout = ...;
  57. * Point2D.Float hitPoint = ...;
  58. * TextHitInfo hitInfo = layout.hitTestChar(hitPoint.x, hitPoint.y);
  59. * int insPoint = hitInfo.getInsertionIndex();
  60. * // insPoint is relative to layout; may need to adjust for use
  61. * // in a text model
  62. * </pre></blockquote>
  63. *
  64. * @see TextLayout
  65. */
  66. public final class TextHitInfo {
  67. private int charIndex;
  68. private boolean isLeadingEdge;
  69. /**
  70. * Constructs a new <code>TextHitInfo</code>.
  71. * @param charIndex the index of the character hit
  72. * @param isLeadingEdge <code>true</code> if the leading edge of the
  73. * character was hit
  74. */
  75. private TextHitInfo(int charIndex, boolean isLeadingEdge) {
  76. this.charIndex = charIndex;
  77. this.isLeadingEdge = isLeadingEdge;
  78. }
  79. /**
  80. * Returns the index of the character hit.
  81. * @return the index of the character hit.
  82. */
  83. public int getCharIndex() {
  84. return charIndex;
  85. }
  86. /**
  87. * Returns <code>true</code> if the leading edge of the character was
  88. * hit.
  89. * @return <code>true</code> if the leading edge of the character was
  90. * hit; <code>false</code> otherwise.
  91. */
  92. public boolean isLeadingEdge() {
  93. return isLeadingEdge;
  94. }
  95. /**
  96. * Returns the insertion index. This is the character index if
  97. * the leading edge of the character was hit, and one greater
  98. * than the character index if the trailing edge was hit.
  99. * @return the insertion index.
  100. */
  101. public int getInsertionIndex() {
  102. return isLeadingEdge ? charIndex : charIndex + 1;
  103. }
  104. /**
  105. * Returns the hash code.
  106. * @return the hash code of this <code>TextHitInfo</code>, which is
  107. * also the <code>charIndex</code> of this <code>TextHitInfo</code>.
  108. */
  109. public int hashCode() {
  110. return charIndex;
  111. }
  112. /**
  113. * Returns <code>true</code> if the specified <code>Object</code> is a
  114. * <code>TextHitInfo</code> and equals this <code>TextHitInfo</code>.
  115. * @param obj the <code>Object</code> to test for equality
  116. * @return <code>true</code> if the specified <code>Object</code>
  117. * equals this <code>TextHitInfo</code> <code>false</code> otherwise.
  118. */
  119. public boolean equals(Object obj) {
  120. return (obj instanceof TextHitInfo) && equals((TextHitInfo)obj);
  121. }
  122. /**
  123. * Returns <code>true</code> if the specified <code>TextHitInfo</code>
  124. * has the same <code>charIndex</code> and <code>isLeadingEdge</code>
  125. * as this <code>TextHitInfo</code>. This is not the same as having
  126. * the same insertion offset.
  127. * @param hitInfo a specified <code>TextHitInfo</code>
  128. * @return <code>true</code> if the specified <code>TextHitInfo</code>
  129. * has the same <code>charIndex</code> and <code>isLeadingEdge</code>
  130. * as this <code>TextHitInfo</code>.
  131. */
  132. public boolean equals(TextHitInfo hitInfo) {
  133. return hitInfo != null && charIndex == hitInfo.charIndex &&
  134. isLeadingEdge == hitInfo.isLeadingEdge;
  135. }
  136. /**
  137. * Returns a <code>String</code> representing the hit for debugging
  138. * use only.
  139. * @return a <code>String</code> representing this
  140. * <code>TextHitInfo</code>.
  141. */
  142. public String toString() {
  143. return "TextHitInfo[" + charIndex + (isLeadingEdge ? "L" : "T")+"]";
  144. }
  145. /**
  146. * Creates a <code>TextHitInfo</code> on the leading edge of the
  147. * character at the specified <code>charIndex</code>.
  148. * @param charIndex the index of the character hit
  149. * @return a <code>TextHitInfo</code> on the leading edge of the
  150. * character at the specified <code>charIndex</code>.
  151. */
  152. public static TextHitInfo leading(int charIndex) {
  153. return new TextHitInfo(charIndex, true);
  154. }
  155. /**
  156. * Creates a hit on the trailing edge of the character at
  157. * the specified <code>charIndex</code>.
  158. * @param charIndex the index of the character hit
  159. * @return a <code>TextHitInfo</code> on the trailing edge of the
  160. * character at the specified <code>charIndex</code>.
  161. */
  162. public static TextHitInfo trailing(int charIndex) {
  163. return new TextHitInfo(charIndex, false);
  164. }
  165. /**
  166. * Creates a <code>TextHitInfo</code> at the specified offset,
  167. * associated with the character before the offset.
  168. * @param offset an offset associated with the character before
  169. * the offset
  170. * @return a <code>TextHitInfo</code> at the specified offset.
  171. */
  172. public static TextHitInfo beforeOffset(int offset) {
  173. return new TextHitInfo(offset-1, false);
  174. }
  175. /**
  176. * Creates a <code>TextHitInfo</code> at the specified offset,
  177. * associated with the character after the offset.
  178. * @param offset an offset associated with the character after
  179. * the offset
  180. * @return a <code>TextHitInfo</code> at the specified offset.
  181. */
  182. public static TextHitInfo afterOffset(int offset) {
  183. return new TextHitInfo(offset, true);
  184. }
  185. /**
  186. * Creates a <code>TextHitInfo</code> on the other side of the
  187. * insertion point. This <code>TextHitInfo</code> remains unchanged.
  188. * @return a <code>TextHitInfo</code> on the other side of the
  189. * insertion point.
  190. */
  191. public TextHitInfo getOtherHit() {
  192. if (isLeadingEdge) {
  193. return trailing(charIndex - 1);
  194. } else {
  195. return leading(charIndex + 1);
  196. }
  197. }
  198. /**
  199. * Creates a <code>TextHitInfo</code> whose character index is offset
  200. * by <code>delta</code> from the <code>charIndex</code> of this
  201. * <code>TextHitInfo</code>. This <code>TextHitInfo</code> remains
  202. * unchanged.
  203. * @param delta the value to offset this <code>charIndex</code>
  204. * @return a <code>TextHitInfo</code> whose <code>charIndex</code> is
  205. * offset by <code>delta</code> from the <code>charIndex</code> of
  206. * this <code>TextHitInfo</code>.
  207. */
  208. public TextHitInfo getOffsetHit(int delta) {
  209. return new TextHitInfo(charIndex + delta, isLeadingEdge);
  210. }
  211. }