/*  
 *  This file is part of abc2ps, 
 *  Copyright (C) 1996,1997,1998  Michael Methfessel
 *  See file abc2ps.c for details.
 */
 
/*  subroutines to define postscript macros which draw symbols  */

/* ----- xxxdef_misc ------- */
void xxxdef_misc (fp)
FILE *fp;
{
  fprintf (fp,
           "\n/box {  %% usage: str box  - draw box around string\n"
           "  gsave 0.5 setlinewidth dup stringwidth pop\n"
           "  -2 -2 rmoveto 4 add fh 4 add 2 copy\n"
           "  0 exch rlineto 0 rlineto neg 0 exch rlineto neg 0 rlineto\n"
           "  stroke grestore\n"
           "} bind def\n");

}

void cgcshow( CGContextRef cx, float x, float y, const char *s )
{
  int length = strlen( s );
  CGContextSelectFont( cx, "Helvetica", 14, kCGEncodingMacRoman );
  CGContextSetTextDrawingMode( cx, kCGTextInvisible );
  CGContextShowTextAtPoint( cx, x, y, s, length );
  CGPoint p = CGContextGetTextPosition( cx );
  CGContextSetTextDrawingMode( cx, kCGTextFill );
  CGContextSetRGBFillColor( cx, 0.0, 0.0, 0.0, 1.0 );
  CGAffineTransform xform = CGAffineTransformMake( 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 );
  CGContextSetTextMatrix( cx, xform );
  CGContextShowTextAtPoint( cx, x-(p.x-x)/2, y, s, length );
}

void cglshow( CGContextRef cx, float x, float y, const char *s )
{
  CGContextSelectFont( cx, "Helvetica", 14, kCGEncodingMacRoman );
  CGContextSetTextDrawingMode( cx, kCGTextFill );
  CGContextSetRGBFillColor( cx, 0.0, 0.0, 0.0, 1.0 );
  CGAffineTransform xform = CGAffineTransformMake( 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 );
  CGContextSetTextMatrix( cx, xform );
  CGContextShowTextAtPoint( cx, x, y, s, strlen(s) );
}

void cgrshow( CGContextRef cx, float x, float y, const char *s )
{
  int length = strlen( s );
  CGContextSelectFont( cx, "Helvetica", 14, kCGEncodingMacRoman );
  CGContextSetTextDrawingMode( cx, kCGTextInvisible );
  CGContextShowTextAtPoint( cx, x, y, s, length );
  CGPoint p = CGContextGetTextPosition( cx );
  CGContextSetTextDrawingMode( cx, kCGTextFill );
  CGContextSetRGBFillColor( cx, 0.0, 0.0, 0.0, 1.0 );
  CGAffineTransform xform = CGAffineTransformMake( 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 );
  CGContextSetTextMatrix( cx, xform );
  CGContextShowTextAtPoint( cx, x-(p.x-x), y, s, length );
}

void cgwd( CGContextRef cx, const char *s, float x, float y )
{
  cglshow( cx, x, y, s );
}

void cgwhf( CGContextRef cx, float x, float y )
{
  CGContextSaveGState( cx );
  CGContextScaleCTM( cx, 0.5f, 1.2f );
  cglshow( cx, x, y, "-" );
  CGContextRestoreGState( cx );
}

void cgwln( CGContextRef cx, float x1, float x2, float y )
{
  CGContextSaveGState( cx );
  CGContextSetLineWidth( cx, 0.6f );
  CGContextMoveToPoint( cx, x1, y );
  CGContextAddLineToPoint( cx, x2, y );
  CGContextStrokePath( cx );
  CGContextRestoreGState( cx );
}

/* ----- xxxdef_typset ------- */
void xxxdef_typeset(fp)
FILE *fp;
{

  fprintf (fp,
           "\n/WS {   %%usage:  w nspaces str WS\n"
           "   dup stringwidth pop 4 -1 roll\n"
           "   sub neg 3 -1 roll div 0 8#040 4 -1 roll\n"
           "   widthshow\n"
           "} bind def\n");


  fprintf (fp, 
           "\n/W1 { show pop pop } bind def\n");


  fprintf (fp, 
           "\n/str 50 string def\n"
           "/W0 {\n"
           "   dup stringwidth pop str cvs exch show (  ) show show pop pop\n"
           "} bind def\n");

  fprintf (fp,
           "\n/WC { counttomark 1 sub dup 0 eq { 0 }\n"
           "  {  ( ) stringwidth pop neg 0 3 -1 roll\n"
           "  {  dup 3 add index stringwidth pop ( ) stringwidth pop add\n"
           "  dup 3 index add 4 index lt 2 index 1 lt or\n"
           "  {3 -1 roll add exch 1 add} {pop exit} ifelse\n"
           "  } repeat } ifelse\n"
           "} bind def\n");

  fprintf (fp,
           "\n/P1 {\n"
           "  {  WC dup 0 le {exit} if\n"
           "      exch pop gsave { exch show ( ) show } repeat grestore LF\n"
           "   } loop pop pop pop pop\n"
           "} bind def\n");

  fprintf (fp,
           "\n/P2 {\n"
           "   {  WC dup 0 le {exit} if\n"
           "      dup 1 sub dup 0 eq\n"
           "      { pop exch pop 0.0 }\n"
           "      { 3 2 roll 3 index exch sub exch div } ifelse\n"
           "      counttomark 3 sub 2 index eq { pop 0 } if exch gsave\n"
           "      {  3 2 roll show ( ) show dup 0 rmoveto } repeat\n"
           "      grestore LF pop\n"
           "   } loop pop pop pop pop\n"
           "} bind def\n");

}

void cgtsig( CGContextRef cx, float x, const char *top, int bottom )
{
  char buf[32];  
  CGContextSelectFont( cx, "Helvetica", 14, kCGEncodingMacRoman );
  CGContextSetTextDrawingMode( cx, kCGTextFill );
  CGContextSetRGBFillColor( cx, 0.0, 0.0, 0.0, 1.0 );
  CGAffineTransform xform = CGAffineTransformMake( 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 );
  CGContextSetTextMatrix( cx, xform );
  CGContextShowTextAtPoint( cx, x, 14, top, strlen(top) );
  sprintf( buf, "%d", bottom );
  CGContextShowTextAtPoint( cx, x, 2, buf, strlen( buf ) );
}

void cgadd_cv( CGContextRef fp, float x, float y, float f1, float f2, float p[][2], int i0, int ncv )
{
  int i1,m;
  
  i1=i0;
  for (m=0; m<ncv; m++) {
    CGContextAddCurveToPoint(fp, 
       x+f1*(p[i1+0][0]), 
       y+f2*(p[i1+0][1]),
       x+f1*(p[i1+1][0]), 
       y+f2*(p[i1+1][1]),
       x+f1*(p[i1+2][0]), 
       y+f2*(p[i1+2][1])
    );
    i1=i1+3;
  }
}

