Add -trueColors option
[xboard.git] / xevalgraph.c
index 95e10c1..f3cac1f 100644 (file)
@@ -67,6 +67,9 @@ extern char *getenv();
 #include <X11/Xaw/AsciiText.h>
 #include <X11/Xaw/Viewport.h>
 
+#include <cairo/cairo.h>
+#include <cairo/cairo-xlib.h>
+
 #include "common.h"
 #include "frontend.h"
 #include "backend.h"
@@ -74,6 +77,8 @@ extern char *getenv();
 #include "menus.h"
 #include "xboard.h"
 #include "evalgraph.h"
+#include "xevalgraph.h"
+#include "draw.h"
 #include "gettext.h"
 
 #ifdef ENABLE_NLS
@@ -105,10 +110,34 @@ Dimension evalGraphW, evalGraphH;
 
 char *crWhite = "#FFFFB0";
 char *crBlack = "#AD5D3D";
-static Window eGraphWindow;
+Option *disp;
+
+static Option *EvalCallback P((int button, int x, int y));
 
-static GC pens[6]; // [HGM] put all pens in one array
-static GC hbrHist[3];
+static void
+ChoosePen(cairo_t *cr, int i)
+{
+  switch(i) {
+    case PEN_BLACK:
+      SetPen(cr, 1.0, "#000000", 0);
+      break;
+    case PEN_DOTTED:
+      SetPen(cr, 1.0, "#A0A0A0", 1);
+      break;
+    case PEN_BLUEDOTTED:
+      SetPen(cr, 1.0, "#0000FF", 1);
+      break;
+    case PEN_BOLDWHITE:
+      SetPen(cr, 3.0, crWhite, 0);
+      break;
+    case PEN_BOLDBLACK:
+      SetPen(cr, 3.0, crBlack, 0);
+      break;
+    case PEN_BACKGD:
+      SetPen(cr, 3.0, "#E0E0F0", 0);
+      break;
+  }
+}
 
 // [HGM] front-end, added as wrapper to avoid use of LineTo and MoveToEx in other routines (so they can be back-end)
 void
@@ -116,8 +145,16 @@ DrawSegment (int x, int y, int *lastX, int *lastY, enum PEN penType)
 {
   static int curX, curY;
 
-  if(penType != PEN_NONE)
-    XDrawLine(xDisplay, eGraphWindow, pens[penType], curX, curY, x, y);
+  if(penType != PEN_NONE) {
+    cairo_t *cr = cairo_create(DRAWABLE(disp));
+    cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+    cairo_move_to (cr, curX, curY);
+    cairo_line_to (cr, x,y);
+    ChoosePen(cr, penType);
+    cairo_stroke (cr);
+    cairo_destroy (cr);
+  }
+
   if(lastX != NULL) { *lastX = curX; *lastY = curY; }
   curX = x; curY = y;
 }
@@ -126,89 +163,100 @@ DrawSegment (int x, int y, int *lastX, int *lastY, enum PEN penType)
 void
 DrawRectangle (int left, int top, int right, int bottom, int side, int style)
 {
-    XFillRectangle(xDisplay, eGraphWindow, hbrHist[side], left, top, right-left, bottom-top);
-    if(style != FILLED)
-      XDrawRectangle(xDisplay, eGraphWindow, pens[PEN_BLACK], left, top, right-left-1, bottom-top-1);
+  cairo_t *cr;
+
+  cr = cairo_create (DRAWABLE(disp));
+  cairo_set_antialias (cr, CAIRO_ANTIALIAS_NONE);
+  cairo_rectangle (cr, left, top, right-left, bottom-top);
+  switch(side)
+    {
+    case 0: ChoosePen(cr, PEN_BOLDWHITE); break;
+    case 1: ChoosePen(cr, PEN_BOLDBLACK); break;
+    case 2: ChoosePen(cr, PEN_BACKGD); break;
+    }
+  cairo_fill (cr);
+
+  if(style != FILLED)
+    {
+      cairo_rectangle (cr, left, top, right-left-1, bottom-top-1);
+      ChoosePen(cr, PEN_BLACK);
+      cairo_stroke (cr);
+    }
+
+  cairo_destroy(cr);
 }
 
 // front-end wrapper for putting text in graph
 void
 DrawEvalText (char *buf, int cbBuf, int y)
 {
-    // the magic constants 7 and 5 should really be derived from the font size somehow
-    XDrawString(xDisplay, eGraphWindow, coordGC, MarginX - 2 - 7*cbBuf, y+5, buf, cbBuf);
-}
-
-// front-end
-static Pixel
-MakeColor (char *color)
-{
-    XrmValue vFrom, vTo;
-
-    vFrom.addr = (caddr_t) color;
-    vFrom.size = strlen(color);
-    XtConvert(shells[EvalGraphDlg], XtRString, &vFrom, XtRPixel, &vTo);
-    // test for NULL?
+    // the magic constants 8 and 5 should really be derived from the font size somehow
+  cairo_text_extents_t extents;
+  cairo_t *cr = cairo_create(DRAWABLE(disp));
 
-    return *(Pixel *) vTo.addr;
-}
+  /* GTK-TODO this has to go into the font-selection */
+  cairo_select_font_face (cr, "Sans",
+                         CAIRO_FONT_SLANT_NORMAL,
+                         CAIRO_FONT_WEIGHT_NORMAL);
+  cairo_set_font_size (cr, 12.0);
 
