%
% Copyright (c) 2011, 2012, Sebastian Schubert <schubert.seb@googlemail.com>
%
% 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
%

def sthick(expr scale) =
%option 1: make symbols thicker with scale 
  sqrt scale
%option 2: keep same thickness
%  1
enddef;

def bop_line_thickness(expr scale) = 
  bop_thickness_fac * letter_line_thickness * sqrt sthick(scale)
enddef;
def bop_part_line_thickness(expr scale) = 
  bop_thickness_fac * line_thickness * sqrt sthick(scale)
enddef;
def bop_dot_size(expr scale) =
  bop_thickness_fac * 3/4dot_size * sqrt sthick(scale)
enddef;

for scale = 1, 1.4:
  beginsquarebigop(scale, scale); "big plus";
    draw_line_linethick(centre + op_height/2 * right, centre + op_height/2 * left, bop_line_thickness(scale), false);
    draw_line_linethick(centre + op_height/2 * up, centre + op_height/2 * down, bop_line_thickness(scale), false);
  endchar;
endfor;
charlist current_char - 1: current_char;

for scale = 1, 1.4:
  beginsquarebigop(scale, scale); "big times";
    z1 - z0 = z3 - z2 = (op_width - bop_line_thickness(scale) / sqrt(2)) * right;
    z2 - z0 = (op_width - bop_line_thickness(scale) / sqrt(2)) * up;
    1/2[1/2[z0,z1], 1/2[z2,z3]] = centre;

    draw_line_linethick(z0, z3, bop_line_thickness(scale), false);
    draw_line_linethick(z1, z2, bop_line_thickness(scale), false);
  endchar;
endfor;
charlist current_char - 1: current_char;

for sign = 1, -1:
  for scale = 1, 1.4:
    beginbigop(scale, scale); "big wedge";
      draw_less(a, centre + sign * op_height/2 * up, centre - sign * op_height/2 * up, op_width - bop_line_thickness(scale), bop_line_thickness(scale), false, true);
    endchar;
  endfor;
  charlist current_char - 1: current_char;
endfor;

for sign = 1, -1:
  for scale = 1, 1.4:
    beginbigop(scale, scale); "big wedge dot";
      draw_less(a, centre + sign * op_height/2 * up, centre - sign * op_height/2 * up, op_width - bop_line_thickness(scale), bop_line_thickness(scale), false, true);
      fill dot(centre - sign * 1/4op_height * up, bop_dot_size(scale));
    endchar;
  endfor;
  charlist current_char - 1: current_char;
endfor;

for sign = 1, -1:
  for scale = 1, 1.4:
    beginbigop(4/3scale, scale); "double big wedge";
      z0 = centre - 1/8op_width * right;
      z1 = centre + 1/8op_width * right;

      draw_less(a, z0 + sign * op_height/2 * up, z0 - sign * op_height/2 * up, 3/4op_width - bop_line_thickness(scale), bop_line_thickness(scale), false, true);
      draw_less(b, z1 + sign * op_height/2 * up, z1 - sign * op_height/2 * up, 3/4op_width - bop_line_thickness(scale), bop_line_thickness(scale), false, true);
    endchar;
  endfor;
  charlist current_char - 1: current_char;
endfor;

for sign = 1, -1:
  for scale = 1, 1.4:
    beginbigop(scale, scale); "big curly wedge";
      draw_prec(a, centre + sign * op_height/2 * up, centre - sign * op_height/2 * up, op_width - bop_line_thickness(scale), bop_line_thickness(scale), false);
    endchar;
  endfor;
  charlist current_char - 1: current_char;
endfor;

for sign = 1, -1:
  for scale = 1, 1.4:
    beginbigop(scale, scale); "big union";
      draw_subset(a, centre + sign * op_height/2 * up, centre - sign * op_height/2 * up, op_width - bop_line_thickness(scale), bop_line_thickness(scale));
    endchar;
  endfor;
  charlist current_char - 1: current_char;
endfor;

for sign = 1, -1:
  for scale = 1, 1.4:
    beginbigop(scale, scale); "big union dot";
      draw_subset(a, centre + sign * op_height/2 * up, centre - sign * op_height/2 * up, op_width - bop_line_thickness(scale), bop_line_thickness(scale));
      fill dot(centre - sign * 1/8op_height * up, bop_dot_size(scale));
    endchar;
  endfor;
  charlist current_char - 1: current_char;