void cgadd_sg (CGContextRef fp, float x, float y, float f1, float f2, float p[][2], int i0, int nseg)
{
  int i;
  for (i=0; i<nseg; i++)
    CGContextAddLineToPoint(fp,
             x+f1*(p[i0+i][0]),
             y+f2*(p[i0+i][1])
    );
}

void cgadd_mv(CGContextRef fp, float x, float y, float f1, float f2, float p[][2], int i0)
{
//  if (i0==0) 
    CGContextMoveToPoint( fp, x+f1*p[i0][0], y+f2*p[i0][1] );
//  else
//    CGContextMoveToPoint( fp, y+f1*(p[i0][0]-p[i0-1][0]), y+f2*(p[i0][1]-p[i0-1][1]) );
}

void cgsu( CGContextRef fp, float x, float y, float u )
{
  CGContextMoveToPoint( fp, x+STEM_XOFF, y+STEM_YOFF );
  CGContextAddLineToPoint( fp, x+STEM_XOFF, y+u );
  CGContextStrokePath( fp );
}

void cgsd( CGContextRef fp, float x, float y, float u )
{
  CGContextMoveToPoint( fp, x-STEM_XOFF, y-STEM_YOFF );
  CGContextAddLineToPoint( fp, x-STEM_XOFF, y-u );
  CGContextStrokePath( fp );
}

void cgdot( CGContextRef fp, float x, float y, float dx, float dy )
{
  CGContextMoveToPoint( fp, x+dx, y+dy );
  CGContextAddArc( fp, x+dx, y+dy, 1.2f, 0, 2*M_PI, 1 );
  CGContextFillPath( fp );
}

void cghat( CGContextRef fp, float x, float y )
{
  CGContextMoveToPoint( fp, x-4, y-2 );
  CGContextAddLineToPoint( fp, x, y+4 );
  CGContextStrokePath( fp );

  CGContextMoveToPoint( fp, x, y+4 );
  CGContextAddLineToPoint( fp, x+4, y-2 );
  CGContextAddLineToPoint( fp, x+2, y-2 );
  CGContextAddLineToPoint( fp, x-1, y+2.5 );
  CGContextFillPath( fp );
}

void cgatt( CGContextRef fp, float x, float y )
{
  CGContextMoveToPoint( fp, x-4, y-3 );
  CGContextAddLineToPoint( fp, x+4, y );
  CGContextAddLineToPoint( fp, x-4, y+3 );
  CGContextStrokePath( fp );
}

void cgcpd( CGContextRef cx, float x, float y ) {
  float q[7][2] = {
    {-13,0},{-12,-9},{12,-9},{13,0},{10,-7.4},{-10,-7.4},{-13,-0} };

  float f1,f2;

  f1=0.5;
  f2=0.5;
  f2=f2*1.8;
  cgadd_mv (cx, x, y,f1,f2,q,0);
  cgadd_cv (cx, x, y,f1,f2,q,1,2);
  CGContextFillPath( cx );
}

void cgcpu( CGContextRef cx, float x, float y ) {
  float q[7][2] = {
    {-13,0},{-12,9},{12,9},{13,0},{10,7.4},{-10,7.4},{-13,-0} };

  float f1,f2;

  f1=0.5;
  f2=0.5;
  f2=f2*1.8;
  cgadd_mv (cx, x, y,f1,f2,q,0);
  cgadd_cv (cx, x, y,f1,f2,q,1,2);
  CGContextFillPath( cx );
}

void cgsld( CGContextRef cx, float x, float y, float dy ) {
  float s[7][2] = {
    {-8,-4.8},{-6,-5.5},{-3,-4.6},{0,0},{-2.3,-5},{-6,-6.8},{-8.5,-6} };

  float f1,f2;
  f1=0.9;
  f2=1.0;
  cgadd_mv (cx, x, y-dy,f1,f2,s,0);
  cgadd_cv (cx, x, y-dy,f1,f2,s,1,2);
  CGContextFillPath( cx );
}

void cgtrl( CGContextRef cx, float x, float y ) {
  cgcshow( cx, x, y, "tr" );//FIXME-italic
}

void cggrm( CGContextRef cx, float x, float y ) {
  float p[7][2] = {
    {-10,-2},{0,15},{1,-11},{10,2},{0,-15},{-1,11},{-10,-2} };

  cgadd_mv( cx, x, y, 0.5, 0.5, p, 0 );
  cgadd_cv( cx, x, y, 0.5, 0.5, p, 1, 2 );
  CGContextFillPath( cx );
}

void cgstc( CGContextRef cx, float x, float y ) {
  CGContextMoveToPoint( cx, x, y );
  CGContextAddArc( cx, x, y, 1.2f, 0, 2*M_PI, 1 );
  CGContextFillPath( cx );
}

void cgemb( CGContextRef cx, float x, float y ) {
	CGContextSaveGState( cx );
  CGContextSetLineWidth( cx, 1.4f );
  CGContextSetLineCap( cx, kCGLineCapRound );
  CGContextMoveToPoint( cx, x-3.5f, y );
  CGContextAddLineToPoint( cx, x+3.5f, y );
  CGContextStrokePath( cx );
	CGContextRestoreGState( cx );
}

void cghld( CGContextRef cx, float x, float y ) {
  float p[8][2] = {     /* for hold sign */
    {-15,0},{-15,23},{15,23},{15,0},
    {14.5,0},{12,18},{-12,18},{-14.5,0} };

  float f1,f2;

  f1=f2=0.5;
  CGContextMoveToPoint( cx, x, y );
  CGContextAddArc( cx, x, y+1.5f, 1.3f, 0, 2*M_PI, 1 );
  CGContextFillPath( cx );

  cgadd_mv (cx, x, y,f1,f2,p,0);
  cgadd_cv (cx, x, y,f1,f2,p,1,1);
  cgadd_sg (cx, x, y,f1,f2,p,4,1);
  cgadd_cv (cx, x, y,f1,f2,p,5,1);
  CGContextFillPath( cx );
}

void cgupb( CGContextRef cx, float x, float y ) {
  float r[3][2] = {    /* for up bow sign */
    {-3.2,11},{0,0},{3.2,11} };

  float f1,f2;

  f1=f2=0.8;
  cgadd_mv (cx, x, y,f1,f2,r,0);
  cgadd_sg (cx, x, y,f1,f2,r,1,2);
  CGContextStrokePath( cx );
}

void cgdnb( CGContextRef cx, float x, float y ) {
  float q[8][2] = {    /* for down bow sign */
    {-4,0},{-4,9},{4,9},{4,0},
    {-4,6},{-4,9},{4,9},{4,6} };

  float f1,f2;

  f1=f2=0.8;
  cgadd_mv(cx, x, y, f1,f2,q,0);
  cgadd_sg(cx, x, y, f1,f2,q,1,3);
  CGContextStrokePath( cx );
  cgadd_mv(cx, x, y, f1,f2,q,4);
  cgadd_sg(cx, x, y, f1,f2,q,5,3);
  CGContextFillPath( cx );
}

