mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-161827 use line metrics to align text effects
This commit is contained in:
@@ -830,18 +830,18 @@ public class SimpleColoredComponent extends JComponent implements Accessible, Co
|
||||
|
||||
// 1. Strikeout effect
|
||||
if (attributes.isStrikeout() && !attributes.isSearchMatch()) {
|
||||
EffectPainter.STRIKE_THROUGH.paint(g, offset, textBaseline, fragmentWidth, getCharHeight(g), null);
|
||||
EffectPainter.STRIKE_THROUGH.paint(g, offset, textBaseline, fragmentWidth, getCharHeight(g), font);
|
||||
}
|
||||
// 2. Waved effect
|
||||
if (attributes.isWaved()) {
|
||||
if (attributes.getWaveColor() != null) {
|
||||
g.setColor(attributes.getWaveColor());
|
||||
}
|
||||
EffectPainter.WAVE_UNDERSCORE.paint(g, offset, textBaseline + 1, fragmentWidth, Math.max(2, metrics.getDescent()), null);
|
||||
EffectPainter.WAVE_UNDERSCORE.paint(g, offset, textBaseline + 1, fragmentWidth, Math.max(2, metrics.getDescent()), font);
|
||||
}
|
||||
// 3. Underline
|
||||
if (attributes.isUnderline()) {
|
||||
EffectPainter.LINE_UNDERSCORE.paint(g, offset, textBaseline, fragmentWidth, metrics.getDescent(), null);
|
||||
EffectPainter.LINE_UNDERSCORE.paint(g, offset, textBaseline, fragmentWidth, metrics.getDescent(), font);
|
||||
}
|
||||
// 4. Bold Dotted Line
|
||||
if (attributes.isBoldDottedLine()) {
|
||||
@@ -885,7 +885,7 @@ public class SimpleColoredComponent extends JComponent implements Accessible, Co
|
||||
g.drawString(text, x1, baseline);
|
||||
|
||||
if (((SimpleTextAttributes)info[5]).isStrikeout()) {
|
||||
EffectPainter.STRIKE_THROUGH.paint(g, x1, baseline, x2 - x1, getCharHeight(g), null);
|
||||
EffectPainter.STRIKE_THROUGH.paint(g, x1, baseline, x2 - x1, getCharHeight(g), g.getFont());
|
||||
}
|
||||
}
|
||||
return offset;
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.intellij.ui.paint;
|
||||
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.util.JBHiDPIScaledImage;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
@@ -24,6 +23,7 @@ import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.util.ui.WavePainter;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.font.LineMetrics;
|
||||
import java.awt.geom.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -31,7 +31,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
/**
|
||||
* @author Sergey.Malenkov
|
||||
*/
|
||||
public enum EffectPainter implements RegionPainter<Paint> {
|
||||
public enum EffectPainter implements RegionPainter<Font> {
|
||||
/**
|
||||
* @see com.intellij.openapi.editor.markup.EffectType#LINE_UNDERSCORE
|
||||
*/
|
||||
@@ -44,17 +44,15 @@ public enum EffectPainter implements RegionPainter<Paint> {
|
||||
* @param y text baseline
|
||||
* @param width text width
|
||||
* @param height available space under text
|
||||
* @param paint optional color patterns
|
||||
* @param font optional font to calculate line metrics
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics2D g, int x, int y, int width, int height, Paint paint) {
|
||||
public void paint(Graphics2D g, int x, int y, int width, int height, Font font) {
|
||||
if (!Registry.is("ide.text.effect.new")) {
|
||||
if (paint != null) g.setPaint(paint);
|
||||
g.drawLine(x, y + 1, x + width, y + 1);
|
||||
}
|
||||
else if (width > 0 && height > 0) {
|
||||
if (paint != null) g.setPaint(paint);
|
||||
drawLineUnderscore(g, x, y, width, height, 1, this);
|
||||
drawLineUnderscore(g, x, y, width, height, font, 1, this);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -70,18 +68,16 @@ public enum EffectPainter implements RegionPainter<Paint> {
|
||||
* @param y text baseline
|
||||
* @param width text width
|
||||
* @param height available space under text
|
||||
* @param paint optional color patterns
|
||||
* @param font optional font to calculate line metrics
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics2D g, int x, int y, int width, int height, Paint paint) {
|
||||
public void paint(Graphics2D g, int x, int y, int width, int height, Font font) {
|
||||
if (!Registry.is("ide.text.effect.new")) {
|
||||
if (paint != null) g.setPaint(paint);
|
||||
int h = JBUI.scale(Registry.intValue("editor.bold.underline.height", 2));
|
||||
g.fillRect(x, y, width, h);
|
||||
}
|
||||
else if (width > 0 && height > 0) {
|
||||
if (paint != null) g.setPaint(paint);
|
||||
drawLineUnderscore(g, x, y, width, height, 2, this);
|
||||
drawLineUnderscore(g, x, y, width, height, font, 2, this);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -97,16 +93,12 @@ public enum EffectPainter implements RegionPainter<Paint> {
|
||||
* @param y text baseline
|
||||
* @param width text width
|
||||
* @param height available space under text
|
||||
* @param paint optional color patterns
|
||||
* @param font optional font to calculate line metrics
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics2D g, int x, int y, int width, int height, Paint paint) {
|
||||
if (!Registry.is("ide.text.effect.new")) {
|
||||
UIUtil.drawBoldDottedLine(g, x, x + width, SystemInfo.isMac ? y : y + 1, g.getColor(), (Color)paint, false);
|
||||
}
|
||||
else if (width > 0 && height > 0) {
|
||||
if (paint != null) g.setPaint(paint);
|
||||
drawLineUnderscore(g, x, y, width, height, 2, this);
|
||||
public void paint(Graphics2D g, int x, int y, int width, int height, Font font) {
|
||||
if (width > 0 && height > 0) {
|
||||
drawLineUnderscore(g, x, y, width, height, font, 2, this);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -122,16 +114,15 @@ public enum EffectPainter implements RegionPainter<Paint> {
|
||||
* @param y text baseline
|
||||
* @param width text width
|
||||
* @param height available space under text
|
||||
* @param paint optional color patterns
|
||||
* @param font optional font to calculate line metrics
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics2D g, int x, int y, int width, int height, Paint paint) {
|
||||
public void paint(Graphics2D g, int x, int y, int width, int height, Font font) {
|
||||
if (!Registry.is("ide.text.effect.new")) {
|
||||
if (paint != null) g.setPaint(paint);
|
||||
WavePainter.forColor(g.getColor()).paint(g, x, x + width, y + height);
|
||||
}
|
||||
else if (width > 0 && height > 0) {
|
||||
Cached.WAVE_UNDERSCORE.paint(g, x, y, width, height, paint);
|
||||
Cached.WAVE_UNDERSCORE.paint(g, x, y, width, height, null);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -147,13 +138,21 @@ public enum EffectPainter implements RegionPainter<Paint> {
|
||||
* @param y text baseline
|
||||
* @param width text width
|
||||
* @param height text height
|
||||
* @param paint optional color patterns
|
||||
* @param font optional font to calculate line metrics
|
||||
*/
|
||||
@Override
|
||||
public void paint(Graphics2D g, int x, int y, int width, int height, Paint paint) {
|
||||
public void paint(Graphics2D g, int x, int y, int width, int height, Font font) {
|
||||
if (width > 0 && height > 0) {
|
||||
if (paint != null) g.setPaint(paint);
|
||||
drawLineCentered(g, x, y - height, width, height, 1, this);
|
||||
if (!Registry.is("ide.text.effect.new.metrics")) {
|
||||
drawLineCentered(g, x, y - height, width, height, 1, this);
|
||||
}
|
||||
else {
|
||||
if (font == null) font = g.getFont();
|
||||
LineMetrics metrics = font.getLineMetrics("", g.getFontRenderContext());
|
||||
int offset = (int)(0.5 - metrics.getStrikethroughOffset());
|
||||
int thickness = Math.max(1, (int)(0.5 + metrics.getStrikethroughThickness()));
|
||||
drawLine(g, x, y - offset, width, thickness, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -162,16 +161,28 @@ public enum EffectPainter implements RegionPainter<Paint> {
|
||||
return height > 7 && Registry.is("ide.text.effect.new.scale") ? height >> 1 : 3;
|
||||
}
|
||||
|
||||
private static void drawLineUnderscore(Graphics2D g, int x, int y, int width, int height, int thickness, EffectPainter painter) {
|
||||
if (height > 3) {
|
||||
int max = getMaxHeight(height);
|
||||
y += height - max;
|
||||
height = max;
|
||||
if (thickness > 1 && height > 3) {
|
||||
thickness = JBUI.scale(thickness);
|
||||
private static void drawLineUnderscore(Graphics2D g, int x, int y, int width, int height, Font font, int thickness,
|
||||
EffectPainter painter) {
|
||||
if (width > 0 && height > 0) {
|
||||
if (Registry.is("ide.text.effect.new.metrics")) {
|
||||
if (font == null) font = g.getFont();
|
||||
LineMetrics metrics = font.getLineMetrics("", g.getFontRenderContext());
|
||||
int offset = Math.max(1, (int)(0.5 + metrics.getUnderlineOffset()));
|
||||
thickness = Math.max(thickness, (int)(0.5 + thickness * metrics.getUnderlineThickness()));
|
||||
drawLine(g, x, y + offset, width, thickness, painter);
|
||||
}
|
||||
else {
|
||||
if (height > 3) {
|
||||
int max = getMaxHeight(height);
|
||||
y += height - max;
|
||||
height = max;
|
||||
if (thickness > 1 && height > 3) {
|
||||
thickness = JBUI.scale(thickness);
|
||||
}
|
||||
}
|
||||
drawLineCentered(g, x, y, width, height, thickness, painter);
|
||||
}
|
||||
}
|
||||
drawLineCentered(g, x, y, width, height, thickness, painter);
|
||||
}
|
||||
|
||||
private static void drawLineCentered(Graphics2D g, int x, int y, int width, int height, int thickness, EffectPainter painter) {
|
||||
@@ -180,6 +191,10 @@ public enum EffectPainter implements RegionPainter<Paint> {
|
||||
y += offset - (offset >> 1);
|
||||
height = thickness;
|
||||
}
|
||||
drawLine(g, x, y, width, height, painter);
|
||||
}
|
||||
|
||||
private static void drawLine(Graphics2D g, int x, int y, int width, int height, EffectPainter painter) {
|
||||
if (painter == BOLD_DOTTED_UNDERSCORE) {
|
||||
int dx = (x % height + height) % height;
|
||||
int w = width + dx;
|
||||
|
||||
@@ -2456,21 +2456,26 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
if (attributes != null && attributes.getEffectColor() != null) {
|
||||
int y = visibleLineToY(visibleStartLine) + getAscent() + 1;
|
||||
g.setColor(attributes.getEffectColor());
|
||||
if (attributes.getEffectType() == EffectType.WAVE_UNDERSCORE) {
|
||||
EffectPainter.WAVE_UNDERSCORE.paint((Graphics2D)g, end.x, y - 1, charWidth - 1, getDescent(), attributes.getEffectColor());
|
||||
EffectPainter.WAVE_UNDERSCORE.paint((Graphics2D)g, end.x, y - 1, charWidth - 1, getDescent(),
|
||||
getColorsScheme().getFont(EditorFontType.PLAIN));
|
||||
}
|
||||
else if (attributes.getEffectType() == EffectType.BOLD_DOTTED_LINE) {
|
||||
g.setColor(getBackgroundColor(attributes));
|
||||
EffectPainter.BOLD_DOTTED_UNDERSCORE.paint((Graphics2D)g, end.x, y - 1, charWidth - 1, getDescent(), attributes.getEffectColor());
|
||||
EffectPainter.BOLD_DOTTED_UNDERSCORE.paint((Graphics2D)g, end.x, y - 1, charWidth - 1, getDescent(),
|
||||
getColorsScheme().getFont(EditorFontType.PLAIN));
|
||||
}
|
||||
else if (attributes.getEffectType() == EffectType.STRIKEOUT) {
|
||||
EffectPainter.STRIKE_THROUGH.paint((Graphics2D)g, end.x, y - 1, charWidth - 1, getCharHeight(), attributes.getEffectColor());
|
||||
EffectPainter.STRIKE_THROUGH.paint((Graphics2D)g, end.x, y - 1, charWidth - 1, getCharHeight(),
|
||||
getColorsScheme().getFont(EditorFontType.PLAIN));
|
||||
}
|
||||
else if (attributes.getEffectType() == EffectType.BOLD_LINE_UNDERSCORE) {
|
||||
EffectPainter.BOLD_LINE_UNDERSCORE.paint((Graphics2D)g, end.x, y - 1, charWidth - 1, getDescent(), attributes.getEffectColor());
|
||||
EffectPainter.BOLD_LINE_UNDERSCORE.paint((Graphics2D)g, end.x, y - 1, charWidth - 1, getDescent(),
|
||||
getColorsScheme().getFont(EditorFontType.PLAIN));
|
||||
}
|
||||
else if (attributes.getEffectType() != EffectType.BOXED) {
|
||||
EffectPainter.LINE_UNDERSCORE.paint((Graphics2D)g, end.x, y - 1, charWidth - 1, getDescent(), attributes.getEffectColor());
|
||||
EffectPainter.LINE_UNDERSCORE.paint((Graphics2D)g, end.x, y - 1, charWidth - 1, getDescent(),
|
||||
getColorsScheme().getFont(EditorFontType.PLAIN));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3568,6 +3573,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
|
||||
if (effectColor != null) {
|
||||
final Color savedColor = g.getColor();
|
||||
g.setColor(effectColor);
|
||||
|
||||
// myBorderEffect.flushIfCantProlong(g, this, effectType, effectColor);
|
||||
int xEnd = x;
|
||||
@@ -3583,25 +3589,26 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
|
||||
}
|
||||
|
||||
if (effectType == EffectType.LINE_UNDERSCORE) {
|
||||
EffectPainter.LINE_UNDERSCORE.paint((Graphics2D)g, xStart, y, xEnd - xStart, getDescent(), effectColor);
|
||||
g.setColor(savedColor);
|
||||
EffectPainter.LINE_UNDERSCORE.paint((Graphics2D)g, xStart, y, xEnd - xStart, getDescent(),
|
||||
getColorsScheme().getFont(EditorFontType.PLAIN));
|
||||
}
|
||||
else if (effectType == EffectType.BOLD_LINE_UNDERSCORE) {
|
||||
EffectPainter.BOLD_LINE_UNDERSCORE.paint((Graphics2D)g, xStart, y, xEnd - xStart, getDescent(), effectColor);
|
||||
g.setColor(savedColor);
|
||||
EffectPainter.BOLD_LINE_UNDERSCORE.paint((Graphics2D)g, xStart, y, xEnd - xStart, getDescent(),
|
||||
getColorsScheme().getFont(EditorFontType.PLAIN));
|
||||
}
|
||||
else if (effectType == EffectType.STRIKEOUT) {
|
||||
EffectPainter.STRIKE_THROUGH.paint((Graphics2D)g, xStart, y, xEnd - xStart, getCharHeight(), effectColor);
|
||||
g.setColor(savedColor);
|
||||
EffectPainter.STRIKE_THROUGH.paint((Graphics2D)g, xStart, y, xEnd - xStart, getCharHeight(),
|
||||
getColorsScheme().getFont(EditorFontType.PLAIN));
|
||||
}
|
||||
else if (effectType == EffectType.WAVE_UNDERSCORE) {
|
||||
EffectPainter.WAVE_UNDERSCORE.paint((Graphics2D)g, xStart, y, xEnd - xStart, getDescent(), effectColor);
|
||||
g.setColor(savedColor);
|
||||
EffectPainter.WAVE_UNDERSCORE.paint((Graphics2D)g, xStart, y, xEnd - xStart, getDescent(),
|
||||
getColorsScheme().getFont(EditorFontType.PLAIN));
|
||||
}
|
||||
else if (effectType == EffectType.BOLD_DOTTED_LINE) {
|
||||
g.setColor(getBackgroundColor());
|
||||
EffectPainter.BOLD_DOTTED_UNDERSCORE.paint((Graphics2D)g, xStart, y, xEnd - xStart, getDescent(), effectColor);
|
||||
EffectPainter.BOLD_DOTTED_UNDERSCORE.paint((Graphics2D)g, xStart, y, xEnd - xStart, getDescent(),
|
||||
getColorsScheme().getFont(EditorFontType.PLAIN));
|
||||
}
|
||||
g.setColor(savedColor);
|
||||
}
|
||||
|
||||
return x;
|
||||
|
||||
+11
-7
@@ -431,26 +431,30 @@ class EditorPainter implements TextDrawingCallback {
|
||||
}
|
||||
|
||||
private void paintTextEffect(Graphics2D g, float xFrom, float xTo, int y, Color effectColor, EffectType effectType, boolean allowBorder) {
|
||||
g.setColor(effectColor);
|
||||
int xStart = (int)xFrom;
|
||||
int xEnd = (int)xTo;
|
||||
if (effectType == EffectType.LINE_UNDERSCORE) {
|
||||
EffectPainter.LINE_UNDERSCORE.paint(g, xStart, y, xEnd - xStart, myView.getDescent(), effectColor);
|
||||
EffectPainter.LINE_UNDERSCORE.paint(g, xStart, y, xEnd - xStart, myView.getDescent(),
|
||||
myEditor.getColorsScheme().getFont(EditorFontType.PLAIN));
|
||||
}
|
||||
else if (effectType == EffectType.BOLD_LINE_UNDERSCORE) {
|
||||
EffectPainter.BOLD_LINE_UNDERSCORE.paint(g, xStart, y, xEnd - xStart, myView.getDescent(), effectColor);
|
||||
EffectPainter.BOLD_LINE_UNDERSCORE.paint(g, xStart, y, xEnd - xStart, myView.getDescent(),
|
||||
myEditor.getColorsScheme().getFont(EditorFontType.PLAIN));
|
||||
}
|
||||
else if (effectType == EffectType.STRIKEOUT) {
|
||||
EffectPainter.STRIKE_THROUGH.paint(g, xStart, y, xEnd - xStart, myView.getCharHeight(), effectColor);
|
||||
EffectPainter.STRIKE_THROUGH.paint(g, xStart, y, xEnd - xStart, myView.getCharHeight(),
|
||||
myEditor.getColorsScheme().getFont(EditorFontType.PLAIN));
|
||||
}
|
||||
else if (effectType == EffectType.WAVE_UNDERSCORE) {
|
||||
EffectPainter.WAVE_UNDERSCORE.paint(g, xStart, y, xEnd - xStart, myView.getDescent(), effectColor);
|
||||
EffectPainter.WAVE_UNDERSCORE.paint(g, xStart, y, xEnd - xStart, myView.getDescent(),
|
||||
myEditor.getColorsScheme().getFont(EditorFontType.PLAIN));
|
||||
}
|
||||
else if (effectType == EffectType.BOLD_DOTTED_LINE) {
|
||||
g.setColor(myEditor.getBackgroundColor());
|
||||
EffectPainter.BOLD_DOTTED_UNDERSCORE.paint(g, xStart, y, xEnd - xStart, myView.getDescent(), effectColor);
|
||||
EffectPainter.BOLD_DOTTED_UNDERSCORE.paint(g, xStart, y, xEnd - xStart, myView.getDescent(),
|
||||
myEditor.getColorsScheme().getFont(EditorFontType.PLAIN));
|
||||
}
|
||||
else if (allowBorder && (effectType == EffectType.BOXED || effectType == EffectType.ROUNDED_BOX)) {
|
||||
g.setColor(effectColor);
|
||||
drawSimpleBorder(g, xStart, xEnd - 1, y - myView.getAscent(), effectType == EffectType.ROUNDED_BOX);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -830,6 +830,8 @@ ide.text.effect.new=true
|
||||
ide.text.effect.new.description=Enables new effect painter for text
|
||||
ide.text.effect.new.scale=true
|
||||
ide.text.effect.new.scale.description=Enables scalable effect painter for text
|
||||
ide.text.effect.new.metrics=true
|
||||
ide.text.effect.new.metrics.description=Use line metrics to calculate text offset in the effect painter
|
||||
|
||||
ide.intellij.laf.win10.ui=false
|
||||
ide.intellij.laf.win10.ui.description=Enables Windows 10 look
|
||||
|
||||
Reference in New Issue
Block a user