Rounding a diagonal line to the grid in TrueType

Is there a method in TrueType hinting to round a point to the grid along one axis, and then shift another point by the same amount, but along a different axis?

I am attempting to shift a diagonal line such that it remains at a 45 degree angle, but has both its endpoints rounded to the nearest intersections of the raster grid lines. I have managed to get the top point in the attached picture rounded to the grid in the vertical direction, and the bottom left point shifted in the vertical direction to match, and to get the bottom left point rounded to the grid in the horizontal direction, and the top point shifted in the horizontal direction to match, using this xgridfit code:

<with-round-state round="to-grid">
<with-vectors axis="x">
<move>
<point num="1"/>
<shift><point num="2"/></shift>
</move>
</with-vectors>

<with-vectors axis="y">
<move>
<point num="2"/>
<shift><point num="1"/></shift>
</move>
</with-vectors>
</with-round-state>

Point 1 is the point in the bottom left of the picture. Point 2 is the point at the top of the picture. The line connecting them is the one I am trying to keep at 45 degrees.



The next step is to round the top point in the horizontal direction, and move the bottom point in the vertical direction the same amount to compensate and keep the angle of the line at 45 degrees.

Thank you for your time,
Patrick

Comments

  • The larger encompassing question that I should probably have asked is how to hint these four points such that the diagonal stem width matches the horizontal and vertical stem widths as closely as mathematically possible at every point size.

  • This is an attempt to describe what I mean by "as closely as mathematically possible".

    I note that the width of a diagonal line at 45 degrees can be any half integer multiple of sqrt(2) that is greater than or equal to sqrt(2). For example, the line on the left in the attached picture has a width of sqrt(2) and the line on the right in the attached picture has a width of 1.5 * sqrt(2).

    Therefore, if the width of the horizontal and vertical stems is n pixels across, then the width of the diagonal stem should be the half integer multiple of sqrt(2) that is as close to n as possible.



  • Is it possible in the TrueType hinting instructions to say something like "If the current ppem is x then render the font by turning on the same pixels that would be if the ppem was y.", where y is the nearest integer multiple of 16 to x?
  • At two different ppems, there is no possibility of “the same pixels” as such.

    And other than dropout control being on/off, there is no notion of pixels being on: all you do is control distances between specified points (typically on-curve points, but they can be off-curve). You can move specified points either before or after you interpolate untouched points (IUP) for all other points. For most big effects and regularization, you are doing “before” hints. For fine tuning of a curve or diagonal, it might be after. 
  • I guess I mean, I can achieve what I am after to a degree in the TrueType instructions by scaling all of the point coordinates in proportion to the current ppem, but I'm wondering if there is a less complicated and more exact way.
  • You can get the difference between the original position of a point and its current position and shift a point by that amount on the current axis (I am using the compact syntax of xgridfit3, and do note that I haven't tested--but post here or message me if this doesn't work):
     
    <setvs axis="x"/>
    <mv p="1">
      <sh p="2"/>
    </mv>
    <setvs axis="y"/>
    <!-- There is no compact version of shift-absolute -->
    <shift-absolute pixel-distance="x-coord(2) - initial-x-coord(2)">
      <pt n="2"/>
    </shift-absolute>

  • Thank you.
  • pthomas505
    pthomas505 Posts: 54
    This is confusing me. The hinted distance projected onto the x axis from point 14 to point 15 (bottom left line of bottom right contour) should be equal to the CVT value of 5: 32 (0.50), that is 0.50 pixels. Looking at the images it jumped from about 0.50 pixels at 35 ppem (correct) to about 1.5 pixels at 36 ppem (incorrect), but the CVT value is 0.50 pixels at both ppems. It makes odd jumps like this at other ppems too.

    The hinting code is here. The TTF is generated from the UFO here.


  • pthomas505
    pthomas505 Posts: 54
    I think I found the issue. I think it was being caused by the control-value-cut-in. Setting the control-value-cut-in to 2.0 seemed to make the problem go away.

    Is there a way to ensure that the control values are always used rather than just increasing this value to one that should be big enough?
  • Mike Duggan
    Mike Duggan Posts: 239
    Perhaps delete the cvt cut in code : ) 
  • pthomas505
    pthomas505 Posts: 54
    Do you mean this line: <set-control-value-cut-in value="2.0" /> ? I had to add that entire line for the fix. Without it it defaults to something smaller than 2.0.
  • Mike Duggan
    Mike Duggan Posts: 239
    ahh ok, I didnt know it defaults to that smaller number 
  • Peter Baker
    Peter Baker Posts: 190
    Xgridfit leaves the cut-in at the TrueType default of 17/16 pixels unless you change it.