void cghl( CGContextRef cx, float x, float y )
{
  CGContextBeginPath( cx );
  CGContextMoveToPoint( cx, x-5.5f, y );
  CGContextAddLineToPoint( cx, x+5.5f, y );
  CGContextStrokePath( cx );
}

void cghl1( CGContextRef cx, float x, float y )
{
  CGContextBeginPath( cx );
  CGContextMoveToPoint( cx, x-7, y );
  CGContextAddLineToPoint( cx, x+7, y );
  CGContextStrokePath( cx );
}

void cgbm( CGContextRef cx, float x1, float y1, float x2, float y2, float t )
{
  CGContextMoveToPoint( cx, x2, y2 );
  CGContextAddLineToPoint( cx, x2, y2-t );
  CGContextAddLineToPoint( cx, x1, y1-t );
  CGContextAddLineToPoint( cx, x1, y1 );
  CGContextFillPath( cx );
}

void cgbnum( CGContextRef cx, float x, float y, int n )
{
  char s[32];
  sprintf( s, "%d", n );
  int length = strlen( s );
  CGContextSelectFont( cx, "Helvetica", 12, kCGEncodingMacRoman );
  CGContextSetTextDrawingMode( cx, kCGTextInvisible );
  CGContextShowTextAtPoint( cx, x, y, s, length );
  CGPoint p = CGContextGetTextPosition( cx );
  CGContextSetTextDrawingMode( cx, kCGTextFill );
  CGContextSetRGBFillColor( cx, 0.0, 0.0, 0.0, 1.0 );
  CGAffineTransform xform = CGAffineTransformMake( 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 );
  CGContextSetTextMatrix( cx, xform );
  CGContextShowTextAtPoint( cx, x-(p.x-x)/2, y, s, length );
}

void cghbr( CGContextRef cx, float x1, float y1, float x2, float y2 )
{
  CGContextMoveToPoint( cx, x2, y2 );
  CGContextAddLineToPoint( cx, x1, y1 );
  CGContextAddLineToPoint( cx, x1, y1-3 );
  CGContextStrokePath( cx );
}

static float sFlagUpPath[13][2] = {
  {0.0, 0.0},  {1.5, -3.0},  {1.0, -2.5},  {4.0, -6.0},  {9.0, -10.0},  
  {9.0, -16.0},  {8.0, -20.0},  {7.0, -24.0},  {4.0, -26.0},  
  {6.5, -21.5},  {9.0, -15.0},  {4.0, -9.0},  {0.0, -8.0} } ;

static float sFlagDownPath[13][2] = {
  {0.0, 0.0},  {1.5, 3.0},  {1.0, 2.5},  {4.0, 6.0},  {9.0, 10.0},  
  {9.0, 16.0},  {8.0, 20.0},  {7.0, 24.0},  {4.0, 26.0},  
  {6.5, 21.5},  {9.0, 15.0},  {4.0, 9.0},  {0.0, 8.0} } ;

void cgflag( CGContextRef cx, float x, float y, float len, int s, char du )
{
  //FIXME use "s"
  float f1,f2;
  int i;

  f1=f2=6.0/9.0;

  if ( du == 'u' ) {
    x += STEM_XOFF;
    y += len;
    cgadd_mv (cx,x,y,f1,f2,sFlagUpPath,0);
    cgadd_cv (cx,x,y,f1,f2,sFlagUpPath,1,4);
    CGContextFillPath( cx );
  } else {
    x -= STEM_XOFF;
    y -= len;
    cgadd_mv (cx,x,y,f1,f2,sFlagDownPath,0);
    cgadd_cv (cx,x,y,f1,f2,sFlagDownPath,1,4);
    CGContextFillPath( cx );
  }
}

/* ----- xxxdef_flags2 ------- */
void xxxdef_flags2 (fp)
FILE *fp;
{

  float p[13][2] = {
    {0.0, 0.0},  
    {2.0, -5.0},  {9.0, -6.0},  {7.5, -18.0},  
    {7.5, -9.0},  {1.5, -6.5},  {0.0, -6.5},  
    {2.0, -14.0},  {9.0, -14.0}, {7.5, -26.0}, 
    {7.5, -17.0},  {1.5, -14.5},  {0.0, -14.0},
  };

  float f1,f2;
  int i;

  f1=f2=6.0/9.0;                       /* up flags */
  fprintf (fp, "\n/f2u {  %% usage:  len f2u  - double flag up\n"
           "  y add x %.1f add exch moveto\n", STEM_XOFF); 
  add_mv (fp,f1,f2,p,0);
  add_cv (fp,f1,f2,p,1,4);
  fprintf (fp, "   fill\n} bind def\n");

  f1=1.2*f1;                           /* down flags */
  for (i=0;i<13;i++) p[i][1]=-p[i][1];
  fprintf (fp, "\n/f2d {  %% usage:  len f2d  - double flag down\n"
           "  neg y add x %.1f sub exch moveto\n", STEM_XOFF); 
  add_mv (fp,f1,f2,p,0);
  add_cv (fp,f1,f2,p,1,4);
  fprintf (fp, "   fill\n} bind def\n");

}  



/* ----- xxxdef_xflags ------- */
void xxxdef_xflags (fp)
FILE *fp;
{

  float p[7][2] = {
    {0.0, 0.0},  
    {2.0, -7.5},  {9.0, -7.5}, {7.5, -19.5}, 
    {7.5, -10.5},  {1.5, -8.0},  {0.0, -7.5}
  };

  float f1,f2;
  int i;

  f1=f2=6.0/9.0;                       /* extra up flag */
  fprintf (fp, "\n/xfu {  %% usage:  len xfu  - extra flag up\n"
           "  y add x %.1f add exch moveto\n", STEM_XOFF); 
  add_mv (fp,f1,f2,p,0);
  add_cv (fp,f1,f2,p,1,2);
  fprintf (fp, "   fill\n} bind def\n");

  f1=1.2*f1;                           /* extra down flag */
  for (i=0;i<7;i++) p[i][1]=-p[i][1];
  fprintf (fp, "\n/xfd {  %% usage:  len xfd  - extra flag down\n"
           "  neg y add x %.1f sub exch moveto\n", STEM_XOFF); 
  add_mv (fp,f1,f2,p,0);
  add_cv (fp,f1,f2,p,1,2);
  fprintf (fp, "   fill\n} bind def\n");

  fprintf (fp, 
           "\n/f3d {dup f2d 9.5 sub xfd} bind def\n");

  fprintf (fp, 
           "\n/f4d {dup dup f2d 9.5 sub xfd 14.7 sub xfd} bind def\n");

  fprintf (fp, 
           "\n/f3u {dup f2u 9.5 sub xfu} bind def\n");

  fprintf (fp, 
           "\n/f4u {dup dup f2u 9.5 sub xfu 14.7 sub xfu} bind def\n");

}  

