mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2026-01-24 01:10:52 +01:00
Compare commits
1 Commits
1368
...
avu/HarfBu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9db9a9add7 |
@@ -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 {
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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: " +
|
||||
|
||||
@@ -75,8 +75,6 @@ typedef struct GlyphInfo {
|
||||
UInt16 height;
|
||||
UInt16 rowBytes;
|
||||
UInt8 managed;
|
||||
UInt8 subpixelResolutionX;
|
||||
UInt8 subpixelResolutionY;
|
||||
float topLeftX;
|
||||
float topLeftY;
|
||||
void *cellInfo;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user