Changeset 1210 for trunk/src/org/expeditee/items/Text.java
- Timestamp:
- 01/30/19 12:57:45 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/expeditee/items/Text.java
r1200 r1210 27 27 import java.util.List; 28 28 import java.util.StringTokenizer; 29 import java.util.stream.Stream; 29 30 30 31 import org.expeditee.core.Colour; … … 65 66 public class Text extends Item { 66 67 private static final int ADJUST_WIDTH_THRESHOLD = 200; 67 68 68 69 public static final char DELETE_CHARACTER = 0x7F; 69 70 70 71 public static final char BACKSPACE_CHARACTER = '\b'; 71 72 72 73 public static final char TAB_CHARACTER = '\t'; 73 74 74 75 public static final char ESC_CHARACTER = 0x1B; 75 76 … … 130 131 */ 131 132 /** 132 * The maximum allowable width of the Text item. Actual width may be less than this133 * value, subject to text wrapping. Negative values indicate the width was implicitly134 * set by the system, positive values indicate explicit setting by the user. Initially135 * set to be as wide as possible.133 * The maximum allowable width of the Text item. Actual width may be less than 134 * this value, subject to text wrapping. Negative values indicate the width was 135 * implicitly set by the system, positive values indicate explicit setting by 136 * the user. Initially set to be as wide as possible. 136 137 */ 137 138 private Integer _maxWidth = -Integer.MAX_VALUE; 138 139 139 140 private Integer _minWidth = -Integer.MAX_VALUE; 140 141 … … 156 157 /** Keeps track of the last Text item selected. */ 157 158 private static Text _lastSelected = null; 158 159 159 160 // Range selection colours 160 161 /** Colour of selected range when for selecting text. */ … … 166 167 /** Colour of selected range when for deleting text. */ 167 168 public static final Colour RANGE_DELETE_COLOUR = Colour.FromRGB255(235, 235, 140); 168 169 169 170 /** The colour to draw range selections in. */ 170 171 private Colour _selectionColour = RANGE_SELECT_COLOUR; 171 172 172 173 // whether autowrap is on/off for this item 173 174 protected boolean _autoWrap = false; … … 176 177 protected StringBuffer _text = new StringBuffer(); 177 178 178 protected List<TextLayout> _textLayouts = new LinkedList<TextLayout>(); 179 private List<TextLayout> _textLayouts = new LinkedList<TextLayout>(); 180 private List<TextLayout> _maskTextLayouts = new LinkedList<TextLayout>(); 179 181 180 182 // The font to display this text in 181 183 private Font _font; 182 184 183 185 // The optional mask character to us in place of the text's content. 184 186 private Integer _mask = null; 185 187 186 protected static void InitFontFamily(File fontFamilyDir) 187 { 188 protected static void InitFontFamily(File fontFamilyDir) { 188 189 File[] fontFiles = fontFamilyDir.listFiles(); 189 190 … … 205 206 206 207 if (font != null) { 207 208 209 208 209 String font_family = font.getFamilyName(); 210 if (!FONT_WHEEL_ADDITIONAL_LOOKUP.containsKey(font_family)) { 210 211 211 212 if (FONT_WHEEL_ADDITIONAL_LOOKUP.size() > 0) { … … 217 218 218 219 /* 219 int cdut = font.canDisplayUpTo("09AZaz"); 220 if (cdut >= 0) { 221 // Some problem has occured (should return -1 to show all chars possible) 222 223 System.out.println(" [Non-ASCII font]"); 224 } 225 */ 220 * int cdut = font.canDisplayUpTo("09AZaz"); if (cdut >= 0) { // Some problem 221 * has occured (should return -1 to show all chars possible) 222 * 223 * System.out.println(" [Non-ASCII font]"); } 224 */ 226 225 System.out.flush(); 227 226 } … … 255 254 } 256 255 } 257 System.out.println();258 256 } 259 257 } … … 396 394 invalidateAll(); 397 395 } 398 396 399 397 @Override 400 398 public void setMinWidth(final Integer width) { 401 399 invalidateAll(); 402 400 403 401 if (width == null) { 404 402 setJustification(Justification.left); … … 406 404 return; 407 405 } 408 406 409 407 _minWidth = width; 410 408 rebuild(true); … … 413 411 414 412 /** 415 <<<<<<< .mine 416 * Returns the maximum width of this Text item when justification is used. If 417 * the width is negative, it means no explicit width has been set 418 ||||||| .r1094 419 * Returns the maximum width of this Text item when justifcation is used. If 420 * the width is negative, it means no explicit width has been set 421 ======= 422 * Returns the maximum width of this Text item when justifcation is used. If the 423 * width is negative, it means no explicit width has been set 424 >>>>>>> .r1100 413 * <<<<<<< .mine Returns the maximum width of this Text item when justification 414 * is used. If the width is negative, it means no explicit width has been set 415 * ||||||| .r1094 Returns the maximum width of this Text item when justifcation 416 * is used. If the width is negative, it means no explicit width has been set 417 * ======= Returns the maximum width of this Text item when justifcation is 418 * used. If the width is negative, it means no explicit width has been set 419 * >>>>>>> .r1100 425 420 * 426 421 * @return The maximum width of this Text item when justification is used 427 422 */ 428 423 @Override 429 public Integer getWidth() 430 { 424 public Integer getWidth() { 431 425 if (_maxWidth == null || _maxWidth <= 0) { 432 426 return null; 433 427 } 434 428 435 429 return _maxWidth; 436 430 } … … 443 437 return Math.abs(_maxWidth); 444 438 } 445 439 446 440 public Integer getMinWidth() { 447 441 if (_minWidth == null || _minWidth <= 0) { … … 450 444 return _minWidth; 451 445 } 452 446 453 447 public Integer getAbsoluteMinWidth() { 454 448 if (_minWidth == null) { … … 495 489 * @return The justification of this Text item 496 490 */ 497 public Justification getJustification() 498 { 491 public Justification getJustification() { 499 492 if (_justification == null || _justification.equals(Justification.left)) { 500 493 return null; 501 494 } 502 495 503 496 return _justification; 504 497 } … … 509 502 * 510 503 * @param layout 511 * The line of text to calculate the justification offset for. 512 * 513 * @return 514 * The distance to shift the line of text by. 504 * The line of text to calculate the justification offset for. 505 * 506 * @return The distance to shift the line of text by. 515 507 */ 516 508 private int getJustOffset(TextLayout layout) { … … 587 579 * The String to insert. 588 580 */ 589 public void prependText(String text) 590 { 581 public void prependText(String text) { 591 582 invalidateAll(); 592 583 _text.insert(0, text); … … 731 722 732 723 public Point getParagraphEndPosition() { 733 return getEdgePosition( _textLayouts.size() - 1, false);724 return getEdgePosition(getTextLayouts().size() - 1, false); 734 725 } 735 726 … … 740 731 private Point getEdgePosition(int line, boolean start) { 741 732 // if there is no text yet, or the line is invalid 742 if (_text == null || _text.length() == 0 || line < 0 || line > _textLayouts.size() - 1) {733 if (_text == null || _text.length() == 0 || line < 0 || line > getTextLayouts().size() - 1) { 743 734 return new Point(getX(), getY()); 744 735 } 745 736 746 TextLayout last = _textLayouts.get(line);737 TextLayout last = getTextLayouts().get(line); 747 738 TextHitInfo hit; 748 739 if (start) { … … 758 749 float x = getX() + caret[0] + getJustOffset(last); 759 750 760 x = Math.min( 761 x, 762 (getX() - Item.MARGIN_RIGHT - (2 * getGravity()) + getBoundsWidth()) 763 ); 751 x = Math.min(x, (getX() - Item.MARGIN_RIGHT - (2 * getGravity()) + getBoundsWidth())); 764 752 return new Point((int) x, (int) (getY() + y + caret[1])); 765 753 } 766 754 767 public void setSelectionStart(Point p) 768 { 755 public void setSelectionStart(Point p) { 769 756 setSelectionStart(p.getX(), p.getY()); 770 757 } 771 758 772 759 public void setSelectionStart(float mouseX, float mouseY) { 773 760 // determine what line is being pointed to … … 776 763 // get the character being pointed to 777 764 TextHitInfo hit = getCharPosition(line, mouseX); 778 _selectionStart = hit.getInsertionIndex() + _textLayouts.get(line).getStartCharIndex();779 765 _selectionStart = hit.getInsertionIndex() + getTextLayouts().get(line).getStartCharIndex(); 766 780 767 // Clear the last selected 781 768 updateLastSelected(); 782 783 invalidateAll(); 784 } 785 786 public void setSelectionEnd(Point p) 787 { 769 770 invalidateAll(); 771 } 772 773 public void setSelectionEnd(Point p) { 788 774 setSelectionEnd(p.getX(), p.getY()); 789 775 } … … 795 781 // get the character being pointed to 796 782 TextHitInfo hit = getCharPosition(line, mouseX); 797 _selectionEnd = hit.getInsertionIndex() + _textLayouts.get(line).getStartCharIndex();798 783 _selectionEnd = hit.getInsertionIndex() + getTextLayouts().get(line).getStartCharIndex(); 784 799 785 // Clear the last selected 800 786 updateLastSelected(); 801 787 802 788 invalidateAll(); 803 789 } … … 813 799 invalidateAll(); 814 800 } 815 801 816 802 /** Makes sure only one text has a selection at a time. */ 817 public void updateLastSelected() 818 { 803 public void updateLastSelected() { 819 804 if (_lastSelected != this) { 820 805 if (_lastSelected != null) { … … 904 889 * @return The new location that the mouse cursor should be moved to 905 890 */ 906 public Point insertText(String text, float mouseX, float mouseY) 907 { 891 public Point insertText(String text, float mouseX, float mouseY) { 908 892 final Point newPos = insertText(text, mouseX, mouseY, -1); 909 893 return newPos; 910 894 } 911 895 912 public Point insertText(String text, float mouseX, float mouseY, int insertPos) 913 { 896 public Point insertText(final String text, final float mouseX, final float mouseY, int insertPos) { 914 897 TextHitInfo hit; 915 TextLayout current = null;898 TextLayout currentLayout = null; 916 899 int lineIndex; 917 918 invalidateAll(); 919 920 // check for empty string 900 invalidateAll(); 901 902 // if it is a empty string then do not move the mouse 921 903 if (text == null || text.length() == 0) { 922 904 return new Point((int) mouseX, (int) mouseY); 923 905 } 924 925 // if there is no text yet 906 907 // if there is no text yet then simply append parameter and rebuild before moving on. 908 // rebuild re-initialises the TextLayouts 909 // calculate were we are in the content (hit, lineIndex, currentLayout) 926 910 if (_text == null || _text.length() == 0) { 927 911 _text = new StringBuffer().append(text); 928 // create the linebreaker and layouts929 912 rebuild(true); 930 assert (_textLayouts.size() == 1); 931 current = _textLayouts.get(0); 932 hit = current.getNextRightHit(0); 913 914 assert (getTextLayouts().size() == 1); 915 currentLayout = getTextLayouts().get(0); 916 hit = currentLayout.getNextRightHit(0); 933 917 lineIndex = 0; 934 935 // otherwise, we are inserting text 936 } else { 918 } 919 // otherwise we are inserting text and calculating the index into the content that we are at 920 else { 921 937 922 clearCache(); 938 923 // determine what line is being pointed to … … 942 927 hit = getCharPosition(lineIndex, mouseX); 943 928 944 int insertionIndex = hit.getInsertionIndex() + _textLayouts.get(lineIndex).getStartCharIndex();929 int insertionIndex = hit.getInsertionIndex() + getTextLayouts().get(lineIndex).getStartCharIndex(); 945 930 946 931 if (lineIndex > 0 && hit.getInsertionIndex() == 0) { … … 1033 1018 1034 1019 // determine the new position the cursor should have 1035 for (int i = 0; i < _textLayouts.size(); i++) {1036 if ( _textLayouts.get(i).getEndCharIndex() + 1 >= insertionIndex) {1020 for (int i = 0; i < getTextLayouts().size(); i++) { 1021 if (getTextLayouts().get(i).getEndCharIndex() + 1 >= insertionIndex) { 1037 1022 newLine = i; 1038 1023 break; … … 1040 1025 } 1041 1026 1042 current = _textLayouts.get(newLine);1043 insertionIndex -= current .getStartCharIndex();1027 currentLayout = getTextLayouts().get(newLine); 1028 insertionIndex -= currentLayout.getStartCharIndex(); 1044 1029 1045 1030 if (newLine == lineIndex) { 1046 // System.err.println("newLine == lineIndex");1047 1031 if (insertionIndex > 0) { 1048 hit = current .getNextRightHit(insertionIndex - 1);1032 hit = currentLayout.getNextRightHit(insertionIndex - 1); 1049 1033 } else { 1050 hit = current .getNextLeftHit(1);1034 hit = currentLayout.getNextLeftHit(1); 1051 1035 } 1052 1036 } else if (newLine < lineIndex) { 1053 hit = current .getNextRightHit(insertionIndex - 1);1037 hit = currentLayout.getNextRightHit(insertionIndex - 1); 1054 1038 } else { 1055 hit = current .getNextRightHit(insertionIndex - 1);1039 hit = currentLayout.getNextRightHit(insertionIndex - 1); 1056 1040 } 1057 1041 … … 1059 1043 } 1060 1044 1061 if (this.getMask() != null) { 1062 // If we are working with a mask than the positioning of the mouse is simplified. (as character length is constant) 1063 String content = ""; 1064 for (int i = 0; i < this._text.length(); i++) { 1065 content += (char) this.getMask().intValue(); 1066 } 1067 final TextLayout fakeLayout = TextLayout.getManager().layoutStringSimple(content, this.getFont()); 1068 //final TextHitInfo fakeHitInfo = fakeLayout.getNextRightHit(hit.getCharIndex()); 1069 final float[] fakeCaretInfo = fakeLayout.getCaretInfo(hit); 1070 1071 float y = getLineDrop(current) * lineIndex; 1072 y = getY() + y + fakeCaretInfo[1]; 1073 float x = getX() + fakeCaretInfo[0] + getJustOffset(current); 1074 x = Math.min(x, (getX() - Item.MARGIN_RIGHT - (2 * getGravity()) + getBoundsWidth())); 1075 1076 return new Point(Math.round(x), Math.round(y)); 1077 } else { 1078 // If we have no mask then.... 1079 // move the cursor to the new location 1080 float[] caret = current.getCaretInfo(hit); 1081 float y = getLineDrop(current) * lineIndex; 1082 y = getY() + y + caret[1]; 1083 1084 float x = getX() + caret[0] + getJustOffset(current); 1085 x = Math.min(x, (getX() - Item.MARGIN_RIGHT - (2 * getGravity()) + getBoundsWidth())); 1086 1087 invalidateAll(); 1088 1089 final Point newCursor = new Point(Math.round(x), Math.round(y)); 1090 return newCursor; 1091 } 1045 // If we have no mask then.... 1046 // move the cursor to the new location 1047 float[] caret = currentLayout.getCaretInfo(hit); 1048 float y = getLineDrop(currentLayout) * lineIndex; 1049 y = getY() + y + caret[1]; 1050 1051 float x = getX() + caret[0] + getJustOffset(currentLayout); 1052 x = Math.min(x, (getX() - Item.MARGIN_RIGHT - (2 * getGravity()) + getBoundsWidth())); 1053 1054 invalidateAll(); 1055 1056 final Point newCursor = new Point(Math.round(x), Math.round(y)); 1057 return newCursor; 1092 1058 } 1093 1059 … … 1113 1079 } 1114 1080 1115 public Point moveCursor(int direction, float mouseX, float mouseY, boolean setSelection, boolean wholeWord) 1116 { 1081 public Point moveCursor(int direction, float mouseX, float mouseY, boolean setSelection, boolean wholeWord) { 1117 1082 if (setSelection) { 1118 1083 if (!hasSelection()) { … … 1152 1117 line = getLinePosition(mouseY); 1153 1118 if (line < 0) { 1154 line = _textLayouts.size() - 1;1119 line = getTextLayouts().size() - 1; 1155 1120 } 1156 1121 … … 1159 1124 line = Math.max(line - 1, 0); 1160 1125 } else if (direction == DOWN) { 1161 line = Math.min(line + 1, _textLayouts.size() - 1);1126 line = Math.min(line + 1, getTextLayouts().size() - 1); 1162 1127 } 1163 1128 … … 1169 1134 char prevChar = ' '; 1170 1135 do { 1171 hit = _textLayouts.get(line).getNextLeftHit(hit);1136 hit = getTextLayouts().get(line).getNextLeftHit(hit); 1172 1137 1173 1138 // Stop if at the start of the line … … 1177 1142 // Keep going if the char to the left is a 1178 1143 // letterOrDigit 1179 prevChar = _text.charAt(hit.getInsertionIndex() - 1 + _textLayouts.get(line).getStartCharIndex()); 1144 prevChar = _text 1145 .charAt(hit.getInsertionIndex() - 1 + getTextLayouts().get(line).getStartCharIndex()); 1180 1146 } while (wholeWord && Character.isLetterOrDigit(prevChar)); 1181 1147 1182 1148 // TODO Go to the start of the word instead of before the word 1183 char nextChar = _text.charAt(hit.getInsertionIndex() + _textLayouts.get(line).getStartCharIndex()); 1184 1149 char nextChar = _text 1150 .charAt(hit.getInsertionIndex() + getTextLayouts().get(line).getStartCharIndex()); 1151 1185 1152 // This takes care of hard line break in 1186 1153 if (line > 0 && nextChar == '\n') { 1187 1154 line--; 1188 hit = _textLayouts.get(line).getNextRightHit(_textLayouts.get(line).getCharacterCount() - 1); 1155 hit = getTextLayouts().get(line) 1156 .getNextRightHit(getTextLayouts().get(line).getCharacterCount() - 1); 1189 1157 } 1190 1191 // This takes care of soft line breaks.1158 1159 // This takes care of soft line breaks. 1192 1160 } else if (line > 0) { 1193 1161 line--; 1194 hit = _textLayouts.get(line).getNextRightHit(_textLayouts.get(line).getCharacterCount() - 1);1195 1162 hit = getTextLayouts().get(line).getNextRightHit(getTextLayouts().get(line).getCharacterCount() - 1); 1163 1196 1164 // Skip the spaces at the end of a line with soft linebreak 1197 while (hit.getCharIndex() > 0 && _text.charAt(_textLayouts.get(line).getStartCharIndex() + hit.getCharIndex() - 1) == ' ') { 1198 hit = _textLayouts.get(line).getNextLeftHit(hit); 1165 while (hit.getCharIndex() > 0 && _text 1166 .charAt(getTextLayouts().get(line).getStartCharIndex() + hit.getCharIndex() - 1) == ' ') { 1167 hit = getTextLayouts().get(line).getNextLeftHit(hit); 1199 1168 } 1200 1169 } 1201 1170 } else if (direction == RIGHT) { 1202 if (hit.getInsertionIndex() < _textLayouts.get(line).getCharacterCount()) {1203 hit = _textLayouts.get(line).getNextRightHit(hit);1171 if (hit.getInsertionIndex() < getTextLayouts().get(line).getCharacterCount()) { 1172 hit = getTextLayouts().get(line).getNextRightHit(hit); 1204 1173 // Skip whole word if needs be 1205 while (wholeWord 1206 && hit.getCharIndex() > 0 1207 && hit.getCharIndex() < _textLayouts.get(line).getCharacterCount() 1208 && Character.isLetterOrDigit(_text.charAt(_textLayouts.get(line).getStartCharIndex() + hit.getCharIndex() - 1))) 1209 { 1210 hit = _textLayouts.get(line).getNextRightHit(hit); 1174 while (wholeWord && hit.getCharIndex() > 0 1175 && hit.getCharIndex() < getTextLayouts().get(line).getCharacterCount() 1176 && Character.isLetterOrDigit(_text 1177 .charAt(getTextLayouts().get(line).getStartCharIndex() + hit.getCharIndex() - 1))) { 1178 hit = getTextLayouts().get(line).getNextRightHit(hit); 1211 1179 } 1212 } else if (line < _textLayouts.size() - 1) {1180 } else if (line < getTextLayouts().size() - 1) { 1213 1181 line++; 1214 hit = _textLayouts.get(line).getNextLeftHit(1);1182 hit = getTextLayouts().get(line).getNextLeftHit(1); 1215 1183 } 1216 1184 } 1217 current = _textLayouts.get(line);1185 current = getTextLayouts().get(line); 1218 1186 } 1219 1187 … … 1226 1194 break; 1227 1195 } 1228 1196 1229 1197 if (setSelection) { 1230 1198 setSelectionEnd(resultPos.getX(), resultPos.getY()); 1231 1199 } 1232 1200 1233 1201 return resultPos; 1234 1202 } … … 1244 1212 * @return The position in the string of the character being pointed at. 1245 1213 */ 1246 public TextHitInfo getCharPosition( int line, float mouseX) {1247 if (line < 0 || line >= _textLayouts.size()) {1214 public TextHitInfo getCharPosition(final int line, float mouseX) { 1215 if (line < 0 || line >= getTextLayouts().size()) { 1248 1216 return null; 1249 1217 } 1250 1251 TextLayout layout = _textLayouts.get(line);1218 1219 final TextLayout layout = getTextLayouts().get(line); 1252 1220 mouseX += getOffset().getX(); 1253 1221 mouseX -= getJustOffset(layout); … … 1257 1225 1258 1226 /** 1259 * Gets the index into the <code>_textLayout</code> list which corresponds to the line1260 * covered by the given <code>mouseY</code> position.1227 * Gets the index into the <code>_textLayout</code> list which corresponds to 1228 * the line covered by the given <code>mouseY</code> position. 1261 1229 * 1262 1230 * @param mouseY 1263 * 1264 * 1265 * @return 1266 * The line which occupies the given y-coordinate, or the last line ifnone do.1231 * The y-coordinate to test for line coverage. 1232 * 1233 * @return The line which occupies the given y-coordinate, or the last line if 1234 * none do. 1267 1235 */ 1268 1236 public int getLinePosition(float mouseY) { … … 1271 1239 float y = getY(); 1272 1240 1273 for (TextLayout text : _textLayouts) {1241 for (TextLayout text : getTextLayouts()) { 1274 1242 // calculate X to ensure it is in the shape 1275 1243 AxisAlignedBoxBounds bounds = text.getLogicalHighlightShape(0, text.getCharacterCount()); … … 1282 1250 1283 1251 if (bounds.contains((int) x, (int) (mouseY - y))) { 1284 return _textLayouts.indexOf(text);1252 return getTextLayouts().indexOf(text); 1285 1253 } 1286 1254 1287 1255 // check if the cursor is between lines 1288 1256 if (mouseY - y < bounds.getMinY()) { 1289 return Math.max(0, _textLayouts.indexOf(text) - 1);1257 return Math.max(0, getTextLayouts().indexOf(text) - 1); 1290 1258 } 1291 1259 … … 1293 1261 } 1294 1262 1295 return _textLayouts.size() - 1;1263 return getTextLayouts().size() - 1; 1296 1264 } 1297 1265 … … 1302 1270 * The Font to display the Text of this Item in. 1303 1271 */ 1304 public void setFont(Font font) 1305 { 1306 invalidateAll(); 1307 1272 public void setFont(Font font) { 1273 invalidateAll(); 1274 1308 1275 _font = font; 1309 1276 … … 1327 1294 * @return The font to paint the text item with. 1328 1295 */ 1329 public Font getPaintFont() 1330 { 1296 public Font getPaintFont() { 1331 1297 final Font f = getFont(); 1332 1298 if (f == null) { 1333 _font = EcosystemManager.getFontManager().getDefaultFont().clone(); 1299 _font = EcosystemManager.getFontManager().getDefaultFont().clone(); 1334 1300 return _font; 1335 1301 } … … 1341 1307 } 1342 1308 1343 public void setFamily(String newFamily) 1344 { 1309 public void setFamily(String newFamily) { 1345 1310 setFont(new Font(newFamily, getFontStyle(), Math.round(getSize()))); 1346 1311 … … 1386 1351 Font.Style newStyle = Font.Style.PLAIN; 1387 1352 switch (currentStyle) { 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1353 case PLAIN: 1354 newStyle = Font.Style.BOLD; 1355 break; 1356 case BOLD: 1357 newStyle = Font.Style.ITALIC; 1358 break; 1359 case ITALIC: 1360 newStyle = Font.Style.BOLD_ITALIC; 1361 break; 1362 default: 1363 newStyle = Font.Style.PLAIN; 1364 break; 1400 1365 } 1401 1366 setFont(new Font(currentFont.getFamilyName(), newStyle, currentFont.getSize())); … … 1408 1373 Font currentFont = getPaintFont(); 1409 1374 currentFont.toggleBold(); 1410 // setFont(currentFont);1375 // setFont(currentFont); 1411 1376 rebuild(true); 1412 1377 invalidateAll(); … … 1417 1382 Font currentFont = getPaintFont(); 1418 1383 currentFont.toggleItalic(); 1419 // setFont(currentFont);1384 // setFont(currentFont); 1420 1385 rebuild(true); 1421 1386 invalidateAll(); 1422 1387 } 1423 1388 1424 public void setFontStyle(String newFace) 1425 { 1389 public void setFontStyle(String newFace) { 1426 1390 Font currentFont = getPaintFont(); 1427 1391 if (newFace == null || newFace.trim().length() == 0) { 1428 1392 currentFont.setStyle(Font.Style.PLAIN); 1429 // setFont(currentFont);1393 // setFont(currentFont); 1430 1394 return; 1431 1395 } … … 1439 1403 } else if (newFace.equals("italic") || newFace.equals("i")) { 1440 1404 currentFont.setStyle(Font.Style.ITALIC); 1441 } else if (newFace.equals("bolditalic") || newFace.equals("italicbold") || newFace.equals("bi") || newFace.equals("ib")) { 1405 } else if (newFace.equals("bolditalic") || newFace.equals("italicbold") || newFace.equals("bi") 1406 || newFace.equals("ib")) { 1442 1407 currentFont.setStyle(Font.Style.BOLD_ITALIC); 1443 1408 } 1444 1445 // setFont(currentFont);1409 1410 // setFont(currentFont); 1446 1411 1447 1412 } … … 1461 1426 1462 1427 // Rebuilding prevents errors when displaying frame bitmaps 1463 if ( _textLayouts.size() == 0) {1428 if (getTextLayouts().size() == 0) { 1464 1429 rebuild(false); 1465 1430 } 1466 1431 1467 for (TextLayout layout : _textLayouts) {1432 for (TextLayout layout : getTextLayouts()) { 1468 1433 String text = layout.getLine().replaceAll("\n", ""); 1469 1434 if (!text.equals("")) { … … 1474 1439 return list; 1475 1440 } catch (Exception e) { 1476 System.out.println( e.getMessage());1441 System.out.println("Exception in Text::getTextList::message is: " + e.getMessage()); 1477 1442 return null; 1478 1443 } … … 1534 1499 * 1535 1500 * @param layout 1536 * The TextLayout to calculate line-drop for. 1537 * 1538 * @return 1539 * The distance to advance in the y-direction before the next line. 1540 */ 1541 protected float getLineDrop(TextLayout layout) 1542 { 1501 * The TextLayout to calculate line-drop for. 1502 * 1503 * @return The distance to advance in the y-direction before the next line. 1504 */ 1505 protected float getLineDrop(TextLayout layout) { 1543 1506 if (getSpacing() < 0) { 1544 1507 return layout.getAscent() + layout.getDescent() + layout.getLeading(); … … 1568 1531 Font currentFont = getPaintFont(); 1569 1532 currentFont.setSpacing(spacing); 1570 // setFont(currentFont);1533 // setFont(currentFont); 1571 1534 } 1572 1535 … … 1588 1551 1589 1552 // @Override 1590 /* public boolean intersectsOLD(Polygon p) { 1591 if (super.intersects(p)) { 1592 float textY = getY(); 1593 1594 for (TextLayout text : _textLayouts) { 1595 // check left and right of each box 1596 Rectangle2D textOutline = text.getLogicalHighlightShape(0, text.getCharacterCount()).getBounds2D(); 1597 textOutline.setRect(textOutline.getX() + getX() - 1, textOutline.getY() + textY - 1, 1598 textOutline.getWidth() + 2, textOutline.getHeight() + 2); 1599 if (p.intersects(textOutline)) 1600 return true; 1601 textY += getLineDrop(text); 1602 } 1603 } 1604 return false; 1605 }*/ 1553 /* 1554 * public boolean intersectsOLD(Polygon p) { if (super.intersects(p)) { float 1555 * textY = getY(); 1556 * 1557 * for (TextLayout text : _textLayouts) { // check left and right of each box 1558 * Rectangle2D textOutline = text.getLogicalHighlightShape(0, 1559 * text.getCharacterCount()).getBounds2D(); 1560 * textOutline.setRect(textOutline.getX() + getX() - 1, textOutline.getY() + 1561 * textY - 1, textOutline.getWidth() + 2, textOutline.getHeight() + 2); if 1562 * (p.intersects(textOutline)) return true; textY += getLineDrop(text); } } 1563 * return false; } 1564 */ 1606 1565 1607 1566 // The following version of intersect uses a tighter definition for the text, … … 1612 1571 // float textY = getY(); 1613 1572 1614 for (TextLayout text : _textLayouts) {1573 for (TextLayout text : getTextLayouts()) { 1615 1574 1616 1575 AxisAlignedBoxBounds text_pixel_bounds_rect = getPixelBounds(text); … … 1629 1588 return contains(mousePosition.getX(), mousePosition.getY(), getGravity() * NEARBY_GRAVITY); 1630 1589 } 1631 1632 public boolean contains(int mouseX, int mouseY) 1633 { 1590 1591 public boolean contains(int mouseX, int mouseY) { 1634 1592 return contains(new Point(mouseX, mouseY)); 1635 1593 } 1636 1594 1637 public boolean contains(int mouseX, int mouseY, int gravity) 1638 { 1595 public boolean contains(int mouseX, int mouseY, int gravity) { 1639 1596 mouseX += getOffset().getX(); 1640 1597 mouseY += getOffset().getY(); … … 1644 1601 1645 1602 AxisAlignedBoxBounds outline = getBoundingBox(); 1646 1603 1647 1604 if (outline == null) { 1648 1605 return false; … … 1650 1607 1651 1608 // Check if its outside the top and left and bottom bounds 1652 if (outline.getMinX() - mouseX > gravity 1653 || outline.getMinY() - mouseY > gravity 1609 if (outline.getMinX() - mouseX > gravity || outline.getMinY() - mouseY > gravity 1654 1610 || mouseY - (outline.getMinY() + outline.getHeight()) > gravity 1655 1611 || mouseX - (outline.getMinX() + outline.getWidth()) > gravity) { 1656 1612 return false; 1657 1613 } 1658 1659 if (this.getMinWidth() != null && outline.contains(mouseX, 1614 1615 if (this.getMinWidth() != null && outline.contains(mouseX, mouseY)) { 1660 1616 return true; 1661 1617 } 1662 1618 1663 for (TextLayout text : _textLayouts) {1619 for (TextLayout text : getTextLayouts()) { 1664 1620 // check left and right of each box 1665 1621 AxisAlignedBoxBounds textOutline = text.getLogicalHighlightShape(0, text.getCharacterCount()); … … 1668 1624 // gravity of right 1669 1625 int justOffset = getJustOffset(text); 1670 1671 if (mouseY - textY > textOutline.getMinY() && 1672 mouseY - textY < textOutline.getMinY() + textOutline.getHeight() && 1673 mouseX - textX - justOffset < textOutline.getWidth() + gravity + Item.MARGIN_RIGHT) 1674 { 1626 1627 if (mouseY - textY > textOutline.getMinY() 1628 && mouseY - textY < textOutline.getMinY() + textOutline.getHeight() 1629 && mouseX - textX - justOffset < textOutline.getWidth() + gravity + Item.MARGIN_RIGHT) { 1675 1630 return true; 1676 1631 } 1677 1632 1678 1633 textY += getLineDrop(text); 1679 1634 } … … 1686 1641 */ 1687 1642 @Override 1688 public AxisAlignedBoxBounds updateBounds() 1689 {1643 public AxisAlignedBoxBounds updateBounds() { 1644 boolean isFakeLayout = false; 1690 1645 // if there is no text, there is nothing to do 1691 1646 if (_text == null) { … … 1694 1649 1695 1650 // if there is no text layouts and the text has no min width, do nothing 1696 if ( _textLayouts == null || (_textLayouts.size() < 1 && this.getMinWidth() == null)) {1651 if (getTextLayouts() == null || (getTextLayouts().size() < 1 && this.getMinWidth() == null)) { 1697 1652 return null; 1698 } 1653 } 1654 1655 if (this.getMinWidth() != null && getTextLayouts().size() == 0 && this.getFont() != null) { 1656 getTextLayouts().add(TextLayout.getManager().layoutStringSimple("p", this.getFont())); 1657 isFakeLayout = true; 1658 } 1699 1659 1700 1660 int preChangeWidth = 0; … … 1710 1670 1711 1671 float y = -1; 1712 1713 if (this.getMinWidth() != null && _textLayouts.size() == 0 && this.getFont() != null) {1714 final TextLayout fakeLayout = TextLayout.getManager().layoutStringSimple("p", this.getFont());1715 final int xPos = getX() - getGravity();1716 final int yPos = getY() - getGravity() - (int) fakeLayout.getAscent();1717 final int width = 2 * getGravity() + this.getMinWidth();1718 final int height = 2 * getGravity() + EcosystemManager.getGraphicsManager().getFontHeight(getFont());1719 TextLayout.getManager().releaseLayout(fakeLayout);1720 return new AxisAlignedBoxBounds(xPos, yPos, width, height);1721 }1722 1672 1723 1673 // Fix concurrency error in ScaleFrameset 1724 1674 List<TextLayout> tmpTextLayouts; 1725 synchronized ( _textLayouts) {1726 tmpTextLayouts = new LinkedList<TextLayout>( _textLayouts);1675 synchronized (getTextLayouts()) { 1676 tmpTextLayouts = new LinkedList<TextLayout>(getTextLayouts()); 1727 1677 } 1728 1678 … … 1733 1683 if (y < 0) { 1734 1684 y = 0; 1735 } else { 1685 } else { 1736 1686 y += getLineDrop(layout); 1737 1687 } 1738 1688 1739 1689 int minWidth = getAbsoluteMinWidth(); 1740 1690 1741 1691 minX = Math.min(minX, bounds.getMinX()); 1742 maxX = minWidth < Integer.MAX_VALUE 1743 ? Math.max(minX + minWidth, bounds.getMaxX()) 1692 maxX = minWidth < Integer.MAX_VALUE ? Math.max(minX + minWidth, bounds.getMaxX()) 1744 1693 : Math.max(maxX, bounds.getMaxX()); 1745 1694 minY = Math.min(minY, (int) (bounds.getMinY() + y)); … … 1760 1709 final int height = 2 * getGravity() + maxY - minY; 1761 1710 AxisAlignedBoxBounds ret = new AxisAlignedBoxBounds(xPos, yPos, width, height); 1762 1711 1763 1712 Dimension polySize = ret.getSize(); 1764 1765 if (preChangeWidth != 0 && preChangeWidth != polySize.width) {1713 1714 if (preChangeWidth != 0 && preChangeWidth != polySize.width) { 1766 1715 if (polySize.width > preChangeWidth) { 1767 1716 MagneticConstraints.getInstance().textGrown(this, polySize.width - preChangeWidth); … … 1770 1719 } 1771 1720 } 1772 1721 1722 if (isFakeLayout) { 1723 getTextLayouts().remove(0).release(); 1724 } 1725 1773 1726 return ret; 1774 1727 } … … 1788 1741 */ 1789 1742 private void rebuild(boolean limitWidth, boolean newLinebreakerAlways) { 1790 // TODO make this more efficient so it only clears annotation list when it really has to 1743 // TODO make this more efficient so it only clears annotation list when it 1744 // really has to 1791 1745 if (isAnnotation()) { 1792 1746 Frame parent = getParent(); … … 1805 1759 } 1806 1760 1807 EcosystemManager.getTextLayoutManager().releaseLayouts(_textLayouts); 1808 if (_textLayouts != null) { 1809 _textLayouts.clear(); 1761 EcosystemManager.getTextLayoutManager().releaseLayouts(getTextLayouts()); 1762 if (getTextLayouts() != null) { 1763 getTextLayouts().clear(); 1764 } 1765 EcosystemManager.getTextLayoutManager().releaseLayouts(_maskTextLayouts); 1766 if (_maskTextLayouts != null) { 1767 _maskTextLayouts.clear(); 1810 1768 } 1811 1769 1812 1770 // Calculate the maximum allowable width of this line of text 1813 1771 List<org.expeditee.core.Line> lines = null; 1814 if (_autoWrap || ExperimentalFeatures.AutoWrap.get()) {1772 if (_autoWrap || ExperimentalFeatures.AutoWrap.get()) { 1815 1773 lines = new LinkedList<org.expeditee.core.Line>(); 1816 if(DisplayController.getCurrentFrame() == null) {1817 1818 1819 for(Item item : DisplayController.getCurrentFrame().getItems()) {1820 if(item instanceof Line) {1821 lines.add(new org.expeditee.core.Line (((Line) item).getStartItem().getPosition(), ((Line) item).getEndItem().getPosition())); 1822 } 1823 if(item instanceof Picture) { 1824 lines.add(new org.expeditee.core.Line(item.getPosition(), new Point(item.getX(), item.getY() + item.getHeight()))); 1825 } 1826 } 1827 for(Item item : FreeItems.getInstance()) { 1828 if(item instanceof Line) { 1829 lines.add(new org.expeditee.core.Line(((Line) item).getStartItem().getPosition(), ((Line) item).getEndItem().getPosition())); 1830 } 1831 if(item instanceof Picture) { 1832 lines.add(new org.expeditee.core.Line(item.getPosition(), new Point(item.getX(), item.getY() + item.getHeight())));1833 1834 } 1835 }1836 1837 if (_text.toString().startsWith("Title")) { 1838 //System.err.println("TitleTemplate doing stuffs"); 1839 1774 if (DisplayController.getCurrentFrame() == null) { 1775 return; 1776 } 1777 for (Item item : DisplayController.getCurrentFrame().getItems()) { 1778 if (item instanceof Line) { 1779 lines.add(new org.expeditee.core.Line(((Line) item).getStartItem().getPosition(), 1780 ((Line) item).getEndItem().getPosition())); 1781 } 1782 if (item instanceof Picture) { 1783 lines.add(new org.expeditee.core.Line(item.getPosition(), 1784 new Point(item.getX(), item.getY() + item.getHeight()))); 1785 } 1786 } 1787 for (Item item : FreeItems.getInstance()) { 1788 if (item instanceof Line) { 1789 lines.add(new org.expeditee.core.Line(((Line) item).getStartItem().getPosition(), 1790 ((Line) item).getEndItem().getPosition())); 1791 } 1792 if (item instanceof Picture) { 1793 lines.add(new org.expeditee.core.Line(item.getPosition(), 1794 new Point(item.getX(), item.getY() + item.getHeight()))); 1795 } 1796 } 1797 } 1840 1798 1841 1799 float width = Float.MAX_VALUE; 1842 if (limitWidth) { 1843 if(_maxWidth == null) { 1844 width = DisplayController.getFramePaintArea().getWidth() - getX(); 1845 } else { 1846 width = getAbsoluteWidth(); 1847 } 1848 } 1849 1850 _textLayouts = EcosystemManager.getTextLayoutManager().layoutString(_text.toString(), 1851 getPaintFont(), 1852 new Point(getX(), getY()), 1853 lines != null ? lines.toArray(new org.expeditee.core.Line[1]) : null, 1854 (int) width, 1855 (int) getSpacing(), 1856 true, 1857 getJustification() == Justification.full); 1858 1859 if (_textLayouts.size() > 1) { 1860 //System.err.println("Text::rebuild::" + _text.toString() + " is split up over " + _textLayouts.size() + " text layouts"); 1861 //System.err.println(Arrays.toString(_text.toString().toCharArray())); 1862 } 1863 1800 if (limitWidth) { 1801 if (_maxWidth == null) { 1802 width = DisplayController.getFramePaintArea().getWidth() - getX(); 1803 } else { 1804 width = getAbsoluteWidth(); 1805 } 1806 } 1807 1808 this._textLayouts = 1809 EcosystemManager.getTextLayoutManager().layoutString( 1810 _text.toString(), 1811 getPaintFont(), 1812 new Point(getX(), getY()), lines != null ? lines.toArray(new org.expeditee.core.Line[1]) : null, 1813 (int) width, 1814 (int) getSpacing(), 1815 true, 1816 getJustification() == Justification.full 1817 ); 1818 if (this.getMask() != null) { 1819 final Stream<Character> maskStream = _text.toString().chars().mapToObj(c -> (char) this.getMask().intValue()); 1820 final StringBuilder sb = new StringBuilder(); 1821 maskStream.forEach(c -> sb.append(c)); 1822 this._maskTextLayouts = 1823 EcosystemManager.getTextLayoutManager().layoutString( 1824 sb.toString(), 1825 getPaintFont(), 1826 new Point(getX(), getY()), lines != null ? lines.toArray(new org.expeditee.core.Line[1]) : null, 1827 (int) width, 1828 (int) getSpacing(), 1829 true, 1830 getJustification() == Justification.full 1831 ); 1832 } 1833 1864 1834 invalidateBounds(); 1865 1835 } 1866 1836 1867 1837 /** 1868 * Calculates the maximum possible distance a line can extend to the right from a given (x,y) point1869 * without crossing any of the lines in the given list.1838 * Calculates the maximum possible distance a line can extend to the right from 1839 * a given (x,y) point without crossing any of the lines in the given list. 1870 1840 * 1871 1841 * @param x 1872 * 1842 * The x-coordinate of the beginning point. 1873 1843 * 1874 1844 * @param y 1875 * 1845 * The y-coordinate of the beginning point. 1876 1846 * 1877 1847 * @param lines 1878 * A list of pairs of points describing the lines that should stop the extension. 1879 * 1880 * @return 1881 * The length of the extended line. 1882 */ 1883 /* private float getLineWidth(int x, float y, List<Point[]> lines) { 1884 float width = FrameGraphics.getMaxFrameSize().width; 1885 for (Point[] l : lines) { 1886 // check for lines that cross over our y 1887 if ((l[0].y >= y && l[1].y <= y) || (l[0].y <= y && l[1].y >= y)) { 1888 float dX = l[0].x - l[1].x; 1889 float dY = l[0].y - l[1].y; 1890 float newWidth; 1891 if (dX == 0) { 1892 newWidth = l[0].x; 1893 } else if (dY == 0) { 1894 newWidth = Math.min(l[0].x, l[1].x); 1895 } else { 1896 // System.out.print("gradient: " + (dY / dX)); 1897 newWidth = l[0].x + (y - l[0].y) * dX / dY; 1898 } 1899 // System.out.println("dY:" + dY + " dX:" + dX + " width:" + newWidth); 1900 if (newWidth < x) { 1901 continue; 1902 } 1903 if (newWidth < width) { 1904 width = newWidth; 1905 } 1906 } 1907 } 1908 return width - x; 1909 }*/ 1848 * A list of pairs of points describing the lines that should stop 1849 * the extension. 1850 * 1851 * @return The length of the extended line. 1852 */ 1853 /* 1854 * private float getLineWidth(int x, float y, List<Point[]> lines) { float width 1855 * = FrameGraphics.getMaxFrameSize().width; for (Point[] l : lines) { // check 1856 * for lines that cross over our y if ((l[0].y >= y && l[1].y <= y) || (l[0].y 1857 * <= y && l[1].y >= y)) { float dX = l[0].x - l[1].x; float dY = l[0].y - 1858 * l[1].y; float newWidth; if (dX == 0) { newWidth = l[0].x; } else if (dY == 0) 1859 * { newWidth = Math.min(l[0].x, l[1].x); } else { // 1860 * System.out.print("gradient: " + (dY / dX)); newWidth = l[0].x + (y - l[0].y) 1861 * * dX / dY; } // System.out.println("dY:" + dY + " dX:" + dX + " width:" + 1862 * newWidth); if (newWidth < x) { continue; } if (newWidth < width) { width = 1863 * newWidth; } } } return width - x; } 1864 */ 1910 1865 1911 1866 private boolean hasFixedWidth() { … … 1940 1895 1941 1896 // if the selection is after this line, return null 1942 if ( _textLayouts.get(line).getStartCharIndex() > selectionRight) {1897 if (getTextLayouts().get(line).getStartCharIndex() > selectionRight) { 1943 1898 return null; 1944 1899 } 1945 1900 1946 1901 // if the selection is before this line, return null 1947 if ( _textLayouts.get(line).getEndCharIndex() < selectionLeft) {1902 if (getTextLayouts().get(line).getEndCharIndex() < selectionLeft) { 1948 1903 return null; 1949 1904 } … … 1955 1910 // the selection occurs on this line, determine where it lies on the 1956 1911 // line 1957 int start = Math.max(0, selectionLeft - _textLayouts.get(line).getStartCharIndex());1912 int start = Math.max(0, selectionLeft - getTextLayouts().get(line).getStartCharIndex()); 1958 1913 // int end = Math.min(_lineOffsets.get(line) + 1959 1914 // _textLayouts.get(line).getCharacterCount(), _selectionEnd); 1960 int end = Math.min(selectionRight - _textLayouts.get(line).getStartCharIndex(), _textLayouts.get(line).getCharacterCount()); 1915 int end = Math.min(selectionRight - getTextLayouts().get(line).getStartCharIndex(), 1916 getTextLayouts().get(line).getCharacterCount()); 1961 1917 1962 1918 // System.out.println(line + ": " + start + "x" + end + " (" + … … 1966 1922 1967 1923 /** Sets the colour that should be used to render the selected range. */ 1968 public void setSelectionColour(Colour colour) 1969 { 1924 public void setSelectionColour(Colour colour) { 1970 1925 if (colour == null) { 1971 1926 colour = RANGE_SELECT_COLOUR; 1972 1927 } 1973 1928 1974 1929 _selectionColour = colour; 1975 1930 } 1976 1931 1977 1932 /** Gets the colour that should be used to render the selected range. */ 1978 public Colour getSelectionColour() 1979 { 1933 public Colour getSelectionColour() { 1980 1934 return _selectionColour; 1981 1935 } 1982 1936 1983 1937 @Override 1984 public void paint() 1985 { 1938 public void paint() { 1986 1939 if (!isVisible()) { 1987 1940 return; … … 1992 1945 return; 1993 1946 } 1994 1947 1995 1948 // if the text to paint is empty string and there is no min width, do nothing. 1996 1949 if ((_text.length() == 0 && getMinWidth() == null)) { … … 2002 1955 2003 1956 rebuild(true); 2004 } else if ( _textLayouts.size() < 1) {1957 } else if (getTextLayouts().size() < 1) { 2005 1958 clipFrameMargin(); 2006 1959 rebuild(true); 2007 1960 // return; 2008 1961 } 2009 1962 2010 1963 // check if its a vector item and paint all the vector stuff too if this 2011 1964 // item is a free item … … 2017 1970 // associated vector 2018 1971 } 2019 1972 2020 1973 GraphicsManager g = EcosystemManager.getGraphicsManager(); 2021 1974 AxisAlignedBoxBounds bounds = (AxisAlignedBoxBounds) getBounds(); … … 2025 1978 Colour bgc = getBackgroundColor(); 2026 1979 if (_alpha > 0) { 2027 bgc = new Colour(bgc.getRed(), bgc.getGreen(), bgc.getBlue(), 2028 Colour.FromComponent255(_alpha)); 1980 bgc = new Colour(bgc.getRed(), bgc.getGreen(), bgc.getBlue(), Colour.FromComponent255(_alpha)); 2029 1981 } 2030 1982 2031 1983 Colour gradientColor = getGradientColor(); 2032 1984 2033 1985 Fill fill; 2034 1986 2035 1987 if (gradientColor != null && bounds != null) { 2036 fill = new GradientFill(bgc, new Point((int) (bounds.getMinX() + bounds.getWidth() * 0.3), bounds.getMinY()), gradientColor, new Point((int) (bounds.getMinX() + bounds.getWidth() * 1.3), bounds.getMinY())); 1988 fill = new GradientFill(bgc, 1989 new Point((int) (bounds.getMinX() + bounds.getWidth() * 0.3), bounds.getMinY()), gradientColor, 1990 new Point((int) (bounds.getMinX() + bounds.getWidth() * 1.3), bounds.getMinY())); 2037 1991 } else { 2038 1992 fill = new Fill(bgc); … … 2054 2008 } 2055 2009 2056 if (isHighlighted()) { 2010 if (isHighlighted()) { 2057 2011 Stroke highlightStroke = new Stroke(getHighlightThickness(), DEFAULT_CAP, DEFAULT_JOIN); 2058 2012 Fill fill; … … 2070 2024 paintColour = new Colour(paintColour); 2071 2025 paintColour.setAlpha(Colour.FromComponent255(_alpha)); 2072 2026 2073 2027 } 2074 2028 … … 2078 2032 // int line = 0; 2079 2033 // boolean tab = false; 2080 synchronized ( _textLayouts) {2081 for (int i = 0; i < _textLayouts.size(); i++) {2082 TextLayout layout = _textLayouts.get(i);2034 synchronized (getTextLayouts()) { 2035 for (int i = 0; i < getTextLayouts().size(); i++) { 2036 TextLayout layout = getTextLayouts().get(i); 2083 2037 2084 2038 Range<Integer> selectedRange = getSelectedRange(i); 2085 2039 if (selectedRange != null) { 2086 AxisAlignedBoxBounds highlight = layout.getLogicalHighlightShape(selectedRange.lowerBound, selectedRange.upperBound); 2040 AxisAlignedBoxBounds highlight = layout.getLogicalHighlightShape(selectedRange.lowerBound, 2041 selectedRange.upperBound); 2087 2042 highlight.getTopLeft().add(getX() + getJustOffset(layout), (int) y); 2088 g.drawRectangle(highlight, 2089 0.0, 2090 new Fill(selectionColour), 2091 null, null, null); 2092 } 2093 2094 if (layout.getCharacterCount() == 0) { continue; } 2043 g.drawRectangle(highlight, 0.0, new Fill(selectionColour), null, null, null); 2044 } 2045 2046 if (layout.getCharacterCount() == 0) { 2047 continue; 2048 } 2095 2049 int ldx = 1 + getX() + getJustOffset(layout); // Layout draw x 2096 if (_mask == null) { 2097 g.drawTextLayout(layout, new Point(ldx, (int) y), paintColour); 2098 } else { 2099 String mask = ""; 2100 for(int o = 0; o < layout.getCharacterCount(); o++) { mask += (char) getMask().intValue(); } 2101 g.drawString(mask, new Point(ldx, (int) y), layout.getFont(), paintColour); 2102 } 2050 g.drawTextLayout(layout, new Point(ldx, (int) y), paintColour); 2103 2051 2104 2052 y += getLineDrop(layout); 2105 2053 } 2106 2054 } 2107 2055 2108 2056 paintLink(); 2109 2057 } … … 2111 2059 // TODO: Revise 2112 2060 @Override 2113 protected AxisAlignedBoxBounds getLinkDrawArea() 2114 { 2061 protected AxisAlignedBoxBounds getLinkDrawArea() { 2115 2062 return getDrawingArea(); 2116 2063 } … … 2121 2068 * @return True if this Item has no text in it, false otherwise. 2122 2069 */ 2123 public boolean isEmpty() 2124 { 2070 public boolean isEmpty() { 2125 2071 return (_text == null || _text.length() == 0); 2126 2072 } … … 2181 2127 Font currentFont = getPaintFont(); 2182 2128 currentFont.setSize((int) size); 2183 // setFont(currentFont);2129 // setFont(currentFont); 2184 2130 rebuild(true); 2185 2131 invalidateAll(); … … 2237 2183 if (_text.length() == 0) { 2238 2184 if (this.getMinWidth() != null) { 2239 //final TextLayout base = _textLayouts.get(0);2240 //_textLayouts.set(0, TextLayout.get(" ", base.getFont(), 0, 1));2241 _textLayouts.clear();2185 // final TextLayout base = _textLayouts.get(0); 2186 // _textLayouts.set(0, TextLayout.get(" ", base.getFont(), 0, 1)); 2187 getTextLayouts().clear(); 2242 2188 } 2243 2189 if (this.isLineEnd()) { … … 2401 2347 float textX = getX(); 2402 2348 2403 for (TextLayout text : _textLayouts) {2349 for (TextLayout text : getTextLayouts()) { 2404 2350 // check left and right of each box 2405 2351 AxisAlignedBoxBounds textOutline = text.getLogicalHighlightShape(0, text.getCharacterCount()); … … 2407 2353 // check if the cursor is within the top, bottom and within the 2408 2354 // gravity of right 2409 if (y - textY > textOutline.getMinY() - NEAR_DISTANCE && 2410 y - textY < textOutline.getMinY() + textOutline.getHeight() + NEAR_DISTANCE && 2411 x - textX < textOutline.getWidth() + NEAR_DISTANCE) 2412 { 2355 if (y - textY > textOutline.getMinY() - NEAR_DISTANCE 2356 && y - textY < textOutline.getMinY() + textOutline.getHeight() + NEAR_DISTANCE 2357 && x - textX < textOutline.getWidth() + NEAR_DISTANCE) { 2413 2358 return true; 2414 2359 } 2415 2360 2416 2361 textY += getLineDrop(text); 2417 2362 } … … 2460 2405 public void justify(boolean fixWidth, PolygonBounds enclosure) { 2461 2406 // if autowrap is on, wrapping is done every time we draw 2462 if (ExperimentalFeatures.AutoWrap.get()) {2407 if (ExperimentalFeatures.AutoWrap.get()) { 2463 2408 return; 2464 2409 } … … 2496 2441 public void justify(boolean fixWidth) { 2497 2442 // if autowrap is on, wrapping is done every time we draw 2498 if (ExperimentalFeatures.AutoWrap.get()) {2443 if (ExperimentalFeatures.AutoWrap.get()) { 2499 2444 return; 2500 2445 } … … 2513 2458 @Override 2514 2459 protected int getLinkYOffset() { 2515 if ( _textLayouts.size() == 0) {2460 if (getTextLayouts().size() == 0) { 2516 2461 return 0; 2517 2462 } 2518 return Math.round(-( _textLayouts.get(0).getAscent() / 2));2463 return Math.round(-(getTextLayouts().get(0).getAscent() / 2)); 2519 2464 } 2520 2465 … … 2729 2674 2730 2675 public float getLineHeight() { 2731 return getLineDrop( _textLayouts.get(0));2676 return getLineDrop(getTextLayouts().get(0)); 2732 2677 } 2733 2678 … … 2763 2708 // Subtract off the link width 2764 2709 if (anchor != null) { 2765 setX(DisplayController.getFramePaintArea().getWidth() - anchor 2766 - getBoundsWidth() + getLeftMargin()); 2710 setX(DisplayController.getFramePaintArea().getWidth() - anchor - getBoundsWidth() + getLeftMargin()); 2767 2711 } 2768 2712 return; … … 2775 2719 int oldX = getX(); 2776 2720 if (anchor != null) { 2777 float deltaX = DisplayController.getFramePaintArea().getWidth() - anchor 2778 - getBoundsWidth()+ getLeftMargin() - oldX;2721 float deltaX = DisplayController.getFramePaintArea().getWidth() - anchor - getBoundsWidth() 2722 + getLeftMargin() - oldX; 2779 2723 anchorConnected(AnchorEdgeType.Right, deltaX); 2780 2724 } … … 2786 2730 @Override 2787 2731 public void setAnchorTop(Integer anchor) { 2788 if (!isLineEnd()) { 2732 if (!isLineEnd()) { 2789 2733 super.setAnchorTop(anchor); 2790 2734 if (anchor != null) { 2791 if (! _textLayouts.isEmpty()) {2792 final float ascent = _textLayouts.get(0).getAscent();2735 if (!getTextLayouts().isEmpty()) { 2736 final float ascent = getTextLayouts().get(0).getAscent(); 2793 2737 setY(anchor + ascent); 2794 } else if (this.getFont() != null) { 2738 } else if (this.getFont() != null) { 2795 2739 // p could be any character 2796 2740 final TextLayout fakeLayout = TextLayout.getManager().layoutStringSimple("p", this.getFont()); … … 2798 2742 EcosystemManager.getTextLayoutManager().releaseLayout(fakeLayout); 2799 2743 setY(anchor + ascent); 2800 } 2744 } 2801 2745 } 2802 2746 return; … … 2822 2766 super.setAnchorBottom(anchor); 2823 2767 if (anchor != null) { 2824 if (!_textLayouts.isEmpty()) { 2825 final float ascent = _textLayouts.get(0).getAscent(); 2826 final float descent = _textLayouts.get(0).getDescent(); 2827 setY(DisplayController.getFramePaintArea().getHeight() - (anchor + this.getBoundsHeight() - ascent - descent)); 2768 if (!getTextLayouts().isEmpty()) { 2769 final float ascent = getTextLayouts().get(0).getAscent(); 2770 final float descent = getTextLayouts().get(0).getDescent(); 2771 setY(DisplayController.getFramePaintArea().getHeight() 2772 - (anchor + this.getBoundsHeight() - ascent - descent)); 2828 2773 } else if (this.getFont() != null) { 2829 2774 // p could be any character … … 2831 2776 final float ascent = fakeLayout.getAscent(); 2832 2777 final float descent = fakeLayout.getDescent(); 2833 setY(DisplayController.getFramePaintArea().getHeight() - (anchor + this.getBoundsHeight() - ascent - descent)); 2834 } 2835 2778 setY(DisplayController.getFramePaintArea().getHeight() 2779 - (anchor + this.getBoundsHeight() - ascent - descent)); 2780 } 2781 2836 2782 } 2837 2783 return; … … 2866 2812 } 2867 2813 2868 protected AxisAlignedBoxBounds getPixelBounds(TextLayout layout) 2869 { 2814 protected AxisAlignedBoxBounds getPixelBounds(TextLayout layout) { 2870 2815 // Does 'layout' need to be synchronized (similar to _textLayouts below)?? 2871 2816 int x = getX(); … … 2877 2822 return layout_rect; 2878 2823 } 2879 2824 2880 2825 /** 2881 2826 * Creates the smallest possible rectangle object to enclose the Text Item … … 2887 2832 * @see #getPixelBoundsUnionTight() 2888 2833 */ 2889 public AxisAlignedBoxBounds getPixelBoundsUnion() 2890 { 2891 final AxisAlignedBoxBounds rect = getPixelBounds(_textLayouts.get(0)); 2834 public AxisAlignedBoxBounds getPixelBoundsUnion() { 2835 final AxisAlignedBoxBounds rect = getPixelBounds(getTextLayouts().get(0)); 2892 2836 2893 2837 int cumulativeHeight = rect.getSize().height; 2894 2838 int maxWidth = rect.getSize().width; 2895 2839 2896 if ( _textLayouts.size() > 1) {2897 for (int i = 1; i < _textLayouts.size(); i++) {2898 final AxisAlignedBoxBounds r = getPixelBounds( _textLayouts.get(i));2899 cumulativeHeight += _textLayouts.get(i).getDescent() + _textLayouts.get(i).getAscent();2840 if (getTextLayouts().size() > 1) { 2841 for (int i = 1; i < getTextLayouts().size(); i++) { 2842 final AxisAlignedBoxBounds r = getPixelBounds(getTextLayouts().get(i)); 2843 cumulativeHeight += getTextLayouts().get(i).getDescent() + getTextLayouts().get(i).getAscent(); 2900 2844 if (r.getSize().width > maxWidth) { 2901 2845 maxWidth = r.getSize().width; … … 2903 2847 } 2904 2848 } 2905 2849 2906 2850 rect.getSize().width = maxWidth; 2907 2851 rect.getSize().height = cumulativeHeight; … … 2918 2862 * @see #getPixelBoundsUnion() 2919 2863 */ 2920 public PolygonBounds getPixelBoundsUnionTight() 2921 { 2922 final AxisAlignedBoxBounds rect = getPixelBounds(_textLayouts.get(0)); 2923 if (_textLayouts.size() == 1) { 2864 public PolygonBounds getPixelBoundsUnionTight() { 2865 final AxisAlignedBoxBounds rect = getPixelBounds(getTextLayouts().get(0)); 2866 if (getTextLayouts().size() == 1) { 2924 2867 return PolygonBounds.fromBox(rect); 2925 2868 } else { … … 2927 2870 poly.addPoint(rect.getMinX(), rect.getMinY()); 2928 2871 poly.addPoint(rect.getMaxX(), rect.getMinY()); 2929 poly.addPoint(rect.getMaxX(), Math.round(rect.getMaxY() + _textLayouts.get(0).getDescent()));2930 int y = (int) (rect.getMaxY() + _textLayouts.get(0).getDescent());2931 for (int i = 1; i < _textLayouts.size(); i++) {2932 final AxisAlignedBoxBounds r = getPixelBounds( _textLayouts.get(i));2872 poly.addPoint(rect.getMaxX(), Math.round(rect.getMaxY() + getTextLayouts().get(0).getDescent())); 2873 int y = (int) (rect.getMaxY() + getTextLayouts().get(0).getDescent()); 2874 for (int i = 1; i < getTextLayouts().size(); i++) { 2875 final AxisAlignedBoxBounds r = getPixelBounds(getTextLayouts().get(i)); 2933 2876 poly.addPoint(r.getMaxX(), y); 2934 poly.addPoint(r.getMaxX(), Math.round(y + r.getHeight() + _textLayouts.get(i).getDescent())); 2935 y = Math.round(y + r.getHeight() + _textLayouts.get(i).getDescent()); 2936 } 2937 poly.addPoint(rect.getMinX() + getPixelBounds(_textLayouts.get(_textLayouts.size() - 1)).getWidth(), Math.round(y + _textLayouts.get(_textLayouts.size() - 1).getDescent())); 2938 poly.addPoint(rect.getMinX(), Math.round(y + _textLayouts.get(_textLayouts.size() - 1).getDescent())); 2877 poly.addPoint(r.getMaxX(), Math.round(y + r.getHeight() + getTextLayouts().get(i).getDescent())); 2878 y = Math.round(y + r.getHeight() + getTextLayouts().get(i).getDescent()); 2879 } 2880 poly.addPoint(rect.getMinX() + getPixelBounds(getTextLayouts().get(getTextLayouts().size() - 1)).getWidth(), 2881 Math.round(y + getTextLayouts().get(getTextLayouts().size() - 1).getDescent())); 2882 poly.addPoint(rect.getMinX(), Math.round(y + getTextLayouts().get(getTextLayouts().size() - 1).getDescent())); 2939 2883 return poly; 2940 2884 } 2941 2885 } 2942 2886 2943 2887 /* 2944 public AxisAlignedBoxBounds getPixelBoundsUnion() 2945 { 2946 synchronized (_textLayouts) { 2947 2948 CombinationBoxBounds c = null; 2949 2950 for (TextLayout layout: _textLayouts) { 2951 if (c == null) { 2952 c = new CombinationBoxBounds(getPixelBounds(layout)); 2953 } else { 2954 c.add(getPixelBounds(layout)); 2955 } 2956 } 2957 2958 return AxisAlignedBoxBounds.getEnclosing(c); 2959 2960 } 2961 } 2962 */ 2888 * public AxisAlignedBoxBounds getPixelBoundsUnion() { synchronized 2889 * (_textLayouts) { 2890 * 2891 * CombinationBoxBounds c = null; 2892 * 2893 * for (TextLayout layout: _textLayouts) { if (c == null) { c = new 2894 * CombinationBoxBounds(getPixelBounds(layout)); } else { 2895 * c.add(getPixelBounds(layout)); } } 2896 * 2897 * return AxisAlignedBoxBounds.getEnclosing(c); 2898 * 2899 * } } 2900 */ 2963 2901 2964 2902 // public Rectangle getPixelBoundsUnion() … … 3031 2969 3032 2970 /** 3033 * Creates a new Text Item whose text contains the given character. This 3034 * method also moves the mouse cursor to be pointing at the newly created3035 * Text Itemready to insert the next character.2971 * Creates a new Text Item whose text contains the given character. This method 2972 * also moves the mouse cursor to be pointing at the newly created Text Item 2973 * ready to insert the next character. 3036 2974 * 3037 2975 * @param start … … 3040 2978 */ 3041 2979 public static Text createText(char start) { 3042 Text t = DisplayController.getCurrentFrame().createBlankText( 3043 "" + start); 2980 Text t = DisplayController.getCurrentFrame().createBlankText("" + start); 3044 2981 3045 2982 Point newMouse = t.insertChar(start, DisplayController.getMouseX(), DisplayController.getMouseY()); … … 3050 2987 3051 2988 /** 3052 * Creates a new Text Item with no text. The newly created Item is a copy of 3053 * any ItemTemplate if one is present, and inherits all the attributes of3054 * theTemplate2989 * Creates a new Text Item with no text. The newly created Item is a copy of any 2990 * ItemTemplate if one is present, and inherits all the attributes of the 2991 * Template 3055 2992 * 3056 2993 * @return The newly created Text Item … … 3061 2998 3062 2999 /** 3063 * If the given Item is null, then a new Text item is created with the 3064 * current date. If the given Item is not null, then the current date is3065 * prepended tothe Item's text3000 * If the given Item is null, then a new Text item is created with the current 3001 * date. If the given Item is not null, then the current date is prepended to 3002 * the Item's text 3066 3003 * 3067 3004 * @param toAdd … … 3149 3086 } 3150 3087 } 3151 3152 public Integer getMask() { 3153 if (_mask == null) { return null; } 3154 else { return _mask; } 3155 } 3156 3157 public void setMask(final Integer c) { _mask = c; } 3088 3089 public Integer getMask() { 3090 if (_mask == null) { 3091 return null; 3092 } else { 3093 return _mask; 3094 } 3095 } 3096 3097 public void setMask(final Integer c) { 3098 _mask = c; 3099 } 3100 3101 protected List<TextLayout> getTextLayouts() { 3102 if (this.getMask() != null) { 3103 return _maskTextLayouts; 3104 } else { 3105 return _textLayouts; 3106 } 3107 } 3158 3108 }
Note:
See TracChangeset
for help on using the changeset viewer.