Changeset 1095
- Timestamp:
- 01/30/18 11:51:48 (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/expeditee/items/Text.java
r1047 r1095 129 129 130 130 /* 131 * Set the width to be IMPLICIT, but as wide as possible, a negative width 132 * value is one that is implicitly set by the system... a positive value is133 * oneexplicitly set by the user.131 * Set the width to be IMPLICIT, but as wide as possible, a negative width value 132 * is one that is implicitly set by the system... a positive value is one 133 * explicitly set by the user. 134 134 */ 135 135 private Integer _maxWidth = Integer.MIN_VALUE + 1; … … 149 149 150 150 private int _selectionEnd = -1; 151 151 152 152 // whether autowrap is on/off for this item 153 153 protected boolean _autoWrap = false; … … 165 165 // The font to display this text in 166 166 private Font _font; 167 168 169 protected static void InitFontFamily(GraphicsEnvironment ge, File fontFamilyDir) 170 { 167 168 protected static void InitFontFamily(GraphicsEnvironment ge, File fontFamilyDir) { 171 169 File[] fontFiles = fontFamilyDir.listFiles(); 172 170 … … 179 177 180 178 if (i > p) { 181 ext = fileName.substring(i +1);179 ext = fileName.substring(i + 1); 182 180 } 183 181 … … 187 185 Font font = Font.createFont(Font.TRUETYPE_FONT, fontFile); 188 186 189 boolean registered_status_ok = ge.registerFont(font);187 boolean registered_status_ok = ge.registerFont(font); 190 188 191 189 if (registered_status_ok) { 192 193 String font_family = font.getFamily(); 194 if (!FONT_WHEEL_ADDITIONAL_LOOKUP.containsKey(font_family)) { 195 196 if (FONT_WHEEL_ADDITIONAL_LOOKUP.size()>0) { 197 System.out.print(", "); 190 191 String font_family = font.getFamily(); 192 if (!FONT_WHEEL_ADDITIONAL_LOOKUP.containsKey(font_family)) { 193 194 if (FONT_WHEEL_ADDITIONAL_LOOKUP.size() > 0) { 195 System.out.print(", "); 196 } 197 System.out.print("'" + font.getFamily() + "'"); 198 199 FONT_WHEEL_ADDITIONAL_LOOKUP.put(font_family, font); 200 201 int cdut = font.canDisplayUpTo("09AZaz"); 202 if (cdut >= 0) { 203 // Some problem has occured (should return -1 to show all chars possible) 204 205 System.out.println(" [Non-ASCII font]"); 206 } 207 System.out.flush(); 198 208 } 199 System.out.print("'" + font.getFamily() + "'"); 200 201 FONT_WHEEL_ADDITIONAL_LOOKUP.put(font_family,font); 202 203 int cdut = font.canDisplayUpTo("09AZaz"); 204 if (cdut>=0) { 205 // Some problem has occured (should return -1 to show all chars possible) 206 207 System.out.println(" [Non-ASCII font]"); 208 } 209 System.out.flush(); 210 } 211 209 210 } else { 211 System.err.println("Error: Failed to add custom True-Type Font file: " + fontFile); 212 212 } 213 else { 214 System.err.println("Error: Failed to add custom True-Type Font file: " + fontFile); 215 } 216 217 } 218 catch (Exception e) { 213 214 } catch (Exception e) { 219 215 System.err.println("Failed to load custon font file: " + fontFile); 220 216 } … … 222 218 } 223 219 } 224 220 225 221 public static void InitFonts() { 226 222 227 223 GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 228 224 … … 234 230 if (fontFamilyDirs != null) { 235 231 236 if (fontFamilyDirs.length >0) {232 if (fontFamilyDirs.length > 0) { 237 233 System.out.println("Loading custom fonts:"); 238 234 } 239 235 240 boolean first_item = true; 236 boolean first_item = true; 241 237 for (File fontFamilyDir : fontFamilyDirs) { 242 238 if (fontFamilyDir.isDirectory()) { 243 InitFontFamily(ge, fontFamilyDir);239 InitFontFamily(ge, fontFamilyDir); 244 240 } 245 241 } 246 System.out.println(); 242 System.out.println(); 247 243 } 248 244 } 249 } 250 else { 245 } else { 251 246 System.err.println("No graphics environment detected. Skipping the loading of the custom fonts"); 252 247 } … … 254 249 255 250 /** 256 * Similar to parseArgs() in InteractiveWidget. 257 * Code based on routine used in Apache Ant: 258 * org.apache.tools.ant.types.Commandline::translateCommandline() 259 * @param toProcess the command line to process. 260 * @return the command line broken into strings.261 * An empty or null toProcess parameter results in a zero sized array. 262 */ 263 public static String[] parseArgsApache(String toProcess) { 264 if (toProcess == null || toProcess.length() == 0) {265 //no command? no string 266 return new String[0]; 267 } 268 // parse with a simple finite state machine 269 270 final int normal = 0; 271 final int inQuote = 1;272 final int inDoubleQuote = 2;273 int state = normal;274 final StringTokenizer tok = new StringTokenizer(toProcess, "\"\' ", true);275 final ArrayList<String> result = new ArrayList<String>();276 final StringBuilder current = new StringBuilder();277 boolean lastTokenHasBeenQuoted = false;278 279 while (tok.hasMoreTokens()) { 280 String nextTok = tok.nextToken(); 281 switch (state) { 282 case inQuote: 283 if ("\'".equals(nextTok)) { 284 lastTokenHasBeenQuoted = true; 285 state = normal;286 } else { 287 current.append(nextTok); 288 } 289 break; 290 case inDoubleQuote: 291 if ("\"".equals(nextTok)) { 292 lastTokenHasBeenQuoted = true; 293 state = normal;294 } else { 295 current.append(nextTok); 296 } 297 break; 298 default: 299 if ("\'".equals(nextTok)) { 300 state = inQuote; 301 } else if ("\"".equals(nextTok)) { 302 state = inDoubleQuote; 303 } else if (" ".equals(nextTok)) { 304 if (lastTokenHasBeenQuoted || current.length() != 0) {305 result.add(current.toString()); 306 current.setLength(0);307 } 308 } else { 309 current.append(nextTok); 310 } 311 lastTokenHasBeenQuoted = false; 312 break;313 } 314 315 if (lastTokenHasBeenQuoted || current.length() != 0) { 316 result.add(current.toString()); 317 } 318 if (state == inQuote || state == inDoubleQuote) { 319 System.err.println("Error: Unbalanced quotes -- failed to parse '" + toProcess + "'");320 return null;321 } 322 323 return result.toArray(new String[result.size()]); 324 } 325 251 * Similar to parseArgs() in InteractiveWidget. Code based on routine used in 252 * Apache Ant: org.apache.tools.ant.types.Commandline::translateCommandline() 253 * 254 * @param toProcess 255 * the command line to process. 256 * @return the command line broken into strings. An empty or null toProcess 257 * parameter results in a zero sized array. 258 */ 259 public static String[] parseArgsApache(String toProcess) { 260 if (toProcess == null || toProcess.length() == 0) { 261 // no command? no string 262 return new String[0]; 263 } 264 // parse with a simple finite state machine 265 266 final int normal = 0; 267 final int inQuote = 1; 268 final int inDoubleQuote = 2; 269 int state = normal; 270 final StringTokenizer tok = new StringTokenizer(toProcess, "\"\' ", true); 271 final ArrayList<String> result = new ArrayList<String>(); 272 final StringBuilder current = new StringBuilder(); 273 boolean lastTokenHasBeenQuoted = false; 274 275 while (tok.hasMoreTokens()) { 276 String nextTok = tok.nextToken(); 277 switch (state) { 278 case inQuote: 279 if ("\'".equals(nextTok)) { 280 lastTokenHasBeenQuoted = true; 281 state = normal; 282 } else { 283 current.append(nextTok); 284 } 285 break; 286 case inDoubleQuote: 287 if ("\"".equals(nextTok)) { 288 lastTokenHasBeenQuoted = true; 289 state = normal; 290 } else { 291 current.append(nextTok); 292 } 293 break; 294 default: 295 if ("\'".equals(nextTok)) { 296 state = inQuote; 297 } else if ("\"".equals(nextTok)) { 298 state = inDoubleQuote; 299 } else if (" ".equals(nextTok)) { 300 if (lastTokenHasBeenQuoted || current.length() != 0) { 301 result.add(current.toString()); 302 current.setLength(0); 303 } 304 } else { 305 current.append(nextTok); 306 } 307 lastTokenHasBeenQuoted = false; 308 break; 309 } 310 } 311 if (lastTokenHasBeenQuoted || current.length() != 0) { 312 result.add(current.toString()); 313 } 314 if (state == inQuote || state == inDoubleQuote) { 315 System.err.println("Error: Unbalanced quotes -- failed to parse '" + toProcess + "'"); 316 return null; 317 } 318 319 return result.toArray(new String[result.size()]); 320 } 326 321 327 322 /** … … 371 366 372 367 /** 373 * Sets the maximum width of this Text item when justifcation is used. 374 * passingin 0 or -1 means there is no maximum width368 * Sets the maximum width of this Text item when justifcation is used. passing 369 * in 0 or -1 means there is no maximum width 375 370 * 376 371 * @param width 377 * The maximum width of this item when justification is applied 378 * toit.372 * The maximum width of this item when justification is applied to 373 * it. 379 374 */ 380 375 @Override … … 394 389 395 390 /** 396 * Returns the maximum width of this Text item when justifcation is used. If 397 * thewidth is negative, it means no explicit width has been set391 * Returns the maximum width of this Text item when justifcation is used. If the 392 * width is negative, it means no explicit width has been set 398 393 * 399 394 * @return The maximum width of this Text item when justification is used … … 422 417 423 418 /** 424 * Sets the justification of this Text item. The given integer should 425 * correspondto one of the JUSTIFICATION constants defined in Item419 * Sets the justification of this Text item. The given integer should correspond 420 * to one of the JUSTIFICATION constants defined in Item 426 421 * 427 422 * @param just … … 443 438 444 439 /** 445 * Returns the current justification of this Text item. The default value 446 * leftjustification.440 * Returns the current justification of this Text item. The default value left 441 * justification. 447 442 * 448 443 * @return The justification of this Text item … … 464 459 465 460 /** 466 * Sets the text displayed on the screen to the given String. It does not 467 * resetthe formula, attributeValuePair or other cached values.461 * Sets the text displayed on the screen to the given String. It does not reset 462 * the formula, attributeValuePair or other cached values. 468 463 * 469 464 * @param text … … 481 476 482 477 /* 483 * Always clearingCach remove formulas when moving in and out of XRay 484 * mode 478 * Always clearingCach remove formulas when moving in and out of XRay mode 485 479 */ 486 480 if (clearCache) { … … 520 514 521 515 /** 522 * Inserts the given String at the start of the first line of this Text 523 * Item. 516 * Inserts the given String at the start of the first line of this Text Item. 524 517 * 525 518 * @param text … … 533 526 534 527 /** 535 * If the first line of text starts with the given String, then it is 536 * removedotherwise no action is taken.528 * If the first line of text starts with the given String, then it is removed 529 * otherwise no action is taken. 537 530 * 538 531 * @param text … … 586 579 587 580 _text.append(text); 588 581 589 582 rebuild(true); 590 583 } … … 595 588 * @param text 596 589 * The prefix to check for 597 * @return True if the first line starts with the given String, False 598 * otherwise. 590 * @return True if the first line starts with the given String, False otherwise. 599 591 */ 600 592 public boolean startsWith(String text) { … … 607 599 608 600 if (ignoreCase) 609 return _text.toString().toLowerCase() 610 .startsWith(text.toLowerCase()); 601 return _text.toString().toLowerCase().startsWith(text.toLowerCase()); 611 602 else 612 603 return _text.indexOf(text) == 0; … … 668 659 private Point2D.Float getEdgePosition(int line, boolean start) { 669 660 // if there is no text yet, or the line is invalid 670 if (_text == null || _text.length() == 0 || line < 0 671 || line > _textLayouts.size() - 1) 661 if (_text == null || _text.length() == 0 || line < 0 || line > _textLayouts.size() - 1) 672 662 return new Point2D.Float(getX(), getY()); 673 663 … … 684 674 685 675 float x = getX() + caret[0] + getJustOffset(last); 686 x = Math 687 .min( 688 x, 689 (getX() - Item.MARGIN_RIGHT - (2 * getGravity()) + getBoundsWidth())); 676 x = Math.min(x, (getX() - Item.MARGIN_RIGHT - (2 * getGravity()) + getBoundsWidth())); 690 677 return new Point2D.Float(x, getY() + y + caret[1]); 691 678 } … … 728 715 _selectionEnd = _text.length(); 729 716 730 return _text.substring(Math.min(_selectionStart, _selectionEnd), Math 731 .max(_selectionStart, _selectionEnd)); 717 return _text.substring(Math.min(_selectionStart, _selectionEnd), Math.max(_selectionStart, _selectionEnd)); 732 718 } 733 719 … … 787 773 788 774 /** 789 * Inserts the given String into the Text at the position given by the 790 * mouseXand mouseY coordinates775 * Inserts the given String into the Text at the position given by the mouseX 776 * and mouseY coordinates 791 777 * 792 778 * @param text … … 803 789 } 804 790 805 public Point2D.Float insertText(String text, float mouseX, float mouseY, 806 int insertPos) { 791 public Point2D.Float insertText(String text, float mouseX, float mouseY, int insertPos) { 807 792 TextHitInfo hit; 808 793 TextLayout current = null; … … 874 859 } 875 860 // Check if there is a space after the bullet 876 if (index < _text.length() - 1 877 && _text.charAt(index + 1) == ' ') { 861 if (index < _text.length() - 1 && _text.charAt(index + 1) == ' ') { 878 862 // Change the bullet 879 _text.setCharAt(index, getPreviousBullet(_text 880 .charAt(index))); 863 _text.setCharAt(index, getPreviousBullet(_text.charAt(index))); 881 864 } 882 865 // Remove the spacing at the start 883 866 for (int i = 0; i < TAB_STRING.length(); i++) { 884 if (_text.length() > 0 885 && Character.isSpaceChar(_text.charAt(0))) { 867 if (_text.length() > 0 && Character.isSpaceChar(_text.charAt(0))) { 886 868 deleteChar(0); 887 869 pos--; … … 898 880 } 899 881 // Check if there is a space after the bullet 900 if (index < _text.length() - 1 901 && _text.charAt(index + 1) == ' ') { 882 if (index < _text.length() - 1 && _text.charAt(index + 1) == ' ') { 902 883 char nextBullet = getNextBullet(_text.charAt(index)); 903 884 // Change the bullet … … 954 935 955 936 float x = getX() + caret[0] + getJustOffset(current); 956 x = Math 957 .min( 958 x, 959 (getX() - Item.MARGIN_RIGHT - (2 * getGravity()) + getBoundsWidth())); 937 x = Math.min(x, (getX() - Item.MARGIN_RIGHT - (2 * getGravity()) + getBoundsWidth())); 960 938 961 939 invalidateAll(); 962 940 963 return new Point2D.Float(Math.round(x), Math.round(getY() + y 964 + caret[1])); 941 return new Point2D.Float(Math.round(x), Math.round(getY() + y + caret[1])); 965 942 } 966 943 … … 986 963 } 987 964 988 public Point2D.Float moveCursor(int direction, float mouseX, float mouseY, 989 boolean setSelection, booleanwholeWord) {965 public Point2D.Float moveCursor(int direction, float mouseX, float mouseY, boolean setSelection, 966 boolean wholeWord) { 990 967 if (setSelection) { 991 968 if (!hasSelection()) { … … 1047 1024 // Keep going if the char to the left is a 1048 1025 // letterOrDigit 1049 prevChar = _text.charAt(hit.getInsertionIndex() - 1 1050 + _lineOffsets.get(line)); 1051 } while (wholeWord 1052 && Character.isLetterOrDigit(prevChar)); 1026 prevChar = _text.charAt(hit.getInsertionIndex() - 1 + _lineOffsets.get(line)); 1027 } while (wholeWord && Character.isLetterOrDigit(prevChar)); 1053 1028 // TODO Go to the start of the word instead of before 1054 1029 // the word 1055 char nextChar = _text.charAt(hit.getInsertionIndex() 1056 + _lineOffsets.get(line)); 1030 char nextChar = _text.charAt(hit.getInsertionIndex() + _lineOffsets.get(line)); 1057 1031 /* 1058 1032 * This takes care of hard line break in … … 1061 1035 line--; 1062 1036 hit = _textLayouts.get(line) 1063 .getNextRightHit( 1064 _textLayouts.get(line) 1065 .getCharacterCount() - 1); 1037 .getNextRightHit(_textLayouts.get(line).getCharacterCount() - 1); 1066 1038 } 1067 1039 // This takes care of soft line breaks. 1068 1040 } else if (line > 0) { 1069 1041 line--; 1070 hit = _textLayouts.get(line).getNextRightHit( 1071 _textLayouts.get(line).getCharacterCount() - 1); 1042 hit = _textLayouts.get(line).getNextRightHit(_textLayouts.get(line).getCharacterCount() - 1); 1072 1043 /* 1073 * Skip the spaces at the end of a line with soft 1074 * linebreak 1044 * Skip the spaces at the end of a line with soft linebreak 1075 1045 */ 1076 1046 while (hit.getCharIndex() > 0 1077 && _text.charAt(_lineOffsets.get(line) 1078 + hit.getCharIndex() - 1) == ' ') { 1047 && _text.charAt(_lineOffsets.get(line) + hit.getCharIndex() - 1) == ' ') { 1079 1048 hit = _textLayouts.get(line).getNextLeftHit(hit); 1080 1049 } 1081 1050 } 1082 1051 } else if (direction == RIGHT) { 1083 if (hit.getInsertionIndex() < _textLayouts.get(line) 1084 .getCharacterCount()) { 1052 if (hit.getInsertionIndex() < _textLayouts.get(line).getCharacterCount()) { 1085 1053 hit = _textLayouts.get(line).getNextRightHit(hit); 1086 1054 // Skip whole word if needs be 1087 while (wholeWord 1088 && hit.getCharIndex() > 0 1089 && hit.getCharIndex() < _textLayouts.get(line) 1090 .getCharacterCount() 1091 && Character.isLetterOrDigit(_text 1092 .charAt(_lineOffsets.get(line) 1093 + hit.getCharIndex() - 1))) 1055 while (wholeWord && hit.getCharIndex() > 0 1056 && hit.getCharIndex() < _textLayouts.get(line).getCharacterCount() && Character 1057 .isLetterOrDigit(_text.charAt(_lineOffsets.get(line) + hit.getCharIndex() - 1))) 1094 1058 hit = _textLayouts.get(line).getNextRightHit(hit); 1095 1059 } else if (line < _textLayouts.size() - 1) { … … 1105 1069 float y = getLineDrop(current) * line; 1106 1070 1107 resultPos = new Point2D.Float(getX() + caret[0] 1108 + getJustOffset(current), getY() + y + caret[1]); 1071 resultPos = new Point2D.Float(getX() + caret[0] + getJustOffset(current), getY() + y + caret[1]); 1109 1072 break; 1110 1073 } … … 1142 1105 for (TextLayout text : _textLayouts) { 1143 1106 // calculate X to ensure it is in the shape 1144 Rectangle2D bounds = text.getLogicalHighlightShape(0, 1145 text.getCharacterCount()).getBounds2D(); 1107 Rectangle2D bounds = text.getLogicalHighlightShape(0, text.getCharacterCount()).getBounds2D(); 1146 1108 1147 1109 if (bounds.getWidth() < 1) 1148 bounds.setRect(bounds.getMinX(), bounds.getMinY(), 10, bounds 1149 .getHeight()); 1110 bounds.setRect(bounds.getMinX(), bounds.getMinY(), 10, bounds.getHeight()); 1150 1111 1151 1112 double x = bounds.getCenterX(); … … 1202 1163 1203 1164 public void setFamily(String newFamily) { 1204 String toDecode = newFamily + "-" + getFontStyle() + "-" 1205 + Math.round(getSize()); 1165 String toDecode = newFamily + "-" + getFontStyle() + "-" + Math.round(getSize()); 1206 1166 setFont(Font.decode(toDecode)); 1207 1167 1208 1168 setLetterSpacing(this._letter_spacing); 1209 1169 } … … 1228 1188 1229 1189 public static final String[] FONT_WHEEL = { "sansserif", "monospaced", "serif", "dialog", "dialoginput" }; 1230 public static final char[] FONT_CHARS = { 's', 'm', 't', 'd', 'i' }; 1231 1232 // A hashtable to store the font family names that are loaded in through the TTF files 1233 // provided in the 'assets' folder 1234 public static HashMap<String, Font> FONT_WHEEL_ADDITIONAL_LOOKUP = new HashMap<>(); 1235 1190 public static final char[] FONT_CHARS = { 's', 'm', 't', 'd', 'i' }; 1191 1192 // A hashtable to store the font family names that are loaded in through the TTF 1193 // files 1194 // provided in the 'assets' folder 1195 public static HashMap<String, Font> FONT_WHEEL_ADDITIONAL_LOOKUP = new HashMap<>(); 1196 1236 1197 private static final int NEARBY_GRAVITY = 2; 1237 1198 … … 1308 1269 } else if (newFace.equals("italic") || newFace.equals("i")) { 1309 1270 setFont(getPaintFont().deriveFont(Font.ITALIC)); 1310 } else if (newFace.equals("bolditalic") || newFace.equals("italicbold") 1311 || newFace.equals(" bi") || newFace.equals("ib")) {1271 } else if (newFace.equals("bolditalic") || newFace.equals("italicbold") || newFace.equals("bi") 1272 || newFace.equals("ib")) { 1312 1273 setFont(getPaintFont().deriveFont(Font.BOLD + Font.ITALIC)); 1313 1274 } … … 1335 1296 for (int offset : _lineOffsets) { 1336 1297 if (offset != last) { 1337 list 1338 .add(_text.substring(last, offset).replaceAll("\n", 1339 "")); 1298 list.add(_text.substring(last, offset).replaceAll("\n", "")); 1340 1299 } 1341 1300 last = offset; … … 1399 1358 private float getLineDrop(TextLayout layout) { 1400 1359 if (getSpacing() < 0) 1401 return layout.getAscent() + layout.getDescent() 1402 + layout.getLeading(); 1360 return layout.getAscent() + layout.getDescent() + layout.getLeading(); 1403 1361 1404 1362 return layout.getAscent() + layout.getDescent() + getSpacing(); … … 1417 1375 * 1418 1376 * @param spacing 1419 * Additional spacing to add between letters. See {@link java.awt.font.TextAttribute#TRACKING} 1377 * Additional spacing to add between letters. See 1378 * {@link java.awt.font.TextAttribute#TRACKING} 1420 1379 */ 1421 1380 public void setLetterSpacing(float spacing) { … … 1423 1382 HashMap<TextAttribute, Object> attr = new HashMap<TextAttribute, Object>(); 1424 1383 attr.put(TextAttribute.TRACKING, spacing); 1425 1384 1426 1385 if (this._font == null) { 1427 1386 this._font = Font.decode(DEFAULT_FONT); … … 1432 1391 1433 1392 /** 1434 * @return The spacing (proportional to the font size) between letters. See {@link java.awt.font.TextAttribute#TRACKING} 1393 * @return The spacing (proportional to the font size) between letters. See 1394 * {@link java.awt.font.TextAttribute#TRACKING} 1435 1395 */ 1436 1396 public float getLetterSpacing() { … … 1446 1406 } 1447 1407 1448 // @Override1408 // @Override 1449 1409 public boolean intersectsOLD(Polygon p) { 1450 1410 if (super.intersects(p)) { … … 1453 1413 for (TextLayout text : _textLayouts) { 1454 1414 // check left and right of each box 1455 Rectangle2D textOutline = text.getLogicalHighlightShape(0, 1456 text.getCharacterCount()).getBounds2D(); 1457 textOutline 1458 .setRect(textOutline.getX() + getX() - 1, textOutline 1459 .getY() 1460 + textY - 1, textOutline.getWidth() + 2, 1461 textOutline.getHeight() + 2); 1415 Rectangle2D textOutline = text.getLogicalHighlightShape(0, text.getCharacterCount()).getBounds2D(); 1416 textOutline.setRect(textOutline.getX() + getX() - 1, textOutline.getY() + textY - 1, 1417 textOutline.getWidth() + 2, textOutline.getHeight() + 2); 1462 1418 if (p.intersects(textOutline)) 1463 1419 return true; … … 1467 1423 return false; 1468 1424 } 1469 1470 // The following version of intersect uses a tighter definition for the text, based on 1471 @Override 1425 1426 // The following version of intersect uses a tighter definition for the text, 1427 // based on 1428 @Override 1472 1429 public boolean intersects(Polygon p) { 1473 1430 if (super.intersects(p)) { 1474 //float textY = getY();1431 // float textY = getY(); 1475 1432 1476 1433 for (TextLayout text : _textLayouts) { 1477 1434 1478 1435 Rectangle text_pixel_bounds_rect = this.getPixelBounds(text); 1479 1436 1480 1437 if (p.intersects(text_pixel_bounds_rect)) { 1481 1438 return true; … … 1483 1440 } 1484 1441 } 1485 1442 1486 1443 return false; 1487 1444 } … … 1502 1459 1503 1460 // Check if its outside the top and left and bottom bounds 1504 if (outline.getX() - mouseX > gravity 1505 || outline.getY() - mouseY > gravity 1461 if (outline.getX() - mouseX > gravity || outline.getY() - mouseY > gravity 1506 1462 || mouseY - (outline.getY() + outline.getHeight()) > gravity 1507 1463 || mouseX - (outline.getX() + outline.getWidth()) > gravity) { … … 1511 1467 for (TextLayout text : _textLayouts) { 1512 1468 // check left and right of each box 1513 Rectangle2D textOutline = text.getLogicalHighlightShape(0, 1514 text.getCharacterCount()).getBounds2D(); 1469 Rectangle2D textOutline = text.getLogicalHighlightShape(0, text.getCharacterCount()).getBounds2D(); 1515 1470 1516 1471 // check if the cursor is within the top, bottom and within the … … 1518 1473 int justOffset = getJustOffset(text); 1519 1474 1520 if (mouseY - textY > textOutline.getY() 1521 && mouseY - textY < textOutline.getY() 1522 + textOutline.getHeight() 1523 && mouseX - textX - justOffset < textOutline.getWidth() 1524 + gravity + Item.MARGIN_RIGHT 1475 if (mouseY - textY > textOutline.getY() && mouseY - textY < textOutline.getY() + textOutline.getHeight() 1476 && mouseX - textX - justOffset < textOutline.getWidth() + gravity + Item.MARGIN_RIGHT 1525 1477 /* &&(justOffset == 0 || mouseX > textX + justOffset - gravity ) */) 1526 1478 return true; … … 1555 1507 1556 1508 float y = -1; 1557 1509 1558 1510 // Fix concurrency error in ScaleFrameset 1559 1511 List<TextLayout> tmpTextLayouts; 1560 synchronized (_textLayouts) {1512 synchronized (_textLayouts) { 1561 1513 tmpTextLayouts = new LinkedList<TextLayout>(_textLayouts); 1562 1514 } 1563 1515 1564 1516 for (TextLayout layout : tmpTextLayouts) { 1565 Rectangle2D bounds = layout.getLogicalHighlightShape(0, 1566 layout.getCharacterCount()).getBounds2D(); 1567 1517 Rectangle2D bounds = layout.getLogicalHighlightShape(0, layout.getCharacterCount()).getBounds2D(); 1518 1568 1519 if (y < 0) 1569 1520 y = 0; … … 1591 1542 1592 1543 _poly.translate(getX(), getY()); 1593 1594 if(preChangeWidth != 0 && preChangeWidth != _poly.getBounds().width) 1595 if(_poly.getBounds().width > preChangeWidth) MagneticConstraints.getInstance().textGrown(this, _poly.getBounds().width - preChangeWidth); 1596 else MagneticConstraints.getInstance().textShrunk(this, preChangeWidth - _poly.getBounds().width); 1544 1545 if (preChangeWidth != 0 && preChangeWidth != _poly.getBounds().width) 1546 if (_poly.getBounds().width > preChangeWidth) 1547 MagneticConstraints.getInstance().textGrown(this, _poly.getBounds().width - preChangeWidth); 1548 else 1549 MagneticConstraints.getInstance().textShrunk(this, preChangeWidth - _poly.getBounds().width); 1597 1550 } 1598 1551 … … 1630 1583 1631 1584 if (_lineBreaker == null || newLinebreakerAlways) { 1632 AttributedString paragraphText = new AttributedString(_text 1633 .toString()); 1585 AttributedString paragraphText = new AttributedString(_text.toString()); 1634 1586 paragraphText.addAttribute(TextAttribute.FONT, getPaintFont()); 1635 1587 frc = new FontRenderContext(null, true, true); … … 1637 1589 } 1638 1590 1639 /* float width = Float.MAX_VALUE; 1640 1641 if (limitWidth) { 1642 width = getAbsoluteWidth(); 1643 // else if (getMaxWidth() > 0) 1644 // width = Math.max(50, getMaxWidth() - getX() 1645 // - Item.MARGIN_RIGHT); 1646 } */ 1591 /* 1592 * float width = Float.MAX_VALUE; 1593 * 1594 * if (limitWidth) { width = getAbsoluteWidth(); // else if (getMaxWidth() > 0) 1595 * // width = Math.max(50, getMaxWidth() - getX() // - Item.MARGIN_RIGHT); } 1596 */ 1647 1597 1648 1598 _textLayouts.clear(); … … 1652 1602 1653 1603 TextLayout layout; 1654 1604 1655 1605 float width; 1656 1606 float lineHeight = Float.NaN; 1657 1607 List<Point[]> lines = null; 1658 1659 if(_autoWrap || ExperimentalFeatures.AutoWrap.get()) { 1660 lines = new LinkedList<Point[]>(); 1661 if(DisplayIO.getCurrentFrame() == null) { 1662 return; 1663 } 1664 for(Item item : DisplayIO.getCurrentFrame().getItems()) { 1665 if(item instanceof Line) { 1666 lines.add(new Point[] { ((Line) item).getStartItem().getPosition(), ((Line) item).getEndItem().getPosition() }); 1667 } 1668 if(item instanceof Picture) { 1669 lines.add(new Point[] { item.getPosition(), new Point(item.getX(), item.getY() + item.getHeight()) }); 1670 } 1671 } 1672 for(Item item : FreeItems.getInstance()) { 1673 if(item instanceof Line) { 1674 lines.add(new Point[] { ((Line) item).getStartItem().getPosition(), ((Line) item).getEndItem().getPosition() }); 1675 } 1676 if(item instanceof Picture) { 1677 lines.add(new Point[] { item.getPosition(), new Point(item.getX(), item.getY() + item.getHeight()) }); 1678 } 1679 } 1680 width = getLineWidth(getX(), getY(), lines); 1608 1609 if (_autoWrap || ExperimentalFeatures.AutoWrap.get()) { 1610 lines = new LinkedList<Point[]>(); 1611 if (DisplayIO.getCurrentFrame() == null) { 1612 return; 1613 } 1614 for (Item item : DisplayIO.getCurrentFrame().getItems()) { 1615 if (item instanceof Line) { 1616 lines.add(new Point[] { ((Line) item).getStartItem().getPosition(), 1617 ((Line) item).getEndItem().getPosition() }); 1618 } 1619 if (item instanceof Picture) { 1620 lines.add( 1621 new Point[] { item.getPosition(), new Point(item.getX(), item.getY() + item.getHeight()) }); 1622 } 1623 } 1624 for (Item item : FreeItems.getInstance()) { 1625 if (item instanceof Line) { 1626 lines.add(new Point[] { ((Line) item).getStartItem().getPosition(), 1627 ((Line) item).getEndItem().getPosition() }); 1628 } 1629 if (item instanceof Picture) { 1630 lines.add( 1631 new Point[] { item.getPosition(), new Point(item.getX(), item.getY() + item.getHeight()) }); 1632 } 1633 } 1634 width = getLineWidth(getX(), getY(), lines); 1681 1635 } else { 1682 1636 width = Float.MAX_VALUE; 1683 1684 if(_maxWidth == null) {1685 1686 1687 1688 1689 1690 1691 1692 1693 } 1694 1637 if (limitWidth) { 1638 if (_maxWidth == null) { 1639 width = FrameGraphics.getMaxFrameSize().width - getX(); 1640 } else { 1641 width = getAbsoluteWidth(); 1642 } 1643 // else if (getMaxWidth() > 0) 1644 // width = Math.max(50, getMaxWidth() - getX() 1645 // - Item.MARGIN_RIGHT); 1646 } 1647 } 1648 1695 1649 _lineBreaker.setPosition(0); 1696 1650 boolean requireNextWord = false; … … 1698 1652 // --- Get the output of the LineBreakMeasurer and store it in a 1699 1653 while (_lineBreaker.getPosition() < _text.length()) { 1700 1701 if (_autoWrap || ExperimentalFeatures.AutoWrap.get()) {1654 1655 if (_autoWrap || ExperimentalFeatures.AutoWrap.get()) { 1702 1656 requireNextWord = width < FrameGraphics.getMaxFrameSize().width - getX(); 1703 1657 } 1704 1658 1705 1659 layout = _lineBreaker.nextLayout(width, _text.length(), requireNextWord); 1706 1660 1707 1661 // lineBreaker does not break on newline 1708 1662 // characters so they have to be check manually 1709 1663 int start = _lineOffsets.get(_lineOffsets.size() - 1); 1710 1711 // int y = getY() + (getLineDrop(layout) * (_lineOffsets.size() - 1) 1712 1664 1665 // int y = getY() + (getLineDrop(layout) * (_lineOffsets.size() - 1) 1666 1713 1667 // check through the current line for newline characters 1714 1668 for (int i = start + 1; i < _text.length(); i++) { … … 1721 1675 1722 1676 _lineOffsets.add(_lineBreaker.getPosition()); 1723 1724 if (layout == null) {1677 1678 if (layout == null) { 1725 1679 layout = new TextLayout(" ", getPaintFont(), frc); 1726 1680 } … … 1729 1683 && _lineBreaker.getPosition() < _text.length()) 1730 1684 layout = layout.getJustifiedLayout(width); 1731 1685 1732 1686 _textLayouts.add(layout); 1733 1734 if (_autoWrap || ExperimentalFeatures.AutoWrap.get()) {1735 1736 if(lineHeight != Float.NaN) {1737 1738 1739 1687 1688 if (_autoWrap || ExperimentalFeatures.AutoWrap.get()) { 1689 1690 if (lineHeight != Float.NaN) { 1691 lineHeight = getLineDrop(layout); 1692 } 1693 width = getLineWidth(getX(), getY() + (lineHeight * (_textLayouts.size() - 1)), lines); 1740 1694 } 1741 1695 } … … 1744 1698 1745 1699 } 1746 1700 1747 1701 private float getLineWidth(int x, float y, List<Point[]> lines) { 1748 1702 float width = FrameGraphics.getMaxFrameSize().width; 1749 for (Point[] l : lines) {1703 for (Point[] l : lines) { 1750 1704 // check for lines that cross over our y 1751 if ((l[0].y >= y && l[1].y <= y) || (l[0].y <= y && l[1].y >= y)) {1705 if ((l[0].y >= y && l[1].y <= y) || (l[0].y <= y && l[1].y >= y)) { 1752 1706 float dX = l[0].x - l[1].x; 1753 1707 float dY = l[0].y - l[1].y; 1754 1708 float newWidth; 1755 if (dX == 0) {1709 if (dX == 0) { 1756 1710 newWidth = l[0].x; 1757 } else if (dY == 0) {1711 } else if (dY == 0) { 1758 1712 newWidth = Math.min(l[0].x, l[1].x); 1759 1713 } else { … … 1762 1716 } 1763 1717 // System.out.println("dY:" + dY + " dX:" + dX + " width:" + newWidth); 1764 if (newWidth < x) {1765 1718 if (newWidth < x) { 1719 continue; 1766 1720 } 1767 if (newWidth < width) {1721 if (newWidth < width) { 1768 1722 width = newWidth; 1769 1723 } … … 1807 1761 // if the selection is before this line, return null 1808 1762 if (_lineOffsets.get(line) < selectionLeft 1809 && _lineOffsets.get(line) 1810 + _textLayouts.get(line).getCharacterCount() < selectionLeft) 1763 && _lineOffsets.get(line) + _textLayouts.get(line).getCharacterCount() < selectionLeft) 1811 1764 return null; 1812 1765 … … 1820 1773 // int end = Math.min(_lineOffsets.get(line) + 1821 1774 // _textLayouts.get(line).getCharacterCount(), _selectionEnd); 1822 int end = Math.min(selectionRight - _lineOffsets.get(line), 1823 +_textLayouts.get(line).getCharacterCount()); 1775 int end = Math.min(selectionRight - _lineOffsets.get(line), +_textLayouts.get(line).getCharacterCount()); 1824 1776 1825 1777 // System.out.println(line + ": " + start + "x" + end + " (" + … … 1840 1792 * Color main = getPaintColor(); Color back = getPaintBackgroundColor(); 1841 1793 * 1842 * if (Math.abs(main.getRed() - back.getRed()) < 10 && 1843 * Math.abs(main.getGreen() - back.getGreen()) < 10 && 1844 * Math.abs(main.getBlue() - back.getBlue()) < 10) { selection = new 1845 * Color(Math.abs(255 - main.getRed()), Math .abs(255 - 1846 * main.getGreen()), Math.abs(255 - main.getBlue())); } else { selection = 1847 * new Color((main.getRed() + (back.getRed() * 2)) / 3, (main.getGreen() + 1848 * (back.getGreen() * 2)) / 3, (main .getBlue() + (back.getBlue() * 2)) / 1849 * 3); } 1794 * if (Math.abs(main.getRed() - back.getRed()) < 10 && Math.abs(main.getGreen() 1795 * - back.getGreen()) < 10 && Math.abs(main.getBlue() - back.getBlue()) < 10) { 1796 * selection = new Color(Math.abs(255 - main.getRed()), Math .abs(255 - 1797 * main.getGreen()), Math.abs(255 - main.getBlue())); } else { selection = new 1798 * Color((main.getRed() + (back.getRed() * 2)) / 3, (main.getGreen() + 1799 * (back.getGreen() * 2)) / 3, (main .getBlue() + (back.getBlue() * 2)) / 3); } 1850 1800 */ 1851 1801 int green = 160; … … 1876 1826 if (_text == null || _text.length() == 0) 1877 1827 return; 1878 1879 if (_autoWrap || ExperimentalFeatures.AutoWrap.get()) {1828 1829 if (_autoWrap || ExperimentalFeatures.AutoWrap.get()) { 1880 1830 invalidateAll(); 1881 1831 1882 1832 rebuild(true); 1883 1833 } else if (_textLayouts.size() < 1) { … … 1901 1851 Color bgc = getBackgroundColor(); 1902 1852 if (_alpha > 0) { 1903 bgc = new Color(bgc.getRed(), bgc.getGreen(), bgc.getBlue(), 1904 _alpha); 1853 bgc = new Color(bgc.getRed(), bgc.getGreen(), bgc.getBlue(), _alpha); 1905 1854 } 1906 1855 g.setColor(bgc); … … 1912 1861 if (s != null) { 1913 1862 Rectangle b = s.getBounds(); 1914 GradientPaint gp = new GradientPaint( 1915 (int) (b.x + b.width * 0.3), b.y, bgc, 1863 GradientPaint gp = new GradientPaint((int) (b.x + b.width * 0.3), b.y, bgc, 1916 1864 (int) (b.x + b.width * 1.3), b.y, gradientColor); 1917 1865 g.setPaint(gp); … … 1936 1884 Point2D.Float start = getEdgePosition(0, true); 1937 1885 Point2D.Float end = getEdgePosition(0, false); 1938 g.drawLine(Math.round(start.x), Math.round(start.y), Math 1939 .round(end.x), Math.round(end.y)); 1886 g.drawLine(Math.round(start.x), Math.round(start.y), Math.round(end.x), Math.round(end.y)); 1940 1887 } 1941 1888 1942 1889 if (isHighlighted()) { 1943 1890 g.setColor(getPaintHighlightColor()); 1944 Stroke highlightStroke = new BasicStroke( 1945 (float) getHighlightThickness(), CAP, JOIN); 1891 Stroke highlightStroke = new BasicStroke((float) getHighlightThickness(), CAP, JOIN); 1946 1892 g.setStroke(highlightStroke); 1947 1893 if (HighlightMode.Enclosed.equals(getHighlightMode())) … … 1958 1904 g.setColor(c); 1959 1905 1960 Color selection = getSelectionColor(FrameMouseActions 1961 .getLastMouseButton()); 1906 Color selection = getSelectionColor(FrameMouseActions.getLastMouseButton()); 1962 1907 1963 1908 // width -= getX(); … … 1982 1927 } 1983 1928 1984 int ldx = 1 +getX()+getJustOffset(layout); // Layout draw x1985 1929 int ldx = 1 + getX() + getJustOffset(layout); // Layout draw x 1930 1986 1931 boolean debug = false; 1987 1932 if (debug) { 1988 g.setColor(new Color(c.getRed(), c.getGreen(),c.getBlue(),40));1933 g.setColor(new Color(c.getRed(), c.getGreen(), c.getBlue(), 40)); 1989 1934 Rectangle layout_rect = layout.getPixelBounds(null, ldx, y); 1990 1935 g.fillRect(layout_rect.x, layout_rect.y, layout_rect.width, layout_rect.height); 1991 1936 g.setColor(c); 1992 1937 } 1993 1994 1938 1995 1939 layout.draw(g, ldx, y); 1996 1940 1997 1941 /* 1998 * AffineTransform at = new AffineTransform(); AffineTransform 1999 * orig = g.getTransform(); at.translate(getX() + 2000 * getJustOffset(layout), y); g.setTransform(at); 2001 * g.draw(layout.getLogicalHighlightShape(0, 1942 * AffineTransform at = new AffineTransform(); AffineTransform orig = 1943 * g.getTransform(); at.translate(getX() + getJustOffset(layout), y); 1944 * g.setTransform(at); g.draw(layout.getLogicalHighlightShape(0, 2002 1945 * layout.getCharacterCount())); g.setTransform(orig); /* 2003 * if(_text.charAt(_lineOffsets.get(line) + 2004 * (layout.getCharacterCount() - 1)) == '\t'){ tab = true; x =2005 * (int) (getX() + x + 20 + layout.getVisibleAdvance());}else{1946 * if(_text.charAt(_lineOffsets.get(line) + (layout.getCharacterCount() - 1)) == 1947 * '\t'){ tab = true; x = (int) (getX() + x + 20 + layout.getVisibleAdvance()); 1948 * }else{ 2006 1949 */ 2007 1950 y += getLineDrop(layout); … … 2097 2040 if (isAnnotation()) 2098 2041 return; 2099 if (!isLineEnd() && _text.length() > 0 2100 && _text.charAt(0) == DEFAULT_BULLET) { 2101 newPoint.setLocation(insertText("" 2102 + (char) KeyEvent.VK_BACK_SPACE, mouseX, mouseY, 1)); 2042 if (!isLineEnd() && _text.length() > 0 && _text.charAt(0) == DEFAULT_BULLET) { 2043 newPoint.setLocation(insertText("" + (char) KeyEvent.VK_BACK_SPACE, mouseX, mouseY, 1)); 2103 2044 if (_text.length() > 0 && _text.charAt(0) == ' ') 2104 newPoint.setLocation(insertText("" 2105 + (char) KeyEvent.VK_BACK_SPACE, newPoint.x, 2106 newPoint.y, 1)); 2045 newPoint.setLocation(insertText("" + (char) KeyEvent.VK_BACK_SPACE, newPoint.x, newPoint.y, 1)); 2107 2046 } else { 2108 2047 newPoint.setLocation(insertText("@", mouseX, mouseY, 0)); … … 2113 2052 return; 2114 2053 if (!isLineEnd() && _text.charAt(0) == '@') { 2115 newPoint.setLocation(insertText("" 2116 + (char) KeyEvent.VK_BACK_SPACE, mouseX, mouseY, 1)); 2117 newPoint.setLocation(insertText(DEFAULT_BULLET_STRING, 2118 newPoint.x, newPoint.y, 0)); 2054 newPoint.setLocation(insertText("" + (char) KeyEvent.VK_BACK_SPACE, mouseX, mouseY, 1)); 2055 newPoint.setLocation(insertText(DEFAULT_BULLET_STRING, newPoint.x, newPoint.y, 0)); 2119 2056 } else { 2120 newPoint.setLocation(insertText("" 2121 + (char) KeyEvent.VK_BACK_SPACE, mouseX, mouseY, 1)); 2057 newPoint.setLocation(insertText("" + (char) KeyEvent.VK_BACK_SPACE, mouseX, mouseY, 1)); 2122 2058 } 2123 2059 } … … 2178 2114 String s = _text.toString().toLowerCase(); 2179 2115 if (s.length() > 0 && s.indexOf("@") == 0) { 2180 if (s.equals("@old") || s.equals("@ao") 2181 || s.equals("@itemtemplate") || s.equals("@parent") 2182 || s.equals("@next") || s.equals("@previous") 2183 || s.equals("@first") || s.equals("@i") || s.equals("@iw") 2184 || s.equals("@f")) 2116 if (s.equals("@old") || s.equals("@ao") || s.equals("@itemtemplate") || s.equals("@parent") 2117 || s.equals("@next") || s.equals("@previous") || s.equals("@first") || s.equals("@i") 2118 || s.equals("@iw") || s.equals("@f")) 2185 2119 return true; 2186 2120 } … … 2245 2179 setRightMargin(modelFrame.getNameItem().getX() - MARGIN_LEFT, true); 2246 2180 } else { 2247 System.out 2248 .print("Error: text.resetTitlePosition, getParent or currentFrame returned null"); 2181 System.out.print("Error: text.resetTitlePosition, getParent or currentFrame returned null"); 2249 2182 setRightMargin(MARGIN_LEFT, true); 2250 2183 } … … 2283 2216 Text template = this.copy(); 2284 2217 template.setID(-1); 2285 // reset width of global templates so the widths of the items on the settings frames don't cause issues 2286 // this is in response to the fact that FrameCreator.addItem() sets rightMargin when it adds items 2218 // reset width of global templates so the widths of the items on the settings 2219 // frames don't cause issues 2220 // this is in response to the fact that FrameCreator.addItem() sets rightMargin 2221 // when it adds items 2287 2222 template.setWidth(null); 2288 2223 /* 2289 * The template must have text otherwise the bounds height will be 2290 * zero!! This will stop escape drop down from working if there is no 2291 * item template 2224 * The template must have text otherwise the bounds height will be zero!! This 2225 * will stop escape drop down from working if there is no item template 2292 2226 */ 2293 2227 template.setText("@"); … … 2308 2242 for (TextLayout text : _textLayouts) { 2309 2243 // check left and right of each box 2310 Rectangle2D textOutline = text.getLogicalHighlightShape(0, 2311 text.getCharacterCount()).getBounds2D(); 2244 Rectangle2D textOutline = text.getLogicalHighlightShape(0, text.getCharacterCount()).getBounds2D(); 2312 2245 2313 2246 // check if the cursor is within the top, bottom and within the 2314 2247 // gravity of right 2315 2248 if (y - textY > textOutline.getY() - NEAR_DISTANCE 2316 && y - textY < textOutline.getY() 2317 + textOutline.getHeight() + NEAR_DISTANCE 2249 && y - textY < textOutline.getY() + textOutline.getHeight() + NEAR_DISTANCE 2318 2250 && x - textX < textOutline.getWidth() + NEAR_DISTANCE) 2319 2251 return true; … … 2342 2274 } 2343 2275 } 2344 2276 2345 2277 private void clipFrameMargin() { 2346 2278 if (!hasFixedWidth()) { 2347 2279 int frameWidth = FrameGraphics.getMaxFrameSize().width; 2348 2280 /* 2349 * Only change width if it is more than 150 pixels from the right of 2350 * the screen 2281 * Only change width if it is more than 150 pixels from the right of the screen 2351 2282 */ 2352 2283 if (!_text.toString().contains(" ")) { … … 2360 2291 } 2361 2292 } 2362 2293 2363 2294 public void justify(boolean fixWidth, Polygon enclosure) { 2364 2295 // if autowrap is on, wrapping is done every time we draw 2365 if (ExperimentalFeatures.AutoWrap.get()) {2296 if (ExperimentalFeatures.AutoWrap.get()) { 2366 2297 return; 2367 2298 } 2368 2299 2369 2300 Integer width = FrameGraphics.getMaxFrameSize().width; 2370 2301 … … 2384 2315 // on the frame 2385 2316 String widthString; 2386 if ((widthString = getParentOrCurrentFrame().getAnnotationValue( 2387 "maxwidth")) != null) { 2317 if ((widthString = getParentOrCurrentFrame().getAnnotationValue("maxwidth")) != null) { 2388 2318 try { 2389 2319 int oldWidth = getWidth(); … … 2399 2329 public void justify(boolean fixWidth) { 2400 2330 // if autowrap is on, wrapping is done every time we draw 2401 if (ExperimentalFeatures.AutoWrap.get()) {2331 if (ExperimentalFeatures.AutoWrap.get()) { 2402 2332 return; 2403 2333 } … … 2452 2382 if (!text.startsWith("@")) 2453 2383 return false; 2454 return text.startsWith("@o") || text.startsWith("@ao") 2455 || text.startsWith("@v") || text.startsWith("@av"); 2384 return text.startsWith("@o") || text.startsWith("@ao") || text.startsWith("@v") || text.startsWith("@av"); 2456 2385 } 2457 2386 … … 2505 2434 } 2506 2435 } // else { 2507 // Add anonomous vars2436 // Add anonomous vars 2508 2437 try { 2509 2438 double value = pair.getDoubleValue(); … … 2528 2457 // If the frame is linked add vector variable for the frame 2529 2458 if (lowercaseFormula.contains("$frame")) { 2530 myParser.addVectorVariable(frame.getNonAnnotationItems(true), 2531 "$frame"); 2459 myParser.addVectorVariable(frame.getNonAnnotationItems(true), "$frame"); 2532 2460 } 2533 2461 } … … 2553 2481 } 2554 2482 } catch (Throwable e) { 2555 // e.printStackTrace();2483 // e.printStackTrace(); 2556 2484 String formula2 = getFormula(); 2557 2485 this.setText(formula2); … … 2566 2494 2567 2495 /** 2568 * Gets items which are in the same enclosure as this item. 2569 * In the event more than one enclosure meets this criteria, then 2570 * the one returned is the one with the smallest area. 2571 * TODO: Improve the efficiency of this method 2496 * Gets items which are in the same enclosure as this item. In the event more 2497 * than one enclosure meets this criteria, then the one returned is the one with 2498 * the smallest area. TODO: Improve the efficiency of this method 2572 2499 * 2573 2500 * @return … … 2580 2507 for (Item i : parent.getVisibleItems()) { 2581 2508 /* 2582 * Go through all the enclosures looking for one that includes this 2583 * item 2509 * Go through all the enclosures looking for one that includes this item 2584 2510 */ 2585 2511 if (!seen.contains(i) && i.isEnclosed()) { … … 2589 2515 // Check it is smaller than any other enclosure found containing 2590 2516 // this item 2591 if (enclosed.contains(this) 2592 && i.getEnclosedArea() < enclosureArea) { 2517 if (enclosed.contains(this) && i.getEnclosedArea() < enclosureArea) { 2593 2518 sameEnclosure = enclosed; 2594 2519 } … … 2601 2526 return sameEnclosure; 2602 2527 } 2603 2604 /** 2605 * Returns true if items of the parent frame should be recalculated when 2606 * thisitem is modified2528 2529 /** 2530 * Returns true if items of the parent frame should be recalculated when this 2531 * item is modified 2607 2532 */ 2608 2533 public boolean recalculateWhenChanged() { … … 2639 2564 invalidateFill(); 2640 2565 invalidateCommonTrait(ItemAppearence.PreMoved); 2641 2566 2642 2567 this._anchorLeft = anchor; 2643 2568 this._anchorRight = null; 2644 2569 2645 2570 int oldX = getX(); 2646 2571 if (anchor != null) { … … 2659 2584 // Subtract off the link width 2660 2585 if (anchor != null) { 2661 setX(FrameGraphics.getMaxFrameSize().width - anchor 2662 - getBoundsWidth() + getLeftMargin()); 2586 setX(FrameGraphics.getMaxFrameSize().width - anchor - getBoundsWidth() + getLeftMargin()); 2663 2587 } 2664 2588 return; … … 2666 2590 invalidateFill(); 2667 2591 invalidateCommonTrait(ItemAppearence.PreMoved); 2668 2592 2669 2593 this._anchorRight = anchor; 2670 2594 this._anchorLeft = null; 2671 2595 2672 2596 int oldX = getX(); 2673 2597 if (anchor != null) { 2674 float deltaX = FrameGraphics.getMaxFrameSize().width - anchor 2675 - getBoundsWidth() + getLeftMargin() - oldX; 2598 float deltaX = FrameGraphics.getMaxFrameSize().width - anchor - getBoundsWidth() + getLeftMargin() - oldX; 2676 2599 anchorConnected(AnchorEdgeType.Right, deltaX); 2677 2600 } … … 2680 2603 invalidateFill(); 2681 2604 } 2682 2683 2684 2605 2685 2606 @Override … … 2694 2615 invalidateFill(); 2695 2616 invalidateCommonTrait(ItemAppearence.PreMoved); 2696 2617 2697 2618 this._anchorTop = anchor; 2698 2619 this._anchorBottom = null; 2699 2620 2700 2621 int oldY = getY(); 2701 2622 if (anchor != null) { … … 2713 2634 super.setAnchorBottom(anchor); 2714 2635 if (anchor != null) { 2715 setY(FrameGraphics.getMaxFrameSize().height - (anchor + this.getBoundsHeight() - _textLayouts.get(0).getAscent() - _textLayouts.get(0).getDescent())); 2636 setY(FrameGraphics.getMaxFrameSize().height - (anchor + this.getBoundsHeight() 2637 - _textLayouts.get(0).getAscent() - _textLayouts.get(0).getDescent())); 2716 2638 } 2717 2639 return; … … 2719 2641 invalidateFill(); 2720 2642 invalidateCommonTrait(ItemAppearence.PreMoved); 2721 2643 2722 2644 this._anchorBottom = anchor; 2723 2645 this._anchorTop = null; 2724 2646 2725 2647 int oldY = getY(); 2726 2648 if (anchor != null) { … … 2742 2664 setWidth(Math.round(width * scale)); 2743 2665 } 2744 2666 2745 2667 super.scale(scale, originX, originY); 2746 2668 rebuild(true); 2747 2669 } 2748 2670 2749 2750 protected Rectangle getPixelBounds(TextLayout layout) 2751 { 2671 protected Rectangle getPixelBounds(TextLayout layout) { 2752 2672 // Does 'layout' need to be synchronized (similar to _textLayouts below)?? 2753 2673 int x = getX(); 2754 2674 int y = getY(); 2755 2675 2756 int ldx = 1 +x+getJustOffset(layout); // Layout draw x2676 int ldx = 1 + x + getJustOffset(layout); // Layout draw x 2757 2677 Rectangle layout_rect = layout.getPixelBounds(null, ldx, y); 2758 2678 2759 return layout_rect; 2760 } 2761 2762 2763 public Rectangle getPixelBoundsUnion() 2764 { 2765 synchronized (_textLayouts) { 2766 2767 int x = getX(); 2768 int y = getY(); 2769 2770 int min_xl = Integer.MAX_VALUE; 2771 int max_xr = Integer.MIN_VALUE; 2772 2773 int min_yt = Integer.MAX_VALUE; 2774 int max_yb = Integer.MIN_VALUE; 2775 2776 2777 for (int i = 0; i < _textLayouts.size(); i++) { 2778 TextLayout layout = _textLayouts.get(i); 2779 2780 int ldx = 1+x+getJustOffset(layout); // Layout draw x 2781 Rectangle layout_rect = layout.getPixelBounds(null, ldx, y); 2782 2783 int xl = layout_rect.x; 2784 int xr = xl + layout_rect.width -1; 2785 2786 int yt = layout_rect.y; 2787 int yb = yt + layout_rect.height -1; 2788 2789 min_xl = Math.min(min_xl,xl); 2790 max_xr = Math.max(max_xr,xr); 2791 2792 min_yt = Math.min(min_yt,yt); 2793 max_yb = Math.max(max_yb,yb); 2794 } 2795 2796 if ((min_xl >= max_xr) || (min_yt >= max_yb)) { 2797 // No valid rectangle are found 2798 return null; 2799 } 2800 2801 return new Rectangle(min_xl,min_yt,max_xr-min_xl+1,max_yb-min_yt+1); 2802 2803 } 2804 2805 } 2679 return layout_rect; 2680 } 2681 2682 /** 2683 * Creates the smallest possible rectangle object to enclose the Text Item 2684 * completely. Width of the rectangle is determined by the line in the Text Item 2685 * that protrudes to the right the most. Height of the rectangle is determined 2686 * by the number of lines in the Text Item. 2687 * 2688 * @return A rectangle enclosing the Text Item, without gravity represented. 2689 * @see #getPixelBoundsUnionTight() 2690 */ 2691 public Rectangle getPixelBoundsUnion() { 2692 final Rectangle rect = getPixelBounds(_textLayouts.get(0)); 2693 2694 int cumulativeHeight = rect.height; 2695 int maxWidth = rect.width; 2696 2697 if (_textLayouts.size() > 1) { 2698 for (int i = 1; i < _textLayouts.size(); i++) { 2699 final Rectangle r = getPixelBounds(_textLayouts.get(i)); 2700 cumulativeHeight += _textLayouts.get(i).getDescent() + _textLayouts.get(i).getAscent(); 2701 if (r.width > maxWidth) 2702 maxWidth = r.width; 2703 } 2704 } 2705 2706 rect.setSize(maxWidth, cumulativeHeight); 2707 2708 return rect; 2709 } 2710 2711 /** 2712 * Creates the smallest possible polygon to enclose the Text Item completely. 2713 * The shape of the polygon is determined by the length of each line, tightly 2714 * fitting the shape so that no white space is inside the resulting polygon. 2715 * 2716 * @return A polygon enclosing the Text Item, without gravity represented. 2717 * @see #getPixelBoundsUnion() 2718 */ 2719 public Polygon getPixelBoundsUnionTight() { 2720 final Rectangle rect = getPixelBounds(_textLayouts.get(0)); 2721 if (_textLayouts.size() == 1) { 2722 int x = (int) rect.getX(); 2723 int y = (int) rect.getY(); 2724 return new Polygon(new int[] { x, x + rect.width, x + rect.width, x }, 2725 new int[] { y, y, y + rect.height, y + rect.height }, 4); 2726 } else { 2727 final Polygon poly = new Polygon(); 2728 poly.addPoint(rect.x, rect.y); 2729 poly.addPoint(rect.x + rect.width, rect.y); 2730 poly.addPoint(rect.x + rect.width, Math.round(rect.y + rect.height + _textLayouts.get(0).getDescent())); 2731 int y = (int) (rect.y + rect.height + _textLayouts.get(0).getDescent()); 2732 for (int i = 1; i < _textLayouts.size(); i++) { 2733 final Rectangle r = getPixelBounds(_textLayouts.get(i)); 2734 poly.addPoint(r.x + r.width, y); 2735 poly.addPoint(r.x + r.width, Math.round(y + r.height + _textLayouts.get(i).getDescent())); 2736 y = Math.round(y + r.height + _textLayouts.get(i).getDescent()); 2737 } 2738 poly.addPoint(rect.x + getPixelBounds(_textLayouts.get(_textLayouts.size() - 1)).width, Math.round(y + _textLayouts.get(_textLayouts.size() - 1).getDescent())); 2739 poly.addPoint(rect.x, Math.round(y + _textLayouts.get(_textLayouts.size() - 1).getDescent())); 2740 return poly; 2741 } 2742 } 2743 2744 // public Rectangle getPixelBoundsUnion() 2745 // { 2746 // synchronized (_textLayouts) { 2747 // 2748 // int x = getX(); 2749 // int y = getY(); 2750 // 2751 // int min_xl = Integer.MAX_VALUE; 2752 // int max_xr = Integer.MIN_VALUE; 2753 // 2754 // int min_yt = Integer.MAX_VALUE; 2755 // int max_yb = Integer.MIN_VALUE; 2756 // 2757 // 2758 // for (int i = 0; i < _textLayouts.size(); i++) { 2759 // TextLayout layout = _textLayouts.get(i); 2760 // 2761 // int ldx = 1+x+getJustOffset(layout); // Layout draw x 2762 // Rectangle layout_rect = layout.getPixelBounds(null, ldx, y); 2763 // 2764 // int xl = layout_rect.x; 2765 // int xr = xl + layout_rect.width -1; 2766 // 2767 // int yt = layout_rect.y; 2768 // int yb = yt + layout_rect.height -1; 2769 // 2770 // min_xl = Math.min(min_xl,xl); 2771 // max_xr = Math.max(max_xr,xr); 2772 // 2773 // min_yt = Math.min(min_yt,yt); 2774 // max_yb = Math.max(max_yb,yb); 2775 // } 2776 // 2777 // if ((min_xl >= max_xr) || (min_yt >= max_yb)) { 2778 // // No valid rectangle are found 2779 // return null; 2780 // } 2781 // 2782 // return new Rectangle(min_xl,min_yt,max_xr-min_xl+1,max_yb-min_yt+1); 2783 // 2784 // } 2785 // 2786 // } 2806 2787 /* 2807 2788 * Returns the SIMPLE statement contained by this text item. … … 2811 2792 return getText().split("\\s+")[0]; 2812 2793 } 2813 2794 2814 2795 public boolean getAutoWrap() { 2815 2796 return _autoWrap; 2816 2797 } 2817 2818 // workaround since true is the default value and would not be displayed normally 2798 2799 // workaround since true is the default value and would not be displayed 2800 // normally 2819 2801 public String getAutoWrapToSave() { 2820 if (!_autoWrap) {2802 if (!_autoWrap) { 2821 2803 return null; 2822 2804 } 2823 2805 return "true"; 2824 2806 } 2825 2807 2826 2808 public void setAutoWrap(boolean autoWrap) { 2827 2809 _autoWrap = autoWrap;
Note:
See TracChangeset
for help on using the changeset viewer.