Ignore:
Timestamp:
01/30/19 12:57:45 (5 years ago)
Author:
bln4
Message:
 
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/expeditee/items/Text.java

    r1200 r1210  
    2727import java.util.List;
    2828import java.util.StringTokenizer;
     29import java.util.stream.Stream;
    2930
    3031import org.expeditee.core.Colour;
     
    6566public class Text extends Item {
    6667        private static final int ADJUST_WIDTH_THRESHOLD = 200;
    67        
     68
    6869        public static final char DELETE_CHARACTER = 0x7F;
    69        
     70
    7071        public static final char BACKSPACE_CHARACTER = '\b';
    71        
     72
    7273        public static final char TAB_CHARACTER = '\t';
    73        
     74
    7475        public static final char ESC_CHARACTER = 0x1B;
    7576
     
    130131         */
    131132        /**
    132          * The maximum allowable width of the Text item. Actual width may be less than this
    133          * value, subject to text wrapping. Negative values indicate the width was implicitly
    134          * set by the system, positive values indicate explicit setting by the user. Initially
    135          * 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.
    136137         */
    137138        private Integer _maxWidth = -Integer.MAX_VALUE;
    138        
     139
    139140        private Integer _minWidth = -Integer.MAX_VALUE;
    140141
     
    156157        /** Keeps track of the last Text item selected. */
    157158        private static Text _lastSelected = null;
    158        
     159
    159160        // Range selection colours
    160161        /** Colour of selected range when for selecting text. */
     
    166167        /** Colour of selected range when for deleting text. */
    167168        public static final Colour RANGE_DELETE_COLOUR = Colour.FromRGB255(235, 235, 140);
    168        
     169
    169170        /** The colour to draw range selections in. */
    170171        private Colour _selectionColour = RANGE_SELECT_COLOUR;
    171                
     172
    172173        // whether autowrap is on/off for this item
    173174        protected boolean _autoWrap = false;
     
    176177        protected StringBuffer _text = new StringBuffer();
    177178
    178         protected List<TextLayout> _textLayouts = new LinkedList<TextLayout>();
     179        private List<TextLayout> _textLayouts = new LinkedList<TextLayout>();
     180        private List<TextLayout> _maskTextLayouts = new LinkedList<TextLayout>();
    179181
    180182        // The font to display this text in
    181183        private Font _font;
    182        
     184
    183185        // The optional mask character to us in place of the text's content.
    184186        private Integer _mask = null;
    185187
    186         protected static void InitFontFamily(File fontFamilyDir)
    187         {
     188        protected static void InitFontFamily(File fontFamilyDir) {
    188189                File[] fontFiles = fontFamilyDir.listFiles();
    189190
     
    205206
    206207                                        if (font != null) {
    207                                            
    208                                             String font_family = font.getFamilyName();
    209                                             if (!FONT_WHEEL_ADDITIONAL_LOOKUP.containsKey(font_family)) {
     208
     209                                                String font_family = font.getFamilyName();
     210                                                if (!FONT_WHEEL_ADDITIONAL_LOOKUP.containsKey(font_family)) {
    210211
    211212                                                        if (FONT_WHEEL_ADDITIONAL_LOOKUP.size() > 0) {
     
    217218
    218219                                                        /*
    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                                                         */
    226225                                                        System.out.flush();
    227226                                                }
     
    255254                                        }
    256255                                }
    257                                 System.out.println();     
    258256                        }
    259257                }
     
    396394                invalidateAll();
    397395        }
    398        
     396
    399397        @Override
    400398        public void setMinWidth(final Integer width) {
    401399                invalidateAll();
    402                
     400
    403401                if (width == null) {
    404402                        setJustification(Justification.left);
     
    406404                        return;
    407405                }
    408                
     406
    409407                _minWidth = width;
    410408                rebuild(true);
     
    413411
    414412        /**
    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
    425420         *
    426421         * @return The maximum width of this Text item when justification is used
    427422         */
    428423        @Override
    429         public Integer getWidth()
    430         {
     424        public Integer getWidth() {
    431425                if (_maxWidth == null || _maxWidth <= 0) {
    432426                        return null;
    433427                }
    434                
     428
    435429                return _maxWidth;
    436430        }
     
    443437                return Math.abs(_maxWidth);
    444438        }
    445        
     439
    446440        public Integer getMinWidth() {
    447441                if (_minWidth == null || _minWidth <= 0) {
     
    450444                return _minWidth;
    451445        }
    452        
     446
    453447        public Integer getAbsoluteMinWidth() {
    454448                if (_minWidth == null) {
     
    495489         * @return The justification of this Text item
    496490         */
    497         public Justification getJustification()
    498         {
     491        public Justification getJustification() {
    499492                if (_justification == null || _justification.equals(Justification.left)) {
    500493                        return null;
    501494                }
    502                
     495
    503496                return _justification;
    504497        }
     
    509502         *
    510503         * @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.
    515507         */
    516508        private int getJustOffset(TextLayout layout) {
     
    587579         *            The String to insert.
    588580         */
    589         public void prependText(String text)
    590         {
     581        public void prependText(String text) {
    591582                invalidateAll();
    592583                _text.insert(0, text);
     
    731722
    732723        public Point getParagraphEndPosition() {
    733                 return getEdgePosition(_textLayouts.size() - 1, false);
     724                return getEdgePosition(getTextLayouts().size() - 1, false);
    734725        }
    735726
     
    740731        private Point getEdgePosition(int line, boolean start) {
    741732                // 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) {
    743734                        return new Point(getX(), getY());
    744735                }
    745736
    746                 TextLayout last = _textLayouts.get(line);
     737                TextLayout last = getTextLayouts().get(line);
    747738                TextHitInfo hit;
    748739                if (start) {
     
    758749                float x = getX() + caret[0] + getJustOffset(last);
    759750
    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()));
    764752                return new Point((int) x, (int) (getY() + y + caret[1]));
    765753        }
    766754
    767         public void setSelectionStart(Point p)
    768         {
     755        public void setSelectionStart(Point p) {
    769756                setSelectionStart(p.getX(), p.getY());
    770757        }
    771        
     758
    772759        public void setSelectionStart(float mouseX, float mouseY) {
    773760                // determine what line is being pointed to
     
    776763                // get the character being pointed to
    777764                TextHitInfo hit = getCharPosition(line, mouseX);
    778                 _selectionStart = hit.getInsertionIndex() + _textLayouts.get(line).getStartCharIndex();
    779                
     765                _selectionStart = hit.getInsertionIndex() + getTextLayouts().get(line).getStartCharIndex();
     766
    780767                // Clear the last selected
    781768                updateLastSelected();
    782                
    783                 invalidateAll();
    784         }
    785 
    786         public void setSelectionEnd(Point p)
    787         {
     769
     770                invalidateAll();
     771        }
     772
     773        public void setSelectionEnd(Point p) {
    788774                setSelectionEnd(p.getX(), p.getY());
    789775        }
     
    795781                // get the character being pointed to
    796782                TextHitInfo hit = getCharPosition(line, mouseX);
    797                 _selectionEnd = hit.getInsertionIndex() + _textLayouts.get(line).getStartCharIndex();
    798                
     783                _selectionEnd = hit.getInsertionIndex() + getTextLayouts().get(line).getStartCharIndex();
     784
    799785                // Clear the last selected
    800786                updateLastSelected();
    801                
     787
    802788                invalidateAll();
    803789        }
     
    813799                invalidateAll();
    814800        }
    815        
     801
    816802        /** Makes sure only one text has a selection at a time. */
    817         public void updateLastSelected()
    818         {
     803        public void updateLastSelected() {
    819804                if (_lastSelected != this) {
    820805                        if (_lastSelected != null) {
     
    904889         * @return The new location that the mouse cursor should be moved to
    905890         */
    906         public Point insertText(String text, float mouseX, float mouseY)
    907         {
     891        public Point insertText(String text, float mouseX, float mouseY) {
    908892                final Point newPos = insertText(text, mouseX, mouseY, -1);
    909893                return newPos;
    910894        }
    911895
    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)       {
    914897                TextHitInfo hit;
    915                 TextLayout current = null;
     898                TextLayout currentLayout = null;
    916899                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
    921903                if (text == null || text.length() == 0) {
    922904                        return new Point((int) mouseX, (int) mouseY);
    923905                }
    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)
    926910                if (_text == null || _text.length() == 0) {
    927911                        _text = new StringBuffer().append(text);
    928                         // create the linebreaker and layouts
    929912                        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);
    933917                        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                       
    937922                        clearCache();
    938923                        // determine what line is being pointed to
     
    942927                        hit = getCharPosition(lineIndex, mouseX);
    943928
    944                         int insertionIndex = hit.getInsertionIndex() + _textLayouts.get(lineIndex).getStartCharIndex();
     929                        int insertionIndex = hit.getInsertionIndex() + getTextLayouts().get(lineIndex).getStartCharIndex();
    945930
    946931                        if (lineIndex > 0 && hit.getInsertionIndex() == 0) {
     
    10331018                       
    10341019                        // 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) {
    10371022                                        newLine = i;
    10381023                                        break;
     
    10401025                        }
    10411026
    1042                         current = _textLayouts.get(newLine);
    1043                         insertionIndex -= current.getStartCharIndex();
     1027                        currentLayout = getTextLayouts().get(newLine);
     1028                        insertionIndex -= currentLayout.getStartCharIndex();
    10441029
    10451030                        if (newLine == lineIndex) {
    1046 //                              System.err.println("newLine == lineIndex");
    10471031                                if (insertionIndex > 0) {
    1048                                         hit = current.getNextRightHit(insertionIndex - 1);
     1032                                        hit = currentLayout.getNextRightHit(insertionIndex - 1);
    10491033                                } else {
    1050                                         hit = current.getNextLeftHit(1);
     1034                                        hit = currentLayout.getNextLeftHit(1);
    10511035                                }
    10521036                        } else if (newLine < lineIndex) {
    1053                                 hit = current.getNextRightHit(insertionIndex - 1);
     1037                                hit = currentLayout.getNextRightHit(insertionIndex - 1);
    10541038                        } else {
    1055                                 hit = current.getNextRightHit(insertionIndex - 1);
     1039                                hit = currentLayout.getNextRightHit(insertionIndex - 1);
    10561040                        }
    10571041
     
    10591043                }
    10601044               
    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;
    10921058        }
    10931059
     
    11131079        }
    11141080
    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) {
    11171082                if (setSelection) {
    11181083                        if (!hasSelection()) {
     
    11521117                                line = getLinePosition(mouseY);
    11531118                                if (line < 0) {
    1154                                         line = _textLayouts.size() - 1;
     1119                                        line = getTextLayouts().size() - 1;
    11551120                                }
    11561121
     
    11591124                                        line = Math.max(line - 1, 0);
    11601125                                } else if (direction == DOWN) {
    1161                                         line = Math.min(line + 1, _textLayouts.size() - 1);
     1126                                        line = Math.min(line + 1, getTextLayouts().size() - 1);
    11621127                                }
    11631128
     
    11691134                                                char prevChar = ' ';
    11701135                                                do {
    1171                                                         hit = _textLayouts.get(line).getNextLeftHit(hit);
     1136                                                        hit = getTextLayouts().get(line).getNextLeftHit(hit);
    11721137
    11731138                                                        // Stop if at the start of the line
     
    11771142                                                        // Keep going if the char to the left is a
    11781143                                                        // letterOrDigit
    1179                                                         prevChar = _text.charAt(hit.getInsertionIndex() - 1 + _textLayouts.get(line).getStartCharIndex());
     1144                                                        prevChar = _text
     1145                                                                        .charAt(hit.getInsertionIndex() - 1 + getTextLayouts().get(line).getStartCharIndex());
    11801146                                                } while (wholeWord && Character.isLetterOrDigit(prevChar));
    1181                                                
     1147
    11821148                                                // 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
    11851152                                                // This takes care of hard line break in
    11861153                                                if (line > 0 && nextChar == '\n') {
    11871154                                                        line--;
    1188                                                         hit = _textLayouts.get(line).getNextRightHit(_textLayouts.get(line).getCharacterCount() - 1);
     1155                                                        hit = getTextLayouts().get(line)
     1156                                                                        .getNextRightHit(getTextLayouts().get(line).getCharacterCount() - 1);
    11891157                                                }
    1190                                                
    1191                                         // This takes care of soft line breaks.
     1158
     1159                                                // This takes care of soft line breaks.
    11921160                                        } else if (line > 0) {
    11931161                                                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
    11961164                                                // 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);
    11991168                                                }
    12001169                                        }
    12011170                                } 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);
    12041173                                                // 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);
    12111179                                                }
    1212                                         } else if (line < _textLayouts.size() - 1) {
     1180                                        } else if (line < getTextLayouts().size() - 1) {
    12131181                                                line++;
    1214                                                 hit = _textLayouts.get(line).getNextLeftHit(1);
     1182                                                hit = getTextLayouts().get(line).getNextLeftHit(1);
    12151183                                        }
    12161184                                }
    1217                                 current = _textLayouts.get(line);
     1185                                current = getTextLayouts().get(line);
    12181186                        }
    12191187
     
    12261194                        break;
    12271195                }
    1228                
     1196
    12291197                if (setSelection) {
    12301198                        setSelectionEnd(resultPos.getX(), resultPos.getY());
    12311199                }
    1232                
     1200
    12331201                return resultPos;
    12341202        }
     
    12441212         * @return The position in the string of the character being pointed at.
    12451213         */
    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()) {
    12481216                        return null;
    12491217                }
    1250 
    1251                 TextLayout layout = _textLayouts.get(line);
     1218               
     1219                final TextLayout layout = getTextLayouts().get(line);
    12521220                mouseX += getOffset().getX();
    12531221                mouseX -= getJustOffset(layout);
     
    12571225
    12581226        /**
    1259          * Gets the index into the <code>_textLayout</code> list which corresponds to the line
    1260          * 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.
    12611229         *
    12621230         * @param mouseY
    1263          *              The y-coordinate to test for line coverage.
    1264          *
    1265          * @return
    1266          *              The line which occupies the given y-coordinate, or the last line if none 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.
    12671235         */
    12681236        public int getLinePosition(float mouseY) {
     
    12711239                float y = getY();
    12721240
    1273                 for (TextLayout text : _textLayouts) {
     1241                for (TextLayout text : getTextLayouts()) {
    12741242                        // calculate X to ensure it is in the shape
    12751243                        AxisAlignedBoxBounds bounds = text.getLogicalHighlightShape(0, text.getCharacterCount());
     
    12821250
    12831251                        if (bounds.contains((int) x, (int) (mouseY - y))) {
    1284                                 return _textLayouts.indexOf(text);
     1252                                return getTextLayouts().indexOf(text);
    12851253                        }
    12861254
    12871255                        // check if the cursor is between lines
    12881256                        if (mouseY - y < bounds.getMinY()) {
    1289                                 return Math.max(0, _textLayouts.indexOf(text) - 1);
     1257                                return Math.max(0, getTextLayouts().indexOf(text) - 1);
    12901258                        }
    12911259
     
    12931261                }
    12941262
    1295                 return _textLayouts.size() - 1;
     1263                return getTextLayouts().size() - 1;
    12961264        }
    12971265
     
    13021270         *            The Font to display the Text of this Item in.
    13031271         */
    1304         public void setFont(Font font)
    1305         {
    1306                 invalidateAll();
    1307                
     1272        public void setFont(Font font) {
     1273                invalidateAll();
     1274
    13081275                _font = font;
    13091276
     
    13271294         * @return The font to paint the text item with.
    13281295         */
    1329         public Font getPaintFont()
    1330         {
     1296        public Font getPaintFont() {
    13311297                final Font f = getFont();
    13321298                if (f == null) {
    1333                         _font = EcosystemManager.getFontManager().getDefaultFont().clone(); 
     1299                        _font = EcosystemManager.getFontManager().getDefaultFont().clone();
    13341300                        return _font;
    13351301                }
     
    13411307        }
    13421308
    1343         public void setFamily(String newFamily)
    1344         {
     1309        public void setFamily(String newFamily) {
    13451310                setFont(new Font(newFamily, getFontStyle(), Math.round(getSize())));
    13461311
     
    13861351                Font.Style newStyle = Font.Style.PLAIN;
    13871352                switch (currentStyle) {
    1388                         case PLAIN:
    1389                                 newStyle = Font.Style.BOLD;
    1390                                 break;
    1391                         case BOLD:
    1392                                 newStyle = Font.Style.ITALIC;
    1393                                 break;
    1394                         case ITALIC:
    1395                                 newStyle = Font.Style.BOLD_ITALIC;
    1396                                 break;
    1397                         default:
    1398                                 newStyle = Font.Style.PLAIN;
    1399                                 break;
     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;
    14001365                }
    14011366                setFont(new Font(currentFont.getFamilyName(), newStyle, currentFont.getSize()));
     
    14081373                Font currentFont = getPaintFont();
    14091374                currentFont.toggleBold();
    1410                 //setFont(currentFont);
     1375                // setFont(currentFont);
    14111376                rebuild(true);
    14121377                invalidateAll();
     
    14171382                Font currentFont = getPaintFont();
    14181383                currentFont.toggleItalic();
    1419                 //setFont(currentFont);
     1384                // setFont(currentFont);
    14201385                rebuild(true);
    14211386                invalidateAll();
    14221387        }
    14231388
    1424         public void setFontStyle(String newFace)
    1425         {
     1389        public void setFontStyle(String newFace) {
    14261390                Font currentFont = getPaintFont();
    14271391                if (newFace == null || newFace.trim().length() == 0) {
    14281392                        currentFont.setStyle(Font.Style.PLAIN);
    1429                         //setFont(currentFont);
     1393                        // setFont(currentFont);
    14301394                        return;
    14311395                }
     
    14391403                } else if (newFace.equals("italic") || newFace.equals("i")) {
    14401404                        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")) {
    14421407                        currentFont.setStyle(Font.Style.BOLD_ITALIC);
    14431408                }
    1444                
    1445                 //setFont(currentFont);
     1409
     1410                // setFont(currentFont);
    14461411
    14471412        }
     
    14611426
    14621427                        // Rebuilding prevents errors when displaying frame bitmaps
    1463                         if (_textLayouts.size() == 0) {
     1428                        if (getTextLayouts().size() == 0) {
    14641429                                rebuild(false);
    14651430                        }
    14661431
    1467                         for (TextLayout layout : _textLayouts) {
     1432                        for (TextLayout layout : getTextLayouts()) {
    14681433                                String text = layout.getLine().replaceAll("\n", "");
    14691434                                if (!text.equals("")) {
     
    14741439                        return list;
    14751440                } catch (Exception e) {
    1476                         System.out.println(e.getMessage());
     1441                        System.out.println("Exception in Text::getTextList::message is: " + e.getMessage());
    14771442                        return null;
    14781443                }
     
    15341499         *
    15351500         * @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) {
    15431506                if (getSpacing() < 0) {
    15441507                        return layout.getAscent() + layout.getDescent() + layout.getLeading();
     
    15681531                Font currentFont = getPaintFont();
    15691532                currentFont.setSpacing(spacing);
    1570                 //setFont(currentFont);
     1533                // setFont(currentFont);
    15711534        }
    15721535
     
    15881551
    15891552        // @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         */
    16061565
    16071566        // The following version of intersect uses a tighter definition for the text,
     
    16121571                        // float textY = getY();
    16131572
    1614                         for (TextLayout text : _textLayouts) {
     1573                        for (TextLayout text : getTextLayouts()) {
    16151574
    16161575                                AxisAlignedBoxBounds text_pixel_bounds_rect = getPixelBounds(text);
     
    16291588                return contains(mousePosition.getX(), mousePosition.getY(), getGravity() * NEARBY_GRAVITY);
    16301589        }
    1631        
    1632         public boolean contains(int mouseX, int mouseY)
    1633         {
     1590
     1591        public boolean contains(int mouseX, int mouseY) {
    16341592                return contains(new Point(mouseX, mouseY));
    16351593        }
    16361594
    1637         public boolean contains(int mouseX, int mouseY, int gravity)
    1638         {
     1595        public boolean contains(int mouseX, int mouseY, int gravity) {
    16391596                mouseX += getOffset().getX();
    16401597                mouseY += getOffset().getY();
     
    16441601
    16451602                AxisAlignedBoxBounds outline = getBoundingBox();
    1646                
     1603
    16471604                if (outline == null) {
    16481605                        return false;
     
    16501607
    16511608                // 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
    16541610                                || mouseY - (outline.getMinY() + outline.getHeight()) > gravity
    16551611                                || mouseX - (outline.getMinX() + outline.getWidth()) > gravity) {
    16561612                        return false;
    16571613                }
    1658                
    1659                 if (this.getMinWidth() != null && outline.contains(mouseX,  mouseY)) {
     1614
     1615                if (this.getMinWidth() != null && outline.contains(mouseX, mouseY)) {
    16601616                        return true;
    16611617                }
    16621618
    1663                 for (TextLayout text : _textLayouts) {
     1619                for (TextLayout text : getTextLayouts()) {
    16641620                        // check left and right of each box
    16651621                        AxisAlignedBoxBounds textOutline = text.getLogicalHighlightShape(0, text.getCharacterCount());
     
    16681624                        // gravity of right
    16691625                        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) {
    16751630                                return true;
    16761631                        }
    1677                        
     1632
    16781633                        textY += getLineDrop(text);
    16791634                }
     
    16861641         */
    16871642        @Override
    1688         public AxisAlignedBoxBounds updateBounds()
    1689         {
     1643        public AxisAlignedBoxBounds updateBounds() {
     1644                boolean isFakeLayout = false;
    16901645                // if there is no text, there is nothing to do
    16911646                if (_text == null) {
     
    16941649
    16951650                // 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)) {
    16971652                        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                }
    16991659
    17001660                int preChangeWidth = 0;
     
    17101670
    17111671                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                 }
    17221672
    17231673                // Fix concurrency error in ScaleFrameset
    17241674                List<TextLayout> tmpTextLayouts;
    1725                 synchronized (_textLayouts) {
    1726                         tmpTextLayouts = new LinkedList<TextLayout>(_textLayouts);
     1675                synchronized (getTextLayouts()) {
     1676                        tmpTextLayouts = new LinkedList<TextLayout>(getTextLayouts());
    17271677                }
    17281678
     
    17331683                        if (y < 0) {
    17341684                                y = 0;
    1735                         } else { 
     1685                        } else {
    17361686                                y += getLineDrop(layout);
    17371687                        }
    1738                        
     1688
    17391689                        int minWidth = getAbsoluteMinWidth();
    17401690
    17411691                        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())
    17441693                                        : Math.max(maxX, bounds.getMaxX());
    17451694                        minY = Math.min(minY, (int) (bounds.getMinY() + y));
     
    17601709                final int height = 2 * getGravity() + maxY - minY;
    17611710                AxisAlignedBoxBounds ret = new AxisAlignedBoxBounds(xPos, yPos, width, height);
    1762                
     1711
    17631712                Dimension polySize = ret.getSize();
    1764                                                
    1765                 if(preChangeWidth != 0 && preChangeWidth != polySize.width) {
     1713
     1714                if (preChangeWidth != 0 && preChangeWidth != polySize.width) {
    17661715                        if (polySize.width > preChangeWidth) {
    17671716                                MagneticConstraints.getInstance().textGrown(this, polySize.width - preChangeWidth);
     
    17701719                        }
    17711720                }
    1772                
     1721
     1722                if (isFakeLayout) {
     1723                        getTextLayouts().remove(0).release();
     1724                }
     1725
    17731726                return ret;
    17741727        }
     
    17881741         */
    17891742        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
    17911745                if (isAnnotation()) {
    17921746                        Frame parent = getParent();
     
    18051759                }
    18061760
    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();
    18101768                }
    18111769
    18121770                // Calculate the maximum allowable width of this line of text
    18131771                List<org.expeditee.core.Line> lines = null;
    1814                 if(_autoWrap || ExperimentalFeatures.AutoWrap.get()) {
     1772                if (_autoWrap || ExperimentalFeatures.AutoWrap.get()) {
    18151773                        lines = new LinkedList<org.expeditee.core.Line>();
    1816                 if(DisplayController.getCurrentFrame() == null) {
    1817                         return;
    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                }
    18401798
    18411799                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
    18641834                invalidateBounds();
    18651835        }
    18661836
    18671837        /**
    1868          * Calculates the maximum possible distance a line can extend to the right from a given (x,y) point
    1869          * 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.
    18701840         *
    18711841         * @param x
    1872          *              The x-coordinate of the beginning point.
     1842         *            The x-coordinate of the beginning point.
    18731843         *
    18741844         * @param y
    1875          *              The y-coordinate of the beginning point.
     1845         *            The y-coordinate of the beginning point.
    18761846         *
    18771847         * @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         */
    19101865
    19111866        private boolean hasFixedWidth() {
     
    19401895
    19411896                // if the selection is after this line, return null
    1942                 if (_textLayouts.get(line).getStartCharIndex() > selectionRight) {
     1897                if (getTextLayouts().get(line).getStartCharIndex() > selectionRight) {
    19431898                        return null;
    19441899                }
    19451900
    19461901                // if the selection is before this line, return null
    1947                 if (_textLayouts.get(line).getEndCharIndex() < selectionLeft) {
     1902                if (getTextLayouts().get(line).getEndCharIndex() < selectionLeft) {
    19481903                        return null;
    19491904                }
     
    19551910                // the selection occurs on this line, determine where it lies on the
    19561911                // line
    1957                 int start = Math.max(0, selectionLeft - _textLayouts.get(line).getStartCharIndex());
     1912                int start = Math.max(0, selectionLeft - getTextLayouts().get(line).getStartCharIndex());
    19581913                // int end = Math.min(_lineOffsets.get(line) +
    19591914                // _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());
    19611917
    19621918                // System.out.println(line + ": " + start + "x" + end + " (" +
     
    19661922
    19671923        /** 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) {
    19701925                if (colour == null) {
    19711926                        colour = RANGE_SELECT_COLOUR;
    19721927                }
    1973                
     1928
    19741929                _selectionColour = colour;
    19751930        }
    1976        
     1931
    19771932        /** Gets the colour that should be used to render the selected range. */
    1978         public Colour getSelectionColour()
    1979         {
     1933        public Colour getSelectionColour() {
    19801934                return _selectionColour;
    19811935        }
    19821936
    19831937        @Override
    1984         public void paint()
    1985         {
     1938        public void paint() {
    19861939                if (!isVisible()) {
    19871940                        return;
     
    19921945                        return;
    19931946                }
    1994                
     1947
    19951948                // if the text to paint is empty string and there is no min width, do nothing.
    19961949                if ((_text.length() == 0 && getMinWidth() == null)) {
     
    20021955
    20031956                        rebuild(true);
    2004                 } else if (_textLayouts.size() < 1) {
     1957                } else if (getTextLayouts().size() < 1) {
    20051958                        clipFrameMargin();
    20061959                        rebuild(true);
    20071960                        // return;
    20081961                }
    2009                
     1962
    20101963                // check if its a vector item and paint all the vector stuff too if this
    20111964                // item is a free item
     
    20171970                        // associated vector
    20181971                }
    2019                
     1972
    20201973                GraphicsManager g = EcosystemManager.getGraphicsManager();
    20211974                AxisAlignedBoxBounds bounds = (AxisAlignedBoxBounds) getBounds();
     
    20251978                        Colour bgc = getBackgroundColor();
    20261979                        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));
    20291981                        }
    20301982
    20311983                        Colour gradientColor = getGradientColor();
    2032                        
     1984
    20331985                        Fill fill;
    2034                        
     1986
    20351987                        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()));
    20371991                        } else {
    20381992                                fill = new Fill(bgc);
     
    20542008                }
    20552009
    2056                 if (isHighlighted()) {
     2010                if (isHighlighted()) {                 
    20572011                        Stroke highlightStroke = new Stroke(getHighlightThickness(), DEFAULT_CAP, DEFAULT_JOIN);
    20582012                        Fill fill;
     
    20702024                        paintColour = new Colour(paintColour);
    20712025                        paintColour.setAlpha(Colour.FromComponent255(_alpha));
    2072                        
     2026
    20732027                }
    20742028
     
    20782032                // int line = 0;
    20792033                // 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);
    20832037
    20842038                                Range<Integer> selectedRange = getSelectedRange(i);
    20852039                                if (selectedRange != null) {
    2086                                         AxisAlignedBoxBounds highlight = layout.getLogicalHighlightShape(selectedRange.lowerBound, selectedRange.upperBound);
     2040                                        AxisAlignedBoxBounds highlight = layout.getLogicalHighlightShape(selectedRange.lowerBound,
     2041                                                        selectedRange.upperBound);
    20872042                                        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                                }
    20952049                                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);
    21032051
    21042052                                y += getLineDrop(layout);
    21052053                        }
    21062054                }
    2107                
     2055
    21082056                paintLink();
    21092057        }
     
    21112059        // TODO: Revise
    21122060        @Override
    2113         protected AxisAlignedBoxBounds getLinkDrawArea()
    2114         {
     2061        protected AxisAlignedBoxBounds getLinkDrawArea() {
    21152062                return getDrawingArea();
    21162063        }
     
    21212068         * @return True if this Item has no text in it, false otherwise.
    21222069         */
    2123         public boolean isEmpty()
    2124         {
     2070        public boolean isEmpty() {
    21252071                return (_text == null || _text.length() == 0);
    21262072        }
     
    21812127                Font currentFont = getPaintFont();
    21822128                currentFont.setSize((int) size);
    2183                 //setFont(currentFont);
     2129                // setFont(currentFont);
    21842130                rebuild(true);
    21852131                invalidateAll();
     
    22372183                if (_text.length() == 0) {
    22382184                        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();
    22422188                        }
    22432189                        if (this.isLineEnd()) {
     
    24012347                        float textX = getX();
    24022348
    2403                         for (TextLayout text : _textLayouts) {
     2349                        for (TextLayout text : getTextLayouts()) {
    24042350                                // check left and right of each box
    24052351                                AxisAlignedBoxBounds textOutline = text.getLogicalHighlightShape(0, text.getCharacterCount());
     
    24072353                                // check if the cursor is within the top, bottom and within the
    24082354                                // 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) {
    24132358                                        return true;
    24142359                                }
    2415                                
     2360
    24162361                                textY += getLineDrop(text);
    24172362                        }
     
    24602405        public void justify(boolean fixWidth, PolygonBounds enclosure) {
    24612406                // if autowrap is on, wrapping is done every time we draw
    2462                 if(ExperimentalFeatures.AutoWrap.get()) {
     2407                if (ExperimentalFeatures.AutoWrap.get()) {
    24632408                        return;
    24642409                }
     
    24962441        public void justify(boolean fixWidth) {
    24972442                // if autowrap is on, wrapping is done every time we draw
    2498                 if(ExperimentalFeatures.AutoWrap.get()) {
     2443                if (ExperimentalFeatures.AutoWrap.get()) {
    24992444                        return;
    25002445                }
     
    25132458        @Override
    25142459        protected int getLinkYOffset() {
    2515                 if (_textLayouts.size() == 0) {
     2460                if (getTextLayouts().size() == 0) {
    25162461                        return 0;
    25172462                }
    2518                 return Math.round(-(_textLayouts.get(0).getAscent() / 2));
     2463                return Math.round(-(getTextLayouts().get(0).getAscent() / 2));
    25192464        }
    25202465
     
    27292674
    27302675        public float getLineHeight() {
    2731                 return getLineDrop(_textLayouts.get(0));
     2676                return getLineDrop(getTextLayouts().get(0));
    27322677        }
    27332678
     
    27632708                        // Subtract off the link width
    27642709                        if (anchor != null) {
    2765                                 setX(DisplayController.getFramePaintArea().getWidth() - anchor
    2766                                                 - getBoundsWidth() + getLeftMargin());
     2710                                setX(DisplayController.getFramePaintArea().getWidth() - anchor - getBoundsWidth() + getLeftMargin());
    27672711                        }
    27682712                        return;
     
    27752719                int oldX = getX();
    27762720                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;
    27792723                        anchorConnected(AnchorEdgeType.Right, deltaX);
    27802724                }
     
    27862730        @Override
    27872731        public void setAnchorTop(Integer anchor) {
    2788                 if (!isLineEnd()) {                     
     2732                if (!isLineEnd()) {
    27892733                        super.setAnchorTop(anchor);
    27902734                        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();
    27932737                                        setY(anchor + ascent);
    2794                                 } else if (this.getFont() != null) {           
     2738                                } else if (this.getFont() != null) {
    27952739                                        // p could be any character
    27962740                                        final TextLayout fakeLayout = TextLayout.getManager().layoutStringSimple("p", this.getFont());
     
    27982742                                        EcosystemManager.getTextLayoutManager().releaseLayout(fakeLayout);
    27992743                                        setY(anchor + ascent);
    2800                                 } 
     2744                                }
    28012745                        }
    28022746                        return;
     
    28222766                        super.setAnchorBottom(anchor);
    28232767                        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));
    28282773                                } else if (this.getFont() != null) {
    28292774                                        // p could be any character
     
    28312776                                        final float ascent = fakeLayout.getAscent();
    28322777                                        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
    28362782                        }
    28372783                        return;
     
    28662812        }
    28672813
    2868         protected AxisAlignedBoxBounds getPixelBounds(TextLayout layout)
    2869         {
     2814        protected AxisAlignedBoxBounds getPixelBounds(TextLayout layout) {
    28702815                // Does 'layout' need to be synchronized (similar to _textLayouts below)??
    28712816                int x = getX();
     
    28772822                return layout_rect;
    28782823        }
    2879        
     2824
    28802825        /**
    28812826         * Creates the smallest possible rectangle object to enclose the Text Item
     
    28872832         * @see #getPixelBoundsUnionTight()
    28882833         */
    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));
    28922836
    28932837                int cumulativeHeight = rect.getSize().height;
    28942838                int maxWidth = rect.getSize().width;
    28952839
    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();
    29002844                                if (r.getSize().width > maxWidth) {
    29012845                                        maxWidth = r.getSize().width;
     
    29032847                        }
    29042848                }
    2905                
     2849
    29062850                rect.getSize().width = maxWidth;
    29072851                rect.getSize().height = cumulativeHeight;
     
    29182862         * @see #getPixelBoundsUnion()
    29192863         */
    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) {
    29242867                        return PolygonBounds.fromBox(rect);
    29252868                } else {
     
    29272870                        poly.addPoint(rect.getMinX(), rect.getMinY());
    29282871                        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));
    29332876                                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()));
    29392883                        return poly;
    29402884                }
    29412885        }
    2942        
     2886
    29432887        /*
    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         */
    29632901
    29642902        // public Rectangle getPixelBoundsUnion()
     
    30312969
    30322970        /**
    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 created
    3035          * Text Item ready 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.
    30362974         *
    30372975         * @param start
     
    30402978         */
    30412979        public static Text createText(char start) {
    3042                 Text t = DisplayController.getCurrentFrame().createBlankText(
    3043                                 "" + start);
     2980                Text t = DisplayController.getCurrentFrame().createBlankText("" + start);
    30442981
    30452982                Point newMouse = t.insertChar(start, DisplayController.getMouseX(), DisplayController.getMouseY());
     
    30502987
    30512988        /**
    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 of
    3054          * the Template
     2989         * 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
    30552992         *
    30562993         * @return The newly created Text Item
     
    30612998
    30622999        /**
    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 is
    3065          * prepended to the Item's text
     3000         * 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
    30663003         *
    30673004         * @param toAdd
     
    31493086                }
    31503087        }
    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        }
    31583108}
Note: See TracChangeset for help on using the changeset viewer.