Retina Support:

BlockCursor fixed (IDEA-87500)
Retina icons
MemoryIndicator
Gutter improved
Editor and fragment popups in retina.
This commit is contained in:
Anton Makeev
2012-07-06 18:07:03 +02:00
parent cd58a74f9c
commit 0ee210babe
17 changed files with 269 additions and 62 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -285,25 +285,30 @@ public class UISettings implements PersistentStateComponent<UISettings>, Exporta
UISettings uiSettings=getInstance();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
if (uiSettings == null || uiSettings.ANTIALIASING_IN_EDITOR) {
Toolkit tk = Toolkit.getDefaultToolkit();
//noinspection HardCodedStringLiteral
Map map = (Map)tk.getDesktopProperty("awt.font.desktophints");
if (map != null) {
if (isRemoteDesktopConnected()) {
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
if (!isRemoteDesktopConnected() && UIUtil.isRetina()) {
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
}
else {
if (uiSettings == null || uiSettings.ANTIALIASING_IN_EDITOR) {
Toolkit tk = Toolkit.getDefaultToolkit();
//noinspection HardCodedStringLiteral
Map map = (Map)tk.getDesktopProperty("awt.font.desktophints");
if (map != null) {
if (isRemoteDesktopConnected()) {
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT);
}
else {
g2d.addRenderingHints(map);
}
}
else {
g2d.addRenderingHints(map);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
}
}
else {
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
}
}
else {
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
}
}
/**

View File

@@ -27,6 +27,7 @@ import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.ui.ColorUtil;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.Consumer;
import com.intellij.util.ui.GraphicsUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
@@ -299,6 +300,15 @@ public abstract class ComboBoxAction extends AnAction implements CustomComponent
@Override
public void paint(Graphics g) {
UIUtil.paintWithRetina(getSize(), g, UIUtil.isUnderDarcula(), new Consumer<Graphics2D>() {
@Override
public void consume(Graphics2D graphics) {
doPaint(graphics);
}
});
}
private void doPaint(Graphics g) {
GraphicsUtil.setupAntialiasing(g);
final boolean isEmpty = getIcon() == null && StringUtil.isEmpty(getText());

View File

@@ -15,6 +15,7 @@
*/
package com.intellij.codeInsight.hint;
import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
@@ -43,8 +44,8 @@ public class EditorFragmentComponent extends JPanel {
private EditorFragmentComponent(EditorEx editor, int startLine, int endLine, boolean showFolding, boolean showGutter) {
Document doc = editor.getDocument();
final int endOffset = endLine < doc.getLineCount() ? doc.getLineEndOffset(endLine) : doc.getTextLength();
int textWidth = Math.min(editor.getMaxWidthInRange(doc.getLineStartOffset(startLine), endOffset), ScreenUtil.getScreenRectangle(1, 1).width);
LOG.assertTrue(textWidth > 0, "TextWidth: "+textWidth+"; startLine:" + startLine + "; endLine:" + endLine + ";");
final int textImageWidth = Math.min(editor.getMaxWidthInRange(doc.getLineStartOffset(startLine), endOffset), ScreenUtil.getScreenRectangle(1, 1).width);
LOG.assertTrue(textImageWidth > 0, "TextWidth: "+textImageWidth+"; startLine:" + startLine + "; endLine:" + endLine + ";");
FoldingModelEx foldingModel = editor.getFoldingModel();
boolean isFoldingEnabled = foldingModel.isFoldingEnabled();
@@ -56,8 +57,8 @@ public class EditorFragmentComponent extends JPanel {
Point p2 = editor.logicalPositionToXY(new LogicalPosition(Math.max(endLine, startLine + 1), 0));
int y1 = p1.y;
int y2 = p2.y;
int height = y2 - y1 == 0 ? editor.getLineHeight() : y2 - y1;
LOG.assertTrue(height > 0, "Height: " + height + "; startLine:" + startLine + "; endLine:" + endLine + "; p1:" + p1 + "; p2:" + p2);
final int textImageHeight = y2 - y1 == 0 ? editor.getLineHeight() : y2 - y1;
LOG.assertTrue(textImageHeight > 0, "Height: " + textImageHeight + "; startLine:" + startLine + "; endLine:" + endLine + "; p1:" + p1 + "; p2:" + p2);
int savedScrollOffset = editor.getScrollingModel().getHorizontalScrollOffset();
if (savedScrollOffset > 0) {
@@ -65,29 +66,36 @@ public class EditorFragmentComponent extends JPanel {
editor.getScrollingModel().scrollHorizontally(0);
}
final Image textImage = new BufferedImage(textWidth, height, BufferedImage.TYPE_INT_RGB);
final BufferedImage textImage = UIUtil.createImage(textImageWidth, textImageHeight, BufferedImage.TYPE_INT_RGB);
Graphics textGraphics = textImage.getGraphics();
UISettings.setupAntialiasing(textGraphics);
final JComponent rowHeader;
final Image markersImage;
final BufferedImage markersImage;
final int markersImageWidth;
if (showGutter) {
rowHeader = editor.getGutterComponentEx();
markersImage = new BufferedImage(Math.max(1, rowHeader.getWidth()), height, BufferedImage.TYPE_INT_RGB);
markersImageWidth = Math.max(1, rowHeader.getWidth());
markersImage = UIUtil.createImage(markersImageWidth, textImageHeight, BufferedImage.TYPE_INT_RGB);
Graphics markerGraphics = markersImage.getGraphics();
UISettings.setupAntialiasing(markerGraphics);
markerGraphics.translate(0, -y1);
markerGraphics.setClip(0, y1, rowHeader.getWidth(), height);
markerGraphics.setClip(0, y1, rowHeader.getWidth(), textImageHeight);
markerGraphics.setColor(getBackgroundColor(editor));
markerGraphics.fillRect(0, y1, rowHeader.getWidth(), height);
markerGraphics.fillRect(0, y1, rowHeader.getWidth(), textImageHeight);
rowHeader.paint(markerGraphics);
}
else {
markersImageWidth = 0;
rowHeader = null;
markersImage = null;
}
textGraphics.translate(0, -y1);
textGraphics.setClip(0, y1, textWidth, height);
textGraphics.setClip(0, y1, textImageWidth, textImageHeight);
final boolean wasVisible = editor.setCaretVisible(false);
editor.setPurePaintingMode(true);
try {
@@ -111,7 +119,7 @@ public class EditorFragmentComponent extends JPanel {
JComponent component = new JComponent() {
public Dimension getPreferredSize() {
return new Dimension(textImage.getWidth(null) +(markersImage == null ? 0 : markersImage.getWidth(null)), textImage.getHeight(null));
return new Dimension(textImageWidth + markersImageWidth, textImageHeight);
}
protected void paintComponent(Graphics graphics) {

View File

@@ -28,6 +28,7 @@ import com.intellij.openapi.ui.Queryable;
import com.intellij.openapi.ui.TypingTarget;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.ui.components.Magnificator;
import com.intellij.util.Consumer;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
@@ -145,10 +146,15 @@ public class EditorComponentImpl extends JComponent implements Scrollable, DataP
((ApplicationImpl)ApplicationManager.getApplication()).editorPaintStart();
try {
UIUtil.setupComposite((Graphics2D)g);
UIUtil.paintWithRetina(getSize(), g, myEditor.paintBlockCaret(), new Consumer<Graphics2D>() {
@Override
public void consume(Graphics2D graphics) {
UIUtil.setupComposite(graphics);
UISettings.setupAntialiasing(g);
myEditor.paint((Graphics2D)g);
UISettings.setupAntialiasing(graphics);
myEditor.paint(graphics);
}
});
}
finally {
((ApplicationImpl)ApplicationManager.getApplication()).editorPaintFinish();
@@ -199,12 +205,12 @@ public class EditorComponentImpl extends JComponent implements Scrollable, DataP
@Override
public boolean getScrollableTracksViewportWidth() {
return getParent()instanceof JViewport && getParent().getWidth() > getPreferredSize().width;
return getParent() instanceof JViewport && getParent().getWidth() > getPreferredSize().width;
}
@Override
public boolean getScrollableTracksViewportHeight() {
return getParent()instanceof JViewport && getParent().getHeight() > getPreferredSize().height;
return getParent() instanceof JViewport && getParent().getHeight() > getPreferredSize().height;
}
@Override

View File

@@ -66,8 +66,10 @@ import javax.swing.plaf.ComponentUI;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
class EditorGutterComponentImpl extends EditorGutterComponentEx implements MouseListener, MouseMotionListener {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.editor.impl.EditorGutterComponentImpl");
@@ -188,7 +190,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
paintAnnotations(g, clip);
Object hint = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
if (!UIUtil.isRetina()) g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
try {
int firstVisibleOffset = myEditor.logicalPositionToOffset(myEditor.xyToLogicalPosition(new Point(0, clip.y - myEditor.getLineHeight())));
@@ -873,7 +875,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse
int baseHeight,
boolean active, boolean paintBackground) {
Object antialiasing = g.getRenderingHint(RenderingHints.KEY_ANTIALIASING);
if (SystemInfo.isMac && SystemInfo.JAVA_VERSION.startsWith("1.4.1")) {
if (SystemInfo.isMac && SystemInfo.JAVA_VERSION.startsWith("1.4.1") || UIUtil.isRetina()) {
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
}

View File

@@ -67,7 +67,6 @@ import com.intellij.openapi.util.*;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.util.TraceableDisposable;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.IdeGlassPane;
import com.intellij.ui.GuiUtils;
@@ -4264,7 +4263,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
g.setColor(myScheme.getColor(EditorColors.CARET_COLOR));
if (myIsInsertMode != mySettings.isBlockCursor()) {
if (!paintBlockCaret()) {
for (int i = 0; i < mySettings.getLineCursorWidth(); i++) {
UIUtil.drawLine(g, x + i, y, x + i, y + lineHeight - 1);
}
@@ -4281,6 +4280,10 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
}
boolean paintBlockCaret() {
return myIsInsertMode == mySettings.isBlockCursor();
}
private class ScrollingTimer {
Timer myTimer;
private static final int TIMER_PERIOD = 100;

View File

@@ -49,7 +49,7 @@ public class MemoryUsagePanel extends JButton implements CustomStatusBarWidget {
private long myLastTotal = -1;
private long myLastUsed = -1;
private ScheduledFuture<?> myFuture;
private BufferedImage myBufferedImage;
private Image myBufferedImage;
private boolean myWasPressed;
public MemoryUsagePanel() {
@@ -114,7 +114,7 @@ public class MemoryUsagePanel extends JButton implements CustomStatusBarWidget {
myWasPressed = pressed;
if (myBufferedImage == null || forced) {
myBufferedImage = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_ARGB);
myBufferedImage = UIUtil.createImage(size.width, size.height, BufferedImage.TYPE_INT_ARGB);
final Graphics bg = myBufferedImage.getGraphics().create();
final Runtime runtime = Runtime.getRuntime();

View File

@@ -305,7 +305,8 @@ abstract public class AbstractExpandableItemsHandler<KeyType, ComponentType exte
if (cellBounds.y < visibleRect.y) return null;
if (cellBounds.y + cellBounds.height > visibleRect.y + visibleRect.height) return null;
myImage = createImage(height, width);
Dimension size = getImageSize(width, height);
myImage = UIUtil.createImage(size.width, size.height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = myImage.createGraphics();
g.setClip(null);
@@ -338,8 +339,8 @@ abstract public class AbstractExpandableItemsHandler<KeyType, ComponentType exte
return Color.GRAY;
}
protected BufferedImage createImage(final int height, final int width) {
return new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
protected Dimension getImageSize(final int width, final int height) {
return new Dimension(width, height);
}
protected void doFillBackground(int height, int width, Graphics2D g) {

View File

@@ -31,7 +31,6 @@ import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
@@ -132,9 +131,9 @@ public class TreeExpandableItemsHandler extends AbstractExpandableItemsHandler<I
}
@Override
protected BufferedImage createImage(int height, int width) {
protected Dimension getImageSize(int width, int height) {
final TreeUI ui = myComponent.getUI();
return super.createImage(ui instanceof MacTreeUI && ((MacTreeUI)ui).isWideSelection() ? height - 1 : height, width);
return new Dimension(width, ui instanceof MacTreeUI && ((MacTreeUI)ui).isWideSelection() ? height - 1 : height);
}
@Override

View File

@@ -122,6 +122,9 @@ ide.mac.hide.cursor.when.typing=true
ide.mac.show.native.help=true
ide.mac.useNativeClipboard=false
ide.mac.disableRetina=false
ide.mac.disableRetinaDrawingFix=false
debugger.valueTooltipAutoShow=true
# suppress inspection "UnusedProperty"
debugger.valueTooltipAutoShow.description=Auto show tooltip on mouse over.

View File

@@ -17,8 +17,11 @@ package com.intellij.util;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.io.URLUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -30,10 +33,14 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@Deprecated
public class ImageLoader implements Serializable {
private static final Component ourComponent = new Component() {};
private static final Component ourComponent = new Component() {
};
private static final Logger LOG = Logger.getInstance("#com.intellij.util.ImageLoader");
@@ -44,12 +51,25 @@ public class ImageLoader implements Serializable {
mediatracker.addImage(image, 1);
try {
mediatracker.waitForID(1, 5000);
} catch (InterruptedException ex) {
}
catch (InterruptedException ex) {
LOG.info(ex);
}
return !mediatracker.isErrorID(1);
}
@Nullable
public static Image loadFromUrl(URL url) {
for (Pair<String, Integer> each : getFileNames(url.toString())) {
try {
return loadFromStream(URLUtil.openStream(new URL(each.first)), each.second);
}
catch (IOException ignore) {
}
}
return null;
}
@Nullable
public static Image loadFromResource(@NonNls String s) {
int stackFrameCount = 2;
@@ -64,14 +84,31 @@ public class ImageLoader implements Serializable {
}
@Nullable
public static Image loadFromResource(String s, Class aClass) {
final InputStream stream = aClass.getResourceAsStream(s);
return stream != null ? loadFromStream(stream) : null;
public static Image loadFromResource(String path, Class aClass) {
for (Pair<String, Integer> each : getFileNames(path)) {
InputStream stream = aClass.getResourceAsStream(each.first);
if (stream == null) continue;
Image image = loadFromStream(stream, each.second);
if (image != null) return image;
}
return null;
}
public static List<Pair<String, Integer>> getFileNames(@NotNull String file) {
if (UIUtil.isRetina()) {
return Arrays.asList(Pair.create(FileUtil.getNameWithoutExtension(file) + "@2x." + FileUtil.getExtension(file), 2),
Pair.create(file, 1));
}
return Collections.singletonList(Pair.create(file, 1));
}
public static Image loadFromStream(@NotNull final InputStream inputStream) {
try {
return loadFromStream(inputStream, 1);
}
public static Image loadFromStream(@NotNull final InputStream inputStream, final int scale) {
if (scale <= 0) throw new IllegalArgumentException("Scale must 1 or more");
try {
BufferExposingByteArrayOutputStream outputStream = new BufferExposingByteArrayOutputStream();
try {
byte[] buffer = new byte[1024];
@@ -86,26 +123,22 @@ public class ImageLoader implements Serializable {
}
Image image = Toolkit.getDefaultToolkit().createImage(outputStream.getInternalBuffer(), 0, outputStream.size());
waitForImage(image);
if (UIUtil.isRetina() && scale > 1) {
image = RetinaImage.createFrom(image, scale, ourComponent);
}
return image;
} catch (Exception ex) {
}
catch (Exception ex) {
LOG.error(ex);
}
return null;
}
public static Image loadFromUrl(URL url) {
try {
return loadFromStream(URLUtil.openStream(url));
}
catch (IOException e) {
LOG.error(e);
return null;
}
}
public static boolean isGoodSize(final Icon icon) {
return IconLoader.isGoodSize(icon);
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2000-2012 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.util;
import apple.awt.CImage;
import java.awt.*;
import java.awt.image.BufferedImage;
public class RetinaImage {
public static Image createFrom(Image image, final int scale, Component ourComponent) {
int w = image.getWidth(ourComponent);
int h = image.getHeight(ourComponent);
Image hidpi = create(w / scale, h / scale, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D)hidpi.getGraphics();
g.scale(1f / scale, 1f / scale);
g.drawImage(image, 0, 0, null);
g.dispose();
return hidpi;
}
public static BufferedImage create(final int width, int height, int type) {
return new CImage.HiDPIScaledImage(width, height, type) {
@Override
protected void drawIntoImage(BufferedImage image, float scale) {
}
};
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright 2000-2012 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.util.ui;
import apple.awt.CImage;
import java.awt.image.BufferedImage;
class IsRetina {
public static boolean isRetina() {
try {
final boolean[] isRetina = new boolean[1];
new CImage.HiDPIScaledImage(1, 1, BufferedImage.TYPE_INT_ARGB) {
@Override
public void drawIntoImage(BufferedImage image, float v) {
isRetina[0] = v > 1;
}
};
return isRetina[0];
}
catch (Throwable e) {
e.printStackTrace();
return false;
}
}
}

View File

@@ -20,15 +20,13 @@ import com.intellij.icons.AllIcons;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.ColorUtil;
import com.intellij.ui.Gray;
import com.intellij.ui.PanelWithAnchor;
import com.intellij.ui.SideBorder;
import com.intellij.util.ArrayUtil;
import com.intellij.util.PairFunction;
import com.intellij.util.Processor;
import com.intellij.util.ReflectionUtil;
import com.intellij.util.*;
import com.intellij.util.containers.ContainerUtil;
import org.intellij.lang.annotations.Language;
import org.jetbrains.annotations.NonNls;
@@ -158,6 +156,24 @@ public class UIUtil {
private UIUtil() { }
private static final Ref<Boolean> ourRetina = Ref.create(SystemInfo.isMac ? null : false);
public static boolean isRetina() {
synchronized (ourRetina) {
if (ourRetina.isNull()) {
ourRetina.set(false); // in case HiDPIScaledImage.drawIntoImage is not called for some reason
String vendor = SystemProperties.getJavaVmVendor();
if (SystemInfo.isJavaVersionAtLeast("1.6.0_33") && vendor != null && StringUtil.containsIgnoreCase(vendor, "Apple")) {
if (!Registry.is("ide.mac.disableRetina", false)) {
ourRetina.set(IsRetina.isRetina());
}
}
}
return ourRetina.get();
}
}
public static boolean hasLeakingAppleListeners() {
// in version 1.6.0_29 Apple introduced a memory leak in JViewport class - they add a PropertyChangeListeners to the CToolkit
// but never remove them:
@@ -1258,6 +1274,42 @@ public class UIUtil {
}
}
public static BufferedImage createImage(int width, int height, int type) {
if (isRetina()) {
return RetinaImage.create(width, height, type);
}
return new BufferedImage(width, height, type);
}
public static void paintWithRetina(@NotNull Dimension size, @NotNull Graphics g, Consumer<Graphics2D> paintRoutine) {
paintWithRetina(size, g, true, paintRoutine);
}
public static void paintWithRetina(@NotNull Dimension size, @NotNull Graphics g, boolean useRetinaCondition, Consumer<Graphics2D> paintRoutine) {
if (!useRetinaCondition || !isRetina() || Registry.is("ide.mac.disableRetinaDrawingFix", false)) {
paintRoutine.consume((Graphics2D)g);
}
else {
Rectangle rect = g.getClipBounds();
if (rect == null) rect = new Rectangle(size);
Image image = ((Graphics2D)g).getDeviceConfiguration().createCompatibleImage(rect.width * 2, rect.height * 2);
Graphics2D imageGraphics = (Graphics2D)image.getGraphics();
imageGraphics.scale(2, 2);
imageGraphics.translate(-rect.x, -rect.y);
imageGraphics.setClip(rect.x, rect.y, rect.width, rect.height);
paintRoutine.consume(imageGraphics);
image.flush();
imageGraphics.dispose();
((Graphics2D)g).scale(0.5, 0.5);
g.drawImage(image, rect.x * 2, rect.y * 2, null);
}
}
/**
* Configures composite to use for drawing text with the given graphics container.
* <p/>

View File

@@ -6,6 +6,7 @@
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/testSrc" isTestSource="true" />
</content>
<orderEntry type="library" scope="PROVIDED" name="Mac" level="project" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="JDOM" level="project" />