Compare commits

..

1 Commits

Author SHA1 Message Date
Alexey Ushakov
9db9a9add7 JBR-3066 jbr 11_10 (1145-88) crashes on IDEA startup, jbr 11_09 (1145-77) works fine
Added missing initializations
2021-02-10 16:58:27 +03:00
29 changed files with 158 additions and 789 deletions

View File

@@ -39,8 +39,15 @@ source jb/project/tools/common.sh
function copyJNF {
__contents_dir=$1
mkdir -p ${__contents_dir}/Frameworks
cp -Rp Frameworks/JavaNativeFoundation.framework ${__contents_dir}/Frameworks
# we can't notarize this library as usual framework (with headers and tbd-file)
# but single library notarizes correctly
mkdir -p ${__contents_dir}/Frameworks/JavaNativeFoundation.framework/Resources
cp -p Frameworks/JavaNativeFoundation.framework/JavaNativeFoundation \
${__contents_dir}/Frameworks/JavaNativeFoundation.framework || do_exit $?
cp -p Frameworks/JavaNativeFoundation.framework/Resources/Info.plist \
${__contents_dir}/Frameworks/JavaNativeFoundation.framework/Resources || do_exit $?
# unsign JavaNativeFoundation binary (otherwise notarization will fail)
codesign --remove-signature ${__contents_dir}/Frameworks/JavaNativeFoundation.framework/JavaNativeFoundation || do_exit $?
}
function create_jbr {

View File

@@ -26,7 +26,8 @@ log "Signing libraries and executables..."
# -perm +111 searches for executables
for f in \
"Contents/Home/bin" \
"Contents/Home/lib"; do
"Contents/Home/lib" \
"Contents/Frameworks"; do
if [ -d "$APP_DIRECTORY/$f" ]; then
find "$APP_DIRECTORY/$f" \
-type f \( -name "*.jnilib" -o -name "*.dylib" -o -name "*.so" -o -perm +111 \) \
@@ -36,20 +37,6 @@ for f in \
fi
done
if [ -d "$APP_DIRECTORY/Contents/Frameworks" ]; then
log "Signing frameworks..."
for f in $APP_DIRECTORY/Contents/Frameworks/*; do
find "$f" \
-type f \( -name "*.jnilib" -o -name "*.dylib" -o -name "*.so" \) \
-exec codesign --timestamp --force \
-v -s "$JB_CERT" \
--entitlements entitlements.xml {} \;
codesign --timestamp --force \
-v -s "$JB_CERT" --options=runtime \
--entitlements entitlements.xml "$f"
done
fi
log "Signing libraries in jars in $PWD"
# todo: add set -euo pipefail; into the inner sh -c

View File

@@ -736,17 +736,16 @@ public final class SSLSocketImpl
// Is it ready to close inbound?
//
// No need to throw exception if the initial handshake is not started.
try {
if (checkCloseNotify && !conContext.isInputCloseNotified &&
(conContext.isNegotiated || conContext.handshakeContext != null)) {
throw new SSLException(
if (checkCloseNotify && !conContext.isInputCloseNotified &&
(conContext.isNegotiated || conContext.handshakeContext != null)) {
throw conContext.fatal(Alert.INTERNAL_ERROR,
"closing inbound before receiving peer's close_notify");
}
} finally {
conContext.closeInbound();
if ((autoClose || !isLayered()) && !super.isInputShutdown()) {
super.shutdownInput();
}
}
conContext.closeInbound();
if ((autoClose || !isLayered()) && !super.isInputShutdown()) {
super.shutdownInput();
}
}

View File

@@ -100,17 +100,6 @@ final class ScreenMenuItem extends MenuItem
fMenuItem.removeComponentListener(this);
}
static void syncAcceleratorText(MenuItem menuItem, JMenuItem fMenuItem) {
Object acceleratorText = fMenuItem.getClientProperty("accelerator.text");
if (acceleratorText instanceof String) {
Object peer = AWTAccessor.getMenuComponentAccessor().getPeer(menuItem);
if (peer instanceof CMenuItem) {
final CMenuItem cmi = (CMenuItem) peer;
cmi.setAcceleratorText((String)acceleratorText);
}
}
}
static void syncLabelAndKS(MenuItem menuItem, String label, KeyStroke ks) {
Object peer = AWTAccessor.getMenuComponentAccessor().getPeer(menuItem);
if (!(peer instanceof CMenuItem)) {
@@ -134,12 +123,6 @@ final class ScreenMenuItem extends MenuItem
@Override
public void setAccelerator(final KeyStroke ks) {
syncLabelAndKS(this, fMenuItem.getText(), ks);
syncAcceleratorText(this, fMenuItem);
}
@Override
public void setAcceleratorText(String acceleratorText) {
syncAcceleratorText(this, fMenuItem);
}
public void actionPerformed(final ActionEvent e) {

View File

@@ -123,12 +123,6 @@ final class ScreenMenuItemCheckbox extends CheckboxMenuItem
@Override
public void setAccelerator(final KeyStroke ks) {
ScreenMenuItem.syncLabelAndKS(this, fMenuItem.getText(), ks);
ScreenMenuItem.syncAcceleratorText(this, fMenuItem);
}
@Override
public void setAcceleratorText(String acceleratorText) {
ScreenMenuItem.syncAcceleratorText(this, fMenuItem);
}
public void actionPerformed(final ActionEvent e) {

View File

@@ -36,7 +36,6 @@ interface ScreenMenuPropertyHandler {
public void setLabel(String f);
public void setIcon(Icon icon);
public void setAccelerator(KeyStroke ks);
default void setAcceleratorText(String acceleratorText) {}
public void setToolTipText(String tooltip);
public void setChildVisible(javax.swing.JMenuItem child, boolean b);
public void setIndeterminate(boolean indeterminate);

View File

@@ -67,11 +67,6 @@ class ScreenMenuPropertyListener implements PropertyChangeListener {
return;
}
if ("accelerator.text".equals(propertyName)) {
fMenu.setAcceleratorText((String)e.getNewValue());
return;
}
if (AbstractButton.TEXT_CHANGED_PROPERTY.equals(propertyName)) {
fMenu.setLabel((String)e.getNewValue());
return;

View File

@@ -104,10 +104,6 @@ public class CMenuItem extends CMenuComponent implements MenuItemPeer {
setLabel(label, (char)0, KeyEvent.VK_UNDEFINED, 0);
}
public void setAcceleratorText(String acceleratorText) {
execute(ptr -> nativeSetAcceleratorText(ptr, acceleratorText));
}
/**
* This is new API that we've added to AWT menu items
* because AWT menu items are used for Swing screen menu bars
@@ -154,7 +150,6 @@ public class CMenuItem extends CMenuComponent implements MenuItemPeer {
private native void nativeSetImage(long modelPtr, long image);
private native void nativeSetTooltip(long modelPtr, String text);
private native void nativeSetEnabled(long modelPtr, boolean b);
private native void nativeSetAcceleratorText(long modelPtr, String acceleratorText);
// native callbacks
void handleAction(final long when, final int modifiers) {

View File

@@ -169,25 +169,44 @@ canChooseDirectories:(BOOL)inChooseDirectories
[thePanel setAppearance:fOwner.appearance];
}
fPanelResult = [thePanel runModal];
void (^onComplete)(BOOL, BOOL) = ^(BOOL responseOK, BOOL doStopModal) {
if (responseOK) {
NSOpenPanel *openPanel = (NSOpenPanel *)thePanel;
fURLs = (fMode == java_awt_FileDialog_LOAD)
? [openPanel URLs]
: [NSArray arrayWithObject:[openPanel URL]];
if (menuBar != nil) {
[CMenuBar activate:menuBar modallyDisabled:NO];
}
fPanelResult = NSFileHandlingPanelOKButton;
} else {
fURLs = [NSArray array];
}
[fURLs retain];
if (doStopModal)
[NSApp stopModal];
if (menuBar != nil) {
[CMenuBar activate:menuBar modallyDisabled:NO];
}
};
[thePanel beginSheetModalForWindow:fOwner completionHandler:^(NSInteger result) {
onComplete(result == NSFileHandlingPanelOKButton, YES);
}];
[NSApp runModalForWindow:thePanel];
}
else
{
fPanelResult = [thePanel runModalForDirectory:fDirectory file:fFile];
}
if ([self userClickedOK]) {
if (fMode == java_awt_FileDialog_LOAD) {
NSOpenPanel *openPanel = (NSOpenPanel *)thePanel;
fURLs = [openPanel URLs];
} else {
fURLs = [NSArray arrayWithObject:[thePanel URL]];
if ([self userClickedOK]) {
if (fMode == java_awt_FileDialog_LOAD) {
NSOpenPanel *openPanel = (NSOpenPanel *)thePanel;
fURLs = [openPanel URLs];
} else {
fURLs = [NSArray arrayWithObject:[thePanel URL]];
}
[fURLs retain];
}
[fURLs retain];
}
[thePanel setDelegate:nil];

View File

@@ -38,277 +38,6 @@
#define NOT_A_CHECKBOXMENU -2
@interface CustomMenuItemView : NSView {
int16_t fireTimes;
BOOL isSelected;
NSSize shortcutSize;
NSSize textSize;
NSTrackingArea * trackingArea;
CMenuItem * owner;
}
@property (retain) NSString * keyShortcut;
@end
@implementation CustomMenuItemView
static CGFloat menuItemHeight = 18.f;
static CGFloat marginLeft = 20.f;
static CGFloat marginRight = 10.f;
static CGFloat gapTxtIcon = 5.f;
static CGFloat gapTxtShortcut = 23.f;
static NSFont * menuFont;
static NSFont * menuShortcutFont;
static NSColor * customBg = nil;
+ (void)initialize {
menuFont = [NSFont menuBarFontOfSize:(0)];
menuShortcutFont = [NSFont menuBarFontOfSize:(0)];
NSDictionary * attributes = [NSDictionary dictionaryWithObjectsAndKeys:menuFont, NSFontAttributeName, nil];
NSSize qSize = [[[[NSAttributedString alloc] initWithString:@"Q" attributes:attributes] autorelease] size];
// use empiric proportions (to look like default view)
menuItemHeight = qSize.height * 1.1f;
marginLeft = menuItemHeight * 1.1f;
marginRight = menuItemHeight * 0.55f;
gapTxtIcon = menuItemHeight * 0.27f;
gapTxtShortcut = menuItemHeight * 1.2f;
// Initialize custom bg color (for light theme with enabled accessibility.reduceTransparency)
// If we use transparent bg than we will see visual inconsistency
// And it seems that we can't obtain this color from system
NSUserDefaults * defs = [NSUserDefaults standardUserDefaults];
NSDictionary<NSString *,id> * dict = [defs persistentDomainForName:@"com.apple.universalaccess.plist"];
if (dict != nil) {
id reduceVal = [dict valueForKey:@"reduceTransparency"];
if (reduceVal != nil && [reduceVal isKindOfClass:[NSNumber class]] && [reduceVal intValue] != 0) {
NSString * mode = [defs stringForKey:@"AppleInterfaceStyle"];
if (mode == nil) { // light system theme
customBg = [NSColor colorWithCalibratedWhite:246.f/255 alpha:1.f];
[customBg retain];
// NSLog(@"\treduceTransparency is enabled (use custom background color for menu items)");
}
}
}
// NSLog(@"\tmenuItemHeight=%1.2f, marginLeft=%1.2f, marginRight=%1.2f, gapTxtIcon=%1.2f, gapTxtShortcut=%1.2f",
// menuItemHeight, marginLeft, marginRight, gapTxtIcon, gapTxtShortcut);
}
- (id)initWithOwner:(CMenuItem *)menuItem {
NSRect viewRect = NSMakeRect(0, 0, /* width autoresizes */ 1, menuItemHeight);
self = [super initWithFrame:viewRect];
if (self == nil) {
return self;
}
owner = menuItem;
self.autoresizingMask = NSViewWidthSizable;
self.keyShortcut = nil;
fireTimes = 0;
isSelected = NO;
trackingArea = nil;
shortcutSize = NSZeroSize;
textSize = NSZeroSize;
return self;
}
- (void)dealloc {
if(trackingArea != nil) {
[trackingArea release];
}
[super dealloc];
}
- (void)mouseEntered:(NSEvent*)event {
if ([owner isEnabled] && !isSelected) {
isSelected = YES;
[self setNeedsDisplay:YES];
}
}
- (void)mouseExited:(NSEvent *)event {
if (isSelected) {
isSelected = NO;
[self setNeedsDisplay:YES];
}
}
- (void)mouseUp:(NSEvent*)event {
if (![owner isEnabled])
return;
fireTimes = 0;
isSelected = !isSelected;
[self setNeedsDisplay:YES];
NSTimer *timer = [NSTimer timerWithTimeInterval:0.05 target:self selector:@selector(animateDismiss:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSEventTrackingRunLoopMode];
}
-(void)updateTrackingAreas {
[super updateTrackingAreas];
if(trackingArea != nil) {
[self removeTrackingArea:trackingArea];
[trackingArea release];
}
int opts = (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways);
trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds]
options:opts
owner:self
userInfo:nil];
[self addTrackingArea:trackingArea];
}
-(void)animateDismiss:(NSTimer *)aTimer {
if (fireTimes <= 2) {
isSelected = !isSelected;
[self setNeedsDisplay:YES];
} else {
[aTimer invalidate];
[self sendAction];
}
fireTimes++;
}
- (void)sendAction {
NSMenuItem * mi = owner.menuItem;
[NSApp sendAction:[mi action] to:[mi target] from:mi];
NSMenu *menu = [mi menu];
[menu cancelTracking];
// NOTE: we can also invoke handler directly [owner handleAction:[owner menuItem]];
}
//#define VISUAL_DEBUG_CUSTOM_ITEM_VIEW
- (void) drawRect:(NSRect)dirtyRect {
NSRect rectBounds = [self bounds];
NSString * text = owner.menuItem.title;
#ifdef VISUAL_DEBUG_CUSTOM_ITEM_VIEW
[[NSColor yellowColor] set];
NSFrameRectWithWidth([self bounds], 1.0f);
#endif // VISUAL_DEBUG_CUSTOM_ITEM_VIEW
const BOOL isEnabled = [owner isEnabled];
NSColor * textColor = [NSColor textColor];
NSColor * bgColor = customBg != nil ? customBg : [NSColor clearColor];
if (!isEnabled) {
textColor = [NSColor grayColor];
} else if (isSelected) {
if (@available(macOS 10.14, *)) {
bgColor = [NSColor controlAccentColor];
} else {
bgColor = [NSColor selectedControlColor];
}
textColor = [NSColor selectedMenuItemTextColor];
}
// 1. draw bg
[bgColor set];
NSRectFill(rectBounds);
// 2. draw icon if presented
CGFloat x = rectBounds.origin.x + marginLeft;
NSImage * image = owner.menuItem.image;
if (image != nil) {
NSRect imageBounds = rectBounds;
imageBounds.origin.x = x;
imageBounds.size.width = image.size.width;
[image drawInRect:imageBounds];
x += image.size.width + gapTxtIcon;
#ifdef VISUAL_DEBUG_CUSTOM_ITEM_VIEW
[[NSColor redColor] set];
NSFrameRectWithWidth(imageBounds, 1.0f);
#endif // VISUAL_DEBUG_CUSTOM_ITEM_VIEW
}
// 3. draw text
[textColor set];
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
menuFont, NSFontAttributeName,
textColor, NSForegroundColorAttributeName,
nil];
NSRect txtBounds = rectBounds;
txtBounds.origin.x = x;
txtBounds.size.width = textSize.width;
[text drawInRect:txtBounds withAttributes:attributes];
#ifdef VISUAL_DEBUG_CUSTOM_ITEM_VIEW
[[NSColor blackColor] set];
NSFrameRectWithWidth(txtBounds, 1.0f);
#endif // VISUAL_DEBUG_CUSTOM_ITEM_VIEW
if (self.keyShortcut != nil) {
// 4.1 draw shortcut
NSRect keyBounds = rectBounds;
keyBounds.origin.x = keyBounds.size.width - marginRight - shortcutSize.width;
keyBounds.size.width = shortcutSize.width;
NSDictionary *keyAttr = [NSDictionary dictionaryWithObjectsAndKeys:
menuShortcutFont, NSFontAttributeName,
textColor, NSForegroundColorAttributeName,
nil];
[self.keyShortcut drawInRect:keyBounds withAttributes:keyAttr];
#ifdef VISUAL_DEBUG_CUSTOM_ITEM_VIEW
[[NSColor magentaColor] set];
NSFrameRectWithWidth(keyBounds, 1.0f);
#endif // VISUAL_DEBUG_CUSTOM_ITEM_VIEW
} else {
if ([owner isKindOfClass:CMenu.class]) {
// 4.2 draw arrow-image of submenu
NSImage *arrow = [NSImage imageNamed:NSImageNameRightFacingTriangleTemplate]; // TODO: use correct triangle image
NSRect arrowBounds = rectBounds;
arrowBounds.origin.x = rectBounds.size.width - marginRight - arrow.size.width;
arrowBounds.origin.y = rectBounds.origin.y + (rectBounds.size.height - arrow.size.height) / 2;
arrowBounds.size = arrow.size;
[arrow drawInRect:arrowBounds];
#ifdef VISUAL_DEBUG_CUSTOM_ITEM_VIEW
[[NSColor magentaColor] set];
NSFrameRectWithWidth(arrowBounds, 1.0f);
#endif // VISUAL_DEBUG_CUSTOM_ITEM_VIEW
}
}
}
- (void)recalcSizes {
NSString * text = owner.menuItem.title;
NSImage * image = owner.menuItem.image;
NSDictionary * attributes = [NSDictionary dictionaryWithObjectsAndKeys:menuFont, NSFontAttributeName, nil];
textSize = [[[[NSAttributedString alloc] initWithString:text attributes:attributes] autorelease] size];
NSSize resultSize = NSMakeSize(textSize.width + marginLeft + marginRight, menuItemHeight);
if (image != nil) {
NSSize imgSize = image.size;
resultSize.width += imgSize.width + gapTxtIcon;
}
if (self.keyShortcut != nil) {
NSDictionary * ksa = [NSDictionary dictionaryWithObjectsAndKeys:menuShortcutFont, NSFontAttributeName, nil];
shortcutSize = [[[[NSAttributedString alloc] initWithString:self.keyShortcut attributes:ksa] autorelease] size];
resultSize.width += shortcutSize.width + gapTxtShortcut;
}
[self.widthAnchor constraintGreaterThanOrEqualToConstant:resultSize.width].active = YES;
}
@end
@implementation CMenuItem
@@ -411,20 +140,6 @@ static NSColor * customBg = nil;
}
- (void) setAcceleratorText:(NSString *)acceleratorText {
if ([acceleratorText isEqualToString:@""]) {
acceleratorText = nil;
}
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
CustomMenuItemView *menuItemView = fMenuItem.view;
if (menuItemView == nil) {
fMenuItem.view = menuItemView = [[[CustomMenuItemView alloc] initWithOwner:self] autorelease];
}
menuItemView.keyShortcut = acceleratorText;
[menuItemView recalcSizes];
}];
}
- (void) setJavaLabel:(NSString *)theLabel shortcut:(NSString *)theKeyEquivalent modifierMask:(jint)modifiers {
NSUInteger modifierMask = 0;
@@ -451,18 +166,13 @@ static NSColor * customBg = nil;
[fMenuItem setKeyEquivalent:theKeyEquivalent];
[fMenuItem setKeyEquivalentModifierMask:modifierMask];
[fMenuItem setTitle:theLabel];
if ([fMenuItem.view isKindOfClass:CustomMenuItemView.class]) {
[(CustomMenuItemView *)fMenuItem.view recalcSizes];
}
}];
}
- (void) setJavaImage:(NSImage *)theImage {
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
[fMenuItem setImage:theImage];
if ([fMenuItem.view isKindOfClass:CustomMenuItemView.class]) {
[(CustomMenuItemView *)fMenuItem.view recalcSizes];
}
}];
}
@@ -473,6 +183,7 @@ static NSColor * customBg = nil;
}];
}
- (void)setJavaEnabled:(BOOL) enabled {
[ThreadUtilities performOnMainThreadWaiting:NO block:^(){
@@ -647,21 +358,6 @@ Java_sun_lwawt_macosx_CMenuItem_nativeSetLabel
JNF_COCOA_EXIT(env);
}
/*
* Class: sun_lwawt_macosx_CMenuItem
* Method: nativeSetAcceleratorText
* Signature: (JLjava/lang/String;)V
*/
JNIEXPORT void JNICALL
Java_sun_lwawt_macosx_CMenuItem_nativeSetAcceleratorText
(JNIEnv *env, jobject peer, jlong menuItemObj, jstring acceleratorText)
{
JNF_COCOA_ENTER(env);
NSString *theText = JNFJavaToNSString(env, acceleratorText);
[((CMenuItem *)jlong_to_ptr(menuItemObj)) setAcceleratorText:theText];
JNF_COCOA_EXIT(env);
}
/*
* Class: sun_lwawt_macosx_CMenuItem
* Method: nativeSetTooltip

View File

@@ -606,8 +606,6 @@ CGGI_CreateNewGlyphInfoFrom(CGSize advance, CGRect bbox,
glyphInfo->height = height;
glyphInfo->rowBytes = width * pixelSize;
glyphInfo->cellInfo = NULL;
glyphInfo->subpixelResolutionX = 1;
glyphInfo->subpixelResolutionY = 1;
#ifdef USE_IMAGE_ALIGNED_MEMORY
glyphInfo->image = image;

View File

@@ -163,28 +163,6 @@ AWT_ASSERT_APPKIT_THREAD;
// inform any interested parties that the AWT has arrived and is pumping
[[NSNotificationCenter defaultCenter] postNotificationName:JNFRunLoopDidStartNotification object:self];
// fix for JBR-3127 Modal dialogs invoked from modal or floating dialogs are opened in full screen
[defs setBool:NO forKey:@"NSWindowAllowsImplicitFullScreen"];
// temporary possibility to load deprecated NSJavaVirtualMachine (just for testing)
// todo: remove when completely tested on BigSur
// see https://youtrack.jetbrains.com/issue/JBR-3127#focus=Comments-27-4684465.0-0
NSString * loadNSJVMProp = [PropertiesUtilities
javaSystemPropertyForKey:@"apple.awt.application.instantiate.NSJavaVirtualMachine"
withEnv:env];
if ([@"true" isCaseInsensitiveLike:loadNSJVMProp]) {
if (objc_lookUpClass("NSJavaVirtualMachine") != nil) {
NSLog(@"objc class NSJavaVirtualMachine is already registered");
} else {
Class nsjvm = objc_allocateClassPair([NSObject class], "NSJavaVirtualMachine", 0);
objc_registerClassPair(nsjvm);
NSLog(@"registered class NSJavaVirtualMachine: %@", nsjvm);
id nsjvmInst = [[nsjvm alloc] init];
NSLog(@"instantiated dummy NSJavaVirtualMachine: %@", nsjvmInst);
}
}
}
- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center

View File

@@ -25,7 +25,7 @@
package sun.font;
import java.awt.*;
import java.awt.Font;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
@@ -58,8 +58,6 @@ public final class FontUtilities {
public static boolean isOpenJDK;
public static Dimension supplementarySubpixelGlyphResolution;
static final String LUCIDA_FILE_NAME = "LucidaSansRegular.ttf";
static final String DROID_FILE_NAME = "DroidSans.ttf";
@@ -133,20 +131,6 @@ public final class FontUtilities {
logging = logger.isEnabled();
}
try {
String property = System.getProperty("java2d.font.subpixelResolution", "");
int separatorIndex = property.indexOf('x');
final int MAX_RESOLUTION = 16;
supplementarySubpixelGlyphResolution = new Dimension(
Math.max(Math.min(Integer.parseUnsignedInt(
property.substring(0, separatorIndex)), MAX_RESOLUTION), 1),
Math.max(Math.min(Integer.parseUnsignedInt(
property.substring(separatorIndex + 1)), MAX_RESOLUTION), 1)
);
} catch (Exception ignore) {
supplementarySubpixelGlyphResolution = new Dimension(1, 1);
}
return null;
}
});

View File

@@ -74,14 +74,11 @@ class FreetypeFontScaler extends FontScaler {
});
initIDs(FreetypeFontScaler.class, Toolkit.class, PhysicalFont.class,
fontConfName,
FontUtilities.supplementarySubpixelGlyphResolution.width,
FontUtilities.supplementarySubpixelGlyphResolution.height);
fontConfName);
}
private static native void initIDs(Class<?> FFS, Class<?> toolkitClass, Class<?> pfClass,
String jreFontDirName,
int subpixelResolutionX, int subpixelResolutionY);
String jreFontDirName);
private void invalidateScaler() throws FontScalerException {
nativeScaler = 0;

View File

@@ -114,8 +114,6 @@ public final class StrikeCache {
static int pixelDataOffset;
static int cacheCellOffset;
static int managedOffset;
static int subpixelResolutionXOffset;
static int subpixelResolutionYOffset;
static long invisibleGlyphPtr;
/* Native method used to return information used for unsafe
@@ -132,16 +130,12 @@ public final class StrikeCache {
* arr[8] = offset of topLeftY
* arr[9] = offset of pixel data.
* arr[10] = address of a GlyphImageRef representing the invisible glyph
* arr[11] = offset of cellInfo
* arr[12] = offset of managed
* arr[13] = offset of subpixelResolutionX
* arr[14] = offset of subpixelResolutionY
*/
static native void getGlyphCacheDescription(long[] infoArray);
static {
long[] nativeInfo = new long[15];
long[] nativeInfo = new long[13];
getGlyphCacheDescription(nativeInfo);
//Can also get address size from Unsafe class :-
//nativeAddressSize = unsafe.addressSize();
@@ -158,8 +152,6 @@ public final class StrikeCache {
invisibleGlyphPtr = nativeInfo[10];
cacheCellOffset = (int) nativeInfo[11];
managedOffset = (int) nativeInfo[12];
subpixelResolutionXOffset = (int) nativeInfo[13];
subpixelResolutionYOffset = (int) nativeInfo[14];
if (nativeAddressSize < 4) {
throw new InternalError("Unexpected address size for font data: " +

View File

@@ -75,8 +75,6 @@ typedef struct GlyphInfo {
UInt16 height;
UInt16 rowBytes;
UInt8 managed;
UInt8 subpixelResolutionX;
UInt8 subpixelResolutionY;
float topLeftX;
float topLeftY;
void *cellInfo;

View File

@@ -35,25 +35,6 @@
#include "sun_java2d_loops_DrawGlyphListAA.h"
static UInt8* getSubpixelGlyphImage(GlyphInfo *glyph, float x, float y) {
int rx = glyph->subpixelResolutionX;
int ry = glyph->subpixelResolutionY;
if ((rx == 1 && ry == 1) || rx <= 0 || ry <= 0) {
return glyph->image;
}
int xOffset;
int yOffset;
if (x >= 0 && y >= 0) {
xOffset = ((int) (x * (float) rx)) % rx;
yOffset = ((int) (y * (float) ry)) % ry;
} else {
xOffset = (int) ((x - (float) floor(x)) * (float) rx);
yOffset = (int) ((y - (float) floor(y)) * (float) ry);
}
return glyph->image + (glyph->rowBytes * glyph->height) *
(xOffset + yOffset * rx);
}
/*
* Need to account for the rare case when (eg) repainting damaged
* areas results in the drawing location being negative, in which
@@ -69,9 +50,6 @@ static UInt8* getSubpixelGlyphImage(GlyphInfo *glyph, float x, float y) {
#define FLOOR_ASSIGN(l, r)\
if ((r)<0) (l) = ((int)floor(r)); else (l) = ((int)(r))
#define ADJUST_SUBPIXEL_GLYPH_POSITION(coord, res) \
if ((res) > 1) (coord) += 0.5f / ((float)(res)) - 0.5f;
GlyphBlitVector* setupBlitVector(JNIEnv *env, jobject glyphlist, jint fromGlyph, jint toGlyph) {
int g;
@@ -123,12 +101,8 @@ GlyphBlitVector* setupBlitVector(JNIEnv *env, jobject glyphlist, jint fromGlyph,
jfloat py = y + positions[++n];
ginfo = (GlyphInfo*)imagePtrs[g + fromGlyph];
ADJUST_SUBPIXEL_GLYPH_POSITION(px, ginfo->subpixelResolutionX);
ADJUST_SUBPIXEL_GLYPH_POSITION(py, ginfo->subpixelResolutionY);
gbv->glyphs[g].glyphInfo = ginfo;
gbv->glyphs[g].pixels = getSubpixelGlyphImage(ginfo,
px + ginfo->topLeftX,
py + ginfo->topLeftY);
gbv->glyphs[g].pixels = ginfo->image;
gbv->glyphs[g].width = ginfo->width;
gbv->glyphs[g].rowBytes = ginfo->rowBytes;
gbv->glyphs[g].height = ginfo->height;
@@ -139,21 +113,14 @@ GlyphBlitVector* setupBlitVector(JNIEnv *env, jobject glyphlist, jint fromGlyph,
positions, JNI_ABORT);
} else {
for (g=0; g<len; g++) {
jfloat px = x;
jfloat py = y;
ginfo = (GlyphInfo*)imagePtrs[g + fromGlyph];
ADJUST_SUBPIXEL_GLYPH_POSITION(px, ginfo->subpixelResolutionX);
ADJUST_SUBPIXEL_GLYPH_POSITION(py, ginfo->subpixelResolutionY);
gbv->glyphs[g].glyphInfo = ginfo;
gbv->glyphs[g].pixels = getSubpixelGlyphImage(ginfo,
px + ginfo->topLeftX,
py + ginfo->topLeftY);
gbv->glyphs[g].pixels = ginfo->image;
gbv->glyphs[g].width = ginfo->width;
gbv->glyphs[g].rowBytes = ginfo->rowBytes;
gbv->glyphs[g].height = ginfo->height;
FLOOR_ASSIGN(gbv->glyphs[g].x, px + ginfo->topLeftX);
FLOOR_ASSIGN(gbv->glyphs[g].y, py + ginfo->topLeftY);
FLOOR_ASSIGN(gbv->glyphs[g].x, x + ginfo->topLeftX);
FLOOR_ASSIGN(gbv->glyphs[g].y, y + ginfo->topLeftY);
/* copy image data into this array at x/y locations */
x += ginfo->advanceX;

View File

@@ -79,7 +79,6 @@
#define DEFAULT_DPI 72
#define MAX_DPI 1024
#define ADJUST_FONT_SIZE(X, DPI) (((X)*DEFAULT_DPI + ((DPI)>>1))/(DPI))
#define FLOOR_DIV(X, Y) ((X) >= 0 ? (X) / (Y) : ((X) - (Y) + 1) / (Y))
#ifndef DISABLE_FONTCONFIG
#define FONTCONFIG_DLL JNI_LIB_NAME("fontconfig")
@@ -198,8 +197,6 @@ static FcInitLoadConfigAndFontsPtrType FcInitLoadConfigAndFontsPtr;
static FcGetVersionPtrType FcGetVersionPtr;
#endif
static FT_UnitVector supplementarySubpixelGlyphResolution;
static void* openFontConfig() {
void* libfontconfig = NULL;
#ifndef DISABLE_FONTCONFIG
@@ -230,9 +227,7 @@ static void* openFontConfig() {
JNIEXPORT void JNICALL
Java_sun_font_FreetypeFontScaler_initIDs(
JNIEnv *env, jobject scaler, jclass FFSClass, jclass TKClass,
jclass PFClass, jstring jreFontConfName,
jint subpixelResolutionX,
jint subpixelResolutionY)
jclass PFClass, jstring jreFontConfName)
{
const char *fssLogEnabled = getenv("OPENJDK_LOG_FFS");
const char *fontConf = (jreFontConfName == NULL) ?
@@ -242,9 +237,6 @@ Java_sun_font_FreetypeFontScaler_initIDs(
logFFS = JNI_TRUE;
}
supplementarySubpixelGlyphResolution.x = subpixelResolutionX;
supplementarySubpixelGlyphResolution.y = subpixelResolutionY;
invalidateScalerMID =
(*env)->GetMethodID(env, FFSClass, "invalidateScaler", "()V");
getDefaultToolkitMID =
@@ -1528,68 +1520,6 @@ static void transformBGRABitmapGlyph(FT_GlyphSlot ftglyph, GlyphInfo* glyphInfo,
freeSampledBGRABitmap(&sampledBitmap);
}
/* Size (in pixels) of stack-allocated temporary buffer for glyph downscaling.
* If glyph is too big and requires more memory, it will use malloc. */
#define SUBPIXEL_DOWNSCALE_STATIC_BUFFER_SIZE 2048
/* In order to get an extended set of grayscale glyph images, we pick single
* upscaled image and downscale it with different offsets by x and y axis */
static void CopySupplementarySubpixelToGrey8(const UInt8* srcImage, int srcRowBytes,
int srcWidth, int srcHeight,
UInt8* dstImage, int dstRowBytes,
int dstWidth, int dstHeight,
int xOffset, int yOffset,
int xResolution, int yResolution,
int imageSize) {
short staticBuffer[SUBPIXEL_DOWNSCALE_STATIC_BUFFER_SIZE];
int bufferSize = dstWidth * srcHeight;
int useStaticBuffer = bufferSize <= SUBPIXEL_DOWNSCALE_STATIC_BUFFER_SIZE;
short *buffer = useStaticBuffer ?
staticBuffer : malloc(sizeof(short) * bufferSize);
int xGlyph, yGlyph, x, y;
// For each subpixel offset by x axis
for (xGlyph = 0; xGlyph < xResolution; xGlyph++) {
// Sum values by x axis and store into temporary buffer
for (y = 0; y < srcHeight; y++) {
for (x = 0; x < dstWidth; x++) {
int value = 0;
int xFrom = x * xResolution - xOffset - xGlyph,
xTo = xFrom + xResolution;
if (xFrom < 0) xFrom = 0;
if (xTo > srcWidth) xTo = srcWidth;
int i;
for (i = xFrom; i < xTo; i++) {
value += srcImage[y * srcRowBytes + i];
}
buffer[y * dstWidth + x] = (short) value;
}
}
// For each subpixel offset by y axis
for (yGlyph = 0; yGlyph < yResolution; yGlyph++) {
UInt8 *dst = dstImage +
imageSize * (xGlyph + yGlyph * xResolution);
// Sum values by y axis and store average into destination image
for (y = 0; y < dstHeight; y++) {
for (x = 0; x < dstWidth; x++) {
int value = 0;
int yFrom = y * yResolution - yOffset - yGlyph,
yTo = yFrom + yResolution;
if (yFrom < 0) yFrom = 0;
if (yTo > srcHeight) yTo = srcHeight;
int j;
for (j = yFrom; j < yTo; j++) {
value += buffer[j * dstWidth + x];
}
dst[y * dstRowBytes + x] =
value / xResolution / yResolution;
}
}
}
}
if (!useStaticBuffer) free(buffer);
}
/* JDK does not use glyph images for fonts with a
* pixel size > 100 (see THRESHOLD in OutlineTextRenderer.java)
@@ -1717,29 +1647,7 @@ static jlong
/* generate bitmap if it is not done yet
e.g. if algorithmic styling is performed and style was added to outline */
int subpixelGlyph = FALSE;
int subpixelResolutionX = 1;
int subpixelResolutionY = 1;
if (renderImage && outlineGlyph) {
/* We can create an extended glyph when rendering with grayscale AA thus
* increasing subpixel resolution & reducing glyph spacing issues.
* We do this by rendering the glyph in bigger resolution and then
* downscaling it with different subpixel offsets, which results in
* subpixelResolutionX * subpixelResolutionY images per glyph. */
if (ftglyph->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY &&
context->aaType == TEXT_AA_ON && context->fmType == TEXT_FM_ON) {
subpixelResolutionX = supplementarySubpixelGlyphResolution.x;
subpixelResolutionY = supplementarySubpixelGlyphResolution.y;
if (subpixelResolutionX > 1 || subpixelResolutionY > 1) {
subpixelGlyph = TRUE;
FT_Matrix matrix;
matrix.xx = (long) FT_MATRIX_ONE * subpixelResolutionX;
matrix.xy = 0;
matrix.yx = 0;
matrix.yy = (long) FT_MATRIX_ONE * subpixelResolutionY;
FT_Outline_Transform(&(ftglyph->outline), &matrix);
}
}
FT_BBox bbox;
FT_Outline_Get_CBox(&(ftglyph->outline), &bbox);
int w = (int)((bbox.xMax>>6)-(bbox.xMin>>6));
@@ -1758,23 +1666,10 @@ static jlong
context->ptsz, scalerInfo->face->available_sizes[context->fixedSizeIndex].size);
FT_Matrix manualTransform;
FT_BBox manualTransformBoundingBox;
int topLeftX, topLeftY;
if (renderImage) {
if (subpixelGlyph) {
topLeftX = FLOOR_DIV(ftglyph->bitmap_left, subpixelResolutionX);
topLeftY = FLOOR_DIV(-ftglyph->bitmap_top, subpixelResolutionY);
width = -FLOOR_DIV(
-ftglyph->bitmap_left - (int) ftglyph->bitmap.width -
subpixelResolutionX + 1, subpixelResolutionX) - topLeftX;
height = -FLOOR_DIV(
ftglyph->bitmap_top - (int) ftglyph->bitmap.rows -
subpixelResolutionX + 1, subpixelResolutionY) - topLeftY;
}
else if (context->fixedSizeIndex == -1) {
if (context->fixedSizeIndex == -1) {
width = (UInt16) ftglyph->bitmap.width;
height = (UInt16) ftglyph->bitmap.rows;
topLeftX = ftglyph->bitmap_left;
topLeftY = -ftglyph->bitmap_top;
}
else {
/* Fixed size glyph, prepare matrix and
@@ -1789,8 +1684,6 @@ static jlong
manualTransformBoundingBox.xMin);
height = (UInt16) (manualTransformBoundingBox.yMax -
manualTransformBoundingBox.yMin);
topLeftX = manualTransformBoundingBox.xMin;
topLeftY = -manualTransformBoundingBox.yMax;
}
if (width > MAX_GLYPH_DIM || height > MAX_GLYPH_DIM) {
glyphInfo = getNullGlyphImage();
@@ -1813,8 +1706,7 @@ static jlong
imageSize = rowBytes*height;
glyphInfo = (GlyphInfo*) calloc(sizeof(GlyphInfo) +
imageSize * subpixelResolutionX * subpixelResolutionY, 1);
glyphInfo = (GlyphInfo*) calloc(sizeof(GlyphInfo) + imageSize, 1);
if (glyphInfo == NULL) {
glyphInfo = getNullGlyphImage();
return ptr_to_jlong(glyphInfo);
@@ -1824,12 +1716,17 @@ static jlong
glyphInfo->rowBytes = rowBytes;
glyphInfo->width = width;
glyphInfo->height = height;
glyphInfo->topLeftX = (float) topLeftX;
glyphInfo->topLeftY = (float) topLeftY;
glyphInfo->subpixelResolutionX = subpixelResolutionX;
glyphInfo->subpixelResolutionY = subpixelResolutionY;
if (renderImage) {
if (context->fixedSizeIndex == -1) {
glyphInfo->topLeftX = (float) ftglyph->bitmap_left;
glyphInfo->topLeftY = (float) -ftglyph->bitmap_top;
}
else {
glyphInfo->topLeftX = manualTransformBoundingBox.xMin;
glyphInfo->topLeftY = -manualTransformBoundingBox.yMax;
}
if (ftglyph->bitmap.pixel_mode == FT_PIXEL_MODE_LCD && width > 0) {
glyphInfo->width = width/3;
glyphInfo->topLeftX -= 1;
@@ -1870,25 +1767,8 @@ static jlong
//output format is either 3 bytes per pixel (for subpixel modes)
//4 bytes per pixel for BGRA glyphs
// or 1 byte per pixel for AA and B&W
if (subpixelGlyph) {
int offsetX = ftglyph->bitmap_left - topLeftX * subpixelResolutionX;
int offsetY = -ftglyph->bitmap_top - topLeftY * subpixelResolutionY;
CopySupplementarySubpixelToGrey8(ftglyph->bitmap.buffer,
ftglyph->bitmap.pitch,
ftglyph->bitmap.width,
ftglyph->bitmap.rows,
glyphInfo->image,
rowBytes,
width,
height,
offsetX,
offsetY,
subpixelResolutionX,
subpixelResolutionY,
imageSize);
}
else if (context->fixedSizeIndex == -1) {
// Standard format conversion without image transformation
if (context->fixedSizeIndex == -1) {
// Standard format convertation without image transformation
if (ftglyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {
/* convert from 8 pixels per byte to 1 byte per pixel */
CopyBW2Grey8(ftglyph->bitmap.buffer,

View File

@@ -112,7 +112,7 @@ int initHBAPI() {
(p_hb_font_funcs_set_nominal_glyphs_func_type)dlsym(
libharfbuzz, "hb_font_funcs_set_nominal_glyphs_func");
p_hb_font_funcs_set_nominal_glyph_func = (p_hb_font_funcs_set_nominal_glyph_func_type)dlsym(
libharfbuzz, "hb_font_funcs_set_nominal_glyph_func");
libharfbuzz, "hb_font_funcs_set_nominal_glyph_func_type");
p_hb_font_funcs_set_variation_glyph_func =
(p_hb_font_funcs_set_variation_glyph_func_type)dlsym(
libharfbuzz, "hb_font_funcs_set_variation_glyph_func");
@@ -160,7 +160,7 @@ int initHBAPI() {
p_hb_font_set_scale =
(p_hb_font_set_scale_type)dlsym(libharfbuzz, "hb_font_set_scale");
p_hb_shape_full = (p_hb_shape_full_type)dlsym(libharfbuzz, "hb_shape_full");
p_hb_ot_tag_to_language = (p_hb_ot_tag_to_language_type)dlsym(libharfbuzz, "hb_ot_tag_to_language");
p_hb_ot_tag_to_language = (hb_ot_tag_to_language_type)dlsym(libharfbuzz, "hb_ot_tag_to_language");
#else
p_hb_buffer_create = hb_buffer_create;
p_hb_buffer_set_script = hb_buffer_set_script;

View File

@@ -316,7 +316,7 @@ Java_sun_font_StrikeCache_getGlyphCacheDescription
GlyphInfo *info;
size_t baseAddr;
if ((*env)->GetArrayLength(env, results) < 15) {
if ((*env)->GetArrayLength(env, results) < 13) {
return;
}
@@ -343,8 +343,6 @@ Java_sun_font_StrikeCache_getGlyphCacheDescription
nresults[10] = (jlong)(uintptr_t)info; /* invisible glyph */
nresults[11] = (size_t)&(info->cellInfo)-baseAddr;
nresults[12] = (size_t)&(info->managed)-baseAddr;
nresults[13] = (size_t)&(info->subpixelResolutionX)-baseAddr;
nresults[14] = (size_t)&(info->subpixelResolutionY)-baseAddr;
(*env)->ReleasePrimitiveArrayCritical(env, results, nresults, 0);
}

View File

@@ -1113,11 +1113,14 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
* though, as the latter doesn't track updates to WM_TAKE_FOCUS property
* (it's not required as per ICCCM specification). So another approach is
* used - setting _NET_WM_USER_TIME to 0, as specified in EWMH spec (see
* 'setUserTimeBeforeShowing' method).
* 'setUserTimeBeforeShowing' method). The same method is used currently for
* KDE (KWin) to solve a specific problem in 'focus follows mouse' mode
* (JBR-2934). Ideally, the new approach should be used for all supporting
* window managers, as it doesn't require additional calls to X server.
*/
private boolean shouldSuppressWmTakeFocus() {
int wmId = XWM.getWMID();
return wmId != XWM.I3_WM;
return wmId != XWM.I3_WM && wmId != XWM.KDE2_WM;
}
public void setVisible(boolean vis) {
@@ -1453,21 +1456,16 @@ class XWindowPeer extends XPanelPeer implements WindowPeer,
super.handleMapNotifyEvent(xev);
if (isBeforeFirstMapNotify && !winAttr.initialFocus && shouldSuppressWmTakeFocus()) {
suppressWmTakeFocus(false); // restore the protocol.
if (!XWM.isKDE2()) {
/*
* For some reason, on Metacity, a frame/dialog being shown
* without WM_TAKE_FOCUS protocol doesn't get moved to the front.
* So, we do it evidently.
*
* We don't do it on KDE, as raising a child window will also raise the parent one there,
* and we don't want that.
*/
XToolkit.awtLock();
try {
XlibWrapper.XRaiseWindow(XToolkit.getDisplay(), getWindow());
} finally {
XToolkit.awtUnlock();
}
/*
* For some reason, on Metacity, a frame/dialog being shown
* without WM_TAKE_FOCUS protocol doesn't get moved to the front.
* So, we do it evidently.
*/
XToolkit.awtLock();
try {
XlibWrapper.XRaiseWindow(XToolkit.getDisplay(), getWindow());
} finally {
XToolkit.awtUnlock();
}
}
if (shouldFocusOnMapNotify()) {

View File

@@ -48,6 +48,7 @@ public class XRGlyphCache implements GlyphDisposedListener {
XRCompositeManager maskBuffer;
HashMap<MutableInteger, XRGlyphCacheEntry> cacheMap = new HashMap<MutableInteger, XRGlyphCacheEntry>(256);
int nextID = 1;
MutableInteger tmp = new MutableInteger(0);
int grayGlyphSet;
@@ -58,7 +59,7 @@ public class XRGlyphCache implements GlyphDisposedListener {
int cachedPixels = 0;
static final int MAX_CACHED_PIXELS = 100000;
final GlyphIDAllocator glyphIDAllocator = new GlyphIDAllocator();
ArrayList<Integer> freeGlyphIDs = new ArrayList<Integer>(255);
static final boolean batchGlyphUpload = true; // Boolean.parseBoolean(System.getProperty("sun.java2d.xrender.batchGlyphUpload"));
@@ -96,6 +97,14 @@ public class XRGlyphCache implements GlyphDisposedListener {
}
}
protected int getFreeGlyphID() {
if (freeGlyphIDs.size() > 0) {
int newID = freeGlyphIDs.remove(freeGlyphIDs.size() - 1);
return newID;
}
return nextID++;
}
protected XRGlyphCacheEntry getEntryForPointer(long imgPtr) {
int id = XRGlyphCacheEntry.getGlyphID(imgPtr);
@@ -124,9 +133,7 @@ public class XRGlyphCache implements GlyphDisposedListener {
// Find uncached glyphs and queue them for upload
if ((glyph = getEntryForPointer(imgPtrs[i])) == null) {
glyph = new XRGlyphCacheEntry(imgPtrs[i], glyphList);
glyph.setGlyphID(glyphIDAllocator.allocateID(
glyph.getSubpixelResolutionX() *
glyph.getSubpixelResolutionY()));
glyph.setGlyphID(getFreeGlyphID());
cacheMap.put(new MutableInteger(glyph.getGlyphID()), glyph);
if (uncachedGlyphs == null) {
@@ -269,18 +276,15 @@ public class XRGlyphCache implements GlyphDisposedListener {
for (int i=0; i < glyphIdList.getSize(); i++) {
int glyphId = glyphIdList.getInt(i);
freeGlyphIDs.add(glyphId);
tmp.setValue(glyphId);
XRGlyphCacheEntry entry = cacheMap.get(tmp);
int subglyphs = entry.getSubpixelResolutionX() * entry.getSubpixelResolutionY();
glyphIDAllocator.freeID(glyphId, subglyphs);
cachedPixels -= entry.getPixelCnt();
cacheMap.remove(tmp);
if (entry.getGlyphSet() == grayGlyphSet) {
for (int j = 0; j < subglyphs; j++) {
removedGrayscaleGlyphs.addInt(glyphId + j);
}
removedGrayscaleGlyphs.addInt(glyphId);
} else if (entry.getGlyphSet() == lcdGlyphSet) {
removedLCDGlyphs.addInt(glyphId);
} else if (entry.getGlyphSet() == BGRA_GLYPH_SET) {
@@ -313,46 +317,4 @@ public class XRGlyphCache implements GlyphDisposedListener {
removedBGRAGlyphPtrsCount);
}
}
/**
* Each XR glyph image needs its own ID, which are allocated using
* this class. When using supplementary subpixel glyphs
* ({@code -Djava2d.font.subpixelResolution=4x2}), its XRGlyphCacheEntry
* may correspond to few images and therefore may need a range of IDs
* instead of a single one.
* @implNote This allocator uses a simple strategy for reusing IDs with
* a single pool per capacity (e.g. one pool containing only individual
* IDs and second pool containing ranges each with 8 sequential IDs).
* When pool is empty, new range of IDs is allocated by incrementing
* {@code nextID} counter.
*/
private static class GlyphIDAllocator {
private List<Integer>[] freeIDsByCapacity = new List[]{
new ArrayList<>(255)
};
private int nextID = 1;
private int allocateID(int count) {
if (count <= freeIDsByCapacity.length) {
List<Integer> pool = freeIDsByCapacity[count - 1];
if (pool != null && !pool.isEmpty()) {
return pool.remove(pool.size() - 1);
}
}
int id = nextID;
nextID += count;
return id;
}
private void freeID(int id, int count) {
if (count > freeIDsByCapacity.length) {
freeIDsByCapacity = Arrays.copyOf(freeIDsByCapacity, count);
}
if (freeIDsByCapacity[count - 1] == null) {
freeIDsByCapacity[count - 1] = new ArrayList<>(255);
}
freeIDsByCapacity[count - 1].add(id);
}
}
}

View File

@@ -143,19 +143,15 @@ public class XRGlyphCacheEntry {
int paddedWidth = getPaddedWidth();
if (getType() == Type.GRAYSCALE) {
int subglyphs = getSubpixelResolutionX() * getSubpixelResolutionY();
for (int subglyph = 0; subglyph < subglyphs; subglyph++) {
for (int line = 0; line < height; line++) {
for(int x = 0; x < paddedWidth; x++) {
if(x < width) {
os.write(StrikeCache.unsafe.getByte(pixelDataAddress + (line * rowBytes + x)));
}else {
/*pad to multiple of 4 bytes per line*/
os.write(0);
}
for (int line = 0; line < height; line++) {
for(int x = 0; x < paddedWidth; x++) {
if(x < width) {
os.write(StrikeCache.unsafe.getByte(pixelDataAddress + (line * rowBytes + x)));
}else {
/*pad to multiple of 4 bytes per line*/
os.write(0);
}
}
pixelDataAddress += height * rowBytes;
}
} else {
for (int line = 0; line < height; line++) {
@@ -184,14 +180,6 @@ public class XRGlyphCacheEntry {
return StrikeCache.unsafe.getFloat(glyphInfoPtr + StrikeCache.topLeftYOffset);
}
public byte getSubpixelResolutionX() {
return StrikeCache.unsafe.getByte(glyphInfoPtr + StrikeCache.subpixelResolutionXOffset);
}
public byte getSubpixelResolutionY() {
return StrikeCache.unsafe.getByte(glyphInfoPtr + StrikeCache.subpixelResolutionYOffset);
}
public long getGlyphInfoPtr() {
return glyphInfoPtr;
}
@@ -236,7 +224,7 @@ public class XRGlyphCacheEntry {
}
public int getPixelCnt() {
return getWidth() * getHeight() * getSubpixelResolutionX() * getSubpixelResolutionY();
return getWidth() * getHeight();
}
public boolean isPinned() {

View File

@@ -106,10 +106,6 @@ public class XRTextRenderer extends GlyphListPipe {
int glyphSet = cacheEntry.getGlyphSet();
int subpixelResolutionX = cacheEntry.getSubpixelResolutionX();
int subpixelResolutionY = cacheEntry.getSubpixelResolutionY();
float glyphX = advX;
float glyphY = advY;
if (glyphSet == XRGlyphCache.BGRA_GLYPH_SET) {
/* BGRA glyphs store pointers to BGRAGlyphInfo
* struct instead of glyph index */
@@ -117,20 +113,8 @@ public class XRTextRenderer extends GlyphListPipe {
(int) (cacheEntry.getBgraGlyphInfoPtr() >> 32));
eltList.getGlyphs().addInt(
(int) cacheEntry.getBgraGlyphInfoPtr());
} else if (subpixelResolutionX == 1 && subpixelResolutionY == 1) {
eltList.getGlyphs().addInt(cacheEntry.getGlyphID());
} else {
glyphX += 0.5f / subpixelResolutionX - 0.5f;
glyphY += 0.5f / subpixelResolutionY - 0.5f;
int x = ((int) Math.floor(glyphX *
(float) subpixelResolutionX)) % subpixelResolutionX;
if (x < 0) x += subpixelResolutionX;
int y = ((int) Math.floor(glyphY *
(float) subpixelResolutionY)) % subpixelResolutionY;
if (y < 0) y += subpixelResolutionY;
eltList.getGlyphs().addInt(cacheEntry.getGlyphID() +
x + y * subpixelResolutionX);
}
else eltList.getGlyphs().addInt(cacheEntry.getGlyphID());
containsLCDGlyphs |= (glyphSet == glyphCache.lcdGlyphSet);
@@ -153,8 +137,8 @@ public class XRTextRenderer extends GlyphListPipe {
if (gl.usePositions()) {
// In this case advX only stores rounding errors
float x = positions[i * 2] + glyphX;
float y = positions[i * 2 + 1] + glyphY;
float x = positions[i * 2] + advX;
float y = positions[i * 2 + 1] + advY;
posX = (int) Math.floor(x);
posY = (int) Math.floor(y);
advX -= cacheEntry.getXOff();
@@ -168,8 +152,8 @@ public class XRTextRenderer extends GlyphListPipe {
* later. This way rounding-error can be corrected, and
* is required to be consistent with the software loops.
*/
posX = (int) Math.floor(glyphX);
posY = (int) Math.floor(glyphY);
posX = (int) Math.floor(advX);
posY = (int) Math.floor(advY);
// Advance of ELT = difference between stored relative
// positioning information and required float.

View File

@@ -229,22 +229,12 @@ public class XRBackendNative implements XRBackend {
return glyphInfoPtrs;
}
private static int countTotalSubglyphs(List<XRGlyphCacheEntry> cacheEntries) {
int totalSubglyphs = 0;
for (int i = 0; i < cacheEntries.size(); i++) {
XRGlyphCacheEntry entry = cacheEntries.get(i);
totalSubglyphs += entry.getSubpixelResolutionX() *
entry.getSubpixelResolutionY();
}
return totalSubglyphs;
}
public void XRenderAddGlyphs(int glyphSet, GlyphList gl,
List<XRGlyphCacheEntry> cacheEntries,
byte[] pixelData) {
long[] glyphInfoPtrs = getGlyphInfoPtrs(cacheEntries);
XRAddGlyphsNative(glyphSet, glyphInfoPtrs, glyphInfoPtrs.length,
pixelData, pixelData.length, countTotalSubglyphs(cacheEntries));
XRAddGlyphsNative(glyphSet, glyphInfoPtrs,
glyphInfoPtrs.length, pixelData, pixelData.length);
}
public void XRenderFreeGlyphs(int glyphSet, int[] gids) {
@@ -255,8 +245,7 @@ public class XRBackendNative implements XRBackend {
long[] glyphInfoPtrs,
int glyphCnt,
byte[] pixelData,
int pixelDataLength,
int totalSubglyphs);
int pixelDataLength);
private static native void XRFreeGlyphsNative(int glyphSet,
int[] gids, int idCnt);

View File

@@ -829,20 +829,19 @@ JNIEXPORT void JNICALL
Java_sun_java2d_xr_XRBackendNative_XRAddGlyphsNative
(JNIEnv *env, jclass cls, jint glyphSet,
jlongArray glyphInfoPtrsArray, jint glyphCnt,
jbyteArray pixelDataArray, jint pixelDataLength,
jint subglyphs) {
jbyteArray pixelDataArray, int pixelDataLength) {
jlong *glyphInfoPtrs;
unsigned char *pixelData;
int i, j;
int i;
if (MAX_PAYLOAD / (sizeof(XGlyphInfo) + sizeof(Glyph))
< (unsigned)subglyphs) {
/* subglyphs too big, payload overflow */
< (unsigned)glyphCnt) {
/* glyphCnt too big, payload overflow */
return;
}
XGlyphInfo *xginfo = (XGlyphInfo *) malloc(sizeof(XGlyphInfo) * subglyphs);
Glyph *gid = (Glyph *) malloc(sizeof(Glyph) * subglyphs);
XGlyphInfo *xginfo = (XGlyphInfo *) malloc(sizeof(XGlyphInfo) * glyphCnt);
Glyph *gid = (Glyph *) malloc(sizeof(Glyph) * glyphCnt);
if (xginfo == NULL || gid == NULL) {
if (xginfo != NULL) {
@@ -872,29 +871,24 @@ Java_sun_java2d_xr_XRBackendNative_XRAddGlyphsNative
return;
}
int outputGlyph = 0;
for (i=0; i < glyphCnt; i++) {
GlyphInfo *jginfo = (GlyphInfo *) jlong_to_ptr(glyphInfoPtrs[i]);
int images = jginfo->subpixelResolutionX * jginfo->subpixelResolutionY;
for (j=0; j < images; j++) {
// 'jginfo->cellInfo' is of type 'void*'
// (see definition of 'GlyphInfo' in fontscalerdefs.h)
// 'Glyph' is typedefed to 'unsigned long'
// (see http://www.x.org/releases/X11R7.7/doc/libXrender/libXrender.txt)
// Maybe we should assert that (sizeof(void*) == sizeof(Glyph)) ?
gid[outputGlyph] = (Glyph) (jginfo->cellInfo) + j;
xginfo[outputGlyph].x = (-jginfo->topLeftX);
xginfo[outputGlyph].y = (-jginfo->topLeftY);
xginfo[outputGlyph].width = jginfo->width;
xginfo[outputGlyph].height = jginfo->height;
xginfo[outputGlyph].xOff = round(jginfo->advanceX);
xginfo[outputGlyph].yOff = round(jginfo->advanceY);
outputGlyph++;
}
// 'jginfo->cellInfo' is of type 'void*'
// (see definition of 'GlyphInfo' in fontscalerdefs.h)
// 'Glyph' is typedefed to 'unsigned long'
// (see http://www.x.org/releases/X11R7.7/doc/libXrender/libXrender.txt)
// Maybe we should assert that (sizeof(void*) == sizeof(Glyph)) ?
gid[i] = (Glyph) (jginfo->cellInfo);
xginfo[i].x = (-jginfo->topLeftX);
xginfo[i].y = (-jginfo->topLeftY);
xginfo[i].width = jginfo->width;
xginfo[i].height = jginfo->height;
xginfo[i].xOff = round(jginfo->advanceX);
xginfo[i].yOff = round(jginfo->advanceY);
}
XRenderAddGlyphs(awt_display, glyphSet, &gid[0], &xginfo[0], subglyphs,
XRenderAddGlyphs(awt_display, glyphSet, &gid[0], &xginfo[0], glyphCnt,
(const char*)pixelData, pixelDataLength);
(*env)->ReleasePrimitiveArrayCritical(env, glyphInfoPtrsArray, glyphInfoPtrs, JNI_ABORT);

View File

@@ -623,7 +623,7 @@ public:
OLE_HRT(fileDialog->GetFileName(&fileName));
data->lastIgnoredFileName = fileName;
OLE_HRT(fileDialog->SetOkButtonLabel(data->selectFolderButtonText ? data->selectFolderButtonText : L"Select Folder"));
OLE_HRT(fileDialog->SetOkButtonLabel(data->selectFolderButtonText));
data->forceUseContainerFolder = TRUE;
}
OLE_CATCH

View File

@@ -1411,7 +1411,19 @@ void AwtWindow::Show()
if (nCmdShow == SW_SHOWNA || m_isIgnoringMouseEvents) {
flags |= SWP_NOACTIVATE;
}
HWND hInsertAfter = HWND_TOP;
// This flag allows the toplevel to be bellow other process toplevels.
// This behaviour is preferable for popups, but it is not appropriate
// for menus
BOOL isLightweightDialog = TRUE;
jclass windowPeerClass = env->FindClass("java/awt/peer/WindowPeer");
if (windowPeerClass != NULL) {
jmethodID isLightweightDialogMID = env->GetStaticMethodID(windowPeerClass, "isLightweightDialog", "(Ljava/awt/Window;)Z");
if (isLightweightDialogMID != NULL) {
isLightweightDialog = env->CallStaticBooleanMethod(windowPeerClass, isLightweightDialogMID, target);
}
}
HWND hInsertAfter = isLightweightDialog ? HWND_TOP : HWND_TOPMOST;
if (m_isIgnoringMouseEvents) {
HWND hFgWindow = ::GetForegroundWindow();
HWND hOwner = ::GetWindow(GetHWnd(), GW_OWNER);

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,10 +23,9 @@
/*
* @test
* @bug 8184328 8253368
* @bug 8184328
* @summary JDK8u131-b34-socketRead0 hang at SSL read
* @run main/othervm SSLSocketCloseHang
* @run main/othervm SSLSocketCloseHang shutdownInputTest
*/
import java.io.*;
@@ -73,8 +72,6 @@ public class SSLSocketCloseHang {
*/
static boolean debug = false;
static boolean shutdownInputTest = false;
/*
* If the client or server is doing some kind of object creation
* that the other side depends on, and that thread prematurely
@@ -148,26 +145,7 @@ public class SSLSocketCloseHang {
Thread.sleep(500);
System.err.println("Client closing: " + System.nanoTime());
if (shutdownInputTest) {
try {
sslSocket.shutdownInput();
} catch (SSLException e) {
if (!e.getMessage().contains
("closing inbound before receiving peer's close_notify")) {
throw new RuntimeException("expected different exception message. " +
e.getMessage());
}
}
if (!sslSocket.getSession().isValid()) {
throw new RuntimeException("expected session to remain valid");
}
} else {
sslSocket.close();
}
sslSocket.close();
clientClosed = true;
System.err.println("Client closed: " + System.nanoTime());
}
@@ -201,8 +179,6 @@ public class SSLSocketCloseHang {
if (debug)
System.setProperty("javax.net.debug", "all");
shutdownInputTest = args.length > 0 ? true : false;
/*
* Start the tests.
*/