Compare commits

...

20 Commits

Author SHA1 Message Date
Alexey Ushakov
e309845093 JBR-1624 Fonts rendering is broken in the 2019.2 EAP (Fira Code)
Screen rendering tests in progress
2019-06-25 01:55:17 +03:00
Alexey Ushakov
e838103a24 JBR-1624 Fonts rendering is broken in the 2019.2 EAP (Fira Code)
Lower priority for idea bundled fonts to pickup platform ones
(if installed)
2019-06-24 23:30:57 +03:00
Anton Tarasov
e7ca6db66b JBR-1492 Not able to start Intellij Idea 2017.2.5 with modified vmoptions 2019-06-24 14:29:50 +03:00
Vitaly Provodin
d9656a178b updated JTreg exclude list 2019-06-23 07:54:43 +07:00
Vitaly Provodin
5f6351b0c4 updated JTreg exclude list 2019-06-23 07:40:54 +07:00
Vitaly Provodin
c3a0ec902d updated JTreg exclude list 2019-06-22 06:01:31 +07:00
Anton Tarasov
567d96c428 Merge remote-tracking branch 'origin/master' 2019-06-20 21:02:12 +03:00
Anton Tarasov
1666f05b23 JBR-1617 revert fixes for app icon 2019-06-20 21:01:34 +03:00
Egor Ushakov
ae823a660b JBR-1615 Slow ClassLoaderReferenceImpl.findType 2019-06-20 17:52:15 +03:00
Denis Fokin
f6a31f444c Revert: JBR-1583 Fight MAC OS X "Please call TIS/TSM in main thread!!!" message 2019-06-20 14:15:19 +03:00
Dmitry Batrak
a1b4cd964a JBR-1604 Tooltip with package's info is cut 2019-06-19 17:15:15 +03:00
Elena Sayapina
5845719fe5 updated JTreg exclude list 2019-06-17 16:49:18 +07:00
alexsch
dae56a9e8b JBR-1066: fixed ScreenMenuMemoryLeakTest
re-apply fix that was reverted in 2a92eec5:
8158325: [macosx] Memory leak in com.apple.laf.ScreenMenu
Reviewed-by: azvegint, alexsch
Contributed-by: Robin Stevens <robin.stevens@scz.be>

NOTE: fix 8158325 caused 'JBR-922 Actions from system menu does not work on jdk9 runtime', 'IDEA-183063 MacOS: popups are closing, main menu actions will not open when running under Oracle 1.8.152 JDK'. This fix was reapplied because it is correct and bugs aren't reproduced now.

(cherry picked from commit 0a4920f61d)
2019-06-14 16:36:53 +07:00
Anton Tarasov
9cc97b0c00 [followup] JBR-1351 Borderless UI: Bold frame around IDEA window appears on non-HiDPI display 2019-06-13 20:15:41 +03:00
Denis Fokin
936dc2c40b JBR-1583 Fight MAC OS X "Please call TIS/TSM in main thread!!!" message
Crash is fixed
2019-06-11 12:59:53 +03:00
Anton Tarasov
db6c43b6f4 JBR-1414 DnD on linux (XToolkit) does not honor HIDPI scale 2019-06-10 19:11:43 +03:00
Artem Bochkarev
bd9a95d6fb JRE-220: fixed 'terminal Ctrl+C is not working'
cherry-picked from a8c7db34
2019-06-08 14:28:34 +07:00
Denis Fokin
8d9bac395e JBR-1583 Fight MAC OS X "Please call TIS/TSM in main thread!!!" message 2019-06-07 16:27:58 +03:00
Anton Tarasov
f652c790f4 Merge remote-tracking branch 'origin/master' 2019-06-07 15:21:58 +03:00
Anton Tarasov
8e59bb2f09 JBR-1582 IDEA EAP icon has low resolution on Mac 2019-06-07 15:21:28 +03:00
25 changed files with 568 additions and 205 deletions

2
jb/project/java-gradle/.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,2 @@
# Default ignored files
/workspace.xml

View File

@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

6
jb/project/java-gradle/.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$/../../.." vcs="Git" />
</component>
</project>

View File

