Bug 481144 - [Cocoa] Text lowered badly on Widgets in Preference and
Properties

Update Font init method to directly use the system font
when possible.

Prior to this commit OSX 10.11 and higher (systems that use
the San Francisco font) can render with unusual spacing. The
root cause  seems to be that the system font has an unusual
baseline when a system font is manipulated or obtained by
name.

Specifically:

- Calling `NSFont.systemFontOfSize` will return a font that
  renders correctly.

- Calling `NSFont.boldSystemFontOfSize` will return a font
  that renders correctly.

- Calling `NSFont.systemFontOfSize` followed by `NSFontManager
  .convertFont` will return a font that renders too low.

- Calling `NSFont.fontWithName(".SF NS Text")` will return
  a font that sometimes renders too low (things seem to
  consistently go wrong when it's called after a
  `convertFont` call).

The `Font.init` now attempts to deduce if the font requested
is actually a system font and use direct system font handles.

This update also seems to fix issue 486734.

Change-Id:Ic613f72b911822385dfb9f0b32f82d8a5d895c77
Signed-off-by: pwebb@pivotal.io
Signed-off-by: Lakshmi Shanmugam <lshanmug@in.ibm.com>
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras
index 290c4a5..4e3933d 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/AppKitFull.bridgesupport.extras
@@ -1317,6 +1317,10 @@
 		<method selector="ascender" swt_gen="true">
 			<retval swt_gen="true"></retval>
 		</method>
+		<method class_method="true" selector="boldSystemFontOfSize:" swt_gen="true">
+			<arg swt_gen="true"></arg>
+			<retval swt_gen="true"></retval>
+		</method>
 		<method class_method="true" selector="controlContentFontOfSize:" swt_gen="true">
 			<arg swt_gen="true"></arg>
 			<retval swt_gen="true"></retval>
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSFont.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSFont.java
index 086664e..c2dfb1c 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSFont.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/NSFont.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2012 IBM Corporation and others.
+ * Copyright (c) 2000, 2016 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -28,6 +28,11 @@
 	return (double /*float*/)OS.objc_msgSend_fpret(this.id, OS.sel_ascender);
 }
 