endfor;

for sign = 1, -1:
  for scale = 1, 1.4:
    beginbigop(scale, scale); "big union plus";
      draw_subset(a, centre + sign * op_height/2 * up, centre - sign * op_height/2 * up, op_width - bop_line_thickness(scale), bop_line_thickness(scale));

      r := 1/4op_width;

      draw_line_linethick(centre - sign * 1/8op_width * up + r * right, centre - sign * 1/8op_width * up + r * left, bop_line_thickness(scale), false);
      draw_line_linethick(centre + (r - sign * 1/8op_width) * up, centre + (r + sign * 1/8op_width) * down, bop_line_thickness(scale), false);
    endchar;
  endfor;
  charlist current_char - 1: current_char;
endfor;

for sign = 1, -1:
  for scale = 1, 1.4:
    beginbigop(scale, scale); "big square union";
      z3 - z0 = z2 - z1 = (op_width - bop_line_thickness(scale)) * right;
      z1 - z0 = sign * (op_height - bop_line_thickness(scale)) * up;
      1/2[1/2[z0,z1], 1/2[z2,z3]] = centre;

      draw_line_linethick(z0, z1, bop_line_thickness(scale), true);
      draw_line_linethick(z1, z2, bop_line_thickness(scale), true);
      draw_line_linethick(z2, z3, bop_line_thickness(scale), true);
    endchar;
  endfor;
  charlist current_char - 1: current_char;
endfor;

for sign = 1, -1:
  for scale = 1, 1.4:
    beginbigop(scale, scale); "big square union dot";
      z3 - z0 = z2 - z1 = (op_width - bop_line_thickness(scale)) * right;
      z1 - z0 = sign * (op_height - bop_line_thickness(scale)) * up;
      1/2[1/2[z0,z1], 1/2[z2,z3]] = centre;

      draw_line_linethick(z0, z1, bop_line_thickness(scale), true);
      draw_line_linethick(z1, z2, bop_line_thickness(scale), true);
      draw_line_linethick(z2, z3, bop_line_thickness(scale), true);
      fill dot(centre - sign * 1/8op_height * up, bop_dot_size(scale));
    endchar;
  endfor;
  charlist current_char - 1: current_char;
endfor;

for sign = 1, -1:
  for scale = 1, 1.4:
    beginbigop(scale, scale); "big square union plus";
      z3 - z0 = z2 - z1 = (op_width - bop_line_thickness(scale)) * right;
      z1 - z0 = sign * (op_height - bop_line_thickness(scale)) * up;
      1/2[1/2[z0,z1], 1/2[z2,z3]] = centre;

      draw_line_linethick(z0, z1, bop_line_thickness(scale), true);
      draw_line_linethick(z1, z2, bop_line_thickness(scale), true);
      draw_line_linethick(z2, z3, bop_line_thickness(scale), true);

      r := 1/4op_width;

      draw_line_linethick(centre - sign * 1/8op_width * up + r * right, centre - sign * 1/8op_width * up + r * left, bop_line_thickness(scale), false);
      draw_line_linethick(centre + (r - sign * 1/8op_width) * up, centre + (r + sign * 1/8op_width) * down, bop_line_thickness(scale), false);
    endchar;
  endfor;
  charlist current_char - 1: current_char;
endfor;

for alpha = 0, 45:
  for scale = 1, 1.4:
    beginsquarebigop(scale, scale); "big circle plus";
      r := (op_height - bop_line_thickness(scale))/2;

      draw_circle(centre, r, bop_line_thickness(scale));
      draw_line_linethick(centre - r * dir alpha, centre + r * dir alpha, bop_line_thickness(scale), false);
      draw_line_linethick(centre - r * dir (alpha + 90), centre + r * dir (alpha + 90), bop_line_thickness(scale), false);
    endchar;
  endfor;
  charlist current_char - 1: current_char;
endfor;

for scale = 1, 1.4:
  beginsquarebigop(scale, scale); "big circle dot";
    draw_circle(centre, (op_height - bop_line_thickness(scale))/2, bop_line_thickness(scale));
    fill dot(centre, bop_dot_size(scale));
  endchar;
endfor;
charlist current_char - 1: current_char;

