From 277e65ddddebb5aea0196239be835a6d3e1d1b2c Mon Sep 17 00:00:00 2001 From: tehn Date: Thu, 23 Mar 2023 22:38:00 +0000 Subject: [PATCH] export png --- lua/core/screen.lua | 4 ++++ matron/src/hardware/screen.c | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/lua/core/screen.lua b/lua/core/screen.lua index 7903a3add..d4de20c32 100644 --- a/lua/core/screen.lua +++ b/lua/core/screen.lua @@ -309,6 +309,10 @@ _norns.screen_circle = function(x, y, r) _norns.screen_arc(x, y, r, 0, math.pi*2) end +--- export png +-- @param filename: saved to dust/data/(script)/(filename).png +Screen.export_png = function(filename) _norns.screen_export_png(norns.state.data..filename..'.png') end + --- display png -- @param filename -- @tparam number x x position diff --git a/matron/src/hardware/screen.c b/matron/src/hardware/screen.c index d0cf86e04..6eaf43d15 100644 --- a/matron/src/hardware/screen.c +++ b/matron/src/hardware/screen.c @@ -396,7 +396,38 @@ double *screen_text_extents(const char *s) { extern void screen_export_png(const char *s) { CHECK_CR - cairo_surface_write_to_png(surface, s); + static cairo_surface_t *png; + static cairo_t *temp; // for bg fill + // width = 640 (128*4 pixels with 64 pixel black border) + // hieght = 384 (64*4 pixels plus border) + png = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 640, 384); + temp = cairo_create(png); + // fill + cairo_set_source_rgb(temp, 0, 0, 0); + cairo_rectangle(temp, 0, 0, 640, 384); + cairo_fill(temp); + // copy big pixles + uint32_t *src = (uint32_t *)cairo_image_surface_get_data(surface); + uint32_t *dst = (uint32_t *)cairo_image_surface_get_data(png); + if (!src || !dst) return; + dst += 64 + 640*64; + for(int y=0;y<64;y++) { + for(int x=0;x<128;x++) { + // FIXME: needs some sort of gamma correction? + uint32_t p = *src++ | 0xFF000000; // FF for alpha + for(int xx=0;xx<4;xx++) { + *(dst+1920) = p; + *(dst+1280) = p; + *(dst+640) = p; + *dst++ = p; + } + } + dst += 640*4 - 128*4; + } + // cleanup + cairo_destroy(temp); + cairo_surface_write_to_png(png, s); + cairo_surface_destroy((cairo_surface_t *)png); } void screen_display_png(const char *filename, double x, double y) {