Closed Grimy closed 8 years ago
Here’s the result when turning hinting off:
The middle dot is now symmetrical, but still quite big. Is that the intended design?
Any idea what Xft.autohint is doing there?
And to confirm, these are the ttf fonts?
The middle dot is now symmetrical, but still quite big
It is not intended to render as a dot, but rather as an oval fill. That is the correct design
Yes, these are the ttf fonts. Turning off Xft.autohint
has no visible effect. Turning off Xft.hinting
produces the second screenshot I posted.
I have not particular expertise with xterm hinting settings, but the second image is the intended appearance with the ttfautohint instruction sets that are included in the ttf builds.
Okay, thanks for the quick reply (= I’ll leave hinting off and autohint on, then.
That “oval fill” looks really good on the samples in the README, but much less so at font size 11, where it looks more like a vertical bar. Well, I guess that’s just a matter of opinion x)
Mind trying it at a couple of other text sizes, both smaller and larger? The shape changes as it gets constrained to different sized pixel grids. Interested to see how it appears on your platform with that renderer.
Here is the design:
Updated title of your issue report and we will leave this open to delve a bit deeper into the issue. I think that there is room for improvement here. Perhaps a slight adjustment to the shape at smaller text sizes. Thanks for pointing this out. Will update here with additional information and any changes that are made.
I tried at font sizes 6, 7, 8, 9, 10, 11, 12, 13, 14 and 16, here are the results:
In my opinion, it looks bad at sizes 9, 11 and 13.
Thanks for your attention!
That's extremely helpful and will guide our tests. Thanks much!
@lemzwerg:
We have a reasonably complex fill on the zero glyph here and I am trying to adjust the hints on the fill at a number of ppem. Here is an example of what I am seeing with the attempt to manually adjust the fill in the regular set with the following line in our Control Instructions File at 14ppem:
zero touch 39-48,65-71 y -1 @ 12,13,14
Thoughts? I'm not sure why we are seeing that notch at points 39 and 71 at the bottom of the oval fill. This occurs at several ppem when I attempt adjustments of the oval shape.
The touch
instruction implements pre-IUP deltas; in other words, after applying the deltas there comes the final IUP[y]
instruction, interpolating the 'weak' points of the outlines that are not positioned on edges. If you call ttfautohint with the --debug
option, you get a table of points for every glyph that shows whether a point is 'weak', and whether it lies on an edge.
In general, it is not necessary to explicitly move 'weak' points that are not positioned on horizontal edges. Instead, you should move either 'strong' points or points that lie on horizontal edges.
Without knowing in detail what ttfautohint reports for your 'zero' glyph, I thus think it should be sufficient to move points 39, 40, and 71:
zero touch 39,40,71 y -1 @ 12,13,14
If you move weak non-edge-points for whatever reason, you have to also compensate the IUP[y]
movement that follows. I guess this is the problem that you experience here.
A minor follow-up. It seems that you are using ftview
for showing glyph outlines. Here's a snapshot of the git version, which you probably enjoy :-)
@lemzwerg Thank you very much Werner! That is incredibly helpful. I’ll give it a try later today.
The repository version of ftview
looks great! Is it stable enough for use at this point? I am assuming that image is with the antialiasing view switched ‘on’?
ftview
is stable, yes; the image shows subpixel rendering, but normal grayscale anti-aliasing can also be displayed.
:+1: thanks!
@lemzwerg:
So here is what I get with the --debug
flag for the zero glyph. It only indicates that 39 is a strong point (I assume that the absence of a ‘weak’ indicator in the list means that this is strong point?):
glyph 548 (zero)
================
size 4
------
latin horizontal edge hinting (style `latn_dflt')
BLUE_ANCHOR: edge 0 (opos=-0.05) snapped to 0.00, was -0.05 (anchor=edge 0)
LINK: edge 1 (opos=0.23) linked to 0.28, dist was 0.28, now 0.28
BLUE: edge 3 (opos=1.92) snapped to 2.00, was 1.92
LINK: edge 2 (opos=0.69) linked to 0.77, dist was -1.23, now -1.23
BLUE: edge 5 (opos=2.66) snapped to 3.00, was 2.66
LINK: edge 4 (opos=2.38) linked to 2.72, dist was -0.28, now -0.28
Table of horizontal edges:
index pos dir link serif blue opos pos flags
0 -0.047 left 1 -- y -0.05 0.00 round
1 0.23 right 0 -- n 0.23 0.28 round
2 0.69 left 3 -- n 0.69 0.77 round
3 1.9 right 2 -- y 1.92 2.00 round
4 2.4 left 5 -- n 2.38 2.72 round
5 2.7 right 4 -- y 2.66 3.00 round
Table of horizontal segments:
index pos dir from to link serif edge height extra flags
0 -0.047 left 18 1 2 -- 0 600 121 round
1 2.7 right 7 9 3 -- 5 509 151 round
2 0.23 right 38 20 0 -- 1 246 104 round
3 2.4 left 28 30 1 -- 4 301 86 round
4 1.9 right 55 57 5 -- 3 111 33 round
5 0.69 left 71 39 4 -- 2 54 28 round
Table of points:
index hedge hseg flags xorg yorg xscale yscale xfit yfit
0 0 0 weak 616 -29 1.20 -0.05 1.20 0.00
1 0 0 weak 376 -29 0.73 -0.05 0.73 0.00
2 -- -- weak 255 167 0.50 0.30 0.50 0.38
3 -- -- weak 133 364 0.27 0.64 0.27 0.77
4 -- -- weak 133 745 0.27 1.30 0.27 1.48
5 -- -- weak 133 1127 0.27 1.97 0.27 2.23
6 -- -- weak 255 1324 0.50 2.31 0.50 2.62
7 5 1 weak 376 1520 0.73 2.66 0.73 3.00
8 5 1 weak 616 1520 1.20 2.66 1.20 3.00
9 5 1 weak 734 1520 1.44 2.66 1.44 3.00
10 -- -- weak 916 1424 1.80 2.48 1.80 2.81
11 -- -- weak 978 1324 1.91 2.31 1.91 2.62
12 -- -- weak 1038 1228 2.03 2.14 2.03 2.42
13 -- -- weak 1100 941 2.16 1.64 2.16 1.88
14 -- -- weak 1100 745 2.16 1.30 2.16 1.48
15 -- -- weak 1100 549 2.16 0.95 2.16 1.11
16 -- -- weak 1038 263 2.03 0.45 2.03 0.56
17 -- -- weak 978 167 1.91 0.30 1.91 0.38
18 0 0 weak 855 -29 1.67 -0.05 1.67 0.00
19 1 2 weak 616 131 1.20 0.23 1.20 0.28
20 1 2 weak 689 131 1.34 0.23 1.34 0.28
21 -- -- weak 794 209 1.55 0.36 1.55 0.42
22 -- -- weak 828 283 1.62 0.50 1.62 0.58
23 -- -- weak 897 434 1.75 0.77 1.75 0.89
24 -- -- weak 897 745 1.75 1.30 1.75 1.48
25 -- -- weak 897 1057 1.75 1.84 1.75 2.11
26 -- -- weak 828 1207 1.62 2.11 1.62 2.42
27 -- -- weak 794 1282 1.55 2.23 1.55 2.56
28 4 3 weak 690 1360 1.34 2.38 1.34 2.72
29 4 3 weak 616 1360 1.20 2.38 1.20 2.72
30 4 3 weak 475 1360 0.92 2.38 0.92 2.72
31 -- -- weak 406 1208 0.80 2.11 0.80 2.42
32 -- -- weak 371 1133 0.72 1.98 0.72 2.28
33 -- -- weak 336 906 0.66 1.58 0.66 1.81
34 -- -- weak 336 745 0.66 1.30 0.66 1.48
35 -- -- weak 336 433 0.66 0.75 0.66 0.88
36 -- -- weak 406 283 0.80 0.50 0.80 0.58
37 -- -- weak 442 205 0.86 0.36 0.86 0.42
38 1 2 weak 547 131 1.06 0.23 1.06 0.28
39 2 5 -- 618 396 1.20 0.69 1.20 0.77
40 -- -- weak 603 396 1.17 0.69 1.17 0.77
41 -- -- weak 578 419 1.12 0.73 1.12 0.81
42 -- -- weak 559 458 1.09 0.80 1.09 0.88
43 -- -- weak 545 511 1.06 0.89 1.06 0.97
44 -- -- weak 539 540 1.05 0.94 1.05 1.02
45 -- -- weak 534 564 1.05 0.98 1.05 1.06
46 -- -- weak 526 622 1.03 1.09 1.03 1.17
47 -- -- weak 520 681 1.02 1.19 1.02 1.27
48 -- -- weak 516 733 1.02 1.28 1.02 1.36
49 -- -- weak 516 750 1.02 1.31 1.02 1.39
50 -- -- weak 516 762 1.02 1.33 1.02 1.41
51 -- -- weak 518 808 1.02 1.41 1.02 1.48
52 -- -- weak 523 864 1.02 1.52 1.02 1.59
53 -- -- weak 530 925 1.03 1.62 1.03 1.70
54 -- -- weak 536 953 1.05 1.67 1.05 1.75
55 3 4 weak 564 1096 1.11 1.92 1.11 2.00
56 3 4 weak 614 1096 1.20 1.92 1.20 2.00
57 3 4 weak 642 1096 1.25 1.92 1.25 2.00
58 -- -- weak 681 1020 1.33 1.78 1.33 1.86
59 -- -- weak 695 950 1.36 1.66 1.36 1.73
60 -- -- weak 700 925 1.38 1.62 1.38 1.70
61 -- -- weak 708 867 1.39 1.52 1.39 1.59
62 -- -- weak 714 810 1.39 1.42 1.39 1.50
63 -- -- weak 717 759 1.41 1.33 1.41 1.41
64 -- -- weak 717 742 1.41 1.30 1.41 1.38
65 -- -- weak 717 732 1.41 1.28 1.41 1.36
66 -- -- weak 716 690 1.41 1.20 1.41 1.28
67 -- -- weak 712 635 1.39 1.11 1.39 1.19
68 -- -- weak 705 573 1.38 1.00 1.38 1.08
69 -- -- weak 700 542 1.38 0.95 1.38 1.03
70 -- -- weak 687 468 1.34 0.81 1.34 0.89
71 2 5 weak 644 396 1.27 0.69 1.27 0.77
action hints record:
76 0 70 0 0 1 6 95 0 2 2 1 7 75 64 4 4 0 95 4 5 5 1 8 75 69 1 1 0 95 1 3 3 0
point hints record:
(none)
@lemzwerg :
and here is where we are when 39 is the only point that is used at 14ppem:
zero touch 39 y -1 @ 12,13,14
Getting closer...
And after a bit of experimentation this might be as close as we are going to get.
Using the following:
zero touch 39 y -1 @ 12,13,14
zero touch 71 y -0.5 @ 12,13,14
zero touch 39 y -0.5 @ 7,8
zero touch 71 y -0.25 @ 7,8
zero touch 71 x 0.5 @ 7,8,12,13,14
@Grimy Victor, here are the 9 and 11ppem renders. I did not modify the hints because they appear as designed.
This looks fishy... I'll test by myself later this evening.
@Grimy Test builds of the ttf fonts (v2.020; DEV03172016) are available in this directory if you would be willing to test them:
https://github.com/chrissimpkins/Hack/tree/development/build/test_builds/DEV03172016
This looks fishy... I'll test by myself later this evening.
Thanks for your help @lemzwerg. Let me know if you have any other thoughts.
I've now investigated the issue. Point 40 should form a segment together with points 39 and 71, and point 39 shouldn't be tagged as 'strong'. This is a bug in ttfautohint v1.5 which I'm going to fix in the next version – thanks for the report :-)
A fix to this bug is to change the direction of point 40 to 'left' (ttfautohint must have assigned a different direction, otherwise the point would have already been merged with the segment consisting of points 39 and 71); now you can move the segment as expected with touch
.
zero left 40
zero touch 39,40,71 y -1 @ 12-18
zero touch 55,56,57 y -1 @ 8,19-25
Thank you very much @lemzwerg. I really appreciate it. I will give this a try over the weekend. Is this something that we will need to change once the issue is addressed in ttfautohint?
Fortunately no :-) Even if ttfautohint has improved segment recognition so that it can find out by itself that point 40 must have a 'left' direction, the left
command doesn't do any harm.
@lemzwerg great! I tried this last night and it worked. Just a small tweak on the <10ppem sizes and we are in good shape.
There are updated pre-release builds of the fonts (v2.020;DEV-03192016) that include the new hints on the zero glyph here:
https://github.com/chrissimpkins/Hack/tree/development/build/test_builds/DEV03192016
These will be included in the upcoming v2.020 release.
Thanks for the update! Using DEV-03192016, the 0
glyph now looks nice with the following settings:
xterm*faceName: Hack
xterm*faceSize: 11
Xft.antialias: 1
Xft.autohint: 0
Xft.hinting: 1
Xft.hintstyle: hintfull
Oddly enough, when setting hintstyle
to hintslight
, the asymmetrical fill problem persists. I’m not even sure what this setting is supposed to do, so I’ll stick to hintfull
.
@Grimy We will release these changes in the upcoming v2.020 release Victor. Thank you very much for reporting this issue. The zero is a prominent character that helps to establish the identity of the typeface. This was an important issue for us to address. Glad to hear that it works for you.
Thanks again @lemzwerg! Greatly appreciate your help with this.
@Grimy 'Hintslight' is FreeType's auto-hinter. Contrary to manual hinting corrections (which you get with 'hintfull'), the auto-hinter cannot correctly handle the interior of the 'zero' glyph due to technical restrictions.
@lemzwerg thanks!
@lemzwerg is it appropriate to recommend that Linux users apply full hinting when they use our fonts? Wondering if we need this in our documentation. I wasn't aware that FreeType ignored all manual hints in hint slight mode.
To be pedantic: It's up to the font rendering stack to decide what the three hinting modes 'full', 'medium', and 'slight' exactly do. The FontConfig library only sets up those values without defining them.
For TrueType fonts, 'full' normally means bytecode hinting, and 'slight' the hinting as provided by FreeType's auto-hinter, ignoring bytecode completely. The basic question is what 'medium' means for TrueType fonts...
ttfautohint produces bytecode hinting, thus any manual improvements coming from a control instructions file are only present if bytecode hinting is active, and this normally implies full hinting.
is it appropriate to recommend that Linux users apply full hinting when they use our fonts?
I don’t think that’s necessary: full hinting is the default. Maybe a warning to the effect of “Don’t mess up with fontconfig settings unless you know what you’re doing”.
@lemzwerg That is very helpful information. I wasn't aware of this. Thank you very much Werner.
@Grimy That sounds good Victor. We will leave the docs as is for now. Is there a reason why you modified the settings? Does this make other fonts look better on your system?
@Grimy I came across this information on the FreeType site that addresses these font setting issues:
http://www.freetype.org/freetype2/docs/text-rendering-general.html
It seems that the FreeType project has the goal to move towards increased use of some degree of autohinting as the default based upon these comments in that document:
I also hope this change will make it easier for the non-Windows-and-Apple ecosystem to switch over to slight hinting as the default. Current full/medium native hinting, as is the default, tends to bring out the worst in many, many fonts that haven’t seen the same insane dedication to on-screen display and hinting as many popular Microsoft fonts, for example. And since ClearType is still not fully supported, you usually get a very poor default experience. Slight hinting gives a much better one, as Ubuntu has proven over the years.
This is probably a reasonable goal based upon the quality of autohinting that is now available and the reasons cited there; however, this move would definitely lead to problems with the many typefaces that are currently using ttfautohint
with manual hinting guidance via Control Instruction Files for their TrueType font builds (we want the byte code hinting). I looked into this a bit more and it appears that Debian’s official documentation and the Ubuntu wiki both suggest that their users apply the hintslight
setting in order to improve the general appearance of their fonts system wide. The Arch documentation shows hintfull
in the fontconfig hinting example, but takes a very balanced approach to their documentation of the issue.
Given the above, I am wondering whether we should put a Hack project specific fontconfig setting out there for Linux users so that our intended manual hints are always used by applications that obey these configuration settings?
I am a fontconfig novice but I gather that a granular approach by font family can be defined like this?:
<match target="font">
<test qual="any" name="family" compare="eq">
<string>Hack</string>
</test>
<edit name=“hintstyle" mode="assign">
<const>hintfull</const>
</edit>
</match>
Will this suggestion broadly address the hinting issue across commonly used Linux distros? Is the above setting correct?
I read the advice to use hintslight
somewhere, tried it, noticed it made my terminal font of the time look better, and kept the config fragment ever since.
Yes, I believe shipping a fontconfig file is reasonable. However, the example you show does not work, because the opening quote before hintstyle
is a typographic quote (“
, U+201C) rather than an ASCII quote ("
, U+0022). Once this is fixed, it works just fine.
Excellent, thanks. I will work this into the documentation so that others are aware.
These fixes are available in the v2.020 release. Thanks to all here for your help with this issue!
Here’s a screenshot of how the digit 0 looks in my xterm:
As you can see, the bold ones render correctly, but the regular ones have a middle dot that is way too big and extends more to the top than to the bottom.
I have the following config:
Disabling antialising solves this particular problem, but then everything looks ugly.