--- nanosvgrast.h	2017-08-31 16:22:55.325553338 +0200
+++ altsvgrast.h	2017-08-31 16:19:09.581553338 +0200
@@ -1,3 +1,6 @@
+
+/* Modified from original sources! */
+
 /*
  * Copyright (c) 2013-14 Mikko Mononen memon@inside.org
  *
@@ -22,6 +25,10 @@
  *
  */
 
+ /*
+  * CAUTION: This version modified to support non-square X,Y axes scaling.
+  */
+
 #ifndef NANOSVGRAST_H
 #define NANOSVGRAST_H
 
@@ -41,6 +48,9 @@
 	unsigned char* img = malloc(w*h*4);
 	// Rasterize
 	nsvgRasterize(rast, image, 0,0,1, img, w, h, w*4);
+
+	// For non-square X,Y scaling, use
+	nsvgAltRasterize(rast, image, 0,0,1,1, img, w, h, w*4);
 */
 
 // Allocated rasterizer context.
@@ -50,7 +60,7 @@
 //   r - pointer to rasterizer context
 //   image - pointer to image to rasterize
 //   tx,ty - image offset (applied after scaling)
-//   scale - image scale
+//   scale - image scale (assumes square aspect ratio)
 //   dst - pointer to destination image data, 4 bytes per pixel (RGBA)
 //   w - width of the image to render
 //   h - height of the image to render
@@ -59,6 +69,12 @@
 				   NSVGimage* image, float tx, float ty, float scale,
 				   unsigned char* dst, int w, int h, int stride);
 
+// As above, but allow X and Y axes to scale independently for non-square aspects
+void nsvgAltRasterize(NSVGrasterizer* r,
+				   NSVGimage* image, float tx, float ty,
+				   float sx, float sy,
+				   unsigned char* dst, int w, int h, int stride);
+
 // Deletes rasterizer context.
 void nsvgDeleteRasterizer(NSVGrasterizer*);
 
@@ -363,7 +379,7 @@
 	nsvg__flattenCubicBez(r, x1234,y1234, x234,y234, x34,y34, x4,y4, level+1, type);
 }
 
-static void nsvg__flattenShape(NSVGrasterizer* r, NSVGshape* shape, float scale)
+static void nsvg__flattenShape(NSVGrasterizer* r, NSVGshape* shape, float sx, float sy)
 {
 	int i, j;
 	NSVGpath* path;
@@ -371,13 +387,13 @@
 	for (path = shape->paths; path != NULL; path = path->next) {
 		r->npoints = 0;
 		// Flatten path
-		nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0);
+		nsvg__addPathPoint(r, path->pts[0]*sx, path->pts[1]*sy, 0);
 		for (i = 0; i < path->npts-1; i += 3) {
 			float* p = &path->pts[i*2];
-			nsvg__flattenCubicBez(r, p[0]*scale,p[1]*scale, p[2]*scale,p[3]*scale, p[4]*scale,p[5]*scale, p[6]*scale,p[7]*scale, 0, 0);
+			nsvg__flattenCubicBez(r, p[0]*sx,p[1]*sy, p[2]*sx,p[3]*sy, p[4]*sx,p[5]*sy, p[6]*sx,p[7]*sy, 0, 0);
 		}
 		// Close path
-		nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0);
+		nsvg__addPathPoint(r, path->pts[0]*sx, path->pts[1]*sy, 0);
 		// Build edges
 		for (i = 0, j = r->npoints-1; i < r->npoints; j = i++)
 			nsvg__addEdge(r, r->points[j].x, r->points[j].y, r->points[i].x, r->points[i].y);
@@ -727,7 +743,7 @@
 	}
 }
 
-static void nsvg__flattenShapeStroke(NSVGrasterizer* r, NSVGshape* shape, float scale)
+static void nsvg__flattenShapeStroke(NSVGrasterizer* r, NSVGshape* shape, float sx, float sy)
 {
 	int i, j, closed;
 	NSVGpath* path;
@@ -735,15 +751,16 @@
 	float miterLimit = shape->miterLimit;
 	int lineJoin = shape->strokeLineJoin;
 	int lineCap = shape->strokeLineCap;
-	float lineWidth = shape->strokeWidth * scale;
+	const float sw = (sx + sy) / 2; // average scaling factor
+	const float lineWidth = shape->strokeWidth * sw; // FIXME (?)
 
 	for (path = shape->paths; path != NULL; path = path->next) {
 		// Flatten path
 		r->npoints = 0;
-		nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, NSVG_PT_CORNER);
+		nsvg__addPathPoint(r, path->pts[0]*sx, path->pts[1]*sy, NSVG_PT_CORNER);
 		for (i = 0; i < path->npts-1; i += 3) {
 			float* p = &path->pts[i*2];
-			nsvg__flattenCubicBez(r, p[0]*scale,p[1]*scale, p[2]*scale,p[3]*scale, p[4]*scale,p[5]*scale, p[6]*scale,p[7]*scale, 0, NSVG_PT_CORNER);
+			nsvg__flattenCubicBez(r, p[0]*sx,p[1]*sy, p[2]*sx,p[3]*sy, p[4]*sx,p[5]*sy, p[6]*sx,p[7]*sy, 0, NSVG_PT_CORNER);
 		}
 		if (r->npoints < 2)
 			continue;
@@ -789,7 +806,7 @@
 				dashOffset -= shape->strokeDashArray[idash];
 				idash = (idash + 1) % shape->strokeDashCount;
 			}
-			dashLen = (shape->strokeDashArray[idash] - dashOffset) * scale;
+			dashLen = (shape->strokeDashArray[idash] - dashOffset) * sw;
 
 			for (j = 1; j < r->npoints2; ) {
 				float dx = r->points2[j].x - cur.x;
@@ -811,7 +828,7 @@
 					// Advance dash pattern
 					dashState = !dashState;
 					idash = (idash+1) % shape->strokeDashCount;
-					dashLen = shape->strokeDashArray[idash] * scale;
+					dashLen = shape->strokeDashArray[idash] * sw;
 					// Restart
 					cur.x = x;
 					cur.y = y;
@@ -980,7 +997,7 @@
 }
 
 static void nsvg__scanlineSolid(unsigned char* dst, int count, unsigned char* cover, int x, int y,
-								float tx, float ty, float scale, NSVGcachedPaint* cache)
+								float tx, float ty, float sx, float sy, NSVGcachedPaint* cache)
 {
 
 	if (cache->type == NSVG_PAINT_COLOR) {
@@ -1021,9 +1038,9 @@
 		int i, cr, cg, cb, ca;
 		unsigned int c;
 
-		fx = ((float)x - tx) / scale;
-		fy = ((float)y - ty) / scale;
-		dx = 1.0f / scale;
+		fx = ((float)x - tx) / sx;
+		fy = ((float)y - ty) / sy;
+		dx = 1.0f / sx;
 
 		for (i = 0; i < count; i++) {
 			int r,g,b,a,ia;
@@ -1066,9 +1083,9 @@
 		int i, cr, cg, cb, ca;
 		unsigned int c;
 
-		fx = ((float)x - tx) / scale;
-		fy = ((float)y - ty) / scale;
-		dx = 1.0f / scale;
+		fx = ((float)x - tx) / sx;
+		fy = ((float)y - ty) / sy;
+		dx = 1.0f / sx;
 
 		for (i = 0; i < count; i++) {
 			int r,g,b,a,ia;
@@ -1107,7 +1124,7 @@
 	}
 }
 
-static void nsvg__rasterizeSortedEdges(NSVGrasterizer *r, float tx, float ty, float scale, NSVGcachedPaint* cache, char fillRule)
+static void nsvg__rasterizeSortedEdges(NSVGrasterizer *r, float tx, float ty, float sx, float sy, NSVGcachedPaint* cache, char fillRule)
 {
 	NSVGactiveEdge *active = NULL;
 	int y, s;
@@ -1189,7 +1206,7 @@
 		if (xmin < 0) xmin = 0;
 		if (xmax > r->width-1) xmax = r->width-1;
 		if (xmin <= xmax) {
-			nsvg__scanlineSolid(&r->bitmap[y * r->stride] + xmin*4, xmax-xmin+1, &r->scanline[xmin], xmin, y, tx,ty, scale, cache);
+			nsvg__scanlineSolid(&r->bitmap[y * r->stride] + xmin*4, xmax-xmin+1, &r->scanline[xmin], xmin, y, tx,ty, sx, sy, cache);
 		}
 	}
 
@@ -1357,8 +1374,9 @@
 }
 */
 
-void nsvgRasterize(NSVGrasterizer* r,
-				   NSVGimage* image, float tx, float ty, float scale,
+void nsvgAltRasterize(NSVGrasterizer* r,
+				   NSVGimage* image, float tx, float ty,
+				   float sx, float sy,
 				   unsigned char* dst, int w, int h, int stride)
 {
 	NSVGshape *shape = NULL;
@@ -1389,7 +1407,7 @@
 			r->freelist = NULL;
 			r->nedges = 0;
 
-			nsvg__flattenShape(r, shape, scale);
+			nsvg__flattenShape(r, shape, sx, sy);
 
 			// Scale and translate edges
 			for (i = 0; i < r->nedges; i++) {
@@ -1406,14 +1424,14 @@
 			// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
 			nsvg__initPaint(&cache, &shape->fill, shape->opacity);
 
-			nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache, shape->fillRule);
+			nsvg__rasterizeSortedEdges(r, tx,ty, sx, sy, &cache, shape->fillRule);
 		}
-		if (shape->stroke.type != NSVG_PAINT_NONE && (shape->strokeWidth * scale) > 0.01f) {
+		if (shape->stroke.type != NSVG_PAINT_NONE && (shape->strokeWidth * sx) > 0.01f) {
 			nsvg__resetPool(r);
 			r->freelist = NULL;
 			r->nedges = 0;
 
-			nsvg__flattenShapeStroke(r, shape, scale);
+			nsvg__flattenShapeStroke(r, shape, sx, sy);
 
 //			dumpEdges(r, "edge.svg");
 
@@ -1432,7 +1450,7 @@
 			// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
 			nsvg__initPaint(&cache, &shape->stroke, shape->opacity);
 
-			nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache, NSVG_FILLRULE_NONZERO);
+			nsvg__rasterizeSortedEdges(r, tx,ty,sx, sy, &cache, NSVG_FILLRULE_NONZERO);
 		}
 	}
 
@@ -1444,4 +1462,11 @@
 	r->stride = 0;
 }
 
+void nsvgRasterize(NSVGrasterizer* r,
+				   NSVGimage* image, float tx, float ty, float scale,
+				   unsigned char* dst, int w, int h, int stride)
+{
+	nsvgAltRasterize(r,image, tx, ty, scale, scale, dst, w, h, stride);
+}
+
 #endif