@@ -82,6 +82,7 @@ test {
// Enable Java2D logging (https://confluence.jetbrains.com/display/JRE/Java2D+Rendering+Logging)
// systemProperty "sun.java2d.trace", "log"
// systemProperty "sun.java2d.debugfonts", "warn"
// systemProperty "sun.java2d.trace", "log,pimpl"
outputs.upToDateWhen { false }

View File

@@ -82,11 +82,11 @@ public class AquaImageFactory {
}
static Image getGenericJavaIcon() {
return java.security.AccessController.doPrivileged(new PrivilegedAction<Image>() {
return checkValidOrStub(java.security.AccessController.doPrivileged(new PrivilegedAction<Image>() {
public Image run() {
return com.apple.eawt.Application.getApplication().getDockIconImage();
}
});
}));
}
static String getPathToThisApplication() {
@@ -496,4 +496,23 @@ public class AquaImageFactory {
public static Color getSelectionInactiveForegroundColorUIResource() {
return new SystemColorProxy(LWCToolkit.getAppleColor(LWCToolkit.INACTIVE_SELECTION_FOREGROUND_COLOR));
}
private static class EmptyImage {
static final BufferedImage INSTANCE;
static {
INSTANCE = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
Graphics g = INSTANCE.createGraphics();
g.setColor(new Color(0, 0, 0, 0));
g.fillRect(0, 0, 16, 16);
g.dispose();
}
}
// [tav] a workaround for JBR-1492
private static Image checkValidOrStub(Image image) {
if (image == null || image.getWidth(null) <= 0 || image.getHeight(null) <= 0) {
return EmptyImage.INSTANCE;
}
return image;
}
}

View File

@@ -110,6 +110,7 @@ final class ScreenMenu extends Menu
final Component[] items = fInvoker.getMenuComponents();
if (needsUpdate(items, childHashArray)) {
removeAll();
fItems.clear();
if (count <= 0) return;
childHashArray = new int[count];
@@ -246,7 +247,7 @@ final class ScreenMenu extends Menu
synchronized (getTreeLock()) {
super.addNotify();
if (fModelPtr == 0) {
fInvoker.addContainerListener(this);
fInvoker.getPopupMenu().addContainerListener(this);
fInvoker.addComponentListener(this);
fPropertyListener = new ScreenMenuPropertyListener(this);
fInvoker.addPropertyChangeListener(fPropertyListener);
@@ -281,7 +282,7 @@ final class ScreenMenu extends Menu
if (fModelPtr != 0) {
removeMenuListeners(fModelPtr);
fModelPtr = 0;
fInvoker.removeContainerListener(this);
fInvoker.getPopupMenu().removeContainerListener(this);
fInvoker.removeComponentListener(this);
fInvoker.removePropertyChangeListener(fPropertyListener);
}
@@ -302,11 +303,10 @@ final class ScreenMenu extends Menu
@Override
public void componentRemoved(final ContainerEvent e) {
final Component child = e.getChild();
final MenuItem sm = fItems.get(child);
final MenuItem sm = fItems.remove(child);
if (sm == null) return;
remove(sm);
fItems.remove(sm);
}
/**

View File

@@ -47,7 +47,7 @@ public class CImage extends CFRetainedResource {
private static native long nativeCreateNSImageFromImageName(String name);
private static native long nativeCreateNSImageFromIconSelector(int selector);
private static native byte[] nativeGetPlatformImageBytes(int[] buffer, int w, int h);
private static native void nativeCopyNSImageIntoArray(long image, int[] buffer, int dw, int dh);
private static native void nativeCopyNSImageIntoArray(long image, int[] buffer, int sw, int sh, int dw, int dh);
private static native Dimension2D nativeGetNSImageSize(long image);
private static native void nativeSetNSImageSize(long image, double w, double h);
private static native void nativeResizeNSImageRepresentations(long image, double w, double h);
@@ -280,8 +280,8 @@ public class CImage extends CFRetainedResource {
if (size == null) {
return null;
}
final int baseWidth = (int)size.getWidth();
final int baseHeight = (int)size.getHeight();
final int w = (int)size.getWidth();
final int h = (int)size.getHeight();
AtomicReference<Dimension2D[]> repRef = new AtomicReference<>();
execute(ptr -> {
repRef.set(nativeGetNSImageRepresentationSizes(ptr, size.getWidth(),
@@ -289,31 +289,18 @@ public class CImage extends CFRetainedResource {
});
Dimension2D[] sizes = repRef.get();
// The image may be represented in the only size which differs from the base one.
// For instance, the app's dock icon is represented in a Retina-scaled size on Retina.
// Check if a single represenation has a bigger size and in that case use it as the dest size.
Dimension2D size0 = size;
if (sizes != null && sizes.length == 1 &&
(sizes[0].getWidth() > baseWidth && sizes[0].getHeight() > baseHeight))
{
size0 = sizes[0];
}
final int dstWidth = (int)size0.getWidth();
final int dstHeight = (int)size0.getHeight();
return sizes == null || sizes.length < 2 ?
new MultiResolutionCachedImage(baseWidth, baseHeight, (width, height)
-> toImage(dstWidth, dstHeight))
: new MultiResolutionCachedImage(baseWidth, baseHeight, sizes, (width, height)
-> toImage(width, height));
new MultiResolutionCachedImage(w, h, (width, height)
-> toImage(w, h, width, height))
: new MultiResolutionCachedImage(w, h, sizes, (width, height)
-> toImage(w, h, width, height));
}
private BufferedImage toImage(int dstWidth, int dstHeight) {
private BufferedImage toImage(int srcWidth, int srcHeight, int dstWidth, int dstHeight) {
final BufferedImage bimg = new BufferedImage(dstWidth, dstHeight, BufferedImage.TYPE_INT_ARGB_PRE);
final DataBufferInt dbi = (DataBufferInt)bimg.getRaster().getDataBuffer();
final int[] buffer = SunWritableRaster.stealData(dbi, 0);
execute(ptr->nativeCopyNSImageIntoArray(ptr, buffer, dstWidth, dstHeight));
execute(ptr->nativeCopyNSImageIntoArray(ptr, buffer, srcWidth, srcHeight, dstWidth, dstHeight));
SunWritableRaster.markDirty(dbi);
return bimg;
}

View File

@@ -325,9 +325,9 @@ final class CPlatformResponder {
if (isISOControl) {
characterToSendWithTheEvent = checkedChar;
}
characterToSendWithTheEvent = mapNsCharsToCompatibleWithJava(characterToSendWithTheEvent);
} else {
characterToSendWithTheEvent = mapNsCharsToCompatibleWithJava(characterToSendWithTheEvent);
}
String stringWithChar = NSEvent.nsToJavaChar(characterToSendWithTheEvent, nsEvent.getModifierFlags(), spaceKeyTyped);
characterToSendWithTheEvent = stringWithChar == null ? KeyEvent.CHAR_UNDEFINED : stringWithChar.charAt(0);

View File

@@ -201,11 +201,11 @@ AWT_ASSERT_APPKIT_THREAD;
self.fPreferencesMenu = (NSMenuItem*)[appMenu itemWithTag:PREFERENCES_TAG];
self.fAboutMenu = (NSMenuItem*)[appMenu itemAtIndex:0];
NSDockTile *dockTile = [NSApp dockTile];
self.fProgressIndicator = [[NSProgressIndicator alloc]
initWithFrame:NSMakeRect(3.f, 0.f, dockTile.size.width - 6.f, 20.f)];
[fProgressIndicator setStyle:NSProgressIndicatorBarStyle];
[fProgressIndicator setIndeterminate:NO];
[[dockTile contentView] addSubview:fProgressIndicator];
@@ -476,8 +476,20 @@ AWT_ASSERT_APPKIT_THREAD;
return;
}
// Set the app's icon instead to meet Retina.
[NSApp setApplicationIconImage:image];
// setup an image view for the dock tile
NSRect frame = NSMakeRect(0, 0, dockTile.size.width, dockTile.size.height);
NSImageView *dockImageView = [[NSImageView alloc] initWithFrame: frame];
[dockImageView setImageScaling:NSImageScaleProportionallyUpOrDown];
[dockImageView setImage:image];
[[ApplicationDelegate sharedDelegate].fProgressIndicator removeFromSuperview];
[dockImageView addSubview:[ApplicationDelegate sharedDelegate].fProgressIndicator];
// add it to the NSDockTile
[dockTile setContentView: dockImageView];
[dockTile display];
[dockImageView release];
}
+ (void)_setDockIconProgress:(NSNumber *)value {
@@ -498,8 +510,25 @@ AWT_ASSERT_APPKIT_THREAD;
+ (NSImage *)_dockIconImage {
AWT_ASSERT_APPKIT_THREAD;
// The app's dock icon defaults to the app's icon (see the spec) which is Retina-aware unlike the dock icon.
return [NSApp applicationIconImage];
NSDockTile *dockTile = [NSApp dockTile];
NSView *view = [dockTile contentView];
if ([view isKindOfClass:[NSImageView class]]) {
NSImage *img = [((NSImageView *)view) image];
if (img) return img;
}
if (view == nil) {
return [NSImage imageNamed:@"NSApplicationIcon"];
}
NSRect frame = [view frame];
NSImage *image = [[NSImage alloc] initWithSize:frame.size];
[image lockFocus];
[view drawRect:frame];
[image unlockFocus];
[image autorelease];
return image;
}
@end

View File

@@ -257,24 +257,24 @@ JNF_COCOA_EXIT(env);
/*
* Class: sun_lwawt_macosx_CImage
* Method: nativeCopyNSImageIntoArray
* Signature: (J[III)V
* Signature: (J[IIIII)V
*/
JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CImage_nativeCopyNSImageIntoArray
(JNIEnv *env, jclass klass, jlong nsImgPtr, jintArray buffer, jint dw, jint dh)
(JNIEnv *env, jclass klass, jlong nsImgPtr, jintArray buffer, jint sw, jint sh,
jint dw, jint dh)
{
JNF_COCOA_ENTER(env);
JNF_COCOA_ENTER(env);
NSImage *img = (NSImage *)jlong_to_ptr(nsImgPtr);
jint *dst = (*env)->GetPrimitiveArrayCritical(env, buffer, NULL);
if (dst) {
NSSize size = [(NSImage *)jlong_to_ptr(nsImgPtr) size];
NSRect fromRect = NSMakeRect(0, 0, size.width, size.height);
NSRect fromRect = NSMakeRect(0, 0, sw, sh);
NSRect toRect = NSMakeRect(0, 0, dw, dh);
CImage_CopyNSImageIntoArray(img, dst, fromRect, toRect);
(*env)->ReleasePrimitiveArrayCritical(env, buffer, dst, JNI_ABORT);
}
JNF_COCOA_EXIT(env);
JNF_COCOA_EXIT(env);
}
/*

View File

@@ -1967,6 +1967,7 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory {
* @see DocumentListener#insertUpdate
*/
public final void insertUpdate(DocumentEvent e) {
rootViewInitialized = false;
Document doc = e.getDocument();
Object o = doc.getProperty("i18n");
if (o instanceof Boolean) {
@@ -1995,6 +1996,7 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory {
* @see DocumentListener#removeUpdate
*/
public final void removeUpdate(DocumentEvent e) {
rootViewInitialized = false;
Rectangle alloc = (painted) ? getVisibleEditorRect() : null;
rootView.removeUpdate(e, alloc, rootView.getViewFactory());
}
@@ -2010,6 +2012,7 @@ public abstract class BasicTextUI extends TextUI implements ViewFactory {
* @see DocumentListener#changedUpdate(DocumentEvent)
*/
public final void changedUpdate(DocumentEvent e) {
rootViewInitialized = false;
Rectangle alloc = (painted) ? getVisibleEditorRect() : null;
rootView.changedUpdate(e, alloc, rootView.getViewFactory());
}

View File

@@ -53,6 +53,7 @@ public abstract class Font2D {
public static final int NATIVE_RANK = 5;
public static final int UNKNOWN_RANK = 6;
public static final int DEFAULT_RANK = 4;
public static final int IDEA_RANK = 7;
private static final String[] boldNames = {
"bold", "demibold", "demi-bold", "demi bold", "negreta", "demi", };

View File

@@ -219,7 +219,7 @@ public class FontFamily {
case Font.PLAIN:
case Font.ITALIC:
return (newWeight <= Font2D.FWEIGHT_NORMAL &&
newWeight > currFont.getWeight());
newWeight >= currFont.getWeight());
case Font.BOLD:
case Font.BOLD|Font.ITALIC:

View File

@@ -82,6 +82,24 @@ public abstract class SunFontManager implements FontSupport, FontManagerForSGE {
}
}
private static class TTFilterIdea extends TTFilter {
final private boolean positive;
final private HashSet<String> ideaSet;
public TTFilterIdea(boolean positive, HashSet<String> ideaSet) {
this.positive = positive;
this.ideaSet = ideaSet;
}
@Override
public boolean accept(File dir, String name) {
if (super.accept(dir, name) && ideaSet.contains(name)) {
return positive;
}
return !positive;
}
}
private static class T1Filter implements FilenameFilter {
public boolean accept(File dir,String name) {
if (noType1Font) {
@@ -189,6 +207,7 @@ public abstract class SunFontManager implements FontSupport, FontManagerForSGE {
boolean loadedAllFontFiles = false;
HashMap<String,String> jreFontMap;
HashSet<String> jreBundledFontFiles;
HashSet<String> ideaFontSet;
String[] jreOtherFontFiles;
boolean noOtherJREFontFiles = false; // initial assumption.
@@ -224,6 +243,8 @@ public abstract class SunFontManager implements FontSupport, FontManagerForSGE {
private static final FilenameFilter ttFilter = new TTFilter();
private static final FilenameFilter t1Filter = new T1Filter();
private FilenameFilter ttFilterIdea;
private FilenameFilter ttFilterJre;
private Font[] allFonts;
private String[] allFamilies; // cache for default locale only
private Locale lastDefaultLocale;
@@ -318,6 +339,23 @@ public abstract class SunFontManager implements FontSupport, FontManagerForSGE {
jreFontMap.put("Roboto light", "Roboto-Light.ttf");
jreFontMap.put("Roboto thin", "Roboto-Thin.ttf");
ideaFontSet = new HashSet<>();
ideaFontSet.add("FiraCode-Bold.ttf");
ideaFontSet.add("FiraCode-Light.ttf");
ideaFontSet.add("FiraCode-Medium.ttf");
ideaFontSet.add("FiraCode-Retina.ttf");
ideaFontSet.add("FiraCode-Regular.ttf");
ideaFontSet.add("SourceCodePro-BoldIt.ttf");
ideaFontSet.add("SourceCodePro-Regular.ttf");
ideaFontSet.add("SourceCodePro-Bold.ttf");
ideaFontSet.add("SourceCodePro-It.ttf");
ideaFontSet.add("Inconsolata.ttf");
ideaFontSet.add("Roboto-Light.ttf");
ideaFontSet.add("Roboto-Thin.ttf");
ttFilterIdea = new TTFilterIdea(true, ideaFontSet);
ttFilterJre = new TTFilterIdea(false, ideaFontSet);
for (String ffile : jreFontMap.values()) {
jreBundledFontFiles.add(ffile);
}
@@ -421,8 +459,7 @@ public abstract class SunFontManager implements FontSupport, FontManagerForSGE {
/* Linux font configuration uses these fonts */
registerFontDir(jreFontDirName);
}
registerFontsInDir(jreFontDirName, true, Font2D.JRE_RANK,
true, false);
registerJREFonts();
/* Create the font configuration and get any font path
* that might be specified.
@@ -3302,7 +3339,7 @@ public abstract class SunFontManager implements FontSupport, FontManagerForSGE {
/* Called to register fall back fonts */
public void registerFontsInDir(String dirName) {
registerFontsInDir(dirName, true, Font2D.JRE_RANK, true, false);
registerJREFonts();
}
// MACOSX begin -- need to access this in subclass
@@ -3323,6 +3360,18 @@ public abstract class SunFontManager implements FontSupport, FontManagerForSGE {
defer, resolveSymLinks);
}
protected void registerJREFonts() {
File pathFile = new File(jreFontDirName);
addDirFonts(jreFontDirName, pathFile, ttFilterIdea,
FONTFORMAT_TRUETYPE, true,
Font2D.IDEA_RANK,
true, false);
addDirFonts(jreFontDirName, pathFile, ttFilterJre,
FONTFORMAT_TRUETYPE, true,
Font2D.JRE_RANK,
true, false);
}
protected void registerFontDir(String path) {
}

View File

@@ -586,17 +586,21 @@ class XDnDDropTargetProtocol extends XDropTargetProtocol {
return false;
}
x = (int)(xclient.get_data(2) >> 16);
y = (int)(xclient.get_data(2) & 0xFFFF);
XWindow xwindow = null;
{
XBaseWindow xbasewindow = XToolkit.windowToXWindow(xclient.get_window());
if (xbasewindow instanceof XWindow) {
xwindow = (XWindow)xbasewindow;
// xclient can be a system-generated or a sent event (see XDragSourceContextPeer)
// so x/y is expected to be presented in device space
x = xbasewindow.scaleDown(x);
y = xbasewindow.scaleDown(y);
}
}
x = (int)(xclient.get_data(2) >> 16);
y = (int)(xclient.get_data(2) & 0xFFFF);
if (xwindow == null) {
long receiver =
XDropTargetRegistry.getRegistry().getEmbeddedDropSite(

View File

@@ -524,8 +524,9 @@ public final class XDragSourceContextPeer
updateTargetWindow(xmotion);
if (dragProtocol != null) {
dragProtocol.sendMoveMessage(scaleDown(xmotion.get_x_root()),
scaleDown(xmotion.get_y_root()),
// XDnDDropTargetProtocol.processXdndPosition will scale x/y
dragProtocol.sendMoveMessage(xmotion.get_x_root(),
xmotion.get_y_root(),
sourceAction, sourceActions,
xmotion.get_time());
}
@@ -533,8 +534,9 @@ public final class XDragSourceContextPeer
private void processDrop(XButtonEvent xbutton) {
try {
dragProtocol.initiateDrop(scaleDown(xbutton.get_x_root()),
scaleDown(xbutton.get_y_root()),
// XDnDDropTargetProtocol.processXdndPosition will scale x/y
dragProtocol.initiateDrop(xbutton.get_x_root(),
xbutton.get_y_root(),
sourceAction, sourceActions,
xbutton.get_time());
} catch (XException e) {

View File

@@ -1720,7 +1720,7 @@ void GetSysInsets(RECT* insets, AwtFrame* pFrame) {
int dpi = device ? device->GetScaleX() * 96 : 96;
// GetSystemMetricsForDpi gives incorrect values, use AdjustWindowRectExForDpi for border metrics instead
RECT rect = {0};
RECT rect = {};
DWORD style = pFrame->IsResizable() ? WS_OVERLAPPEDWINDOW : WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME;
AwtToolkit::AdjustWindowRectExForDpi(&rect, style, FALSE, NULL, dpi);
::SetRect(insets, -rect.left, -rect.top, rect.right, rect.bottom);
@@ -1734,7 +1734,7 @@ LRESULT HitTestNCA(AwtFrame* frame, int x, int y) {
GetWindowRect(frame->GetHWnd(), &rcWindow);
// Get the frame rectangle, adjusted for the style without a caption.
RECT rcFrame = {0};
RECT rcFrame = {};
AdjustWindowRectEx(&rcFrame, WS_OVERLAPPEDWINDOW & ~WS_CAPTION, FALSE, NULL);
USHORT uRow = 1;

View File

@@ -103,16 +103,21 @@ public class ClassLoaderReferenceImpl extends ObjectReferenceImpl
Type findType(String signature) throws ClassNotLoadedException {
List<ReferenceType> types = visibleClasses();
Iterator<ReferenceType> iter = types.iterator();
while (iter.hasNext()) {
ReferenceType type = iter.next();
// first check already loaded classes and possibly avoid massive signature retrieval later
String typeName = new JNITypeParser(signature).typeName();
for (ReferenceType type : vm.classesByName(typeName)) {
if (types.contains(type)) {
return type;
}
}
for (ReferenceType type : types) {
if (type.signature().equals(signature)) {
return type;
}
}
JNITypeParser parser = new JNITypeParser(signature);
throw new ClassNotLoadedException(parser.typeName(),
"Class " + parser.typeName() + " not loaded");
throw new ClassNotLoadedException(typeName, "Class " + typeName + " not loaded");
}
byte typeValueKey() {

View File

@@ -61,6 +61,9 @@ applications/ctw/modules/jdk_jconsole.java 8189604 windows-all
compiler/cpuflags/TestAESIntrinsicsOnSupportedConfig.java 8190680 generic-all
compiler/uncommontrap/DeoptReallocFailure.java nobug generic-all causes Out of memory: Java heap space affects run status
compiler/uncommontrap/TestDeoptOOM.java nobug generic-all causes Out of memory: Java heap space affects run status
#############################################################################
# :hotspot_gc

View File

@@ -0,0 +1,39 @@
/*
* Copyright 2000-2019 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.
*/
import javax.swing.*;
import java.awt.*;
import java.lang.reflect.InvocationTargetException;
/*
* @test
* @summary JBR-1604 Tooltip with package's info is cut
*/
public class JEditorPanePreferredSizeTest2 {
public static void main(String[] args) throws InvocationTargetException, InterruptedException {
final Dimension size = new Dimension();
SwingUtilities.invokeAndWait(() -> {
JEditorPane editorPane = new JEditorPane("text/html", "text");
editorPane.setBorder(null);
editorPane.getPreferredSize();
editorPane.setText("another text");
size.setSize(editorPane.getPreferredSize());
});
if (size.width <= 0 || size.height <= 0) {
throw new RuntimeException("Test FAILED: bad preferred size: " + size);
}
}
}

View File

@@ -125,7 +125,6 @@ java/awt/event/KeyEvent/ExtendedKeyCode/ExtendedKeyCodeTest.java
java/awt/event/KeyEvent/KeyChar/KeyCharTest.java nobug macosx-all,windows-all
java/awt/event/KeyEvent/KeyTyped/CtrlASCII.html nobug linux-all,windows-all
java/awt/event/KeyEvent/RobotCrash/RobotCrash.java nobug linux-all,windows-all
java/awt/event/KeyEvent/SwallowKeyEvents/SwallowKeyEvents.java nobug macosx-all,linux-all
java/awt/event/MouseEvent/ClickDuringKeypress/ClickDuringKeypress.java nobug macosx-all,windows-all,linux-all
java/awt/event/MouseEvent/EnterAsGrabbedEvent/EnterAsGrabbedEvent.java nobug macosx-all,windows-all
java/awt/event/MouseEvent/MouseButtonsTest/MouseButtonsTest.java nobug macosx-all,linux-all,windows-all
@@ -155,7 +154,7 @@ java/awt/print/PaintSetEnabledDeadlock/PaintSetEnabledDeadlock.java
javax/swing/JComboBox/4199622/bug4199622.java nobug windows-all
javax/swing/JComboBox/4523758/bug4523758.java nobug macosx-all,windows-all
javax/swing/JDialog/Transparency/TransparencyTest.java nobug macosx-all,windows-all
javax/swing/JDialog/Transparency/TransparencyTest.java nobug linux-all,macosx-all,windows-all
javax/swing/JEditorPane/JEditorPaneGCSwitchTest/JEditorPaneGCSwitchTest.java nobug windows-all
javax/swing/JEditorPane/JEditorPaneGCSwitchTest/JEditorPaneGCSwitchTest_i18n.java nobug windows-all
javax/swing/JFileChooser/6489130/bug6489130.java nobug macosx-all

View File

@@ -24,42 +24,26 @@
package performance.rendering;
import org.junit.Test;
import util.Renderer;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.QuadCurve2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
public class RenderPerfTest {
private final static int N = 1000;
private final static float WIDTH = 800;
private final static float HEIGHT = 800;
private final static float R = 25;
private final static int BW = 50;
private final static int BH = 50;
private final static int COUNT = 300;
private final static int DELAY = 10;
private final static int RESOLUTION = 5;
private final static int COLOR_TOLERANCE = 10;
interface Renderable {
void render(Graphics2D g2d);
void update();
}
static class Particles {
private float[] bx;
private float[] by;
@@ -384,113 +368,7 @@ public class RenderPerfTest {
}
}
class PerfMeter {
private int frame = 0;
private JPanel panel;
private long time;
private double execTime = 0;
private Color expColor = Color.RED;
AtomicBoolean waiting = new AtomicBoolean(false);
double exec(final Renderable renderable) throws Exception {
final CountDownLatch latch = new CountDownLatch(COUNT);
final CountDownLatch latchFrame = new CountDownLatch(1);
final JFrame f = new JFrame();
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
latchFrame.countDown();
}
});
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
panel = new JPanel()
{
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
time = System.nanoTime();
Graphics2D g2d = (Graphics2D) g;
renderable.render(g2d);
g2d.setColor(expColor);
g.fillRect(0, 0, BW, BH);
}
};
panel.setPreferredSize(new Dimension((int)(WIDTH + BW), (int)(HEIGHT + BH)));
panel.setBackground(Color.BLACK);
f.add(panel);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
}
});
Robot robot = new Robot();
Timer timer = new Timer(DELAY, e -> {
if (waiting.compareAndSet(false, true)) {
Color c = robot.getPixelColor(
panel.getTopLevelAncestor().getX() + panel.getTopLevelAncestor().getInsets().left + BW / 2,
panel.getTopLevelAncestor().getY() + panel.getTopLevelAncestor().getInsets().top + BW / 2);
if (isAlmostEqual(c, Color.BLUE)) {
expColor = Color.RED;
} else {
expColor = Color.BLUE;
}
renderable.update();
panel.getParent().repaint();
} else {
while (!isAlmostEqual(
robot.getPixelColor(
panel.getTopLevelAncestor().getX() + panel.getTopLevelAncestor().getInsets().left + BW/2,
panel.getTopLevelAncestor().getY() + panel.getTopLevelAncestor().getInsets().top + BH/2),
expColor))
{
try {
Thread.sleep(RESOLUTION);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
time = System.nanoTime() - time;
execTime += time;
frame++;
waiting.set(false);
}
latch.countDown();
});
timer.start();
latch.await();
SwingUtilities.invokeAndWait(() -> {
timer.stop();
f.setVisible(false);
f.dispose();
});
latchFrame.await();
return 1e9/(execTime / frame);
}
private boolean isAlmostEqual(Color c1, Color c2) {
return Math.abs(c1.getRed() - c2.getRed()) < COLOR_TOLERANCE ||
Math.abs(c1.getGreen() - c2.getGreen()) < COLOR_TOLERANCE ||
Math.abs(c1.getBlue() - c2.getBlue()) < COLOR_TOLERANCE;
}
}
private static final Particles balls = new Particles(N, R, BW, BH, WIDTH, HEIGHT);
private static final Particles balls = new Particles(N, R, 0, 0, Renderer.WIDTH, Renderer.HEIGHT);
private static final ParticleRenderer flatRenderer = new FlatParticleRenderer(N, R);
private static final ParticleRenderer flatOvalRotRenderer = new FlatOvalRotParticleRenderer(N, R);
private static final ParticleRenderer flatBoxRenderer = new FlatBoxParticleRenderer(N, R);
@@ -520,7 +398,7 @@ public class RenderPerfTest {
@Test
public void testFlatBubbles() throws Exception {
double fps = (new PerfMeter()).exec(new Renderable() {
double fps = (new util.Renderer(COUNT)).exec(new Renderer.Renderable() {
@Override
public void render(Graphics2D g2d) {
balls.render(g2d, flatRenderer);
@@ -530,6 +408,11 @@ public class RenderPerfTest {
public void update() {
balls.update();
}
@Override
public void screenShot(BufferedImage result) {
System.err.println();
}
});
report("FlatOval", fps);
@@ -538,7 +421,7 @@ public class RenderPerfTest {
@Test
public void testFlatBoxBubbles() throws Exception {
double fps = (new PerfMeter()).exec(new Renderable() {
double fps = (new util.Renderer(COUNT)).exec(new Renderer.DefaultRenderable() {
@Override
public void render(Graphics2D g2d) {
balls.render(g2d, flatBoxRenderer);
@@ -556,7 +439,7 @@ public class RenderPerfTest {
@Test
public void testImgBubbles() throws Exception {
double fps = (new PerfMeter()).exec(new Renderable() {
double fps = (new util.Renderer(COUNT)).exec(new Renderer.DefaultRenderable() {
@Override
public void render(Graphics2D g2d) {
balls.render(g2d, imgRenderer);
@@ -574,7 +457,7 @@ public class RenderPerfTest {
@Test
public void testFlatBoxRotBubbles() throws Exception {
double fps = (new PerfMeter()).exec(new Renderable() {
double fps = (new util.Renderer(COUNT)).exec(new Renderer.DefaultRenderable() {
@Override
public void render(Graphics2D g2d) {
balls.render(g2d, flatBoxRotRenderer);
@@ -592,7 +475,7 @@ public class RenderPerfTest {
@Test
public void testFlatOvalRotBubbles() throws Exception {
double fps = (new PerfMeter()).exec(new Renderable() {
double fps = (new util.Renderer(COUNT)).exec(new Renderer.DefaultRenderable() {
@Override
public void render(Graphics2D g2d) {
balls.render(g2d, flatOvalRotRenderer);
@@ -610,7 +493,7 @@ public class RenderPerfTest {
@Test
public void testLinGradOvalRotBubbles() throws Exception {
double fps = (new PerfMeter()).exec(new Renderable() {
double fps = (new util.Renderer(COUNT)).exec(new Renderer.DefaultRenderable() {
@Override
public void render(Graphics2D g2d) {
balls.render(g2d, linGradOvalRotRenderer);
@@ -629,7 +512,7 @@ public class RenderPerfTest {
@Test
public void testWiredBubbles() throws Exception {
double fps = (new PerfMeter()).exec(new Renderable() {
double fps = (new util.Renderer(COUNT)).exec(new Renderer.DefaultRenderable() {
@Override
public void render(Graphics2D g2d) {
balls.render(g2d, wiredRenderer);
@@ -647,7 +530,7 @@ public class RenderPerfTest {
@Test
public void testWiredBoxBubbles() throws Exception {
double fps = (new PerfMeter()).exec(new Renderable() {
double fps = (new util.Renderer(COUNT)).exec(new Renderer.DefaultRenderable() {
@Override
public void render(Graphics2D g2d) {
balls.render(g2d, wiredBoxRenderer);
@@ -665,7 +548,7 @@ public class RenderPerfTest {
@Test
public void testLines() throws Exception {
double fps = (new PerfMeter()).exec(new Renderable() {
double fps = (new util.Renderer(COUNT)).exec(new Renderer.DefaultRenderable() {
@Override
public void render(Graphics2D g2d) {
balls.render(g2d, segRenderer);
@@ -683,7 +566,7 @@ public class RenderPerfTest {
@Test
public void testFlatQuad() throws Exception {
double fps = (new PerfMeter()).exec(new Renderable() {
double fps = (new util.Renderer(COUNT)).exec(new Renderer.DefaultRenderable() {
@Override
public void render(Graphics2D g2d) {
balls.render(g2d, flatQuadRenderer);
@@ -701,7 +584,7 @@ public class RenderPerfTest {
@Test
public void testWiredQuad() throws Exception {
double fps = (new PerfMeter()).exec(new Renderable() {
double fps = (new util.Renderer(COUNT)).exec(new Renderer.DefaultRenderable() {
@Override
public void render(Graphics2D g2d) {
balls.render(g2d, wiredQuadRenderer);
@@ -719,7 +602,7 @@ public class RenderPerfTest {
@Test
public void testTextBubblesNoAA() throws Exception {
double fps = (new PerfMeter()).exec(new Renderable() {
double fps = (new util.Renderer(COUNT)).exec(new Renderer.DefaultRenderable() {
@Override
public void render(Graphics2D g2d) {
balls.render(g2d, textRendererNoAA);
@@ -737,7 +620,7 @@ public class RenderPerfTest {
@Test
public void testTextBubblesLCD() throws Exception {
double fps = (new PerfMeter()).exec(new Renderable() {
double fps = (new util.Renderer(COUNT)).exec(new Renderer.DefaultRenderable() {
@Override
public void render(Graphics2D g2d) {
balls.render(g2d, textRendererLCD);
@@ -755,7 +638,7 @@ public class RenderPerfTest {
@Test
public void testTextBubblesGray() throws Exception {
double fps = (new PerfMeter()).exec(new Renderable() {
double fps = (new util.Renderer(COUNT)).exec(new Renderer.DefaultRenderable() {
@Override
public void render(Graphics2D g2d) {
balls.render(g2d, textRendererGray);
@@ -773,7 +656,7 @@ public class RenderPerfTest {
@Test
public void testWhiteTextBubblesNoAA() throws Exception {
double fps = (new PerfMeter()).exec(new Renderable() {
double fps = (new util.Renderer(COUNT)).exec(new Renderer.DefaultRenderable() {
@Override
public void render(Graphics2D g2d) {
balls.render(g2d, whiteTextRendererNoAA);
@@ -791,7 +674,7 @@ public class RenderPerfTest {
@Test
public void testWhiteTextBubblesLCD() throws Exception {
double fps = (new PerfMeter()).exec(new Renderable() {
double fps = (new util.Renderer(COUNT)).exec(new Renderer.DefaultRenderable() {
@Override
public void render(Graphics2D g2d) {
balls.render(g2d, whiteTextRendererLCD);
@@ -809,7 +692,7 @@ public class RenderPerfTest {
@Test
public void testWhiteTextBubblesGray() throws Exception {
double fps = (new PerfMeter()).exec(new Renderable() {
double fps = (new Renderer(COUNT)).exec(new Renderer.DefaultRenderable() {
@Override
public void render(Graphics2D g2d) {
balls.render(g2d, whiteTextRendererGray);

View File

@@ -0,0 +1,37 @@
package quality.text;
import org.junit.Assert;
import org.junit.Test;
import quality.util.RenderUtil;
import util.Renderer;
import java.awt.*;
import java.awt.image.BufferedImage;
public class FiraCodeScrTest {
@Test
public void testRenderText() throws Exception {
String [] testResult = new String[] {null};
(new util.Renderer(2, 300, 30, true)).exec(new Renderer.DefaultRenderable() {
@Override
public void render(Graphics2D g2d) {
g2d.setColor(Color.WHITE);
Font f = new Font("Fira Code", Font.PLAIN, 12);
g2d.setFont(f);
g2d.drawString("The quick brown fox jumps over the lazy dog", 0, 15);
}
@Override
public void screenShot(BufferedImage result) {
try {
RenderUtil.checkImage(result, "text", "firacode.png");
} catch (Exception e) {
testResult[0] = e.getMessage();
}
}
});
if (testResult[0] != null) Assert.fail(testResult[0]);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,170 @@
package util;
import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
public class Renderer {
public final static int WIDTH = 800;
public final static int HEIGHT = 800;
public final static int BW = 50;
public final static int BH = 50;
private final static int RESOLUTION = 5;
private final static int COLOR_TOLERANCE = 10;
private final static int DELAY = 10;
private int frame = 0;
private final int count;
private final int width;
private final int height;
private final boolean capture;
private JPanel panel;
private long time;
private double execTime = 0;
private Color expColor = Color.RED;
AtomicBoolean waiting = new AtomicBoolean(false);
public Renderer(int count) {
this(count, WIDTH, HEIGHT, false);
}
public Renderer(int count, int width, int height, boolean capture) {
this.count = count;
this.width = width;
this.height = height;
this.capture = capture;
}
public double exec(final Renderable renderable) throws Exception {
final CountDownLatch latch = new CountDownLatch(count);
final CountDownLatch latchFrame = new CountDownLatch(1);
final JFrame f = new JFrame();
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
latchFrame.countDown();
}
});
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
panel = new JPanel()
{
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
time = System.nanoTime();
Graphics2D g2d = (Graphics2D) g;
g2d.translate(BW, BH);
renderable.render(g2d);
g2d.translate(-BW, -BH);
g2d.setColor(expColor);
g.fillRect(0, 0, BW, BH);
}
};
panel.setPreferredSize(new Dimension(width + BW, height + BH));
panel.setBackground(Color.BLACK);
f.add(panel);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
}
});
Robot robot = new Robot();
Timer timer = new Timer(DELAY, e -> {
if (waiting.compareAndSet(false, true)) {
Color c = robot.getPixelColor(
panel.getTopLevelAncestor().getX() + panel.getTopLevelAncestor().getInsets().left + BW / 2,
panel.getTopLevelAncestor().getY() + panel.getTopLevelAncestor().getInsets().top + BH / 2);
if (isAlmostEqual(c, Color.BLUE)) {
expColor = Color.RED;
} else {
expColor = Color.BLUE;
}
if (capture) {
renderable.screenShot(robot.createScreenCapture(
new Rectangle(
panel.getTopLevelAncestor().getX() + panel.getTopLevelAncestor().getInsets().left + BW,
panel.getTopLevelAncestor().getY() + panel.getTopLevelAncestor().getInsets().top + BH,
width, height)));
}
renderable.update();
panel.getParent().repaint();
} else {
while (!isAlmostEqual(
robot.getPixelColor(
panel.getTopLevelAncestor().getX() + panel.getTopLevelAncestor().getInsets().left + BW/2,
panel.getTopLevelAncestor().getY() + panel.getTopLevelAncestor().getInsets().top + BH/2),
expColor))
{
try {
Thread.sleep(RESOLUTION);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
time = System.nanoTime() - time;
execTime += time;
frame++;
waiting.set(false);
}
latch.countDown();
});
timer.start();
latch.await();
SwingUtilities.invokeAndWait(() -> {
timer.stop();
f.setVisible(false);
f.dispose();
});
latchFrame.await();
return 1e9/(execTime / frame);
}
private boolean isAlmostEqual(Color c1, Color c2) {
return Math.abs(c1.getRed() - c2.getRed()) < COLOR_TOLERANCE ||
Math.abs(c1.getGreen() - c2.getGreen()) < COLOR_TOLERANCE ||
Math.abs(c1.getBlue() - c2.getBlue()) < COLOR_TOLERANCE;
}
public interface Renderable {
void render(Graphics2D g2d);
void update();
void screenShot(BufferedImage result);
}
public static class DefaultRenderable implements Renderable {
@Override
public void render(Graphics2D g2d) {
}
@Override
public void update() {
}
@Override
public void screenShot(BufferedImage result) {
}
}
}