QGLWidget::renderText() creates some downwards shifted letters - macos

I created a class derived from QGLWidget:
class OpenGLWidget : public QGLWidget
I want to write some text on top of the OpenGL widget. Therefore I used the renderText() method inside the paintGL() of my class:
QString s = QString("AaBbCcDd");
renderText(10, 20, s); // picture line 1
In the created text on top of my widget some letters are shifted downwards / upwards.
Have a look at this picture.
For example in the first line of the picture 'C', 'G', 'O' are shifted upwards and '4', '5' are shifted downwards.
I tried to change the font and the font size, but this only changed the letters, which are shifted, not the problem itself:
QFont font = QFont("Arial");
font.setPointSize(18);
renderText(10, 50, s, font); // picture line 2
font = QFont("Times");
font.setPointSize(18);
renderText(10, 80, s, font); // picture line 3
font = QFont("Courier");
font.setPointSize(18);
renderText(10, 110, s, font); // picture line 4
font = QFont("Courier");
font.setPointSize(16);
renderText(10, 140, s, font); // picture line 5
Does anybody know how to bring the letters on a straight line?
I also tried the QPainter::drawText() method instead of the renderText() inside the paintGL() of my class:
QPainter painter(this);
QString s = QString("AaBbCcDd");
painter.drawText(10, 20, s);
This method causes the same problem.
I am using Qt 4.7.4 with Qt Creator 2.4.1 on Mac OS 10.7.

This is a known bug in Qt 4.8.x. It affects Mac Qt-based applications that are run under OS X 10.7 and 10.8 (Lion and Mountain Lion). If you run your application under OS X 10.6 (Snow Leopard) you will not see the problem.
Qt 5.0.x fixes the renderText() problem for OS X 10.7 and 10.8 but is still too flaky to be used as a substitute for the more-solid 4.8.x builds.
Sadly, the Qt gods have not (yet) taken it upon themselves to retrofit the 4.8.x build with the fix from the 5.0.x build.

Related

How can I set NSTableView column to use monospaced numbers?

