diff --git a/platform/platform-api/src/com/intellij/ui/EffectPainter.java b/platform/platform-api/src/com/intellij/ui/EffectPainter.java new file mode 100644 index 000000000000..050a4a73538d --- /dev/null +++ b/platform/platform-api/src/com/intellij/ui/EffectPainter.java @@ -0,0 +1,85 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ui; + +import com.intellij.openapi.util.registry.Registry; +import com.intellij.util.ui.RegionPainter; + +import java.awt.*; +import java.awt.geom.*; + +/** + * @author Sergey.Malenkov + */ +public enum EffectPainter implements RegionPainter { + WAVE { + private final BasicStroke STROKE = new BasicStroke(.7f); + + @Override + public void paint(Graphics2D g, int x, int y, int width, int height, Paint paint) { + if (paint != null && width > 0 && height > 0) { + if (!Registry.is("ide.text.effect.wave.new.scale")) { + y += height - 3; + height = 3; + } + g = (Graphics2D)g.create(x, y, width, height); + g.clipRect(0, 0, width, height); + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g.setPaint(paint); + + int length = 2 * height; + boolean simple = length < 5; + + double dx = -((x % length + length) % length); // normalize + double size = (double)length / 4; + + double upper = 0; + double lower = height - 1; + double center = lower / 2; + + Path2D path = new Path2D.Double(); + path.moveTo(dx, lower); + while (true) { + if (simple) { + dx += size + size; + path.lineTo(dx, upper); + if (dx > width) break; + dx += size + size; + path.lineTo(dx, lower); + if (dx > width) break; + } + else { + dx += size; + path.quadTo(dx - size / 2, lower, dx, center); + if (dx > width) break; + dx += size; + path.quadTo(dx - size / 2, upper, dx, upper); + if (dx > width) break; + dx += size; + path.quadTo(dx - size / 2, upper, dx, center); + if (dx > width) break; + dx += size; + path.quadTo(dx - size / 2, lower, dx, lower); + if (dx > width) break; + } + } + if (simple) g.setStroke(STROKE); + g.draw(path); + g.dispose(); + } + } + } +} diff --git a/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java b/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java index 6d3e83afa1fe..f983834840fe 100644 --- a/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java +++ b/platform/platform-api/src/com/intellij/ui/SimpleColoredComponent.java @@ -22,6 +22,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.ui.JBInsets; import com.intellij.util.ui.JBUI; @@ -833,10 +834,15 @@ public class SimpleColoredComponent extends JComponent implements Accessible, Co } // 2. Waved effect if (attributes.isWaved()) { - if (attributes.getWaveColor() != null) { - g.setColor(attributes.getWaveColor()); + if (Registry.is("ide.text.effect.wave.new")) { + EffectPainter.WAVE.paint(g, offset, textBaseline + 1, fragmentWidth, Math.max(2, metrics.getDescent()), attributes.getWaveColor()); + } + else { + if (attributes.getWaveColor() != null) { + g.setColor(attributes.getWaveColor()); + } + UIUtil.drawWave(g, new Rectangle(offset, textBaseline + 1, fragmentWidth, Math.max(2, metrics.getDescent()))); } - UIUtil.drawWave(g, new Rectangle(offset, textBaseline + 1, fragmentWidth, Math.max(2, metrics.getDescent()))); } // 3. Underline if (attributes.isUnderline()) { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index 4124067ec1fb..2e56f175f983 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -2413,7 +2413,12 @@ 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) { - UIUtil.drawWave((Graphics2D)g, new Rectangle(end.x, y, charWidth - 1, getDescent()- 1)); + if (Registry.is("ide.text.effect.wave.new")) { + EffectPainter.WAVE.paint((Graphics2D)g, end.x, y, charWidth - 1, getDescent() - 1, attributes.getEffectColor()); + } + else { + UIUtil.drawWave((Graphics2D)g, new Rectangle(end.x, y, charWidth - 1, getDescent() - 1)); + } } else if (attributes.getEffectType() == EffectType.BOLD_DOTTED_LINE) { final int dottedAt = SystemInfo.isMac ? y - 1 : y; @@ -3562,8 +3567,13 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi g.setColor(savedColor); } else if (effectType == EffectType.WAVE_UNDERSCORE) { - g.setColor(effectColor); - UIUtil.drawWave((Graphics2D)g, new Rectangle(xStart, y+1, xEnd - xStart, getDescent() - 1)); + if (Registry.is("ide.text.effect.wave.new")) { + EffectPainter.WAVE.paint((Graphics2D)g, xStart, y + 1, xEnd - xStart, getDescent() - 1, effectColor); + } + else { + g.setColor(effectColor); + UIUtil.drawWave((Graphics2D)g, new Rectangle(xStart, y + 1, xEnd - xStart, getDescent() - 1)); + } g.setColor(savedColor); } else if (effectType == EffectType.BOLD_DOTTED_LINE) { diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/view/EditorPainter.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/view/EditorPainter.java index 1de3624296ea..27a432411458 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/view/EditorPainter.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/view/EditorPainter.java @@ -33,6 +33,7 @@ import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.impl.IdeBackgroundUtil; import com.intellij.ui.ColorUtil; +import com.intellij.ui.EffectPainter; import com.intellij.ui.Gray; import com.intellij.ui.JBColor; import com.intellij.util.ui.JBUI; @@ -439,7 +440,12 @@ class EditorPainter implements TextDrawingCallback { UIUtil.drawLine(g, xStart, y1, xEnd, y1); } else if (effectType == EffectType.WAVE_UNDERSCORE) { - UIUtil.drawWave(g, new Rectangle(xStart, y + 1, xEnd - xStart, myView.getDescent() - 1)); + if (Registry.is("ide.text.effect.wave.new")) { + EffectPainter.WAVE.paint(g, xStart, y + 1, xEnd - xStart, myView.getDescent() - 1, effectColor); + } + else { + UIUtil.drawWave(g, new Rectangle(xStart, y + 1, xEnd - xStart, myView.getDescent() - 1)); + } } else if (effectType == EffectType.BOLD_DOTTED_LINE) { UIUtil.drawBoldDottedLine(g, xStart, xEnd, SystemInfo.isMac ? y : y + 1, myEditor.getBackgroundColor(), g.getColor(), false); diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index 33f273bb4d17..34fa2644cf99 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -761,6 +761,11 @@ cidr.xcode.derived.data.override.description=Ignore Xcode DerivedData location s editor.rainbow.identifiers=false editor.rainbow.identifiers.description=Rainbow identifiers in editor +ide.text.effect.wave.new=false +ide.text.effect.wave.new.description=Enables new wave painter for text +ide.text.effect.wave.new.scale=false +ide.text.effect.wave.new.scale.description=Enables scalable wave painter for text + ide.intellij.laf.win10.ui=false ide.intellij.laf.win10.ui.description=Enables Windows 10 look