for scale = 1, 1.4:
  beginsquarebigop(scale, scale); "big circle asterisk";
    thick := bop_line_thickness(scale);
    r := (op_height - bop_line_thickness(scale))/2;

    draw_circle(centre, r, bop_line_thickness(scale));

    penpos a0(4/3thick, 0);
    penpos a1(4/3thick, 60);
    penpos a2(4/3thick, 120);
    penpos a3(4/3thick, 180);
    penpos a4(4/3thick, 240);
    penpos a5(4/3thick, 300);

    penpos b0(thick, 0);
    penpos b1(thick, 60);
    penpos b2(thick, 120);
    penpos b3(thick, 180);
    penpos b4(thick, 240);
    penpos b5(thick, 300);

    reg_poly_points(a)(6, centre, r, 90);

    z.b0 = z.b1 = z.b2 = z.b3 = z.b4 = z.b5 = centre;

    fill stroke z.a0e -- z.b0e;
    fill stroke z.a1e -- z.b1e;
    fill stroke z.a2e -- z.b2e;
    fill stroke z.a3e -- z.b3e;
    fill stroke z.a4e -- z.b4e;
    fill stroke z.a5e -- z.b5e;
  endchar;
endfor;
charlist current_char - 1: current_char;

for sign = 1, -1:
  for scale = 1, 1.4:
    beginbigop(1.3scale, scale); "product";
      draw_product(centre, op_width, op_height, sign, bop_line_thickness(scale));
    endchar;
  endfor;
  charlist current_char - 1: current_char;
endfor;

for scale = 1, 1.4:
  beginbigop(scale, scale); "sum";
    draw_sum(a)(centre, op_width, op_height, bop_line_thickness(scale));
  endchar;
endfor;
charlist current_char - 1: current_char;

for scale = 1, 1.4:
  beginbigop(scale, scale); "sum modulo two";
    draw_sum(a)(centre, op_width, op_height, bop_line_thickness(scale));
    draw_circle(z4a, sqrt scale * 1/4op_width, bop_part_line_thickness(scale));
  endchar;
endfor;
charlist current_char - 1: current_char;