-static GC
-CreateGC (int width, char *fg, char *bg, int style)
-{
-    XtGCMask value_mask = GCLineWidth | GCLineStyle | GCForeground
-      | GCBackground | GCFunction | GCPlaneMask;
-    XGCValues gc_values;
 
-    gc_values.plane_mask = AllPlanes;
-    gc_values.line_width = width;
-    gc_values.line_style = style;
-    gc_values.function = GXcopy;
+  cairo_text_extents (cr, buf, &extents);
 
-    gc_values.foreground = MakeColor(fg);
-    gc_values.background = MakeColor(bg);
+  cairo_move_to (cr, MarginX - 2 - 8*cbBuf, y+5);
+  cairo_text_path (cr, buf);
+  cairo_set_source_rgb (cr, 0.0, 0.0, 0);
+  cairo_fill_preserve (cr);
+  cairo_set_source_rgb (cr, 0, 1.0, 0);
+  cairo_set_line_width (cr, 0.1);
+  cairo_stroke (cr);
 
-    return XtGetGC(shells[EvalGraphDlg], value_mask, &gc_values);
+  /* free memory */
+  cairo_destroy (cr);
 }
 
 static int initDone = FALSE;
 
 static void
-InitializeEvalGraph (Option *opt)
+InitializeEvalGraph (Option *opt, int w, int h)
 {
-  eGraphWindow = XtWindow(opt->handle);
-
-  pens[PEN_BLACK]      = CreateGC(1, "black", "black", LineSolid);
-  pens[PEN_DOTTED]     = CreateGC(1, "#A0A0A0", "#A0A0A0", LineOnOffDash);
-  pens[PEN_BLUEDOTTED] = CreateGC(1, "#0000FF", "#0000FF", LineOnOffDash);
-  pens[PEN_BOLDWHITE]  = CreateGC(3, crWhite, crWhite, LineSolid);
-  pens[PEN_BOLDBLACK]  = CreateGC(3, crBlack, crBlack, LineSolid);
-  hbrHist[0] = CreateGC(3, crWhite, crWhite, LineSolid);
-  hbrHist[1] = CreateGC(3, crBlack, crBlack, LineSolid);
-  hbrHist[2] = CreateGC(3, "#E0E0F0", "#E0E0F0", LineSolid);; // background (a bit blueish, for contrst with yellow curve)
+  if(w == 0) {
+    Arg args[10];
+    XtSetArg(args[0], XtNwidth, &evalGraphW);
+    XtSetArg(args[1], XtNheight, &evalGraphH);
+    XtGetValues(opt->handle, args, 2);
+    nWidthPB = evalGraphW; nHeightPB = evalGraphH;
+  } else nWidthPB = w, nHeightPB = h;
 
   initDone = TRUE;
 }
 
 // The following stuff is really back-end (but too little to bother with a separate file)
 
+static void
+EvalClick (int x, int y)
+{
+    int index = GetMoveIndexFromPoint( x, y );
+
+    if( index >= 0 && index < currLast ) ToNrEvent( index + 1 );
+}
+
+static Option graphOptions[] = {
+{ 150, 0x9C, 300, NULL, (void*) &EvalCallback, NULL, NULL, Graph , "" },
+{ 0, 2, 0, NULL, NULL, "", NULL, EndMark , "" }
+};
+
 static void
 DisplayEvalGraph ()
 {   // back-end painting; calls back front-end primitives for lines, rectangles and text
     char *t = MakeEvalTitle(_(title));
+    nWidthPB = disp->max; nHeightPB = disp->value;
     if(t != title && nWidthPB < 340) t = MakeEvalTitle(nWidthPB < 240 ? "" : _("Eval"));
     PaintEvalGraph();
+    GraphExpose(graphOptions, 0, 0, nWidthPB, nHeightPB);
     SetDialogTitle(EvalGraphDlg, t);
 }
 
-static void
-EvalClick (int x, int y)
-{
-    int index = GetMoveIndexFromPoint( x, y );
-
-    if( index >= 0 && index < currLast ) ToNrEvent( index + 1 );
-}
-
 static Option *
 EvalCallback (int button, int x, int y)
 {
@@ -217,6 +265,9 @@ EvalCallback (int button, int x, int y)
     switch(button) {
        case 10: // expose event
            /* Create or recreate paint box if needed */
+           if(x != nWidthPB || y != nHeightPB) {
+               InitializeEvalGraph(&graphOptions[0], x, y);
+           }
            nWidthPB = x;
            nHeightPB = y;
            DisplayEvalGraph();
@@ -227,16 +278,12 @@ EvalCallback (int button, int x, int y)
     return NULL; // no context menu!
 }
 
-static Option graphOptions[] = {
-{ 150, 0x9C, 300, NULL, (void*) &EvalCallback, NULL, NULL, Graph , "" },
-{ 0, 2, 0, NULL, NULL, "", NULL, EndMark , "" }
-};
-
 void
 EvalGraphPopUp ()
 {
     if (GenericPopUp(graphOptions, _(title), EvalGraphDlg, BoardWindow, NONMODAL, 1)) {
-       InitializeEvalGraph(&graphOptions[0]); // first time: add callbacks and initialize pens
+       InitializeEvalGraph(&graphOptions[0], 0, 0); // first time: add callbacks and initialize pens
+       disp = graphOptions;
     } else {
        SetDialogTitle(EvalGraphDlg, _(title));
        SetIconName(EvalGraphDlg, _(title));