mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 08:01:30 -07:00
js: keep colour strings in JavaScript rather than in C
The drawing routines in JavaScript used to take pointers to a C string containing a CSS colour name. That meant that JavaScript had to create a new JavaScript string on ever call to a drawing function, which seemed ugly. So now we instead pass colour numbers all the way down into JavaScript and keep an array of JavaScript strings there that can be re-used. The conversion from RGB triples to strings is still done in C, though. This doesn't seem to have fixed either of the bugs I hoped it would, but it does measurably improve drawing performance so I think it's worth doing.
This commit is contained in:
44
emcc.c
44
emcc.c
@ -54,7 +54,7 @@ extern int js_add_preset_submenu(int menuid, const char *name);
|
|||||||
extern int js_get_selected_preset(void);
|
extern int js_get_selected_preset(void);
|
||||||
extern void js_select_preset(int n);
|
extern void js_select_preset(int n);
|
||||||
extern void js_default_colour(float *output);
|
extern void js_default_colour(float *output);
|
||||||
extern void js_set_background_colour(const char *bg);
|
extern void js_set_colour(int colour_number, const char *colour_string);
|
||||||
extern void js_get_date_64(unsigned *p);
|
extern void js_get_date_64(unsigned *p);
|
||||||
extern void js_update_permalinks(const char *desc, const char *seed);
|
extern void js_update_permalinks(const char *desc, const char *seed);
|
||||||
extern void js_enable_undo_redo(bool undo, bool redo);
|
extern void js_enable_undo_redo(bool undo, bool redo);
|
||||||
@ -64,21 +64,18 @@ extern void js_deactivate_timer(void);
|
|||||||
extern void js_canvas_start_draw(void);
|
extern void js_canvas_start_draw(void);
|
||||||
extern void js_canvas_draw_update(int x, int y, int w, int h);
|
extern void js_canvas_draw_update(int x, int y, int w, int h);
|
||||||
extern void js_canvas_end_draw(void);
|
extern void js_canvas_end_draw(void);
|
||||||
extern void js_canvas_draw_rect(int x, int y, int w, int h,
|
extern void js_canvas_draw_rect(int x, int y, int w, int h, int colour);
|
||||||
const char *colour);
|
|
||||||
extern void js_canvas_clip_rect(int x, int y, int w, int h);
|
extern void js_canvas_clip_rect(int x, int y, int w, int h);
|
||||||
extern void js_canvas_unclip(void);
|
extern void js_canvas_unclip(void);
|
||||||
extern void js_canvas_draw_line(float x1, float y1, float x2, float y2,
|
extern void js_canvas_draw_line(float x1, float y1, float x2, float y2,
|
||||||
int width, const char *colour);
|
int width, int colour);
|
||||||
extern void js_canvas_draw_poly(const int *points, int npoints,
|
extern void js_canvas_draw_poly(const int *points, int npoints,
|
||||||
const char *fillcolour,
|
int fillcolour, int outlinecolour);
|
||||||
const char *outlinecolour);
|
|
||||||
extern void js_canvas_draw_circle(int x, int y, int r,
|
extern void js_canvas_draw_circle(int x, int y, int r,
|
||||||
const char *fillcolour,
|
int fillcolour, int outlinecolour);
|
||||||
const char *outlinecolour);
|
|
||||||
extern int js_canvas_find_font_midpoint(int height, bool monospaced);
|
extern int js_canvas_find_font_midpoint(int height, bool monospaced);
|
||||||
extern void js_canvas_draw_text(int x, int y, int halign,
|
extern void js_canvas_draw_text(int x, int y, int halign,
|
||||||
const char *colptr, int height,
|
int colour, int height,
|
||||||
bool monospaced, const char *text);
|
bool monospaced, const char *text);
|
||||||
extern int js_canvas_new_blitter(int w, int h);
|
extern int js_canvas_new_blitter(int w, int h);
|
||||||
extern void js_canvas_free_blitter(int id);
|
extern void js_canvas_free_blitter(int id);
|
||||||
@ -184,12 +181,6 @@ static int strnullcmp(const char *a, const char *b)
|
|||||||
return strcmp(a, b);
|
return strcmp(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* HTMLish names for the colours allocated by the puzzle.
|
|
||||||
*/
|
|
||||||
static char **colour_strings;
|
|
||||||
static int ncolours;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The global midend object.
|
* The global midend object.
|
||||||
*/
|
*/
|
||||||
@ -497,42 +488,38 @@ static void js_draw_text(void *handle, int x, int y, int fonttype,
|
|||||||
else
|
else
|
||||||
halign = 0;
|
halign = 0;
|
||||||
|
|
||||||
js_canvas_draw_text(x, y, halign, colour_strings[colour],
|
js_canvas_draw_text(x, y, halign, colour,
|
||||||
fontsize, fonttype == FONT_FIXED, text);
|
fontsize, fonttype == FONT_FIXED, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void js_draw_rect(void *handle, int x, int y, int w, int h, int colour)
|
static void js_draw_rect(void *handle, int x, int y, int w, int h, int colour)
|
||||||
{
|
{
|
||||||
js_canvas_draw_rect(x, y, w, h, colour_strings[colour]);
|
js_canvas_draw_rect(x, y, w, h, colour);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void js_draw_line(void *handle, int x1, int y1, int x2, int y2,
|
static void js_draw_line(void *handle, int x1, int y1, int x2, int y2,
|
||||||
int colour)
|
int colour)
|
||||||
{
|
{
|
||||||
js_canvas_draw_line(x1, y1, x2, y2, 1, colour_strings[colour]);
|
js_canvas_draw_line(x1, y1, x2, y2, 1, colour);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void js_draw_thick_line(void *handle, float thickness,
|
static void js_draw_thick_line(void *handle, float thickness,
|
||||||
float x1, float y1, float x2, float y2,
|
float x1, float y1, float x2, float y2,
|
||||||
int colour)
|
int colour)
|
||||||
{
|
{
|
||||||
js_canvas_draw_line(x1, y1, x2, y2, thickness, colour_strings[colour]);
|
js_canvas_draw_line(x1, y1, x2, y2, thickness, colour);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void js_draw_poly(void *handle, const int *coords, int npoints,
|
static void js_draw_poly(void *handle, const int *coords, int npoints,
|
||||||
int fillcolour, int outlinecolour)
|
int fillcolour, int outlinecolour)
|
||||||
{
|
{
|
||||||
js_canvas_draw_poly(coords, npoints,
|
js_canvas_draw_poly(coords, npoints, fillcolour, outlinecolour);
|
||||||
fillcolour >= 0 ? colour_strings[fillcolour] : NULL,
|
|
||||||
colour_strings[outlinecolour]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void js_draw_circle(void *handle, int cx, int cy, int radius,
|
static void js_draw_circle(void *handle, int cx, int cy, int radius,
|
||||||
int fillcolour, int outlinecolour)
|
int fillcolour, int outlinecolour)
|
||||||
{
|
{
|
||||||
js_canvas_draw_circle(cx, cy, radius,
|
js_canvas_draw_circle(cx, cy, radius, fillcolour, outlinecolour);
|
||||||
fillcolour >= 0 ? colour_strings[fillcolour] : NULL,
|
|
||||||
colour_strings[outlinecolour]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct blitter {
|
struct blitter {
|
||||||
@ -1035,7 +1022,7 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
const char *param_err;
|
const char *param_err;
|
||||||
float *colours;
|
float *colours;
|
||||||
int i;
|
int i, ncolours;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialise JavaScript event handlers.
|
* Initialise JavaScript event handlers.
|
||||||
@ -1118,17 +1105,14 @@ int main(int argc, char **argv)
|
|||||||
* hex ID strings.
|
* hex ID strings.
|
||||||
*/
|
*/
|
||||||
colours = midend_colours(me, &ncolours);
|
colours = midend_colours(me, &ncolours);
|
||||||
colour_strings = snewn(ncolours, char *);
|
|
||||||
for (i = 0; i < ncolours; i++) {
|
for (i = 0; i < ncolours; i++) {
|
||||||
char col[40];
|
char col[40];
|
||||||
sprintf(col, "#%02x%02x%02x",
|
sprintf(col, "#%02x%02x%02x",
|
||||||
(unsigned)(0.5F + 255 * colours[i*3+0]),
|
(unsigned)(0.5F + 255 * colours[i*3+0]),
|
||||||
(unsigned)(0.5F + 255 * colours[i*3+1]),
|
(unsigned)(0.5F + 255 * colours[i*3+1]),
|
||||||
(unsigned)(0.5F + 255 * colours[i*3+2]));
|
(unsigned)(0.5F + 255 * colours[i*3+2]));
|
||||||
colour_strings[i] = dupstr(col);
|
js_set_colour(i, col);
|
||||||
}
|
}
|
||||||
/* Put the background colour in a CSS variable. */
|
|
||||||
js_set_background_colour(colour_strings[0]);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Request notification when the game ids change (e.g. if the user
|
* Request notification when the game ids change (e.g. if the user
|
||||||
|
46
emcclib.js
46
emcclib.js
@ -181,14 +181,15 @@ mergeInto(LibraryManager.library, {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* void js_set_background_colour(const char *bg);
|
* void js_set_colour(int colour_number, char const *colour_string);
|
||||||
*
|
*
|
||||||
* Record the puzzle background colour in a CSS variable so
|
* Record a colour string used by the puzzle.
|
||||||
* the style sheet can use it if it wants.
|
|
||||||
*/
|
*/
|
||||||
js_set_background_colour: function(bgptr) {
|
js_set_colour: function(colour_number, colour_string) {
|
||||||
document.documentElement.style.setProperty("--puzzle-background",
|
colours[colour_number] = UTF8ToString(colour_string);
|
||||||
UTF8ToString(bgptr));
|
if (colour_number == 0)
|
||||||
|
document.documentElement.style.setProperty("--puzzle-background",
|
||||||
|
colours[colour_number]);
|
||||||
},
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -332,13 +333,12 @@ mergeInto(LibraryManager.library, {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* void js_canvas_draw_rect(int x, int y, int w, int h,
|
* void js_canvas_draw_rect(int x, int y, int w, int h, int colour);
|
||||||
* const char *colour);
|
|
||||||
*
|
*
|
||||||
* Draw a rectangle.
|
* Draw a rectangle.
|
||||||
*/
|
*/
|
||||||
js_canvas_draw_rect: function(x, y, w, h, colptr) {
|
js_canvas_draw_rect: function(x, y, w, h, colour) {
|
||||||
ctx.fillStyle = UTF8ToString(colptr);
|
ctx.fillStyle = colours[colour];
|
||||||
ctx.fillRect(x, y, w, h);
|
ctx.fillRect(x, y, w, h);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -365,7 +365,7 @@ mergeInto(LibraryManager.library, {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* void js_canvas_draw_line(float x1, float y1, float x2, float y2,
|
* void js_canvas_draw_line(float x1, float y1, float x2, float y2,
|
||||||
* int width, const char *colour);
|
* int width, int colour);
|
||||||
*
|
*
|
||||||
* Draw a line. We must adjust the coordinates by 0.5 because
|
* Draw a line. We must adjust the coordinates by 0.5 because
|
||||||
* Javascript's canvas coordinates appear to be pixel corners,
|
* Javascript's canvas coordinates appear to be pixel corners,
|
||||||
@ -375,7 +375,7 @@ mergeInto(LibraryManager.library, {
|
|||||||
* Postscriptish drawing frameworks).
|
* Postscriptish drawing frameworks).
|
||||||
*/
|
*/
|
||||||
js_canvas_draw_line: function(x1, y1, x2, y2, width, colour) {
|
js_canvas_draw_line: function(x1, y1, x2, y2, width, colour) {
|
||||||
colour = UTF8ToString(colour);
|
colour = colours[colour];
|
||||||
|
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(x1 + 0.5, y1 + 0.5);
|
ctx.moveTo(x1 + 0.5, y1 + 0.5);
|
||||||
@ -392,8 +392,7 @@ mergeInto(LibraryManager.library, {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* void js_canvas_draw_poly(int *points, int npoints,
|
* void js_canvas_draw_poly(int *points, int npoints,
|
||||||
* const char *fillcolour,
|
* int fillcolour, int outlinecolour);
|
||||||
* const char *outlinecolour);
|
|
||||||
*
|
*
|
||||||
* Draw a polygon.
|
* Draw a polygon.
|
||||||
*/
|
*/
|
||||||
@ -405,35 +404,34 @@ mergeInto(LibraryManager.library, {
|
|||||||
ctx.lineTo(getValue(pointptr+8*i , 'i32') + 0.5,
|
ctx.lineTo(getValue(pointptr+8*i , 'i32') + 0.5,
|
||||||
getValue(pointptr+8*i+4, 'i32') + 0.5);
|
getValue(pointptr+8*i+4, 'i32') + 0.5);
|
||||||
ctx.closePath();
|
ctx.closePath();
|
||||||
if (fill != 0) {
|
if (fill >= 0) {
|
||||||
ctx.fillStyle = UTF8ToString(fill);
|
ctx.fillStyle = colours[fill];
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
}
|
}
|
||||||
ctx.lineWidth = '1';
|
ctx.lineWidth = '1';
|
||||||
ctx.lineCap = 'round';
|
ctx.lineCap = 'round';
|
||||||
ctx.lineJoin = 'round';
|
ctx.lineJoin = 'round';
|
||||||
ctx.strokeStyle = UTF8ToString(outline);
|
ctx.strokeStyle = colours[outline];
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
},
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* void js_canvas_draw_circle(int x, int y, int r,
|
* void js_canvas_draw_circle(int x, int y, int r,
|
||||||
* const char *fillcolour,
|
* int fillcolour, int outlinecolour);
|
||||||
* const char *outlinecolour);
|
|
||||||
*
|
*
|
||||||
* Draw a circle.
|
* Draw a circle.
|
||||||
*/
|
*/
|
||||||
js_canvas_draw_circle: function(x, y, r, fill, outline) {
|
js_canvas_draw_circle: function(x, y, r, fill, outline) {
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(x + 0.5, y + 0.5, r, 0, 2*Math.PI);
|
ctx.arc(x + 0.5, y + 0.5, r, 0, 2*Math.PI);
|
||||||
if (fill != 0) {
|
if (fill >= 0) {
|
||||||
ctx.fillStyle = UTF8ToString(fill);
|
ctx.fillStyle = colours[fill];
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
}
|
}
|
||||||
ctx.lineWidth = '1';
|
ctx.lineWidth = '1';
|
||||||
ctx.lineCap = 'round';
|
ctx.lineCap = 'round';
|
||||||
ctx.lineJoin = 'round';
|
ctx.lineJoin = 'round';
|
||||||
ctx.strokeStyle = UTF8ToString(outline);
|
ctx.strokeStyle = colours[outline];
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -518,10 +516,10 @@ mergeInto(LibraryManager.library, {
|
|||||||
* alignment is handled here, since we can get the canvas draw
|
* alignment is handled here, since we can get the canvas draw
|
||||||
* function to do it for us with almost no extra effort.
|
* function to do it for us with almost no extra effort.
|
||||||
*/
|
*/
|
||||||
js_canvas_draw_text: function(x, y, halign, colptr, fontsize, monospaced,
|
js_canvas_draw_text: function(x, y, halign, colour, fontsize, monospaced,
|
||||||
text) {
|
text) {
|
||||||
canvas_set_font(ctx, fontsize, monospaced);
|
canvas_set_font(ctx, fontsize, monospaced);
|
||||||
ctx.fillStyle = UTF8ToString(colptr);
|
ctx.fillStyle = colours[colour];
|
||||||
ctx.textAlign = (halign == 0 ? 'left' :
|
ctx.textAlign = (halign == 0 ? 'left' :
|
||||||
halign == 1 ? 'center' : 'right');
|
halign == 1 ? 'center' : 'right');
|
||||||
ctx.textBaseline = 'alphabetic';
|
ctx.textBaseline = 'alphabetic';
|
||||||
|
@ -41,6 +41,10 @@ var ctx;
|
|||||||
// by js_canvas_end_draw.
|
// by js_canvas_end_draw.
|
||||||
var update_xmin, update_xmax, update_ymin, update_ymax;
|
var update_xmin, update_xmax, update_ymin, update_ymax;
|
||||||
|
|
||||||
|
// Colour strings to use when drawing, to save converting them from C
|
||||||
|
// every time.
|
||||||
|
var colours = [];
|
||||||
|
|
||||||
// Module object for Emscripten. We fill in these parameters to ensure
|
// Module object for Emscripten. We fill in these parameters to ensure
|
||||||
// that when main() returns nothing will get cleaned up so we remain
|
// that when main() returns nothing will get cleaned up so we remain
|
||||||
// able to call the puzzle's various callbacks.
|
// able to call the puzzle's various callbacks.
|
||||||
|
Reference in New Issue
Block a user