/* ----- xxxdef_acc ------- */
void xxxdef_acc (fp)
FILE *fp;
{
static  float p[12][2]={  
    {-2,3},{6,6.5},{6,-1},{-2,-4.5},{4,0},{4,4},{-2,2},{-2,10},{-2,-4}};  
static  float q[14][2]={  
    {4,4},{4,7},{-4,5},{-4,2},{4,4},{4,-5},{4,-2},{-4,-4},{-4,-7},{4,-5}, 
    {2,-10},{2,11.5},{-2,-11.5},{-2,10} };
static  float s[25][2]={
    {0.7,0},{3.9,3},{6,3},{6.2,6.2},{3,6},{3,3.9},
    {0,0.7},{-3,3.9},{-3,6},{-6.2,6.2},{-6,3},{-3.9,3},
    {-0.7,0},{-3.9,-3},{-6,-3},{-6.2,-6.2},{-3,-6},{-3,-3.9},
    {0,-0.7},{3,-3.9},{3,-6},{6.2,-6.2},{6,-3},{3.9,-3},
    {0.7,0} };


  float f1,f2;
  
  f2=8.0/9.0;    /* more narrow flat sign for double flat */
  f1=f2*0.8;
//  fprintf (fp, "\n/ftx { %% usage:  x y ftx  - narrow flat sign\n"
//           "  moveto\n"); 
//  add_mv (fp,f1,f2,p,0);
//  add_cv (fp,f1,f2,p,1,2);
//  fprintf (fp, "  currentpoint fill moveto\n");
//  add_mv (fp,f1,f2,p,7);
//  add_sg (fp,f1,f2,p,8,1);
//  fprintf (fp, "  stroke\n } bind def\n");

//  fprintf (fp, "/dft0 { %% usage: x y dft0 ft  - double flat sign\n"
//           "  2 copy exch 2.5 sub exch ftx exch 1.5 add exch ftx } bind def\n"
//           "/dft { %% usage: dx dft  - double flat relative to head\n"
//           "  neg x add y dft0 } bind def\n");
//

  f1=5.0/9.0;
  f2=f1;
  fprintf (fp, "\n/dsh0 {  %% usage:  x y dsh0  - double sharp \n"
           "  moveto\n"); 
  add_mv (fp,f1,f2,s,0);
  add_sg (fp,f1,f2,s,1,24);
  fprintf (fp, "  fill\n } bind def\n");
  fprintf (fp, "/dsh { %% usage: dx dsh  - double sharp relative to head\n"
           " neg x add y dsh0 } bind def\n");
}

void cgsh0( CGContextRef cx, float x, float y )
{
  float q[14][2]={  
    {4,4},{4,7},{-4,5},{-4,2},{4,4},{4,-5},{4,-2},{-4,-4},{-4,-7},{4,-5}, 
    {2,-10},{2,11.5},{-2,-11.5},{-2,10} };

  float f2=6.5/9.0;
  float f1=f2*0.9;

  cgadd_mv(cx, x, y, f1,f2,q,0);
  cgadd_sg(cx, x, y, f1,f2,q,1,4);
  cgadd_mv(cx, x, y, f1,f2,q,0);
  cgadd_sg(cx, x, y, f1,f2,q,6,4);
  CGContextFillPath( cx );
  cgadd_mv (cx,x, y, f1,f2,q,10);
  cgadd_sg (cx,x, y, f1,f2,q,11,1);
  CGContextStrokePath( cx );
  cgadd_mv (cx,x, y, f1,f2,q,12);
  cgadd_sg (cx,x, y, f1,f2,q,13,1);
  CGContextStrokePath( cx );
}

void cgsh( CGContextRef cx, float x, float y, float dx )
{
  cgsh0( cx, x-dx, y );
}

void cgft0( CGContextRef cx, float x, float y )
{
  static float p[12][2]={  
    {-2,3},{6,6.5},{6,-1},{-2,-4.5},{4,0},{4,4},{-2,2},{-2,10},{-2,-4}};  

  float f1,f2;
  
  f2=8.0/9.0;
  f1=f2*0.9;
  cgadd_mv (cx,x, y, f1,f2,p,0);
  cgadd_cv (cx,x, y, f1,f2,p,1,2);
  CGContextFillPath( cx );
  cgadd_mv (cx,x, y, f1,f2,p,7);
  cgadd_sg (cx,x, y, f1,f2,p,8,1);
  CGContextStrokePath( cx );
}

void cgft( CGContextRef cx, float x, float y, float dx )
{
  cgft0( cx, x-dx, y );
}

// Narrow flat sign
void cgftx( CGContextRef cx, float x, float y )
{
  static float p[12][2]={  
    {-2,3},{6,6.5},{6,-1},{-2,-4.5},{4,0},{4,4},{-2,2},{-2,10},{-2,-4}};  

  float f1,f2;
  
  f2=8.0/9.0;
  f1=f2*0.8;
  cgadd_mv (cx,x, y, f1,f2,p,0);
  cgadd_cv (cx,x, y, f1,f2,p,1,2);
  CGContextFillPath( cx );
  cgadd_mv (cx,x, y, f1,f2,p,7);
  cgadd_sg (cx,x, y, f1,f2,p,8,1);
  CGContextStrokePath( cx );
}

// Double flat
void cgdft0( CGContextRef cx, float x, float y )
{
  cgftx( cx, x-2.5f, y );
  cgftx( cx, x+2.5f, y );
}

void cgnt0( CGContextRef cx, float x, float y )
{
  static float r[14][2]={  
    {-2.5,-6}, {2.5,-5}, {2.5,-2}, {-2.5,-3}, {-2.5,6},  
    {-2.5,2}, {2.5,3}, {2.5,6}, {-2.5,5}, {-2.5,2},
    {-2.5,11}, {-2.5,-5.5},  
    {2.5,5.5}, {2.5,-11} };

  float f1,f2;
  
  f2=6.5/9.0;
  f1=f2*0.9;
  cgadd_mv (cx,x,y,f1,f2,r,0);
  cgadd_sg (cx,x,y,f1,f2,r,1,4);
  cgadd_mv (cx,x,y,f1,f2,r,5);
  cgadd_sg (cx,x,y,f1,f2,r,6,4);
  CGContextFillPath( cx );
  cgadd_mv (cx,x,y,f1,f2,r,10);
  cgadd_sg (cx,x,y,f1,f2,r,11,1);
  CGContextStrokePath( cx );
  cgadd_mv (cx,x,y,f1,f2,r,12);
  cgadd_sg (cx,x,y,f1,f2,r,13,1);
  CGContextStrokePath( cx );
}

void cgnt( CGContextRef cx, float x, float y, float dx )
{
  cgnt0( cx, x-dx, y );
}

void cgr1( CGContextRef cx, float x, float y )
{
  CGContextMoveToPoint( cx, x-3, y+6 );
  CGContextAddLineToPoint( cx, x-3, y+3 );
  CGContextAddLineToPoint( cx, x+3, y+3 );
  CGContextAddLineToPoint( cx, x+3, y+6 );
  CGContextClosePath( cx );
  CGContextFillPath( cx );
}

