chiark / gitweb /
Add JOIN_R and JOIN_D flags, and extend effects of JOIN_*
authorBen Harris <bjh21@bjh21.me.uk>
Mon, 22 Sep 2025 19:27:46 +0000 (20:27 +0100)
committerBen Harris <bjh21@bjh21.me.uk>
Mon, 22 Sep 2025 21:24:02 +0000 (22:24 +0100)
The new flags mark glyphs that join to the right and downwards.  The
effect of these, and a new effect of JOIN_U and JOIN_L, is to arrange
that getpix() treats pixels beyond the edge of the character cell as
repeating the last row of real pixels.

In practice, this means that a diagonal stroke touching the right or
bottom edge of the cell will now be drawn as though it turns into an
orthogonal stroke across the edge rather than as though it stops.  This
doesn't affect the outline of any existing glyph.

There is a more subtle consequence, which is that joining glyphs no
longer get edge hints on their joining edges.  I think that's an
improvement: such hints might move those edges so that they don't touch
the adjacent character, which would be rather unhelpful.

bedstead.c

index bdfa86f79e80cf10d6bbfbcb9ca903375ff630d5..f2143000a7adcef775ad8b9de0549aab1f02803f 100644 (file)
@@ -222,7 +222,7 @@ static struct glyph {
        };
        int_least32_t unicode;
        char const *name;
-       uint_least8_t flags;
+       uint_least16_t flags;
 #define SEP  0x01 /* Separated graphics */
 #define MOS6 0x02 /* 6-cell mosaic graphics character */
 #define MOS4 0x04 /* 4-cell mosaic graphics character */
