Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extension proposal: Corner components #213

Open
simoncozens opened this issue Nov 22, 2022 · 3 comments
Open

Extension proposal: Corner components #213

simoncozens opened this issue Nov 22, 2022 · 3 comments

Comments

@simoncozens
Copy link

simoncozens commented Nov 22, 2022

Several font editors implement a concept variously known as "corner components" or "corner skins"; this concept is often used for serifs, ink traps, or other modification and decorations of a on-curve point on a contour.

Definitions

  • A corner component is a component containing at least one open contour (the corner contour) and zero or more other contours.

  • In the editor's interface, this component is associated with a on-curve point (the target point) on a closed contour (the host contour).

  • The on-curve point stores information about the name of the component to apply, an optional scaling factor, and an alignment.

  • The instroke is the segment of the contour which ends at the target point, and the outstroke is the segment of the contour which begins at the target point.

  • The alignment of a corner component is either outstroke (also known as "left", but this terminology is not recommended), instroke ("right"), middle or unaligned. These alignments will be explained below.

  • A component is flipped if either its X scaling factor or Y scaling factor is negative, but not both.

Storage

Corner components should be stored as a dictionary of data in a point-level lib, under this key:

  • uk.co.corvelsoftware.corner-components

with the following items:

key type value default
name string The name of the corner component required
scaleX integer or float The X-axis scaling factor 1.0
scaleY integer or float The Y-axis scaling factor 1.0
alignment string One of "instroke", "outstroke", "middle", "unaligned" instroke

Processing

To process a corner component, the font compiler is expected to perform the following operations:

  • Find the appropriate corner component glyph, and maintain a copy of all of the contours.
  • Test for the presence of origin, left and right anchors within the corner component glyph, and store their values.
  • Locate the target point.
  • Scale all the component contours by the scale factors, and take note of whether or not the corner component is flipped.
  • If there is an origin anchor, translate all the components and anchors of the component glyph such that this anchor becomes placed at (0,0).
  • If the corner component is flipped, reverse the corner contour segmentwise.
  • Align the corner component to the target point. This is done by:
    • Determining the angle of the vector between the origin and the last (or first, if the component is flipped) point of the corner contour. This is the component angle
    • If the component is flipped, adding 90 degrees to the component angle.
    • Finding the outstroke intersection point. This is a point along the outstroke at a distance d away from the target point, where d is the X-coordinate of the last point in the corner component (or Y-coordinate if the component is flipped).
    • Finding the outstroke angle. This is the angle between the target point and the outstroke intersection point.
    • Finding the instroke intersection point. This is a point along the instroke at a distance d2 away from the target point, where d2 is the Y-coordinate of the first point in the corner component (or X-coordinate if the component is flipped).
    • Finding the instroke angle. This is the angle between the target point and the instroke intersection point, plus 90 degrees.
    • If the alignment is outstroke, add the outstroke angle to the component angle. If the alignment is instroke, add the instroke angle to the component angle. If the alignment is middle, add the average of the outstroke and instroke angles to the component angle. If the alignment is unaligned, do nothing.
    • Rotate the corner component by the component angle.
    • Translate the corner component by the coordinates of the target point.
  • Store a copy of the outstroke at this point as the original outstroke.
  • If the alignment is not instroke:
    • find the intersection between the unbounded segments of the instroke and ray connecting the first two points of the corner contour. (If the first segment of the corner contour is a curve, this ray will connect the on-curve and first off-curve points.) This is the corrected instroke intersection point.
    • If the first segment of the corner contour is a curve, translate its first two points so that the first point lays at the instroke intersection point.
  • Split the instroke at the instroke intersection point, such that the target point now lays at the instroke intersection point.
  • Insert all points of the corner contour, except for the first point, into the host contour after the target point. (After the previous two steps, the target point and the first point of the corner contour are both correctly positioned at the instroke intersection point.)
  • Determine the corrected outstroke intersection point, by:
    • If the component is flipped, finding the intersection between the unbounded original outstroke and the last segment of the corner contour.
    • Otherwise, finding the closest point on the original outstroke to the final point of the corner contour.
  • Locate the new points of the outstroke, which will have moved due to the insertion of the corner contour points.
  • Split the outstroke such that its first point now lays at the outstroke intersection point.
  • Insert any other contours into the glyph.

Notes

  • This proposal does not currently support the handling of left and right anchors in the component glyph.
  • This proposal does not support corner components at the virtual points formed by the intersections of multiple contours.
@justvanrossum
Copy link
Contributor

Can you name the font editor(s) among "Several font editors" that is not Glyphs?

@madig
Copy link
Contributor

madig commented Nov 22, 2022

FontLab 8 supports this under the name of "skins": https://help.fontlab.com/fontlab/8/whats-new/whats-new-05-build-assemble/#skin-filter

@schriftgestalt
Copy link

schriftgestalt commented Jan 12, 2023

where d2 is the Y-coordinate of the first point in the corner component (or X-coordinate if the component is flipped).

That should be the distance, not the individual y or x coordinates.

If the component is flipped, adding 90 degrees to the component angle.

I don’t see why that is needed. Maybe the above comment removes that requirement?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants