|
29 | 29 | import java.lang.reflect.InvocationTargetException;
|
30 | 30 | import java.text.MessageFormat;
|
31 | 31 | import java.util.ArrayList;
|
| 32 | +import java.util.Collections; |
32 | 33 | import java.util.HashMap;
|
33 | 34 | import java.util.Iterator;
|
34 | 35 | import java.util.List;
|
@@ -474,6 +475,12 @@ private static RGB interpolate(RGB fg, RGB bg, double scale) {
|
474 | 475 | private IUndoableOperation copyUndoable = null;
|
475 | 476 | private IOperationHistoryListener operationHistoryListener;
|
476 | 477 |
|
| 478 | + // https://github.com/eclipse-platform/eclipse.platform.ui/issues/2143 |
| 479 | + // calling w.getLineHeight(line) + w.getLineSpacing() + |
| 480 | + // w.getLineVerticalIndent(line); again and again for the same line is too slow |
| 481 | + // we therefore introduce a line height cache by viewer |
| 482 | + private final Map<MergeSourceViewer, List<Integer>> lineHeightsByViewer = new HashMap<>(); |
| 483 | + |
477 | 484 | /**
|
478 | 485 | * Preference key for highlighting current line.
|
479 | 486 | */
|
@@ -4001,6 +4008,16 @@ && getCompareConfiguration().getContainer().getActionBars() != null) {
|
4001 | 4008 |
|
4002 | 4009 | @Override
|
4003 | 4010 | protected void handlePropertyChangeEvent(PropertyChangeEvent event) {
|
| 4011 | + |
| 4012 | + // Property changes might change the height of lines, |
| 4013 | + // which means the heights cache should be cleared. |
| 4014 | + // But the actual height change of lines in StyledText does not happen in this |
| 4015 | + // method. |
| 4016 | + // There are other property change listeners for example: |
| 4017 | + // AbstractTextEditor.PropertyChangeListener, |
| 4018 | + // and these handle the height changes of StyledText. |
| 4019 | + lineHeightsByViewer.clear(); |
| 4020 | + |
4004 | 4021 | String key= event.getProperty();
|
4005 | 4022 |
|
4006 | 4023 | if (key.equals(CompareConfiguration.IGNORE_WHITESPACE)
|
@@ -4206,9 +4223,29 @@ private void updateLines(IDocument d) {
|
4206 | 4223 | */
|
4207 | 4224 | private int getHeightBetweenLines(MergeSourceViewer tp, int fromLine, int toLine) {
|
4208 | 4225 | StyledText w = tp.getSourceViewer().getTextWidget();
|
| 4226 | + List<Integer> lineHeights = this.lineHeightsByViewer.get(tp); |
| 4227 | + if (lineHeights == null) { |
| 4228 | + lineHeights = new ArrayList<>(); |
| 4229 | + lineHeights.addAll(Collections.nCopies(w.getLineCount(), null)); |
| 4230 | + this.lineHeightsByViewer.put(tp, lineHeights); |
| 4231 | + tp.getSourceViewer().addTextListener(event -> { |
| 4232 | + List<Integer> lineHeightsList = lineHeightsByViewer.get(tp); |
| 4233 | + if (lineHeightsList != null) { |
| 4234 | + lineHeightsList.clear(); |
| 4235 | + lineHeightsList.addAll(Collections.nCopies(w.getLineCount(), null)); |
| 4236 | + } |
| 4237 | + }); |
| 4238 | + } |
| 4239 | + int lineSpacing = w.getLineSpacing(); |
4209 | 4240 | int height = 0;
|
4210 | 4241 | for (int i = fromLine; i < toLine; i++) {
|
4211 |
| - height += w.getLineHeight(i) + w.getLineSpacing() + w.getLineVerticalIndent(i); |
| 4242 | + Integer heightAtLine = lineHeights.get(i); |
| 4243 | + if (heightAtLine == null) { |
| 4244 | + int lineOffset = w.getOffsetAtLine(i); |
| 4245 | + heightAtLine = w.getLineHeight(lineOffset) + lineSpacing + w.getLineVerticalIndent(i); |
| 4246 | + lineHeights.set(i, heightAtLine); |
| 4247 | + } |
| 4248 | + height += heightAtLine; |
4212 | 4249 | }
|
4213 | 4250 | return height;
|
4214 | 4251 | }
|
|
0 commit comments