void cgr2( CGContextRef cx, float x, float y )
{
  CGContextMoveToPoint( cx, x-3, y );
  CGContextAddLineToPoint( cx, x-3, y+3 );
  CGContextAddLineToPoint( cx, x+3, y+3 );
  CGContextAddLineToPoint( cx, x+3, y );
  CGContextClosePath( cx );
  CGContextFillPath( cx );
}

void cgr4( CGContextRef cx, float x, float y )
{
  float p[14][2]={  
    {-1,17}, {15,4}, {-6,8}, {6.5,-5}, {-2,-2}, {-5,-11}, {1,-15},
    {-9,-11}, {-6,0}, {1,-1},   {-9,7}, {7,5}, {-1,17} };

  float f1,f2;

  f1=f2=6.0/11.5;
  cgadd_mv (cx,x,y,f1,f2,p,0);
  cgadd_cv (cx,x,y,f1,f2,p,1,4);
  CGContextFillPath( cx );
}

void cgr8( CGContextRef cx, float x, float y )
{
  float q[16][2]={  
    {8,14}, {5,9}, {3,5}, {-1.5,4},
    {4,11}, {-9,14}, {-9,7},
    {-9,4}, {-6,2}, {-3,2},
    {4,2}, {5,7}, {7,11},
    {-1.8,-20},  {-0.5,-20}, {8.5,14}};

  float f1,f2;

  f1=f2=7/18.0;
  cgadd_mv (cx,x,y,f1,f2,q,0);
  cgadd_cv (cx,x,y,f1,f2,q,1,4);
  cgadd_sg (cx,x,y,f1,f2,q,13,3);
  CGContextFillPath( cx );
}

void cgr16( CGContextRef cx, float x, float y )
{
  float r[29][2]={  
    {8,14}, {5,9}, {3,5}, {-1.5,4},
    {4,11}, {-9,14}, {-9,7},
    {-9,4}, {-6,2}, {-3,2},
    {4,2}, {5,7}, {7,11},
    {8,14}, {5,9}, {3,5}, {-1.5,4},
    {4,11}, {-9,14}, {-9,7},
    {-9,4}, {-6,2}, {-3,2},
    {4,2}, {5,7}, {7.3,11},
    {-1.8,-21},  {-0.5,-21}, {8.5,14} };
  float f1,f2;
  int i;

  for (i=13;i<26;i++) { r[i][0]-=4.2; r[i][1]-=14; }
  f1=f2=7/18.0;
  cgadd_mv (cx,x,y,f1,f2,r,0);
  cgadd_cv (cx,x,y,f1,f2,r,1,4);
  cgadd_sg (cx,x,y,f1,f2,r,13,1);
  cgadd_cv (cx,x,y,f1,f2,r,14,4);
  cgadd_sg (cx,x,y,f1,f2,r,26,3);
  CGContextFillPath( cx );
}

void cgr32( CGContextRef cx, float x, float y )
{
  /* get 32nd, 64th rest by overwriting 8th and 16th rests */
  cgr16( cx, x, y );
  cgr8( cx, x+1.6f, y+5.5f );
}

void cgr64( CGContextRef cx, float x, float y )
{
  cgr16( cx, x+1.6f, y+5.5f );
  cgr16( cx, x-1.5f, y-5.5f );
}


void cgbar( CGContextRef cx, float x, float y )
{
  CGContextMoveToPoint( cx, x, y );
  CGContextAddLineToPoint( cx, x, y+24 );
  CGContextStrokePath( cx );
}

void cgdbar( CGContextRef cx, float x, float y )
{
  CGContextMoveToPoint( cx, x, y );
  CGContextAddLineToPoint( cx, x, y+24 );
  CGContextMoveToPoint( cx, x-3, y );
  CGContextAddLineToPoint( cx, x-3, y+24 );
  CGContextStrokePath( cx );
}

void cgfbar1( CGContextRef cx, float x, float y )
{
  CGContextMoveToPoint( cx, x, y );
  CGContextAddLineToPoint( cx, x, y+24 );
  CGContextMoveToPoint( cx, x+3, y );
  CGContextAddLineToPoint( cx, x+3, y+24 );
  CGContextStrokePath( cx );
}

void cgfbar2( CGContextRef cx, float x, float y )
{
  CGContextMoveToPoint( cx, x, y );
  CGContextAddLineToPoint( cx, x, y+24 );
  CGContextMoveToPoint( cx, x-3, y );
  CGContextAddLineToPoint( cx, x-3, y+24 );
  CGContextStrokePath( cx );
}

void cgrdots( CGContextRef cx, float x, float y )
{
  y += 9;
  CGContextMoveToPoint( cx, x, y );
  CGContextAddArc( cx, x, y, 1.2f, 0, 2*M_PI, 1 );
  y += 6;
  CGContextMoveToPoint( cx, x, y );
  CGContextAddArc( cx, x, y, 1.2f, 0, 2*M_PI, 1 );
  CGContextFillPath( cx );
}

void cgend1( CGContextRef cx, float x1, float x2, int n )
{
  /* use dy=20 for tall boxes */
  int y=50,dy=6;

  CGContextMoveToPoint( cx, x2, y-dy );
  CGContextAddLineToPoint( cx, x2, y );
  CGContextAddLineToPoint( cx, x1, y );
  CGContextAddLineToPoint( cx, x1, y-dy );
  CGContextStrokePath( cx );
  char text[32];
  sprintf( text, "%d", n );
  cglshow( cx, x1, y-10, text );//FIXME-13 point font
}

void cgend2( CGContextRef cx, float x1, float x2, int n )
{
  /* use dy=20 for tall boxes */
  int y=50,dy=6;

  //FIXME-not done this one yet
  CGContextMoveToPoint( cx, x2, y-dy );
  CGContextAddLineToPoint( cx, x2, y );
  CGContextAddLineToPoint( cx, x1, y );
  CGContextAddLineToPoint( cx, x1, y-dy );
  CGContextStrokePath( cx );
  char text[32];
  sprintf( text, "%d", n );
  cglshow( cx, x1, y-10, text );//FIXME-13 point font
}

void cggc( CGContextRef cx, float x, float y, const char *text )
{
  CGContextSelectFont( cx, "Helvetica", 14, kCGEncodingMacRoman );
  CGContextSetTextDrawingMode( cx, kCGTextFill );
  CGContextSetRGBFillColor( cx, 0.0, 0.0, 0.0, 1.0 );
  CGAffineTransform xform = CGAffineTransformMake( 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 );
  CGContextSetTextMatrix( cx, xform );
  CGContextShowTextAtPoint( cx, x, y, text, strlen( text ) );
}

/* ----- xxxdef_sl ------ */
void cgsl( CGContextRef cx,
  float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4,
  float x5, float y5, float x6, float y6, float x7, float y7, float x8, float y8
)
{
  CGContextBeginPath( cx );
  CGContextMoveToPoint( cx, x8, y8 );
  CGContextAddCurveToPoint( cx, x5, y5, x6, y6, x7, y7 );
  CGContextAddLineToPoint( cx, x4+x7, y4+y7 );
  CGContextAddCurveToPoint( cx, x1, y1, x2, y2, x3, y3 );
  CGContextClosePath( cx );
  CGContextFillPath( cx );
}

void cghd( CGContextRef cx, float x, float y )
{
  float p[7][2] = {
    {8.0, 0.0},  {8.0, 8.0},  {-8.0, 8.0},  {-8.0, 0.0},  {-8.0, -8.0},  
    {8.0, -8.0},  {8.0, 0.0} };

  float c,s,xx,yy,f1,f2;
  int i;
  
  c=0.825; s=0.565;

  for (i=0;i<7;i++) {
    xx = c*p[i][0] - s*p[i][1];
    yy = s*p[i][0] + c*p[i][1];
    p[i][0]=xx;
    p[i][1]=yy;
  }
  
  f1=f2=6.0/12.0;
  CGContextBeginPath( cx );
  cgadd_mv (cx, x, y, f1,f2,p,0);
  cgadd_cv (cx, x, y, f1,f2,p,1,2);
  CGContextClosePath( cx );
  CGContextFillPath( cx );
}

void cgHd( CGContextRef cx, float x, float y )
{

  float p[14][2] = {
    {8.0, 0.0},  {8.0, 8.5},  {-8.0, 8.5},  {-8.0, 0.0},  {-8.0, -8.5},  
    {8.0, -8.5},  {8.0, 0.0},  {7.0, 0.0},  {7.0, -4.0},  {-7.0, -4.0}, 
    {-7.0, 0.0},  {-7.0, 4.0},  {7.0, 4.0},  {7.0, 0.0} };

  float c,s,xx,yy,f1,f2;
  int i;

  c=0.878; s=0.479;

  for (i=0;i<14;i++) {
    xx = c*p[i][0] - s*p[i][1];
    yy = s*p[i][0] + c*p[i][1];
    p[i][0]=xx;
    p[i][1]=yy;
  }
  
  f1=f2=6.0/12.0;
  cgadd_mv (cx,x, y, f1,f2,p,0);
  cgadd_cv (cx,x, y, f1,f2,p,1,2);
  cgadd_mv (cx,x, y, f1,f2,p,7);
  cgadd_cv (cx,x, y, f1,f2,p,8,2);
  CGContextFillPath( cx );
}

void cgHD( CGContextRef cx, float x, float y )
{
  float p[13][2] = {
    {11.0, 0.0}, {11.0, 2.0},  {6.0, 6.5},  {0.0, 6.5},  {-6.0, 6.5}, 
    {-11.0, 2.0},  {-11.0, 0.0},  {-11.0, -2.0},  {-6.0, -6.5}, 
    {0.0, -6.5},  {6.0, -6.5},  {11.0, -2.0},  {11.0, 0.0}  };

  float q[8][2] = {
    {11.0, 0.0},  {5.0, 0.0},  {5.0, -5.0},  {-5.0, -5.0},  {-5.0, 0.0},  
    {-5.0, 5.0},  {5.0, 5.0},  {5.0, 0.0}};
           
/*  float phi; */
  float c,s,xx,yy,f1,f2;
  int i;

/*phi=2.5;
  c=cos(phi);
  s=sin(phi); */
  
  c=-0.801; s=0.598;

  for (i=1;i<8;i++) {
    xx = c*q[i][0] - s*q[i][1];
    yy = s*q[i][0] + c*q[i][1];
    q[i][0]=xx;
    q[i][1]=yy;
  }
  
  f1=f2=6.5/12.0;
  cgadd_mv (cx,x, y, f1,f2,p,0);
  cgadd_cv (cx,x, y, f1,f2,p,1,4);
  cgadd_mv (cx,x, y, f1,f2,q,2);
  cgadd_cv (cx,x, y, f1,f2,q,2,2);
  CGContextFillPath( cx );
}

void cgghl( CGContextRef cx, float x, float y )
{
  CGContextSaveGState( cx );
  CGContextSetLineWidth( cx, 0.7f );
  CGContextMoveToPoint( cx, x-3, y );
  CGContextAddLineToPoint( cx, x+3, y );
  CGContextStrokePath( cx );
  CGContextRestoreGState( cx );
}

void cggnt( CGContextRef cx, float x, float y, float l )
{
  float p[7][2] = {
    {0,10}, {16,10}, {16,-10}, {0,-10}, {-16,-10}, {-16,10}, {0,10} };

/*  float phi; */
  float c,s,xx,yy,f1,f2;
  int i;
  
/*phi=0.7;
  c=cos(phi);
  s=sin(phi); */
  
//  c=0.765; s=0.644;
//
//  for (i=0;i<7;i++) {//FIXME
//    xx = c*p[i][0] - s*p[i][1];
//    yy = s*p[i][0] + c*p[i][1];
//    p[i][0]=xx;
//    p[i][1]=yy;
//  }
  
  f1=f2=2./10.0;

  cgadd_mv(cx, x, y, f1,f2,p,0);
  cgadd_cv(cx, x, y, f1,f2,p,1,2);
  CGContextFillPath( cx );
  CGContextMoveToPoint( cx, x+GSTEM_XOFF, y );
  CGContextAddLineToPoint( cx, x+GSTEM_XOFF, y+l );
  CGContextStrokePath( cx );
}

void cggn1( CGContextRef cx, float x, float y, float l )
{
  float p[7][2] = {
    {0,10}, {16,10}, {16,-10}, {0,-10}, {-16,-10}, {-16,10}, {0,10} };

  float c,s,xx,yy,f1,f2;
  int i;
  
//  c=0.765; s=0.644;
//
//  for (i=0;i<7;i++) {
//    xx = c*p[i][0] - s*p[i][1];
//    yy = s*p[i][0] + c*p[i][1];
//    p[i][0]=xx;
//    p[i][1]=yy;
//  }
  
  f1=f2=2./10.0;

  cgadd_mv(cx, x, y, f1,f2,p,0);
  cgadd_cv(cx, x, y, f1,f2,p,1,2);
  CGContextFillPath( cx );
  x += GSTEM_XOFF;
  CGContextMoveToPoint( cx, x, y );
  CGContextAddLineToPoint( cx, x, y+l );
  y += l;
  CGContextMoveToPoint( cx, x, y );
  CGContextAddCurveToPoint( cx, x+3, y-4, x+4, y-5, x+2, y-8 );

  CGContextMoveToPoint( cx, x-3, y-6 );
  CGContextAddLineToPoint( cx, x+4, y-2 );
  CGContextStrokePath( cx );
}

void cggsh0( CGContextRef cx, float x, float y )
{
  CGContextSaveGState( cx );
  CGContextTranslateCTM( cx, x, y );
  CGContextScaleCTM( cx, 0.7f, 0.7f );
  cgsh0( cx, 0, 0 );
  CGContextRestoreGState( cx );
}

