In case you're on Qt 4.x, look at QFont <-> QString and QFont <-> QDataStream (|de)serialization. I recall there was a bug fixed in ~5.3, though I don't know if it was backported to 4.x.
Konstantin 2015-04-18 14:34 GMT+04:00 René J.V. <[email protected]>: > Hello, > > The specific question: how/where is (QFontEngine *)fe->ctfont set that is > read in QFontDialogPrivate::setFont (qfontdialog_mac.mm around line 514)? > > I have been looking into an issue with the selection of fonts in > weights/styles that don't follow the usual four suspects (Normal, Italic, > Bold, Bold-Italic). > In stock Qt 4.8, selecting a Medium or Semi Bold weight (i.e. a weight > between normal and bold) works during the initial selection (say in > qtconfig's default font selection), but open the font dialog once more, or > relaunch the application, and that medium weight will have been replaced by > standard bold. > > I think I have a fix for this in Qt 4.8, which removes the "easy shortcut" > I found in 2 places ("there's Normal and anything heavier which becomes > Bold") and extends the weight string parser to support most of the font > weights you'll find on a typical OS X install. > > It turns out that almost inevitably I came up with code that looks a lot > like what had already been done for Qt 5.4 (I swear, I didn't peak :)) > except that I didn't introduce additional const variables to complement the > existing QFont::DemiBold etc. styles. > > We're getting to the question. > When opening the font dialog with an initial font, Qt 4 calls > QFontDialogPrivate::setFont() where Qt 5.4 uses > QCocoaFontPanel::setCurrentFont() . Both functions (can) use [NSFontManager > fontWithFamily:traits:weight:size], but the Qt4 version is actually called > with fe->ctfont already set to the appropriate NSFont*. > > And that seems to work more reliably. I have several fonts on my system > (including the Apple-provided Avenir family) where > fontWithFamily:traits:weight:size does *not* return the requested typeface, > as if the weight parameter is ignored. And indeed the documentation for > that function suggests that the weight parameter is used as a hint only ( > https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSFontManager_Class/index.html#//apple_ref/occ/instm/NSFontManager/fontWithFamily:traits:weight:size:) > though I *hope* that it's used as more than a hint when the requested > weight actually exists. > > Hence my question: where is fe->ctfont initialised? Clearly this uses a > different method for obtaining the NSFont (or CFFontRef). > > Note that I've already tried to put all chances on my side for weight: to > be used as more than a hint. I've analysed the weights in question for all > fonts on my system (Apple's documentation doesn't bother to document the > exact value mapping), and came up with the following > > + // RJVB > + // Thin,Light -> 3, Book -> 4 > + // Normal/Regular -> 5 > + // Medium/SemiBold/Demibold -> 6,7,8 > + // Bold -> 9 > + // Ultra/Black/Heavy -> 10,11 > + QByteArray *weights = NULL; > + switch (font.weight()) { > + case QFont::Light: > + weights = new QByteArray((const char[]){3,4}); > + break; > + case QFont::Normal: > + weights = new QByteArray((const char[]){5}); > + break; > + case QFont::DemiBold: > + weights = new QByteArray((const char[]){6,7,8}); > + break; > + case QFont::Bold: > + weights = new QByteArray((const char[]){9}); > + break; > + case QFont::Black: > + weights = new QByteArray((const char[]){10,11}); > + break; > } > > (evidently I did the same for Apple's other scale, that goes from -1.0 to > 1.0). I then test each of the weights corresponding to font.weight(): > > + if (weights) { > + nsFont = NULL; > + for (int i = 0 ; i < weights->size() && !nsFont ; ++i) { > + weight = (int) (*weights)[i]; > + nsFont = [mgr > fontWithFamily:qt_mac_QStringToNSString(fontInfo.family()) > + traits:mask > + weight:weight > + size:fontInfo.pointSize()]; > + } > + delete weights; > + } > > the only thing I haven't yet added is an additional check whether > fontWithFamily did indeed return the requested weight, and not the closest > lower match (which would let DemiBold downgrade to Normal, or Ultra to > Bold). > > Thanks for bearing with me, and (even more :)) for any feedback! > > R. > _______________________________________________ > Development mailing list > [email protected] > http://lists.qt-project.org/mailman/listinfo/development >
_______________________________________________ Development mailing list [email protected] http://lists.qt-project.org/mailman/listinfo/development