for number = 0, 1, 2, 3:
  for scale = 1, 1.8:
    beginsymbol(scale * (5number + 4) * u# + (sthick(scale)) * 3/4bop_thickness_fac*letter_line_thickness# + 2side_bearing#, vcentre(scale * 1.6asc_height#)); "integral";
      italcorr scale * 3u# - (sthick(scale)) * 3/4bop_thickness_fac*letter_line_thickness#; % kerning between upper limit and lower limit

      pair centre;

      for i = 0 upto number:
        centre := (side_bearing + scale * (5i + 7/2) * u, (h - d)/2);
        draw_integral([i])(scale, centre, bop_line_thickness(scale));
      endfor;
    endchar;
  endfor;
  charlist current_char - 1: current_char;
endfor;

for scale = 1, 1.8:
  beginsymbol(scale * 9u# + 4(equal_spread# + sqrt sthick(scale) * bop_thickness_fac*dot_size#) + (sthick(scale)) * 3/4bop_thickness_fac*letter_line_thickness# + 2side_bearing#, vcentre(scale * 1.6asc_height#)); "integral dots";
    italcorr scale * 3u# - (sthick(scale)) * 3/4bop_thickness_fac*letter_line_thickness#; % kerning between upper limit and lower limit

    pair centre;
    centre := (side_bearing + scale * 7/2u, (h - d)/2);

    draw_integral([0])(scale, centre, bop_line_thickness(scale));

    centre := (side_bearing + scale * 6u + 4(equal_spread + bop_dot_size(scale)), (h - d)/2);

    draw_integral([1])(scale, centre, bop_line_thickness(scale));

    z0 = 1/4[z0[0],z0[1]];
    z1 = 2/4[z0[0],z0[1]];
    z2 = 3/4[z0[0],z0[1]];

    fill dot(z0, bop_dot_size(scale));
    fill dot(z1, bop_dot_size(scale));
    fill dot(z2, bop_dot_size(scale));
  endchar;
endfor;
charlist current_char - 1: current_char;

for sign = 1, -1:
  for scale = 1, 1.8:
    beginsymbol(scale * 6u# + if scale > 1: (sthick(scale)) * 3/4bop_thickness_fac*letter_line_thickness# else: scale * 3u# fi + 2side_bearing#, vcentre(scale * 1.6asc_height#)); "oriented integral";
      if scale > 1:
        italcorr scale * 3u# - (sthick(scale)) * 3/4bop_thickness_fac*letter_line_thickness#; % kerning between upper limit and lower limit
      fi

      pair centre;
      centre := (side_bearing + scale * 9/2u, (h - d)/2);

      draw_integral(a)(scale, centre, bop_line_thickness(scale));

      thick := bop_part_line_thickness(scale);
      r := 4u;

      penpos0(thick, 135);
      penpos1(thick, 90);
      penpos2(thick, 45);

      z0 = z0a + sign * scale * (-r, -1/4r);
      z1 = z0a + sign * scale * (0, 1/4r);
      z2 = z0a + sign * scale * (r, -1/4r);

      if sign > 0:
        fill stroke z0.e{dir 45} .. {dir 0}z1.e .. {dir -45}z2.e;
        draw_arrowhead(z2, -40, 2/3scale * arrow_spread, 5/6thick);
      else:
        fill stroke z0.e{dir -135} .. {dir 180}z1.e .. {dir 135}z2.e;
        draw_arrowhead(z0, 40, 2/3scale * arrow_spread, 5/6thick);
      fi

      penlabels(0,1,2);
    endchar;
  endfor;
  charlist current_char - 1: current_char;
endfor;

for scale = 1, 1.8:
  beginsymbol(scale * 4u# + if scale > 1: (sthick(scale)) * 3/4bop_thickness_fac*letter_line_thickness# else: scale * 3u# fi + 2side_bearing#, vcentre(scale * 1.6asc_height#)); "integral with horizontal bar";
    if scale > 1:
      italcorr scale * 3u# - (sthick(scale)) * 3/4bop_thickness_fac*letter_line_thickness#; % kerning between upper limit and lower limit
    fi

    pair centre;
    centre := (side_bearing + scale * 7/2u, (h - d)/2);

    draw_integral(a)(scale, centre, bop_line_thickness(scale));

    r := scale * 5/2u;
    thick := bop_part_line_thickness(scale);

    draw_straight(z0a + r * left, z0a + r * right, thick, true);
  endchar;
endfor;
charlist current_char - 1: current_char;

for scale = 1, 1.8:
  beginsymbol(scale * 4u# + if scale > 1: (sthick(scale)) * 3/4bop_thickness_fac*letter_line_thickness# else: scale * 3u# fi + 2side_bearing#, vcentre(scale * 1.6asc_height#)); "integral with double horizontal bar";
    if scale > 1:
      italcorr scale * 3u# - (sthick(scale)) * 3/4bop_thickness_fac*letter_line_thickness#; % kerning between upper limit and lower limit
    fi

    pair centre;
    centre := (side_bearing + scale * 7/2u, (h - d)/2);

    draw_integral(a)(scale, centre, bop_line_thickness(scale));

    z1 - z0 = equal_spread * up;
    1/2[z0, z1] = z0a;

    r := scale * 5/2u;
    thick := bop_part_line_thickness(scale);

    draw_straight(z0 + r * left, z0 + r * right, thick, true);
    draw_straight(z1 + r * left, z1 + r * right, thick, true);
  endchar;
endfor;
charlist current_char - 1: current_char;

for scale = 1, 1.8:
  beginsymbol(scale * 4u# + (sthick(scale)) * 3/4bop_thickness_fac*letter_line_thickness# + 2side_bearing#, vcentre(scale * 1.6asc_height#)); "stroked integral";
    italcorr scale * 3u# - (sthick(scale)) * 3/4bop_thickness_fac*letter_line_thickness#; % kerning between upper limit and lower limit

    pair centre;
    centre := (side_bearing + scale * 7/2u, (h - d)/2);

    draw_integral(a)(scale, centre, bop_line_thickness(scale));

    r := scale * 7/2u;
    thick := bop_part_line_thickness(scale);

    draw_straight(z0a - r * dir 35, z0a + r * dir 35, thick, true);
  endchar;
endfor;
charlist current_char - 1: current_char;

for number = 0, 1, 2:
  for scale = 1, 1.8:
    beginsymbol(scale * (5number + 5) * u# + if scale > 1: (sthick(scale)) * 3/4bop_thickness_fac*letter_line_thickness# else: scale * 3u# fi + 2side_bearing#, vcentre(scale * 1.6asc_height#)); "contour integral";
      if scale > 1:
        italcorr scale * 3u# - (sthick(scale)) * 3/4bop_thickness_fac*letter_line_thickness#; % kerning between upper limit and lower limit
      fi

      pair centre;

      centre := (side_bearing + scale * (5number/2 + 4) * u, (h - d)/2);
      thick := bop_part_line_thickness(scale);
      r := scale * 4u;
      s := scale * (5number + 8)/2 * u;

      if number = 0:
        fill circle(centre, r);
        unfill circle(centre, r - thick);
      else:
        fill superellipse(centre + s * dir 0, centre + r * dir 90, centre - s * dir 0, centre - r * dir 90, 3/4);
        unfill superellipse(centre + (s - thick) * dir 0, centre + (r - thick) * dir 90, centre - (s - thick) * dir 0, centre - (r - thick) * dir 90, 3/4);
      fi

      % Integral must come after unfill when processed with MetaPost!
      for i = 0 upto number:
        centre := (side_bearing + scale * (5i + 4) * u, (h - d)/2);
        draw_integral([i])(scale, centre, bop_line_thickness(scale));
      endfor;
    endchar;
  endfor;
  charlist current_char - 1: current_char;
endfor;

for alpha = 0, 180:
  for sign = 1, -1:
    for scale = 1, 1.8:
      beginsymbol(scale * 6u# + if scale > 1: (sthick(scale)) * 3/4bop_thickness_fac*letter_line_thickness# else: scale * 3u# fi + 2side_bearing#, vcentre(scale * 1.6asc_height#)); "oriented contour integral";
        if scale > 1:
          italcorr scale * 3u# - (sthick(scale)) * 3/4bop_thickness_fac*letter_line_thickness#; % kerning between upper limit and lower limit
        fi

        pair centre;
        centre := (side_bearing + scale * (4u + if alpha > 90: u else: 0 fi), (h - d)/2);

        draw_integral(a)(scale, centre, bop_line_thickness(scale));

        thick := bop_part_line_thickness(scale);
        r := scale * 4u;

        reg_poly_points(a)(8, z0a, r, alpha + 25);
        reg_poly_points(b)(8, z0a, r - thick, alpha + 25);
        z.a8 = z0a + r * dir alpha;
        z.b8 = z0a + (r - thick) * dir alpha;

        if sign > 0:
          fill z.a0 .. z.a1 .. z.a2 .. z.a3 .. z.a4 .. z.a5 .. z.a6 .. z.a7 .. z.a8 -- z.b8 .. z.b7 .. z.b6 .. z.b5 .. z.b4 .. z.b3 .. z.b2 .. z.b1 .. z.b0 -- cycle;
          draw_arrowhead(1/2[z.a8, z.b8], alpha + 75, 2/3scale * arrow_spread, 5/6thick);
        else:
          fill z.a8 .. z.a0 .. z.a1 .. z.a2 .. z.a3 .. z.a4 .. z.a5 .. z.a6 .. z.a7 -- z.b7 .. z.b6 .. z.b5 .. z.b4 .. z.b3 .. z.b2 .. z.b1 .. z.b0 .. z.b8 -- cycle;
          draw_arrowhead(1/2[z.a8, z.b8], alpha - 75, 2/3scale * arrow_spread, 5/6thick);
        fi
      endchar;
    endfor;
    charlist current_char - 1: current_char;
  endfor;
endfor;

for scale = 1, 1.8:
  beginsymbol(scale * 13/2u# + if scale > 1: 0 else: scale * u# fi + 2side_bearing#, vcentre(scale * 1.6asc_height#)); "sum integral";
    if scale > 1:
      italcorr scale * u#; % kerning between upper limit and lower limit
    fi

    pair centre;
    centre := (side_bearing + scale * 4u, (h - d)/2);

    draw_integral(a)(scale, centre, bop_line_thickness(scale));
    draw_sum(b, 1/4[z0a.l,z0a.r], scale * 7u, scale * 3/4asc_height, bop_line_thickness(scale));

  endchar;
endfor;
charlist current_char - 1: current_char;

for sign = 1, -1:
  for scale = 1, 1.4:
    beginbigop(1.3scale, scale); "product integral";
      draw_productintegral(centre, op_width, op_height, sign, bop_line_thickness(scale));
    endchar;
  endfor;
  charlist current_char - 1: current_char;
endfor;