void cggft0( CGContextRef cx, float x, float y )
{
  CGContextSaveGState( cx );
  CGContextTranslateCTM( cx, x, y );
  CGContextScaleCTM( cx, 0.7f, 0.7f );
  cgft0( cx, 0, 0 );
  CGContextRestoreGState( cx );
}

void cggnt0( CGContextRef cx, float x, float y )
{
  CGContextSaveGState( cx );
  CGContextTranslateCTM( cx, x, y );
  CGContextScaleCTM( cx, 0.7f, 0.7f );
  cgnt0( cx, 0, 0 );
  CGContextRestoreGState( cx );
}

void cggdf0( CGContextRef cx, float x, float y )
{
  CGContextSaveGState( cx );
  CGContextTranslateCTM( cx, x, y );
  CGContextScaleCTM( cx, 0.7f, 0.6f );
  cgdft0( cx, 0, 0 );
  CGContextRestoreGState( cx );
}

//FIXME
void cggds0( CGContextRef cx, float x, float y )
{
  CGContextSaveGState( cx );
  CGContextTranslateCTM( cx, x, y );
  CGContextScaleCTM( cx, 0.7f, 0.7f );
//  cgdsh0( cx, 0, 0 );
  CGContextRestoreGState( cx );
}

void cggbm2( CGContextRef cx, float x0, float y0, float x1, float y1 )
{
  CGContextSaveGState( cx );
  CGContextSetLineWidth( cx, 1.4f );
  CGContextBeginPath( cx );
  CGContextMoveToPoint( cx, x0, y0-0.5f );
  CGContextAddLineToPoint( cx, x1, y1-0.5f );
  CGContextMoveToPoint( cx, x0, y0-3.4f );
  CGContextAddLineToPoint( cx, x1, y1-3.4f );
  CGContextStrokePath( cx );
  CGContextRestoreGState( cx );
}

void cggbm3( CGContextRef cx, float x0, float y0, float x1, float y1 )
{
  CGContextSaveGState( cx );
  CGContextSetLineWidth( cx, 1.2f );
  CGContextBeginPath( cx );
  CGContextMoveToPoint( cx, x0, y0-0.3f );
  CGContextAddLineToPoint( cx, x1, y1-0.3f );
  CGContextMoveToPoint( cx, x0, y0-2.5f );
  CGContextAddLineToPoint( cx, x1, y1-2.5f );
  CGContextMoveToPoint( cx, x0, y0-4.7f );
  CGContextAddLineToPoint( cx, x1, y1-4.7f );
  CGContextStrokePath( cx );
  CGContextRestoreGState( cx );
}

void cggsl( CGContextRef cx, float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3 )
{
  CGContextBeginPath( cx );
  CGContextMoveToPoint( cx, x0, y0 );
  CGContextAddCurveToPoint( cx, x1, y1, x2, y2, x3, y3 );
  CGContextStrokePath( cx );
}

void cgcsig( CGContextRef cx, float x )
{
  float y = 10;
  float p[25][2]={
  {0,26},  
  {4,26}, {11,23},  {11,14}, 
  {11,20},  {5,19}, {5,14}, 
  {5,9}, {12,9}, {12,15}, 
  {12,25}, {6,28},  {0,28}, 
  {-15,28}, {-25,17}, {-25,2}, 
  {-25,-10}, {-10,-28}, {11,-8}, 
  {-6,-20}, {-18,-11}, {-18,2}, 
  {-18,14}, {-14,26}, {0,26} };

  float f1,f2;
  int i;
  
  f1 = f2 = 0.25;
  cgadd_mv (cx,x,y,f1,f2,p,0);
  cgadd_cv (cx,x,y,f1,f2,p,1,8);
  CGContextFillPath( cx );
}

void cgctsig( CGContextRef cx, float x )
{
  float y = 4;
  cgcsig( cx, x );
  CGContextMoveToPoint( cx, x, y );
  CGContextAddLineToPoint( cx, x, y+16 );
  CGContextStrokePath( cx );
}

void cgtclef( CGContextRef cx, float x )
{
  float p[71][2]={
    {-6, 16},  {-8, 13},  {-14, 19},  {-10, 35},  {2, 35},  {8, 37},  
    {21, 30},  {21, 17},  {21, 5},  {10, -1},  {0, -1},  {-12, -1},  
    {-23, 5},  {-23, 22},  {-23, 29},  {-22, 37},  {-7, 49},  {10, 61},  
    {10, 68},  {10, 73},  {10, 78},  {9, 82},  {7, 82},  {2, 78},  
    {-2, 68},  {-2, 62},  {-2, 25},  {10, 18},  {11, -8},  {11, -18}, 
    {5, -23},  {-4, -23},  {-10, -23},  {-15, -18},  {-15, -13},  
    {-15, -8},  {-12, -4},  {-7, -4},  {3, -4},  {3, -20},  {-6, -17},
    {-5, -23},  {9, -20},  {9, -9},  {7, 24},  {-5, 30},  {-5, 67}, 
    {-5, 78},  {-2, 87},  {7, 91},  {13, 87},  {18, 80},  {17, 73},  
    {17, 62},  {10, 54},  {1, 45},  {-5, 38},  {-15, 33},  {-15, 19}, 
    {-15, 7},  {-8, 1},  {0, 1},  {8, 1},  {15, 6},  {15, 14},  {15, 23},
    {7, 26},  {2, 26},  {-5, 26},  {-9, 21},  {-6, 16} };

  float f1,f2;
  
  f1 = f2 = 24.0/65.0;
  cgadd_mv (cx,x, 0, f1,f2,p,0);
  cgadd_sg (cx,x, 0, f1,f2,p,1,1);
  cgadd_cv (cx,x, 0, f1,f2,p,2,23);
  CGContextFillPath( cx );
}

void cgstclef( CGContextRef cx, float x )
{
  CGContextSaveGState( cx );
  CGContextScaleCTM( cx, 0.85f, 0.85f );
  cgtclef( cx, x/0.85f );
  CGContextRestoreGState( cx );
}

void cgbclef( CGContextRef cx, float x )
{
  float p[42][2]={
    {-2.3,3}, {6,7}, {10.5,12}, {10.5,16},
    {10.5,20.5}, {8.5,23.5}, {6.2,23.3},
    {5.2,23.5}, {2,23.5}, {0.5,19.5},
    {2,20}, {4,19.5}, {4,18},
    {4,17}, {3.5,16}, {2,16},
    {1,16}, {0,16.9}, {0,18.5},
    {0,21}, {2.1,24}, {6,24}, 
    {10,24}, {13.5,21.5}, {13.5,16.5},
    {13.5,11}, {7,5.5}, {-2.0,2.8},
    {14.9,21}, 
    {14.9,22.5}, {16.9,22.5}, {16.9,21},
    {16.9,19.5}, {14.9,19.5}, {14.9,21},
    {14.9,15},
    {14.9,16.5}, {16.9,16.5}, {16.9,15},
    {16.9,13.5}, {14.9,13.5}, {14.9,15} };
  
  int i;
  float f1,f2;

  for (i=0;i<42;i++) {p[i][0]-=7.5; p[i][1]-=0.5; }
  f1 = f2 = 1.0;
  cgadd_mv (cx,x, 0, f1,f2,p,0);
  cgadd_cv (cx,x, 0, f1,f2,p,1,9);
  cgadd_cv (cx,x, 0, f1,f2,p,1,9);

  cgadd_mv (cx,x, 0, f1,f2,p,28);
  cgadd_cv (cx,x, 0, f1,f2,p,29,2);

  cgadd_mv (cx,x, 0, f1,f2,p,25);
  cgadd_cv (cx,x, 0, f1,f2,p,36,2);
  CGContextFillPath( cx );
}

void cgsbclef( CGContextRef cx, float x )
{
  CGContextSaveGState( cx );
  CGContextScaleCTM( cx, 0.85f, 0.85f );
  CGContextTranslateCTM( cx, 0, 4 );
  cgbclef( cx, x/0.85f );
  CGContextRestoreGState( cx );
}

void cgcclef( CGContextRef cx, float x )
{
  float p[30][2]={
    {0,0}, {2,5.5}, 
    {9,4.5}, {12,10}, {12,15.5},
    {12,19.5}, {11,23.3}, {6.5,23.5},
    {5.2,23.5}, {2,23.5}, {0.5,19.5},
    {2,20}, {4,19.5}, {4,18},
    {4,17}, {3.5,16}, {2,16},
    {1,16}, {0,16.9}, {0,18.5},
    {0,21}, {2.1,24}, {6,24},
    {12,24}, {15,21.5}, {15,16.5},
    {15,10}, {10,4.5}, {4,5},
    {3,0} };
  int i;
  float f1,f2;

  for (i=0;i<30;i++) p[i][1]+=24;

  f1 = 0.6;
  f2 = 0.5;

  cgadd_mv (cx,x, 0, f1,f2,p,0);
  cgadd_sg (cx,x, 0, f1,f2,p,1,1);
  cgadd_cv (cx,x, 0, f1,f2,p,2,9);
  cgadd_sg (cx,x, 0, f1,f2,p,29,1);
  CGContextFillPath( cx );

  CGContextSaveGState( cx );
  CGContextTranslateCTM( cx, 0, 24 );
  CGContextScaleCTM( cx, 1, -1 );
  cgadd_mv (cx,x, 0, f1,f2,p,0);
  cgadd_sg (cx,x, 0, f1,f2,p,1,1);
  cgadd_cv (cx,x, 0, f1,f2,p,2,9);
  cgadd_sg (cx,x, 0, f1,f2,p,29,1);
  CGContextFillPath( cx );

  CGContextMoveToPoint( cx, x-6.5f, 0 );
  CGContextAddLineToPoint( cx, x-6.5f, 24 );
  CGContextAddLineToPoint( cx, x-3.5f, 24 );
  CGContextAddLineToPoint( cx, x-3.5f, 0 );
  CGContextFillPath( cx );

  CGContextRestoreGState( cx );

  CGContextSetLineWidth( cx, 0.8f );
  CGContextMoveToPoint( cx, x-1.8f, 0 );
  CGContextAddLineToPoint( cx, x-1.8f, 24 );
  CGContextStrokePath( cx );
}

void cgscclef( CGContextRef cx, float x )
{
  cgcclef( cx, x );
}

void cgbrace( CGContextRef cx, float scale, float x, float y )
{
  float p[8][2]={
    {7.2,60}, {-7,39}, {17,17}, {-1,0}, 
    {-1.4,0}, {13,13}, {-11,39}, {7,60} };

  float f1,f2;

  f1 = 0.9;
  f2 = 1.0;

  CGContextSaveGState( cx );
  CGContextTranslateCTM( cx, x, y );
  CGContextScaleCTM( cx, scale, scale );
  cgadd_mv (cx,0, 0, f1,f2,p,0);
  cgadd_cv (cx,0, 0, f1,f2,p,1,1);
  cgadd_sg (cx,0, 0, f1,f2,p,4,1);
  cgadd_cv (cx,0, 0, f1,f2,p,5,1);
  CGContextFillPath( cx );
  CGContextRestoreGState( cx );

  CGContextSaveGState( cx );
  CGContextTranslateCTM( cx, x, y );
  CGContextScaleCTM( cx, scale, -scale );
  cgadd_mv (cx,0, 0, f1,f2,p,0);
  cgadd_cv (cx,0, 0, f1,f2,p,1,1);
  cgadd_sg (cx,0, 0, f1,f2,p,4,1);
  cgadd_cv (cx,0, 0, f1,f2,p,5,1);
  CGContextFillPath( cx );
  CGContextRestoreGState( cx );
}

void cgbracket( CGContextRef cx, float h, float x, float y )
{
  float q[8][2]={
    {-3,0}, {2,0}, {4,1}, {5.5,5}, 
    {5.9,4.7}, {4.7,1.2}, {3.2,-.4}, {-1,-1.2} };

  float f1,f2;

  f1 = 1.0;
  f2 = 1.0;

  cgadd_mv (cx, x, y+h, f1,f2,q,0);
  cgadd_cv (cx, x, y+h, f1,f2,q,1,1);
  cgadd_sg (cx, x, y+h, f1,f2,q,4,1);
  cgadd_cv (cx, x, y+h, f1,f2,q,5,1);
  CGContextFillPath( cx );

  CGContextSaveGState( cx );
  CGContextScaleCTM( cx, 1, -1 );
  cgadd_mv (cx, x, y+h, f1,f2,q,0);
  cgadd_cv (cx, x, y+h, f1,f2,q,1,1);
  cgadd_sg (cx, x, y+h, f1,f2,q,4,1);
  cgadd_cv (cx, x, y+h, f1,f2,q,5,1);
  CGContextFillPath( cx );
  CGContextRestoreGState( cx );

  CGContextSetLineWidth( cx, 0.8f );
  CGContextMoveToPoint( cx, x, y );
  CGContextAddLineToPoint( cx, x-3, y );
  CGContextAddLineToPoint( cx, x-3, y+h );
  CGContextAddLineToPoint( cx, x, y+h );
  CGContextClosePath( cx );
  CGContextFillPath( cx );
}

void cgstaff( CGContextRef cx, float x, float y, float l )
{
	CGContextSaveGState( cx );
  CGContextSetLineWidth( cx, 0.5f );
  for ( int i = 0; i < 5; i++ ) {
    CGContextMoveToPoint( cx, x, y+i*6 );
    CGContextAddLineToPoint( cx, x+l, y+i*6 );
	}
  CGContextStrokePath( cx );
  CGContextRestoreGState( cx );
}

void cgsep( CGContextRef cx, float x1, float x2 )
{
  CGContextMoveToPoint( cx, x1, 0 );
  CGContextAddLineToPoint( cx, x2, 0 );
  CGContextStrokePath( cx );
}