@@ -230,10 +230,14 @@ static struct glyph {
 #define SEP4 (SEP | MOS4)
 #define JOIN_L 0x08 /* Copy left column leftward to join to next character. */
 #define JOIN_U 0x10 /* Copy top row upwards ditto. */
-#define JOIN (JOIN_L | JOIN_U)
-#define IS_ALIAS 0x20 /* Set iff .alias_of is valid (and .data is not). */
-#define IS_SUBR  0x40 /* Set iff .subr_idx is valid.(and .data is not). */
-#define COMPAT   0x80 /* Mark as a compatibility alias in complement PDF. */
+#define JOIN_R 0x20 /* Pretend column to right is identical to right column. */
+#define JOIN_D 0x40 /* Similarly downwards. */
+#define JOIN_H (JOIN_L | JOIN_R)
+#define JOIN_V (JOIN_U | JOIN_D)
+#define JOIN (JOIN_H | JOIN_V)
+#define IS_ALIAS 0x100 /* Set iff .alias_of is valid (and .data is not). */
+#define IS_SUBR  0x200 /* Set iff .subr_idx is valid.(and .data is not). */
+#define COMPAT   0x400 /* Mark as a compatibility alias in complement PDF. */
        uint_least16_t left_sidebearing; /* Set when outline generated. */
 } glyphs[] = {
  /*
@@ -2014,8 +2018,8 @@ static struct glyph {
  {"\37\01\01\01\01\00\00\00\00", U(231D) }, /* top right corner */
  {"\00\00\20\20\20\20\37\00\00", U(231E) }, /* bottom left corner */
  {"\00\00\01\01\01\01\37\00\00", U(231F) }, /* bottom right corner */
- {"\00\00\02\05\04\04\04\04\04", 0x2320, "integraltp" },
- {"\00\00\10\24\04\04\04\04\04", 0xf111, "integraltp.rtlm" },
+ {"\00\00\02\05\04\04\04\04\04", 0x2320, "integraltp", JOIN_D },
+ {"\00\00\10\24\04\04\04\04\04", 0xf111, "integraltp.rtlm", JOIN_D},
  {"\04\04\04\04\04\24\10\00\00", 0x2321, "integralbt", JOIN_U },
  {"\04\04\04\04\04\05\02\00\00", 0xf112, "integralbt.rtlm", JOIN_U },
  {"\02\02\04\10\04\02\02\00\00", 0x2329, "angleleft" },
@@ -2073,34 +2077,34 @@ static struct glyph {
  {"\00\07\12\12\12\34\00\00\00", U(238E) }, /* hysteresis */
  {"\00\00\37\00\25\00\00\00\00", U(2393) }, /* directcurrent */
  {"\37\21\21\21\21\21\37\00\00", U(2395) }, /* APL quad */
- {"\02\04\10\10\10\10\10\10\10", U(239B) }, /* long parenleft top */
- {"\10\10\10\10\10\10\10\10\10", U(239C), JOIN_U }, /* long parenleft middle */
+ {"\02\04\10\10\10\10\10\10\10", U(239B), JOIN_D }, /* long parenleft top */
+ {"\10\10\10\10\10\10\10\10\10", U(239C), JOIN_V }, /* long parenleft middle */
  {"\10\10\10\10\10\04\02\00\00", U(239D), JOIN_U }, /* long parenleft bottom */
- {"\10\04\02\02\02\02\02\02\02", U(239E) }, /* long parenright top */
- {"\02\02\02\02\02\02\02\02\02", U(239F), JOIN_U }, /* long parenright middle */
+ {"\10\04\02\02\02\02\02\02\02", U(239E), JOIN_D }, /* long parenright top */
+ {"\02\02\02\02\02\02\02\02\02", U(239F), JOIN_V }, /* long parenright middle */
  {"\02\02\02\02\02\04\10\00\00", U(23A0), JOIN_U }, /* long parenright bottom */
- {"\17\10\10\10\10\10\10\10\10", U(23A1) }, /* long bracketleft top */
- {"\10\10\10\10\10\10\10\10\10", U(23A2), JOIN_U }, /* long bracketleft mid */
+ {"\17\10\10\10\10\10\10\10\10", U(23A1), JOIN_D }, /* long bracketleft top */
+ {"\10\10\10\10\10\10\10\10\10", U(23A2), JOIN_V }, /* long bracketleft mid */
  {"\10\10\10\10\10\10\17\00\00", U(23A3), JOIN_U }, /* long bracketleft bot */
- {"\36\02\02\02\02\02\02\02\02", U(23A4) }, /* long bracketright top */
- {"\02\02\02\02\02\02\02\02\02", U(23A5), JOIN_U }, /* long bracketright mid */
+ {"\36\02\02\02\02\02\02\02\02", U(23A4), JOIN_D }, /* long bracketright top */
+ {"\02\02\02\02\02\02\02\02\02", U(23A5), JOIN_V }, /* long bracketright mid */
  {"\02\02\02\02\02\02\36\00\00", U(23A6), JOIN_U }, /* long bracketright bot */
- {"\03\04\04\04\04\04\04\04\04", U(23A7) }, /* long braceleft top */
- {"\04\04\04\10\04\04\04\04\04", U(23A8), JOIN_U }, /* long braceleft middle */
+ {"\03\04\04\04\04\04\04\04\04", U(23A7), JOIN_D }, /* long braceleft top */
+ {"\04\04\04\10\04\04\04\04\04", U(23A8), JOIN_V }, /* long braceleft middle */
  {"\04\04\04\04\04\04\03\00\00", U(23A9), JOIN_U }, /* long braceleft bottom */
- {"\04\04\04\04\04\04\04\04\04", U(23AA), JOIN_U }, /* long brace extension */
- {"\30\04\04\04\04\04\04\04\04", U(23AB) }, /* long braceright top */
- {"\04\04\04\02\04\04\04\04\04", U(23AC), JOIN_U }, /* long braceright middle */
+ {"\04\04\04\04\04\04\04\04\04", U(23AA), JOIN_V }, /* long brace extension */
+ {"\30\04\04\04\04\04\04\04\04", U(23AB), JOIN_D }, /* long braceright top */
+ {"\04\04\04\02\04\04\04\04\04", U(23AC), JOIN_V }, /* long braceright middle */
  {"\04\04\04\04\04\04\30\00\00", U(23AD), JOIN_U }, /* long braceright bottom */
- {"\04\04\04\04\04\04\04\04\04", U(23AE), JOIN_U }, /* integral extension */
+ {"\04\04\04\04\04\04\04\04\04", U(23AE), JOIN_V }, /* integral extension */
  {"\03\04\04\04\04\04\04\04\30", U(23B0) }, /* two-level brace / */
  {"\30\04\04\04\04\04\04\04\03", U(23B1) }, /* two-level brace \ */
- {"\37\20\10\10\04\04\02\02\01", U(23B2) }, /* summation top */
+ {"\37\20\10\10\04\04\02\02\01", U(23B2), JOIN_D }, /* summation top */
  {"\01\02\02\04\04\10\10\20\37", U(23B3), JOIN_U }, /* summation bottom */
- {"\37\00\00\00\00\00\00\00\00", U(23BA), JOIN_L }, /* horizontal scan 1 */
- {"\00\00\37\00\00\00\00\00\00", U(23BB), JOIN_L }, /* horizontal scan 3 */
- {"\00\00\00\00\00\00\37\00\00", U(23BC), JOIN_L }, /* horizontal scan 7 */
- {"\00\00\00\00\00\00\00\00\37", U(23BD), JOIN_L }, /* horizontal scan 9 */
+ {"\37\00\00\00\00\00\00\00\00", U(23BA), JOIN_H }, /* horizontal scan 1 */
+ {"\00\00\37\00\00\00\00\00\00", U(23BB), JOIN_H }, /* horizontal scan 3 */
+ {"\00\00\00\00\00\00\37\00\00", U(23BC), JOIN_H }, /* horizontal scan 7 */
+ {"\00\00\00\00\00\00\00\00\37", U(23BD), JOIN_H }, /* horizontal scan 9 */
  {"\04\04\37\00\16\00\04\00\00", U(23DA) }, /* earth */
  {"\00\00\00\00\22\25\25\25\22", U(23E8) }, /* decimal exponent symbol */
 
@@ -2730,11 +2734,11 @@ static struct glyph {
  {"\10\24\21\12\04\12\21\05\02", U(1D10B) }, /* segno */
  {"\16\21\25\00\00\00\00\00\00", U(1D110) }, /* fermata */
  {"\00\00\00\00\00\00\25\21\16", U(1D111) }, /* fermata below */
- {"\00\00\00\00\37\00\00\00\00", U(1D116), JOIN_L }, /* 1-line stave */
- {"\00\00\00\37\00\37\00\00\00", U(1D117), JOIN_L }, /* 2-line stave */
- {"\00\00\37\00\37\00\37\00\00", U(1D118), JOIN_L }, /* 3-line stave */
- {"\00\37\00\37\00\37\00\37\00", U(1D119), JOIN_L }, /* 4-line stave */
- {"\37\00\37\00\37\00\37\00\37", U(1D11A), JOIN_L }, /* 5-line stave */
+ {"\00\00\00\00\37\00\00\00\00", U(1D116), JOIN_H }, /* 1-line stave */
+ {"\00\00\00\37\00\37\00\00\00", U(1D117), JOIN_H }, /* 2-line stave */
+ {"\00\00\37\00\37\00\37\00\00", U(1D118), JOIN_H }, /* 3-line stave */
+ {"\00\37\00\37\00\37\00\37\00", U(1D119), JOIN_H }, /* 4-line stave */
+ {"\37\00\37\00\37\00\37\00\37", U(1D11A), JOIN_H }, /* 5-line stave */
  {"\04\12\12\12\14\26\25\16\04", U(1D11E) }, /* G clef */
  {"\25\25\25\26\24\26\25\25\25", U(1D121) }, /* C clef */
  {"\10\25\04\05\10\20\00\00\00", U(1D122) }, /* F clef */
@@ -3172,8 +3176,10 @@ getpix(char const data[YSIZE - 1], int x, int y, unsigned flags)
         * always reads as 0.
         */
        /* Line-drawing characters repeat top row and/or left column. */
-       if ((flags & JOIN_L) && x == 0) x = 1;
-       if ((flags & JOIN_U) && y == 0) y = 1;
+       if ((flags & JOIN_L) && x < 1) x = 1;
+       if ((flags & JOIN_R) && x >= XSIZE) x = XSIZE - 1;
+       if ((flags & JOIN_U) && y < 1) y = 1;
+       if ((flags & JOIN_D) && y >= YSIZE) y = YSIZE - 1;
        if (x < 1 || x >= XSIZE || y < 1 || y >= YSIZE)
                return 0;
        else