Windows has font substitution logic - if you try to render a character which isn't in the currently selected font, Windows would quietly pull a glyph from another font where a glyph
for that character is present.
Imagine the current font is, for example, a serif one. When picking the source for substitution, will Windows prefer serif fonts to sans-serif ones and vice versa?
As far as I know Windows uses the PANOSE values of a font to find a suitable replacement. Those values categorise the font into descriptive values, and there are in fact multiple values to describe the serif style.
The problem is, that only font with PANOSE values can be replaced by fonts with PANOSE values.
So if the font you’re using doesn’t have PANOSE values, Windows can’t find a replacement. Also, if it does and there are no fonts with fitting PANOSE values in your collection, you will get bad substitutions.
However, the PANOSE system was established for font replacement for PostScript printers.
I’m not sure how other people do it but I don’t provide all the information to the PANOSE values in fonts I produce (unless its explicitly asked). I stick to familytype, weight and letterform (though I use this only to decide between upright or italic).
Related
There are proportional fonts (i.e. not monospaced) that nevertheless provide monospaced numbers. E.g. see this Excel screenshot using Arial:
Note how the numbers are nicely aligned. How can I find out programmatically (probably WinAPI) if a font supports this feature?
You won't find an API for that because there isn't any specific metadata value within the font file to indicate "the glyphs for digits in this font have fixed width". Some fonts may support both proportional and fixed-width ("lining") digits, in which case the font is likely to support the 'lnum' OpenType Layout feature. You should pick a font that supports this feature and then explicitly activate that feature when drawing the text.
I'm using the font Apple SD Gothic Neo. The letters print fine except when I have one with an accent mark, like ú:
This is not a custom font, and it happens on all font weights. If it makes a difference, I'm pulling the string from Firebase.
Why is this happening and what can I do?
Use a different font.
When a font lacks a glyph, that glyph is substituted from another font, resulting in a typographical mismatch. That’s what’s happening here. You are using a font that is very Unicode-incomplete for Latin alphabet characters. It is intended for Korean! Use a more appropriate font.
I wrote a script which parses information from PDF files and outputs it to HTML. It's written in Python, using pdfminer.
On some text segments, the font style can have semantic significance. For instance: bold, italic and color should trigger different behavior. Pdfminer provides scripts with the font name, but not the color, and it has a number of other issues; so I'm working on a Swift version of that program, using Apple's PDFKit, to extract the same features.
I now find that I have the opposite problem. While PDFKit makes it easy to retrieve color, retrieving the original font name seems to be non-obvious. PDFSelection objects have an attributedString property, but for fonts that are not installed on my computer, the NSFont object is Helvetica. Of course, the fonts in question are fairly expensive, and acquiring a copy just for this purpose would be poor form.
Short of dropping to CGPDFContentStream (which is way too big of a hammer for what I want to get), is there a way of getting the original font name? I know in advance what the fonts are going to be, can I use that to my advantage?
PDFKit seems to use the standard font lookup system and then falls back on some default, so this can be resolved by spoofing the font to ensure that PDFKit doesn't need to fall back. Inspecting the document, I was able to identify that it uses the following fonts (referenced with their PostScript name):
"NeoSansIntel"
"NeoSansIntelMedium"
"NeoSansIntel,Italic"
I used a free font creation utility to create dummy fonts with these PostScript names, and I added them to my app bundle. I then used CTFontManagerRegisterFontsForURLs to load these fonts (in the .process scope), and now PDFKit uses these fonts for attributed strings that need them.
Of course, the fonts are bogus and this is useless for rendering. However, it works perfectly for the purpose of identifying text that uses these font.
I have the common Adobe Myriad Pro fonts installed. These include Myriad Pro Regular, Myriad Pro Bold and Myriad Pro Semibold. Assume that I have a CTFontRef baseFont that points to Myriad Pro Regular, and that the font size I desire is size. I run the following code:
CTFontRef boldFont = CTFontCreateCopyWithSymbolicTraits(baseFont, size, NULL, kCTFontBoldTrait, kCTFontBoldTrait);
The returned font is Myriad Pro Semibold, not Myriad Pro Bold.
Is there a way of coercing this to return Myriad Pro Bold instead, other than requesting the named style 'Bold'? I wanted to keep this code entirely generic without hard-wiring style names.
I have tried this in various permutations, including passing the bold trait as part of an attribute dictionary when I initially create my font, avoiding the two-step process described here, but it still returns the semibold font in preference to the normal bold. I've also poked around the fonts themselves a little. The full bold font has a weight of 700 in its <OS/2> table, and the semibold font has a weight of 600. The PANOSE weights correspond with this. However, the macStyle fields in the <head> table of the semibold and bold fonts both have the bold flag set, so presumably this is what Core Text is using. But is there any way to make it more discriminating?
Based on a reading of the documentation, backed up by some knowledge of font handling in general but not Core Text specifically, I'd say it may be possible, but it's not straightforward.
The CTFontCreateCopyWithSymbolicTraits() documentation specifies that the symTraitValue and symTraitMask parameters have type CTFontSymbolicTraits. The CTFontDescriptor() documentation defines that "Bold" value that you are using as
kCTFontBoldTrait = (1 << 1)
So this is clearly a boolean trait. However, as you've seen, font weight is a spectrum, not a boolean trait, even though decades of "bold" buttons in word processor UIs have presented it as a boolean trait. CTFontCreateCopyWithSymbolicTraits() doesn't have the expressive power you need.
One other approach which might work is to try calling CTFontDescriptorCreateMatchingFontDescriptors(). You pass this function a CTFontDescriptorRef to an initial font, and a CFSetRef with attributes which must be present. This function returns an array of font descriptors, all of which match the attributes you requested.
So, you could pass it a CTFontDescriptorRef for Myriad Pro Regular, and maybe a CFSetRef saying you want bold, and then look through every font descriptor in the returned array to find the one with the heaviest weight.
I haven't written this code, and my ignorance of Core Text means I may be missing something, but that seems like a plausible approach.
For the CTFontDescriptor you can specify an attribute kCTFontTraitsAttribute which should be an CFDictionaryRef where you can specify the kCTFontWeightTrait which takes a CFNumberRef that represents floating point between -1 and 1, giving you a spectrum of weights, 1 being the most bold variant, and 0 being the regular/medium.
Suppose you have a string with text in two or more scripts. When you use a GDI function like TextOut, (modern versions of) Windows will do "font-linking". That is, GDI will draw what it can with your selected font and draw the rest in an appropriate font that it chooses automagically. For example, if part of your text is in English (using the Roman alphabet), and part of it is Chinese (using CJK characters), and you have Arial selected, the English portion will be drawn in Arial, and the Chinese portion will be drawn in another font that has the CJK glyphs.
My question is, is there a way to determine which fonts TextOut will choose (or did choose) for the font linking?
I have to draw some text with the low-level Uniscribe API, which doesn't do automatic font-linking. I've implemented my own font-linking, but sometimes my algorithm chooses a different font than TextOut does for the same text. I'm trying to understand the Windows algorithm better, but I'm not real good at identifying fonts on sight (especially in unfamiliar scripts).
The font is selected by a registry entry. It is well described in this article. Quoting the relevant part:
If font linking is enabled on your
device, you can examine the registry
by enumerating the subkeys of the
registry key at
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows
NT\CurrentVersion\FontLink\SystemLink
to determine the mappings of linked
fonts to base fonts. You can add links
by using Regedit to create additional
subkeys.