Better "wave" underscore
authorVassiliy.Kudryashov <Vassiliy.Kudryashov@jetbrains.com>
Tue, 30 Dec 2014 13:44:51 +0000 (16:44 +0300)
committerVassiliy.Kudryashov <Vassiliy.Kudryashov@jetbrains.com>
Tue, 30 Dec 2014 13:46:14 +0000 (16:46 +0300)
platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
platform/util/src/com/intellij/util/ui/UIUtil.java

index 2e24a9f70e018babf6795d9a6fa2c09df15c5eea..3a3037930c854f8c69897c7dd5968bac3db2dde4 100644 (file)
@@ -19,10 +19,8 @@ import com.intellij.ide.BrowserUtil;
 import com.intellij.openapi.application.Application;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.ui.GraphicsConfig;
 import com.intellij.openapi.util.SystemInfo;
 import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.util.ui.GraphicsUtil;
 import com.intellij.util.ui.JBInsets;
 import com.intellij.util.ui.JBUI;
 import com.intellij.util.ui.UIUtil;
@@ -39,8 +37,6 @@ import javax.swing.*;
 import javax.swing.border.Border;
 import javax.swing.tree.TreeCellRenderer;
 import java.awt.*;
-import java.awt.geom.GeneralPath;
-import java.awt.geom.PathIterator;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -686,25 +682,10 @@ public class SimpleColoredComponent extends JComponent implements Accessible, Co
       }
       // 2. Waved effect
       if (attributes.isWaved()) {
-        GraphicsConfig config = GraphicsUtil.setupAAPainting(g);
-        Stroke oldStroke = g.getStroke();
-        try {
-          g.setStroke(new BasicStroke(.7F));
-          if (attributes.getWaveColor() != null) {
-            g.setColor(attributes.getWaveColor());
-          }
-          final int wavedAt = textBaseline + 1;
-          GeneralPath wavePath = new GeneralPath(PathIterator.WIND_EVEN_ODD);
-          wavePath.moveTo(offset, wavedAt);
-          for (int x = offset; x <= offset + fragmentWidth; x += 4) {
-            wavePath.lineTo(x + 2, wavedAt + 2);
-            wavePath.lineTo(x + 4, wavedAt);
-          }
-          g.draw(wavePath);
-        } finally {
-          config.restore();
-          g.setStroke(oldStroke);
+        if (attributes.getWaveColor() != null) {
+          g.setColor(attributes.getWaveColor());
         }
+        UIUtil.drawWave(g, new Rectangle(offset, textBaseline + 1, fragmentWidth, Math.max(2, metrics.getDescent())));
       }
       // 3. Underline
       if (attributes.isUnderline()) {
index 52cdc8c558e291bdf6d7000aa6d03072aa15c833..df63157b40086e41b7a7e777523cf464de073881 100644 (file)
@@ -1713,7 +1713,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
     else {
       endVisLine = offsetToVisualLine(myDocument.getLineEndOffset(Math.min(myDocument.getLineCount() - 1, endLine)));
     }
-    int height = endVisLine * getLineHeight() - yStartLine + getLineHeight() + WAVE_HEIGHT;
+    int height = endVisLine * getLineHeight() - yStartLine + getLineHeight() + 2;
 
     myEditorComponent.repaintEditorComponent(visibleArea.x, yStartLine, visibleArea.x + visibleArea.width, height);
     myGutterComponent.repaint(0, yStartLine, myGutterComponent.getWidth(), height);
@@ -2236,7 +2236,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
         int y = visibleLineToY(visibleStartLine) + getAscent() + 1;
         g.setColor(attributes.getEffectColor());
         if (attributes.getEffectType() == EffectType.WAVE_UNDERSCORE) {
-          drawWave(g, end.x, end.x + charWidth - 1, y);
+          UIUtil.drawWave((Graphics2D)g, new Rectangle(end.x, y, end.x + charWidth - 1, 2));
         }
         else if (attributes.getEffectType() == EffectType.BOLD_DOTTED_LINE) {
           final int dottedAt = SystemInfo.isMac ? y - 1 : y;
@@ -3368,7 +3368,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
       }
       else if (effectType == EffectType.WAVE_UNDERSCORE) {
         g.setColor(effectColor);
-        drawWave(g, xStart, xEnd, y + 1);
+        UIUtil.drawWave((Graphics2D)g, new Rectangle(xStart, y+1, xEnd - xStart, getDescent() - 1));
         g.setColor(savedColor);
       }
       else if (effectType == EffectType.BOLD_DOTTED_LINE) {
@@ -3515,25 +3515,6 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
     }
   }
 
-  private static final int WAVE_HEIGHT = 2;
-  private static final int WAVE_SEGMENT_LENGTH = 4;
-
-  private static void drawWave(Graphics g, int xStart, int xEnd, int y) {
-    int startSegment = xStart / WAVE_SEGMENT_LENGTH;
-    int endSegment = xEnd / WAVE_SEGMENT_LENGTH;
-    for (int i = startSegment; i < endSegment; i++) {
-      drawWaveSegment(g, WAVE_SEGMENT_LENGTH * i, y);
-    }
-
-    int x = WAVE_SEGMENT_LENGTH * endSegment;
-    UIUtil.drawLine(g, x, y + WAVE_HEIGHT, x + WAVE_SEGMENT_LENGTH / 2, y);
-  }
-
-  private static void drawWaveSegment(Graphics g, int x, int y) {
-    UIUtil.drawLine(g, x, y + WAVE_HEIGHT, x + WAVE_SEGMENT_LENGTH / 2, y);
-    UIUtil.drawLine(g, x + WAVE_SEGMENT_LENGTH / 2, y, x + WAVE_SEGMENT_LENGTH, y + WAVE_HEIGHT);
-  }
-
   private int getTextSegmentWidth(@NotNull CharSequence text,
                                   int start,
                                   int end,
index 62d9c5924aed3d2297c21a385040aac2eec00856..0eeadb43594d6877a1fd9dbdc8bf5a23c478f122 100644 (file)
@@ -19,6 +19,7 @@ import com.intellij.BundleBase;
 import com.intellij.icons.AllIcons;
 import com.intellij.openapi.Disposable;
 import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.ui.GraphicsConfig;
 import com.intellij.openapi.util.*;
 import com.intellij.openapi.util.registry.Registry;
 import com.intellij.openapi.util.text.StringUtil;
@@ -57,6 +58,7 @@ import javax.swing.undo.UndoManager;
 import java.awt.*;
 import java.awt.event.*;
 import java.awt.font.FontRenderContext;
+import java.awt.geom.GeneralPath;
 import java.awt.im.InputContext;
 import java.awt.image.BufferedImage;
 import java.awt.image.BufferedImageOp;
@@ -590,6 +592,26 @@ public class UIUtil {
     }
   }
 
+  public static void drawWave(Graphics2D g, Rectangle rectangle) {
+    GraphicsConfig config = GraphicsUtil.setupAAPainting(g);
+    Stroke oldStroke = g.getStroke();
+    try {
+      g.setStroke(new BasicStroke(0.7F));
+      double cycle = 4;
+      final double wavedAt = rectangle.y + (double)rectangle.height /2 - .5;
+      GeneralPath wavePath = new GeneralPath();
+      wavePath.moveTo(rectangle.x, wavedAt -  Math.cos(rectangle.x * 2 * Math.PI / cycle));
+      for (int x = rectangle.x + 1; x <= rectangle.x + rectangle.width; x++) {
+        wavePath.lineTo(x, wavedAt - Math.cos(x * 2 * Math.PI / cycle) );
+      }
+      g.draw(wavePath);
+    }
+    finally {
+      config.restore();
+      g.setStroke(oldStroke);
+    }
+  }
+
   @NotNull
   public static String[] splitText(String text, FontMetrics fontMetrics, int widthLimit, char separator) {
     ArrayList<String> lines = new ArrayList<String>();