El Capitan introduced San Francisco system font, which has proportional digits by default.
This makes numbers in table columns look jagged and hard to compare:
I'd like to enable fixed-width numbers option for the font, but keep using the default system font and keep backwards compatibility with earlier versions of OS X.
In Interface Builder selecting font > Font Panel > Typography > Monospaced Numbers does not affect the font (XIB file remains unchanged).
What's the right way to set monospaced numbers in OS X table view columns? (I suspect IB is unusable for this, so a programmatic solution is OK too).
Just use +[NSFont monospacedDigitSystemFontOfSize:weight:] when it's available. It's new in 10.11, but still not in the NSFont docs. It's in the headers and was discussed in the WWDC 2015 videos. So, something like:
if ([NSFont respondsToSelector:#selector(monospacedDigitSystemFontOfSize:weight:)])
textField.font = [NSFont monospacedDigitSystemFontOfSize:textField.font.pointSize weight:NSFontWeightRegular];
Here's a Swift extension that gives you a monospaced digits font with high legibility.
extension NSFont {
var legibleNumbersVariant: NSFont {
let features = [
[NSFontFeatureTypeIdentifierKey: kNumberSpacingType,
NSFontFeatureSelectorIdentifierKey: kMonospacedNumbersSelector],
[NSFontFeatureTypeIdentifierKey: kStylisticAlternativesType,
NSFontFeatureSelectorIdentifierKey: kStylisticAltSixOnSelector]
]
let descriptor = fontDescriptor.addingAttributes([NSFontFeatureSettingsAttribute: features])
return NSFont(descriptor: descriptor, size: pointSize) ?? self
}
}
Treat the following as pseudo-code, quickly done, not throughly tested, etc.
Given an NSFont which represents a font which has monospaced numbers as a feature the following method will produce another NSFont with that feature selected:
- (NSFont *) newMonospaceNumbersFont:(NSFont *)font
{
CTFontDescriptorRef origDesc = CTFontCopyFontDescriptor((__bridge CTFontRef)font);
CTFontDescriptorRef monoDesc = CTFontDescriptorCreateCopyWithFeature(origDesc, (__bridge CFNumberRef)#(kNumberSpacingType), (__bridge CFNumberRef)#(kMonospacedNumbersSelector));
CFRelease(origDesc);
CTFontRef monoFont = CTFontCreateWithFontDescriptor(monoDesc, font.pointSize, NULL);
CFRelease(monoDesc);
return (__bridge_transfer NSFont *)monoFont;
}
You can use this, say, to take the current font of a UI element and convert it to one with monospace numbers.
HTH
Variant for Swift
Assuming res is the NSTextField with the number to display:
let origDesc = CTFontCopyFontDescriptor(res.font!)
let monoDesc = CTFontDescriptorCreateCopyWithFeature(origDesc, kNumberSpacingType, kMonospacedNumbersSelector)
let monoFont = CTFontCreateWithFontDescriptor(monoDesc, res.font!.pointSize, nil)
res.font = monoFont
In my experience, the "font panel" functionality isn't well defined and I usually just ignore it whenever I'm messing with a XIB or Storyboard.
What should work is to go back to that "Font" attribute in the Text Field Cell attributes inspector and then select "User Fixed Pitch" from the Font drop down menu (the choice should automatically default to size 11).
If you bump the font size up a point, it'll magically switch to Monaco (the default fixed width font).

Weird XCode 7 Interface Builder warnings

I have set font traits (bold, light) for several of my labels in an OSX app and now I get these warnings:
.../MainMenu.xib:9:
Xcode.IDEInterfaceBuilder.Cocoa.NSObject.BroadSystemFontWeights
without any explanation. Often the meant label isn't even selected when I click on the warnings. Can someone shed a light on what those warnings mean and how to get rid of them?
This is a warning shown starting from Xcode 7 when UI elements like a label or table view column header use a font style or variation that is not available on older OSes (and of course your project is still targeting them).
In my project a table view column header was using the system font with the "medium" font style variation instead of regular, in a project targeting OS X 10.9+.
The weird thing is I had to restart Xcode as Interface Builder refused to change the style of the control. Possibly a small glitch of this early 7.0.1 Xcode version.
Current answer almost gets it, but problem is not with font styles being unavailable in older targets, it's with Xcode not handling them properly, see full blog post for details.
If you want to keep your styles, use custom textfield with custom inspectable property. Open up identity inspector and set custom class to TextField, preferred font weight attribute will show up in attribute inspector, set the required value, build and enjoy the result.
import AppKit
#IBDesignable public class TextField: NSTextField
{
#IBInspectable public var preferredFontWeight: Int = 0
override public func awakeFromNib() {
if #available(OSX 10.11, *) {
return
}
guard
let weight: Int = self.preferredFontWeight where weight > 0,
let font: NSFont = self.font,
let name: String = font.familyName,
let manager: NSFontManager = NSFontManager.sharedFontManager() else {
return
}
// Full details here – https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSFontManager_Class/#//apple_ref/occ/instm/NSFontManager/convertWeight:ofFont:
//
// 1 – ultralight
// 2 – thin
// 3 – light, extralight
// 4 – book
// 5 – regular, display
// 6 – medium
// 7 – demi, demibold
// 8 – semi, semibold
// 9 – bold
// 10 – extra, extrabold
// 11 – heavy
// 12 – black
// 13 – ultrablack
// 14 – extrablack
if let font: NSFont = manager.fontWithFamily(name, traits: manager.traitsOfFont(font), weight: weight, size: font.pointSize) {
self.font = font
}
}
}
If you don't really care about the styles, use regular weight font for all text, it should solve the problem, see my earlier answer for available options.

What does NSObject.BroadSystemFontWeights warning message mean?

I recently updated XCode to 7.0 and I get this warning message:
Xcode.IDEInterfaceBuilder.Cocoa.NSObject.BroadSystemFontWeights
What does it mean and how do I get rid of it ?
I got the same error when I set the font weight to Semibold to a label with system font. This weight is available for the new system font (San Francisco) but not for the old Helvetica Neue, so I guess that that error means we won't get the right weight on older OS.
Changing the font to a weight available also for Helvetica Neue, Bold in my case, has fixed the error for me.
The problem is not with changing system font weight, the problem is with Xcode not handling this properly – contradicting statement, I know, see full blog post for details. There are three scenarios.
First – explicit typography is not important, regular weight is acceptable. Then stick with Marco's answer and use explicit regular weight.
Second – explicit typography is preferable, but can be compromised on older systems. This is the default behaviour right now, Xcode simply shows a warning and uses regular font on pre-10.11 targets. If you use adaptive layouts, everything should be fine. To get rid of the warning, you can simply set higher target in storyboard inspector:
Note, if your storyboard uses fallback features for earlier targets, they might become disabled, which will cause problems – I haven't come across any so far.
Third – explicit typography is a must. In this case you can use custom textfield with custom inspectable property. Open up identity inspector and set custom class to TextField, preferred font weight attribute will show up in attribute inspector, set the required value, build and enjoy the result.
import AppKit
#IBDesignable public class TextField: NSTextField
{
#IBInspectable public var preferredFontWeight: Int = 0
override public func awakeFromNib() {
if #available(OSX 10.11, *) {
return
}
guard
let weight: Int = self.preferredFontWeight where weight > 0,
let font: NSFont = self.font,
let name: String = font.familyName,
let manager: NSFontManager = NSFontManager.sharedFontManager() else {
return
}
// Full details here – https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSFontManager_Class/#//apple_ref/occ/instm/NSFontManager/convertWeight:ofFont:
//
// 1 – ultralight
// 2 – thin
// 3 – light, extralight
// 4 – book
// 5 – regular, display
// 6 – medium
// 7 – demi, demibold
// 8 – semi, semibold
// 9 – bold
// 10 – extra, extrabold
// 11 – heavy
// 12 – black
// 13 – ultrablack
// 14 – extrablack
if let font: NSFont = manager.fontWithFamily(name, traits: manager.traitsOfFont(font), weight: weight, size: font.pointSize) {
self.font = font
}
}
}
P.S. Bold weight works probably because it uses a slightly different logic – there's boldSystemFontOfSize(_:) that's available since OS X 10.0, unlike many other methods, which storyboard might rely upon.

What do the new iOS9/OSX10.11 NSNumberFormatterStyle enum values mean?

The iOS and OS X NSNumberFormatterStyle enum gained 4 new values with the new iOS 9 and OS X 10.11 SDK! They sound cool and useful, but Apple's documentation and even Google had nothing to say about them!
What do these new values do when passed to a formula, and how are they different than the old values?
In iOS 9.0 or OS X 10.11 〉Frameworks 〉Foundation 〉NSNumberFormatter.h lines 46-57:
typedef NS_ENUM(NSUInteger, NSNumberFormatterStyle) {
NSNumberFormatterNoStyle = kCFNumberFormatterNoStyle,
NSNumberFormatterDecimalStyle = kCFNumberFormatterDecimalStyle,
NSNumberFormatterCurrencyStyle = kCFNumberFormatterCurrencyStyle,
NSNumberFormatterPercentStyle = kCFNumberFormatterPercentStyle,
NSNumberFormatterScientificStyle = kCFNumberFormatterScientificStyle,
NSNumberFormatterSpellOutStyle = kCFNumberFormatterSpellOutStyle,
NSNumberFormatterOrdinalStyle NS_ENUM_AVAILABLE(10_11, 9_0) = kCFNumberFormatterOrdinalStyle,
NSNumberFormatterCurrencyISOCodeStyle NS_ENUM_AVAILABLE(10_11, 9_0) = kCFNumberFormatterCurrencyISOCodeStyle,
NSNumberFormatterCurrencyPluralStyle NS_ENUM_AVAILABLE(10_11, 9_0) = kCFNumberFormatterCurrencyPluralStyle,
NSNumberFormatterCurrencyAccountingStyle NS_ENUM_AVAILABLE(10_11, 9_0) = kCFNumberFormatterCurrencyAccountingStyle,
};
Take a look at this year's Session 227 - What's New in Internationalization (video; text)
In the video it is explained at 18:34 - here is a screenshot of this particular slide:
In addition to the existing NSNumberFormatterStyles Apple introduced four new styles in iOS 9 and OS X 10.11.
In addition to the already existing 'currency style, we now have 'currency ISO code style, as well 'currency plural style' and 'currency accounting style.' Interestingly here for 'currency accounting style, if you pass it a negative number, it presents it surrounded by parentheses.
This is common in accounting circles.
To see what these currency styles look like, take a look ate the picture above.
The ordinal style can be used for ordered lists.
1st Foo
2nd Bar
...
42nd Foo Bar

Drag n drop Cursor issue in pygtk for windows

I'm writing an interface using pygtk under linux. I've got a tiny very minute and minor issue when trying my program under windows (XP). It's ridiculous but I'm getting a bit obsessed, and some people around me siad I should talk to someone, so here I am.
I'm doing drag n' drop on some EventBoxes containing Images. The idea is to set the drag icon to the Image in the EventBox through a Pixbuf. No problem with set_icon_pixbuf under Linux, works perfectly fine.
Under Windows XP (I unfortunately don't have anything more recent) when the icon covers the cursor hotpoint, the drop doesn't occur anymore. Is there any workaround ? I haven't seen anything similar on google, so I'm trying my luck here.
I've written a code snippet that reproduces this behaviour, if anyone wants to give it a try.
import gtk
TARGET_TYPE_BT = 0
BUTTON = [('button', gtk.TARGET_SAME_APP, TARGET_TYPE_BT)]
def on_drag_begin(widget, context) :
context.set_icon_pixbuf(pixbuf, size / 2, size / 2)
def on_drag_data_get(widget, context, selec, targ, time) :
selec.set( selec.target, 8, widget.get_label())
def on_drag_data_received(widget, context, x, y, selec, targ, time) :
widget.set_label(selec.data)
size = 48
pixbuf = gtk.gdk.Pixbuf( gtk.gdk.COLORSPACE_RGB, True, 8, size, size)
pixbuf.fill(0xff7777ff)
buttons = [gtk.Button('Spam'), gtk.Button('Spam, spam, egg and spam')]
hbox = gtk.HBox(True)
for button in buttons :
button.connect('drag_begin', on_drag_begin)
button.connect('drag_data_get', on_drag_data_get)
button.connect('drag_data_received', on_drag_data_received)
button.drag_source_set(gtk.gdk.BUTTON1_MASK, BUTTON, gtk.gdk.ACTION_MOVE)
button.drag_dest_set(gtk.DEST_DEFAULT_ALL, BUTTON, gtk.gdk.ACTION_MOVE )
hbox.pack_start(button)
win = gtk.Window(gtk.WINDOW_TOPLEVEL)
win.connect("destroy", lambda w: gtk.main_quit())
win.add(hbox)
win.show_all()
for button in buttons :
button.window.set_cursor(gtk.gdk.Cursor( gtk.gdk.HAND1 ))
gtk.main()
In this code the size of the icon seems to have unexpected correlatives : try 24 and everything works fine !
Thanks for your attention. Any suggestions welcome.

Resources