%
% Copyright (c) 2012, Michael Ummels <michael.ummels@rwth-aachen.de>
%
% This Font Software is licensed under the SIL Open Font License,
% Version 1.1. This license is in the accompanying file OFL.txt, and
% is also available with a FAQ at: http://scripts.sil.org/OFL
%

% thickness factor for delimiters
def dthick(expr scale) =
  1
enddef;

% parenthesis

lparen_char = current_char + 1;
rparen_char = current_char + 7;
for sign = 1, -1:
  for scale = 1, 1.2, 1.5, 1.8, 2.4, 3:
    beginsymbol((2scale + 4.5)/2 * u# + line_thickness# + 2side_bearing#, vcentre(2scale * delim_height#)); "parenthesis";
      draw_paren(sign, dthick(scale) * line_thickness);
    endchar;
  endfor;
endfor;

for sign = 1, -1:
  beginsymbol((6 + 4.5)/2 * u# + line_thickness# + 2side_bearing#, vcentre(3delim_height#)); "parenthesis -- top";
    thick := dthick(3) * line_thickness;

    penpos1(thick, -90 + sign * 60);
    penpos2(thick, 90 - sign * 90);
    penpos2'(thick, 90 - sign * 90);

    x1 = x2 + sign * (w - 2side_bearing - thick);
    x2 = x2';
    y1 = h;
    y2 = -d + 1/2line_thickness;
    y2' = -d - 1/2line_thickness;
    1/2[x1r,x2l] = w/2;

    fill stroke z2'.e -- z2e{up} .. {3(x1e - x2e), y1e - y2e}z1e;

    penlabels(1,2,2');
  endchar;
endfor;

for sign = 1, -1:
  beginsymbol((6 + 4.5)/2 * u# + line_thickness# + 2side_bearing#, vcentre(3delim_height#)); "parenthesis -- bot";
    thick := dthick(3) * line_thickness;

    penpos0(thick, 90 - sign * 60);
    penpos2(thick, 90 - sign * 90);
    penpos2'(thick, 90 - sign * 90);

    x0 = x2 + sign * (w - 2side_bearing - thick);
    x2 = x2';
    y2 =  h - 1/2line_thickness;
    y2' =  h + 1/2line_thickness;
    y0 = -d;
    1/2[x0r,x2l] = w/2;

    fill stroke z0e{3(x2e - x0e), y2e - y0e} .. {up}z2e -- z2'.e;

    penlabels(1,2,2');
  endchar;
endfor;

for sign = 1, -1:
  beginsymbol((6 + 4.5)/2 * u# + line_thickness# + 2side_bearing#, vcentre(0.6delim_height#)); "parenthesis -- module";
    thick := dthick(3) * line_thickness;

    penpos1(thick, 90 - sign * 45);
    penpos2(thick, 90 - sign * 90);
    penpos3(thick, 90 - sign * 90);

    x2 = x3 = x1 - sign * (w - 2side_bearing - thick);
    y2 =  h + 1/2line_thickness;
    y3 = -d - 1/2line_thickness;
    1/2[x1r,x2l] = w/2;

    fill stroke z2e -- z3e;
  endchar;
endfor;

extensible current_char - 1: current_char - 5, 0, current_char - 3, current_char - 1; %left parenthesis
extensible current_char: current_char - 4, 0, current_char - 2, current_char;     %right parenthesis

charlist lparen_char: lparen_char + 1: lparen_char + 2: lparen_char + 3: lparen_char + 4: lparen_char + 5: current_char - 1;
charlist rparen_char: rparen_char + 1: rparen_char + 2: rparen_char + 3: rparen_char + 4: rparen_char + 5: current_char;

% brackets

lsquare_char = current_char + 1;
rsquare_char = current_char + 7;
for sign = 1, -1:
  for scale = 1, 1.2, 1.5, 1.8, 2.4, 3:
    beginsymbol((2scale + 4)/2 * u# + line_thickness# + 2side_bearing#, vcentre(2scale * delim_height#)); "square bracket";
      draw_bracket(sign, dthick(scale) * line_thickness, true, true, true, false);
    endchar;
  endfor;
endfor;

lfloor_char = current_char + 1;
rfloor_char = current_char + 7;
for sign = 1, -1:
  for scale = 1, 1.2, 1.5, 1.8, 2.4, 3:
    beginsymbol((2scale + 4)/2 * u# + line_thickness# + 2side_bearing#, vcentre(2scale * delim_height#)); "floor";
      draw_bracket(sign, dthick(scale) * line_thickness, false, true, true, false);
    endchar;
  endfor;
endfor;

lceil_char = current_char + 1;
rceil_char = current_char + 7;
for sign = 1, -1:
  for scale = 1, 1.2, 1.5, 1.8, 2.4, 3:
    beginsymbol((2scale + 4)/2 * u# + line_thickness# + 2side_bearing#, vcentre(2scale * delim_height#)); "ceiling";
      draw_bracket(sign, dthick(scale) * line_thickness, true, true, false, false);
    endchar;
  endfor;
endfor;

ulcorner_char = current_char + 1;
urcorner_char = current_char + 7;
for sign = 1, -1:
  for scale = 1, 1.2, 1.5, 1.8, 2.4, 3:
    beginsymbol((2scale + 4)/2 * u# + line_thickness# + 2side_bearing#, vcentre(2scale * delim_height#)); "upper corner";
      draw_bracket(sign, dthick(scale) * line_thickness, true, false, false, false);
    endchar;
  endfor;
endfor;

charlist ulcorner_char: ulcorner_char + 1: ulcorner_char + 2: ulcorner_char + 3: ulcorner_char + 4: ulcorner_char + 5;
charlist urcorner_char: urcorner_char + 1: urcorner_char + 2: urcorner_char + 3: urcorner_char + 4: urcorner_char + 5;

llcorner_char = current_char + 1;
lrcorner_char = current_char + 7;
for sign = 1, -1:
  for scale = 1, 1.2, 1.5, 1.8, 2.4, 3:
    beginsymbol((2scale + 4)/2 * u# + line_thickness# + 2side_bearing#, vcentre(2scale * delim_height#)); "lower corner";
      draw_bracket(sign, dthick(scale) * line_thickness, false, false, true, false);
    endchar;
  endfor;
endfor;

charlist llcorner_char: llcorner_char + 1: llcorner_char + 2: llcorner_char + 3: llcorner_char + 4: llcorner_char + 5;
charlist lrcorner_char: lrcorner_char + 1: lrcorner_char + 2: lrcorner_char + 3: lrcorner_char + 4: lrcorner_char + 5;

ullcorner_char = current_char + 1;
ulrcorner_char = current_char + 7;
for sign = 1, -1:
  for scale = 1, 1.2, 1.5, 1.8, 2.4, 3:
    beginsymbol((2scale + 4)/2 * u# + line_thickness# + 2side_bearing#, vcentre(2scale * delim_height#)); "upper/lower corner";
      draw_bracket(sign, dthick(scale) * line_thickness, true, false, true, false);
    endchar;
  endfor;
endfor;

charlist ullcorner_char: ullcorner_char + 1: ullcorner_char + 2: ullcorner_char + 3: ullcorner_char + 4: ullcorner_char + 5;
charlist ulrcorner_char: ulrcorner_char + 1: ulrcorner_char + 2: ulrcorner_char + 3: ulrcorner_char + 4: ulrcorner_char + 5;

for sign = 1, -1:
  beginsymbol(5u# + line_thickness# + 2side_bearing#, vcentre(1.2delim_height#)); "square bracket -- top";
    draw_bracket(sign, dthick(3) * line_thickness, true, true, false, false);
  endchar;
endfor;

for sign = 1, -1:
  beginsymbol(5u# + line_thickness# + 2side_bearing#, vcentre(1.2delim_height#)); "square bracket -- bot";
    draw_bracket(sign, dthick(3) * line_thickness, false, true, true, false);
  endchar;
endfor;

for sign = 1, -1:
  beginsymbol(5u# + line_thickness# + 2side_bearing#, vcentre(0.6delim_height#)); "square bracket -- module";
    draw_bracket(sign, dthick(3) * line_thickness, false, true, false, false);
  endchar;
endfor;

extensible current_char - 1: current_char - 5, 0, current_char - 3, current_char - 1; %left square bracket
extensible current_char: current_char - 4, 0, current_char - 2, current_char; %right square bracket
extensible current_char - 3: 0, 0, current_char - 3, current_char - 1; %left floor
extensible current_char - 2: 0, 0, current_char - 2, current_char; %right floor
extensible current_char - 5: current_char - 5, 0, 0, current_char - 1; %left ceiling
extensible current_char - 4: current_char - 4, 0, 0, current_char; %right ceiling

charlist lsquare_char: lsquare_char + 1: lsquare_char + 2: lsquare_char + 3: lsquare_char + 4: lsquare_char + 5: current_char - 1;
charlist rsquare_char: rsquare_char + 1: rsquare_char + 2: rsquare_char + 3: rsquare_char + 4: rsquare_char + 5: current_char;
charlist lfloor_char: lfloor_char + 1: lfloor_char + 2: lfloor_char + 3: lfloor_char + 4: lfloor_char + 5: current_char - 3;
charlist rfloor_char: rfloor_char + 1: rfloor_char + 2: rfloor_char + 3: rfloor_char + 4: rfloor_char + 5: current_char - 2;
charlist lceil_char: lceil_char + 1: lceil_char + 2: lceil_char + 3: lceil_char + 4: lceil_char + 5: current_char - 5;
charlist rceil_char: rceil_char + 1: rceil_char + 2: rceil_char + 3: rceil_char + 4: rceil_char + 5: current_char - 4;

% semantic brackets

lsem_char = current_char + 1;
rsem_char = current_char + 7;
for sign = 1, -1:
  for scale = 1, 1.2, 1.5, 1.8, 2.4, 3:
    beginsymbol((2scale + 4)/2 * u# + 2line_thickness# + 2side_bearing#, vcentre(2scale * delim_height#)); "semantic bracket";
      draw_bracket(sign, dthick(scale) * line_thickness, true, true, true, true);
    endchar;
  endfor;
endfor;

for sign = 1, -1:
  beginsymbol(5u# + 2line_thickness# + 2side_bearing#, vcentre(1.2delim_height#)); "semantic bracket -- top";
    draw_bracket(sign, dthick(3) * line_thickness, true, true, false, true);
  endchar;
endfor;

for sign = 1, -1:
  beginsymbol(5u# + 2line_thickness# + 2side_bearing#, vcentre(1.2delim_height#)); "semantic bracket -- bot";
    draw_bracket(sign, dthick(3) * line_thickness, false, true, true, true);
  endchar;
endfor;

for sign = 1, -1:
  beginsymbol(5u# + line_thickness# + 2side_bearing#, vcentre(0.6delim_height#)); "semantic bracket -- module";
    draw_bracket(sign, dthick(3) * line_thickness, false, true, false, true);
  endchar;
endfor;

extensible current_char - 1: current_char - 5, 0, current_char - 3, current_char - 1; %left semantic bracket
extensible current_char: current_char - 4, 0, current_char - 2, current_char; %right semantic bracket

charlist lsem_char: lsem_char + 1: lsem_char + 2: lsem_char + 3: lsem_char + 4: lsem_char + 5: current_char - 1;
charlist rsem_char: rsem_char + 1: rsem_char + 2: rsem_char + 3: rsem_char + 4: rsem_char + 5: current_char;

% curly braces

lcurly_char = current_char + 1;
rcurly_char = current_char + 7;
for sign = 1, -1:
  for scale = 1, 1.2, 1.5, 1.8, 2.4, 3:
    beginsymbol((2scale + 5.5)/2 * u# + line_thickness# + 2side_bearing#, vcentre(2scale * delim_height#)); "curly brace";
      thick := dthick(scale) * line_thickness;

      draw_brace((w/2, (h-d)/2), h + d, w - 2side_bearing, 90 + sign * 90, thick, 0, 0, 0)
    endchar;
  endfor;
endfor;

beginsymbol((6 + 5.5)/2 * u# + line_thickness# + 2side_bearing#, vcentre(1.2delim_height#)); "curly brace -- top";
  thick := dthick(3) * line_thickness;

  draw_brace((w/2, h - 3delim_height), 6delim_height, w - 2side_bearing, 180, thick, 0, 0, h + d);
endchar;

beginsymbol((6 + 5.5)/2 * u# + line_thickness# + 2side_bearing#, vcentre(1.2delim_height#)); "curly brace -- top";
  thick := dthick(3) * line_thickness;

  draw_brace((w/2, h - 3delim_height), 6delim_height, w - 2side_bearing,   0, thick, h + d, 0, 0);
endchar;

beginsymbol((6 + 5.5)/2 * u# + line_thickness# + 2side_bearing#, vcentre(1.2delim_height#)); "curly brace -- bot";
  thick := dthick(3) * line_thickness;

  draw_brace((w/2, 3delim_height - d), 6delim_height, w - 2side_bearing, 180, thick, h + d, 0, 0)
endchar;

beginsymbol((6 + 5.5)/2 * u# + line_thickness# + 2side_bearing#, vcentre(1.2delim_height#)); "curly brace -- bot";
  thick := dthick(3) * line_thickness;

  draw_brace((w/2, 3delim_height - d), 6delim_height, w - 2side_bearing,   0, thick, 0, 0, h + d)
endchar;

for sign = 1, -1:
  beginsymbol((6 + 5.5)/2 * u# + line_thickness# + 2side_bearing#, vcentre(1.2delim_height#)); "curly brace -- middle";
    thick := dthick(3) * line_thickness;

    draw_brace((w/2, (h-d)/2), 6delim_height, w - 2side_bearing, 90 + sign * 90, thick, 0, h + d, 0);
  endchar;
endfor;

beginsymbol((6 + 5.5)/2 * u# + line_thickness# + 2side_bearing#, vcentre(0.6delim_height#)); "curly brace -- module";
  thick := dthick(3) * line_thickness;

  x2 = x3 = w/2;
  y2 = h + 1/2line_thickness;
  y3 = -d - 1/2line_thickness;

  draw_straight(z2, z3, thick, false);
endchar;

extensible current_char - 6: current_char - 6, 0, current_char - 4, current_char; %sharp left parenthesis
extensible current_char - 5: current_char - 5, 0, current_char - 3, current_char; %sharp right parenthesis
extensible current_char - 3: current_char - 6, 0, current_char - 3, current_char; %left moustache
extensible current_char - 4: current_char - 5, 0, current_char - 4, current_char; %right moustache
extensible current_char - 2: current_char - 6, current_char - 2, current_char - 4, current_char; %left curly brace
extensible current_char - 1: current_char - 5, current_char - 1, current_char - 3, current_char; %right curly brace
extensible current_char: 0, 0, 0, current_char; %vertical line

charlist lcurly_char: lcurly_char + 1: lcurly_char + 2: lcurly_char + 3: lcurly_char + 4: lcurly_char + 5: current_char - 2;
charlist rcurly_char: rcurly_char + 1: rcurly_char + 2: rcurly_char + 3: rcurly_char + 4: rcurly_char + 5: current_char - 1;

% angle brackets

for sign = 1, -1:
  for scale = 1, 1.2, 1.5, 1.8, 2.4, 3:
    beginsymbol((2scale + 4)/2 * u# + line_thickness# + 2side_bearing#, vcentre(2scale * delim_height#)); "angle bracket";
      draw_angle(a, 0, sign, dthick(scale) * line_thickness);
    endchar;
  endfor;
  charlist current_char - 5: current_char - 4: current_char - 3: current_char - 2: current_char - 1: current_char;
endfor;

for sign = 1, -1:
  for scale = 1, 1.2, 1.5, 1.8, 2.4, 3:
    beginsymbol((2scale + 8)/2 * u# + 2line_thickness# + 2side_bearing#, vcentre(2scale * delim_height#)); "double angle bracket";
      thick := dthick(scale) * line_thickness;

      draw_angle(a, -5/4thick, sign, thick);
      draw_angle(b, 5/4thick, sign, thick);
    endchar;
  endfor;
  charlist current_char - 5: current_char - 4: current_char - 3: current_char - 2: current_char - 1: current_char;
endfor;

for sign = 1, -1:
  for scale = 1, 1.2, 1.5, 1.8, 2.4, 3:
    beginsymbol((2scale + 4)/2 * u# + line_thickness# + 2side_bearing#, vcentre(2scale * delim_height#)); "angle bracket with dot";
      thick := dthick(scale) * line_thickness;

      draw_angle(a, 0, sign, thick);
      
      if sign > 0:
        x3 = w - side_bearing - 3/4dot_size;
      else:
        x3 = side_bearing + 3/4dot_size;
      fi
      y3 = 1/2(h - d);

      fill dot(z3, 3/4dot_size);
    endchar;
  endfor;
  charlist current_char - 5: current_char - 4: current_char - 3: current_char - 2: current_char - 1: current_char;
endfor;

% slash

for sign = 1, -1:
  for scale = 1, 1.2, 1.5, 1.8, 2.4, 3:
    beginsymbol(6scale * u# + line_thickness# + side_bearing#, vcentre(2scale * delim_height#)); "slash";
      x1 - x0 = sign * (w - 2side_bearing - line_thickness);
      y1 =  h;
      y0 = -d;
      1/2[x0,x1] = w/2;

      draw_line(z0, z1, false);
    endchar;
  endfor;
  charlist current_char - 5: current_char - 4: current_char - 3: current_char - 2: current_char - 1: current_char;
endfor;

% vertical bars

for negated = false, true:
  for scale = 0.5, 1, 1.2:
    beginsymbol(2u# + if negated: 2u# + floor scale * u# else: 0u# fi + line_thickness# + 2side_bearing#, vcentre(2scale * delim_height#)); "vertical bar";
      x0 = x1 = w/2;
      y0 = h;
      y1 = -d;

      draw_line(z0, z1, false);

      if negated:
        if scale < 1: theta := 30; else: theta := 45; fi
        len := 1/2(4u + floor scale * u) / cosd theta;

        draw_straight(1/2[z0,z1] + len * dir theta, 1/2[z0,z1] - len * dir theta, stroke_through_thickness, true);
      fi
    endchar;
  endfor;
endfor;

beginsymbol(2u# + line_thickness# + 2side_bearing#, vcentre(0.6delim_height#)); "vertical bar -- module";
  x0 = x1 = w/2;
  y0 = h + 1/2line_thickness;
  y1 = -d - 1/2line_thickness;

  draw_line(z0, z1, false);
endchar;

extensible current_char: 0, 0, 0, current_char; % vertical bar
charlist current_char - 5: current_char - 4: current_char;

for negated = false, true:
  for scale = 0.5, 1, 1.2:
    beginsymbol(5u# + if negated: 2u# + floor scale * u# else: 0u# fi + 2line_thickness# + 2side_bearing#, vcentre(2scale * delim_height#)); "double vertical bar";
      x0 = x1;
      x2 = x3;
      1/2[x0,x2] = w/2;
      x2 - x0 = 3u + line_thickness;
      y0 = y2 = h;
      y1 = y3 = -d;

      draw_line(z0, z1, false);
      draw_line(z2, z3, false);

      if negated:
        if scale < 1: theta := 30; else: theta := 45; fi
        len := 1/2(7u + floor scale * u + line_thickness) / cosd theta;
        pair centre;
        centre := 1/2[1/2[z0,z1],1/2[z2,z3]];

        draw_straight(centre + len * dir theta, centre - len * dir theta, stroke_through_thickness, true);
      fi
    endchar;
  endfor;
endfor;

beginsymbol(5u# + 2line_thickness# + 2side_bearing#, vcentre(0.6delim_height#)); "double vertical bar -- module";
  x0 = x1;
  x2 = x3;
  1/2[x0,x2] = w/2;
  x2 - x0 = 3u + line_thickness;
  y0 = y2 = h + 1/2line_thickness;
  y1 = y3 = -d - 1/2line_thickness;

  draw_line(z0, z1, false);
  draw_line(z2, z3, false);
endchar;

extensible current_char: 0, 0, 0, current_char; % double vertical line
charlist current_char - 5: current_char -4: current_char;

for scale = 1, 1.2:
  beginsymbol(8u# + 3line_thickness# + 2side_bearing#, vcentre(2scale * delim_height#)); "triple vertical bar";
    x0 = x1;
    x2 = x3;
    x4 = x5;
    1/2[x0,x4] = w/2;
    x2 - x0 = x4 - x2 = 3u + line_thickness;
    y0 = y2 = y4 = h;
    y1 = y3 = y5 = -d;

    draw_line(z0, z1, false);
    draw_line(z2, z3, false);
    draw_line(z4, z5, false);
  endchar;
endfor;

beginsymbol(8u# + 3line_thickness# + 2side_bearing#, vcentre(0.6delim_height#)); "triple vertical bar -- module";
  x0 = x1;
  x2 = x3;
  x4 = x5;
  1/2[x0,x4] = w/2;
  x2 - x0 = x4 - x2 = 3u + line_thickness;
  y0 = y2 = y4 = h + 1/2line_thickness;
  y1 = y3 = y5 = -d - 1/2line_thickness;

  draw_line(z0, z1, false);
  draw_line(z2, z3, false);
  draw_line(z4, z5, false);
endchar;

extensible current_char: 0, 0, 0, current_char; % triple vertical line
charlist current_char - 2: current_char -1: current_char;

% Arrows

for arrow_dir = 90, 270:
  beginsymbol(5u# + line_thickness# + 2side_bearing#, vcentre(1.2delim_height#)); "arrow up/down";
    pair foot, head;

    if arrow_dir = 90:
      head = (w/2, h - 1/2line_thickness);
      foot = (w/2, -d);
    else:
      head = (w/2, -d + 1/2line_thickness);
      foot = (w/2, h + 1/2line_thickness);
    fi;

    draw_line(foot, head, false);
    draw_arrowhead(head, arrow_dir, arrow_spread, line_thickness);
  endchar;
endfor;

beginsymbol(5u# + line_thickness# + 2side_bearing#, vcentre(0.6delim_height#)); "arrow module";
  z0 = (w/2, h);
  z1 = (w/2, -d);

  draw_line(z0, z1, true);
endchar;

extensible current_char-2: current_char-2, 0, current_char, current_char;
extensible current_char-1: current_char, 0, current_char-1, current_char;
extensible current_char: current_char-2, 0, current_char-1, current_char;

for arrow_dir = 90, 270:
  beginsymbol(7u# + line_thickness# + 2side_bearing#, vcentre(1.2delim_height#)); "double arrow up/down";
    pair foot, head;

    if arrow_dir = 90:
      head = (w/2, h - 1/2line_thickness);
      foot = (w/2, -d - 1/2line_thickness);
    else:
      head = (w/2, -d + 1/2line_thickness);
      foot = (w/2, h + 1/2line_thickness);
    fi;

    z1 - z0 = z3 - z2 = equal_spread * dir (arrow_dir + 90);
    1/2[z0,z1] = foot;
    1/2[z2,z3] = head;

    draw_line(z0, arrowhead_intersection(head, arrow_dir, 13/10arrow_spread, z0 -- z2), false);
    draw_line(z1, arrowhead_intersection(head, arrow_dir, 13/10arrow_spread, z1 -- z3), false);
    draw_arrowhead(head, arrow_dir, 13/10arrow_spread, line_thickness);
  endchar;
endfor;

beginsymbol(7u# + line_thickness# + 2side_bearing#, vcentre(0.6delim_height#)); "double arrow module";
  z1 - z0 = z3 - z2 = equal_spread * right;
  1/2[z0,z1] = (w/2,  h);
  1/2[z2,z3] = (w/2, -d);

  draw_line(z0, z2, true);
  draw_line(z1, z3, true);
endchar;

extensible current_char-2: current_char-2, 0, current_char, current_char;
extensible current_char-1: current_char, 0, current_char-1, current_char;
extensible current_char: current_char-2, 0, current_char-1, current_char;

% horizontal curly braces

beginsymbol(1/2delim_height#, vcentre((6 + 5.5)/2 * u# + line_thickness#)); "horizontal curly brace -- left";
  draw_brace((3delim_height, (h-d)/2), 6delim_height, h + d,  90, line_thickness, w, 0, 0);
endchar;

beginsymbol(1/2delim_height#, vcentre((6 + 5.5)/2 * u# + line_thickness#)); "horizontal curly brace -- left";
  draw_brace((3delim_height, (h-d)/2), 6delim_height, h + d, -90, line_thickness, 0, 0, w);
endchar;

beginsymbol(1/2delim_height#, vcentre((6 + 5.5)/2 * u# + line_thickness#)); "horizontal curly brace -- right";
  draw_brace((w - 3delim_height, (h-d)/2), 6delim_height, h + d,  90, line_thickness, 0, 0, w);
endchar;

beginsymbol(1/2delim_height#, vcentre((6 + 5.5)/2 * u# + line_thickness#)); "horizontal curly brace -- right";
  draw_brace((w - 3delim_height, (h-d)/2), 6delim_height, h + d, -90, line_thickness, w, 0, 0);
endchar;

for sign = 1, -1:
  beginsymbol(delim_height#, vcentre((6 + 5.5)/2 * u# + line_thickness#)); "horizontal curly brace -- middle";
    draw_brace((w/2, (h-d)/2), 6delim_height, h + d, sign * 90, line_thickness, 0, w, 0);
  endchar;
endfor;

beginsymbol(u#, vcentre((6 + 5.5)/2 * u# + line_thickness#)); "horizontal curly brace -- module";
  y2 = y3 = (h - d)/2;
  x2 = -1/2line_thickness;
  x3 = w + 1/2line_thickness;

  draw_line(z2, z3, false);
endchar;

% roots

root_char = current_char + 1;

for scale = 1, 1.2, 1.5, 1.8, 2.4, 3:
  beginsymbol((4scale + 2) * u# + 5/2line_thickness# + 2side_bearing#, rule_thickness#, 2scale * delim_height# - rule_thickness#); "root";
    draw_root(line_thickness);
  endchar;
endfor;

beginsymbol(14u# + 5/2line_thickness# + 2side_bearing#, rule_thickness#, 1.2delim_height# - rule_thickness#); "root -- top";
  draw_root_top(line_thickness);
endchar;

beginsymbol(14u# + 5/2line_thickness# + 2side_bearing#, 0, 2.4delim_height#); "root -- bottom";
  draw_root_bot(line_thickness);
endchar;

beginsymbol(14u# + 5/2line_thickness# + 2side_bearing#, vcentre(0.6delim_height#)); "root -- module";
  x0 = x1 = 4/9w + 1/2line_thickness;
  y0 = h;
  y1 = -d;

  draw_line(z0, z1, true);
endchar;

extensible current_char - 2: current_char - 2, 0, current_char - 1, current_char;
charlist root_char: root_char + 1: root_char + 2: root_char + 3: root_char + 4: root_char + 5: current_char - 2;

% more roots

for scale = 1, 1.2, 1.5, 1.8, 2.4, 3:
  beginsymbol((4scale + 2) * u# + 5/2line_thickness# + 2side_bearing#, vcentre(2scale * delim_height#)); "root";
    draw_root(line_thickness);
  endchar;
endfor;

beginsymbol(14u# + 5/2line_thickness# + 2side_bearing#, 1.2delim_height#, 0); "root -- top";
  draw_root_top(line_thickness);
endchar;

beginsymbol(14u# + 5/2line_thickness# + 2side_bearing#, 2.4delim_height#, 0); "root -- bottom";
  draw_root_bot(line_thickness);
endchar;