+public static NSFont boldSystemFontOfSize(double /*float*/ fontSize) {
+	long /*int*/ result = OS.objc_msgSend(OS.class_NSFont, OS.sel_boldSystemFontOfSize_, fontSize);
+	return result != 0 ? new NSFont(result) : null;
+}
+
 public static NSFont controlContentFontOfSize(double /*float*/ fontSize) {
 	long /*int*/ result = OS.objc_msgSend(OS.class_NSFont, OS.sel_controlContentFontOfSize_, fontSize);
 	return result != 0 ? new NSFont(result) : null;
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java
index ff722d7..131b242 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/cocoa/org/eclipse/swt/internal/cocoa/OS.java
@@ -1065,6 +1065,7 @@
 public static final long /*int*/ sel_bitsPerSample = sel_registerName("bitsPerSample");
 public static final long /*int*/ sel_blackColor = sel_registerName("blackColor");
 public static final long /*int*/ sel_blueComponent = sel_registerName("blueComponent");
+public static final long /*int*/ sel_boldSystemFontOfSize_ = sel_registerName("boldSystemFontOfSize:");
 public static final long /*int*/ sel_boolValue = sel_registerName("boolValue");
 public static final long /*int*/ sel_borderWidth = sel_registerName("borderWidth");
 public static final long /*int*/ sel_boundingRectForGlyphRange_inTextContainer_ = sel_registerName("boundingRectForGlyphRange:inTextContainer:");
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Font.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Font.java
index 5ea2b84..83ef6c3 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Font.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Font.java
@@ -11,8 +11,8 @@
 package org.eclipse.swt.graphics;
 
 
-import org.eclipse.swt.internal.cocoa.*;
 import org.eclipse.swt.*;
+import org.eclipse.swt.internal.cocoa.*;
 
 /**
  * Instances of this class manage operating system resources that
@@ -312,52 +312,40 @@
 	if (height < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
 	Point dpi = device.dpi, screenDPI = device.getScreenDPI();
 	float size = height * dpi.y / screenDPI.y;
-	if (nsName != null) {
+	NSFont systemFont = NSFont.systemFontOfSize(size);
+	NSFont boldSystemFont = NSFont.boldSystemFontOfSize(size);
+	String systemFontName = systemFont.familyName().getString();
+	String boldSystemFontName = boldSystemFont.familyName().getString();
+	if (systemFontName.equals(name) || boldSystemFontName.equals(name)) {
+		// Use system font to prevent baseline problems with bold text
+		handle = ((style & SWT.BOLD) == 0 ? systemFont : boldSystemFont);
+	} else if (nsName != null) {
 		handle = NSFont.fontWithName(NSString.stringWith(nsName), size);
 	} else {
 		NSString family = NSString.stringWith(name);
-		NSFont nsFont = NSFont.fontWithName(family, size);
-		if (nsFont == null) nsFont = NSFont.systemFontOfSize(size);
-		NSFontManager manager = NSFontManager.sharedFontManager();
-		if (nsFont != null) {
-			if ((style & (SWT.BOLD | SWT.ITALIC)) == 0) {
-				handle = nsFont;
-			} else {
-				int traits = 0;
-				if ((style & SWT.ITALIC) != 0) traits |= OS.NSItalicFontMask;
-				if ((style & SWT.BOLD) != 0) traits |= OS.NSBoldFontMask;
-				handle = manager.convertFont(nsFont, traits);
-				if ((style & SWT.ITALIC) != 0 && (handle == null || (manager.traitsOfFont(handle) & OS.NSItalicFontMask) == 0)) {
-					traits &= ~OS.NSItalicFontMask;
-					handle = null;
-					if ((style & SWT.BOLD) != 0) {
-						handle = manager.convertFont(nsFont, traits);
-					}
-				}
-				if ((style & SWT.BOLD) != 0 && handle == null) {
-					traits &= ~OS.NSBoldFontMask;
-					if ((style & SWT.ITALIC) != 0) {
-						traits |= OS.NSItalicFontMask;
-						handle = manager.convertFont(nsFont, traits);
-					}
-				}
-				if (handle == null) handle = nsFont;
-			}
-		}
-		if (handle == null) {
-			handle = NSFont.systemFontOfSize(size);
-		}
-		if ((style & SWT.ITALIC) != 0 && (manager.traitsOfFont(handle) & OS.NSItalicFontMask) == 0) {
-			extraTraits |= OS.NSItalicFontMask;
-		}
-		if ((style & SWT.BOLD) != 0 && (manager.traitsOfFont(handle) & OS.NSBoldFontMask) == 0) {
-			extraTraits |= OS.NSBoldFontMask;
-		}
+		handle = NSFont.fontWithName(family, size);
+	}
+	initTraits(style, systemFont);
+	handle.retain();
+}
+
+private void initTraits(int style, NSFont systemFont) {
+	NSFontManager manager = NSFontManager.sharedFontManager();
+	if (handle != null && (manager.traitsOfFont(handle) & OS.NSBoldFontMask) == 0 && ((style & SWT.BOLD) != 0)) {
+		handle = manager.convertFont(handle, OS.NSBoldFontMask);
+	}
+	if (handle != null && (manager.traitsOfFont(handle) & OS.NSItalicFontMask) == 0 && ((style & SWT.ITALIC) != 0)) {
+		handle = manager.convertFont(handle, OS.NSItalicFontMask);
 	}
 	if (handle == null) {
-		handle = device.systemFont.handle;
+		handle = systemFont;
 	}
-	handle.retain();
+	if ((style & SWT.ITALIC) != 0 && (manager.traitsOfFont(handle) & OS.NSItalicFontMask) == 0) {
+		extraTraits |= OS.NSItalicFontMask;
+	}
+	if ((style & SWT.BOLD) != 0 && (manager.traitsOfFont(handle) & OS.NSBoldFontMask) == 0) {
+		extraTraits |= OS.NSBoldFontMask;
+	}
 }
 
 /**