Always render svg pieces anew on size change
authorH.G. Muller <h.g.muller@hccnet.nl>
Tue, 9 Oct 2012 12:56:16 +0000 (14:56 +0200)
committerH.G. Muller <h.g.muller@hccnet.nl>
Sun, 21 Oct 2012 09:28:21 +0000 (11:28 +0200)
The svg pieces are now unconditionally rendered to supply the pngPieceImage
master source otherwise read from png file. This is then fed into the
original png code (so that if for some reason it fails, we fall back on png
pieces, and finally on built-in pixmaps).

args.h
common.h
dialogs.c
draw.c

diff --git a/args.h b/args.h
index 1890830..d4f8683 100644 (file)
--- a/args.h
+++ b/args.h
@@ -213,6 +213,8 @@ ArgDescriptor argDescriptors[] = {
   { "flashRate", ArgInt, (void *) &appData.flashRate, XBOARD, (ArgIniType) FLASH_RATE },
   { "pngDirectory", ArgFilename, (void *) &appData.pngDirectory, XBOARD, (ArgIniType) "" },
   { "png", ArgFilename, (void *) &appData.pngDirectory, FALSE, INVALID },
+  { "svgDirectory", ArgFilename, (void *) &appData.svgDirectory, XBOARD, (ArgIniType) "" },
+  { "svg", ArgFilename, (void *) &appData.svgDirectory, FALSE, INVALID },
   { "soundDirectory", ArgFilename, (void *) &appData.soundDirectory, XBOARD, (ArgIniType) "" },
   { "msLoginDelay", ArgInt, (void *) &appData.msLoginDelay, XBOARD, (ArgIniType) MS_LOGIN_DELAY },
   { "pasteSelection", ArgBoolean, (void *) &appData.pasteSelection, XBOARD, (ArgIniType) FALSE },
index d41851d..2044c03 100644 (file)
--- a/common.h
+++ b/common.h
@@ -409,6 +409,7 @@ typedef struct {
     Boolean noChessProgram;
     char *host[ENGINES];
     char *pngDirectory;
+    char *svgDirectory;
     char *soundDirectory;
     char *remoteShell;
     char *remoteUser;
index 7659f5b..42e6379 100644 (file)
--- a/dialogs.c
+++ b/dialogs.c
@@ -753,12 +753,13 @@ static void DefColor P((int n));
 static void AdjustColor P((int i));
 
 static char oldPngDir[MSG_SIZ];
+static char oldSvgDir[MSG_SIZ];
 
 static int
 BoardOptionsOK (int n)
 {
     if(appData.overrideLineGap >= 0) lineGap = appData.overrideLineGap; else lineGap = defaultLineGap;
-    InitDrawingParams(strcmp(oldPngDir, appData.pngDirectory));
+    InitDrawingParams(strcmp(oldPngDir, appData.pngDirectory) || strcmp(oldSvgDir, appData.svgDirectory));
     InitDrawingSizes(-1, 0);
     DrawPosition(True, NULL);
     return 1;
@@ -813,6 +814,7 @@ static Option boardOptions[] = {
 { 0, 0, 0, NULL, (void*) &appData.liteBackTextureFile, ".xpm", NULL, FileName, N_("Light-Squares Texture File:") },
 { 0, 0, 0, NULL, (void*) &appData.darkBackTextureFile, ".xpm", NULL, FileName, N_("Dark-Squares Texture File:") },
 { 0, 0, 0, NULL, (void*) &appData.pngDirectory, "", NULL, PathName, N_("Directory with PNG Pieces:") },
+{ 0, 0, 0, NULL, (void*) &appData.svgDirectory, "", NULL, PathName, N_("Directory with SVG Pieces:") },
 { 0, 0, 0, NULL, (void*) &BoardOptionsOK, "", NULL, EndMark , "" }
 };
 
@@ -862,6 +864,7 @@ void
 BoardOptionsProc ()
 {
    strncpy(oldPngDir, appData.pngDirectory, MSG_SIZ-1); // to see if it changed
+   strncpy(oldSvgDir, appData.svgDirectory, MSG_SIZ-1); // to see if it changed
    GenericPopUp(boardOptions, _("Board Options"), TransientDlg, BoardWindow, MODAL, 0);
 }
 
diff --git a/draw.c b/draw.c
index 200d05a..da0c4d2 100644 (file)
--- a/draw.c
+++ b/draw.c
@@ -268,33 +268,35 @@ ScaleOnePiece (char *name, int color, int piece)
   GError **svgerror=NULL;
   cairo_surface_t *img, *cs;
   cairo_t *cr;
-  int stride = squareSize * 4;
-  double scale;
 
   g_type_init ();
 
-  if((img = pngPieceImages[color][piece]) == NULL) { // if PNG file for this piece was not yet read, read it now and store it
-    if(!*appData.pngDirectory) img = ConvertPixmap(color, piece); else {
-      snprintf(buf, MSG_SIZ, "%s/%s%s.svg", appData.pngDirectory, color ? "Black" : "White", pngPieceNames[piece]);
+  if(*appData.svgDirectory) { // try to freshly render svg pieces first, always from file, to supply the source bitmap
+    snprintf(buf, MSG_SIZ, "%s/%s%s.svg", appData.svgDirectory, color ? "Black" : "White", pngPieceNames[piece]);
 
-      svg = rsvg_handle_new ();
-      svg = rsvg_handle_new_from_file(buf,svgerror);
+    if(svg = rsvg_handle_new_from_file(buf,svgerror)) {
 
       rsvg_handle_get_dimensions(svg, &svg_dimensions);
+      img = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, squareSize,  squareSize);
 
-      unsigned char* cairo_data =(unsigned char *) calloc(stride * squareSize, 1);
-      img = cairo_image_surface_create_for_data(cairo_data, CAIRO_FORMAT_ARGB32, squareSize,  squareSize, stride);
-
-      cairo_t *cr_svg = cairo_create(img);
+      cr = cairo_create(img);
+      cairo_scale(cr, squareSize/(double) svg_dimensions.width, squareSize/(double) svg_dimensions.height);
+      rsvg_handle_render_cairo(svg, cr);
+      if(cairo_surface_status(img) == CAIRO_STATUS_SUCCESS) {
+        if(pngPieceImages[color][piece]) cairo_surface_destroy(pngPieceImages[color][piece]);
+        pngPieceImages[color][piece] = img;
+      }
+      cairo_destroy(cr);
 
-      scale = (double) squareSize/(double) svg_dimensions.height;
-      cairo_scale(cr_svg, scale,scale);
-      cairo_set_antialias (cr_svg, CAIRO_ANTIALIAS_NONE);
-      rsvg_handle_render_cairo(svg, cr_svg);
+      rsvg_handle_close (svg,NULL);
+    }
+  }
 
+  if((img = pngPieceImages[color][piece]) == NULL) { // if PNG file for this piece was not yet read, read it now and store it
+    if(!*appData.pngDirectory) img = ConvertPixmap(color, piece); else {
+      snprintf(buf, MSG_SIZ, "%s/%s%s.png", appData.pngDirectory, color ? "Black" : "White", pngPieceNames[piece]);
+      img = cairo_image_surface_create_from_png (buf);
       if(cairo_surface_status(img) != CAIRO_STATUS_SUCCESS) img = ConvertPixmap(color, piece);
-
-      rsvg_handle_close (svg,NULL);
     }
   }
   pngPieceImages[color][piece] = img;