Skip to content

Commit

Permalink
Merge pull request #77 from ndsl7109256/tvg
Browse files Browse the repository at this point in the history
Support TinyVG format decoding and rendering
  • Loading branch information
jserv authored Dec 19, 2024
2 parents 9b84ea1 + 1ca2d39 commit 3bee378
Show file tree
Hide file tree
Showing 15 changed files with 1,500 additions and 15 deletions.
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ ifeq ($(CONFIG_LOADER_GIF), y)
libtwin.a_files-y += src/image-gif.c
endif

ifeq ($(CONFIG_LOADER_TVG), y)
libtwin.a_files-y += src/image-tvg.c
endif

# Applications

libapps.a_files-y := apps/dummy.c
Expand All @@ -96,6 +100,7 @@ libapps.a_files-$(CONFIG_DEMO_CALCULATOR) += apps/calc.c
libapps.a_files-$(CONFIG_DEMO_LINE) += apps/line.c
libapps.a_files-$(CONFIG_DEMO_SPLINE) += apps/spline.c
libapps.a_files-$(CONFIG_DEMO_ANIMATION) += apps/animation.c
libapps.a_files-$(CONFIG_DEMO_IMAGE) += apps/image.c

libapps.a_includes-y := include

Expand Down
14 changes: 14 additions & 0 deletions apps/apps_image.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Twin - A Tiny Window System
* Copyright (c) 2024 National Cheng Kung University
* All rights reserved.
*/

#ifndef _APPS_IMAGE_H_
#define _APPS_IMAGE_H_

#include <twin.h>

void apps_image_start(twin_screen_t *screen, const char *name, int x, int y);

#endif /* _APPS_ANIMATION_H_ */
122 changes: 122 additions & 0 deletions apps/image.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/*
* Twin - A Tiny Window System
* Copyright (c) 2024 National Cheng Kung University
* All rights reserved.
*/

#include <stdlib.h>

#include "twin_private.h"

#include "apps_image.h"

#define _apps_image_pixmap(image) ((image)->widget.window->pixmap)
#define D(x) twin_double_to_fixed(x)
#define ASSET_PATH "assets/"
#define APP_WIDTH 400
#define APP_HEIGHT 400
typedef struct {
twin_widget_t widget;
twin_pixmap_t **pixes;
int image_idx;
} apps_image_t;

static const char *tvg_files[] = {
/* https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/ */
ASSET_PATH "tiger.tvg",
/* https://tinyvg.tech/img/chart.svg */
ASSET_PATH "chart.tvg",
/* https://freesvg.org/betrayed */
ASSET_PATH "comic.tvg",
/* https://github.com/PapirusDevelopmentTeam/papirus-icon-theme */
ASSET_PATH "folder.tvg",
/* https://materialdesignicons.com/ */
ASSET_PATH "shield.tvg",
/* https://tinyvg.tech/img/flowchart.png */
ASSET_PATH "flowchart.tvg",
};

static void _apps_image_paint(apps_image_t *img)
{
twin_operand_t srcop = {
.source_kind = TWIN_PIXMAP,
.u.pixmap = img->pixes[img->image_idx],
};

twin_composite(_apps_image_pixmap(img), 0, 0, &srcop, 0, 0, NULL, 0, 0,
TWIN_SOURCE, APP_WIDTH, APP_HEIGHT);
}

static twin_dispatch_result_t _apps_image_dispatch(twin_widget_t *widget,
twin_event_t *event)
{
apps_image_t *img = (apps_image_t *) widget;
if (_twin_widget_dispatch(widget, event) == TwinDispatchDone)
return TwinDispatchDone;
switch (event->kind) {
case TwinEventPaint:
_apps_image_paint(img);
break;
default:
break;
}
return TwinDispatchContinue;
}

static void _apps_image_button_signal(maybe_unused twin_button_t *button,
twin_button_signal_t signal,
void *closure)
{
if (signal != TwinButtonSignalDown)
return;

apps_image_t *img = closure;
const int n = sizeof(tvg_files) / sizeof(tvg_files[0]);
img->image_idx = img->image_idx == n - 1 ? 0 : img->image_idx + 1;
if (!img->pixes[img->image_idx]) {
twin_pixmap_t *pix = twin_tvg_to_pixmap_scale(
tvg_files[img->image_idx], TWIN_ARGB32, APP_WIDTH, APP_HEIGHT);
if (!pix)
return;
img->pixes[img->image_idx] = pix;
}
_twin_widget_queue_paint(&img->widget);
}

static void _apps_image_init(apps_image_t *img,
twin_box_t *parent,
twin_dispatch_proc_t dispatch)
{
static twin_widget_layout_t preferred = {0, 0, 1, 1};
preferred.height = parent->widget.window->screen->height * 3.0 / 4.0;
_twin_widget_init(&img->widget, parent, 0, preferred, dispatch);
img->image_idx = 0;
img->pixes = calloc(sizeof(tvg_files), sizeof(twin_pixmap_t *));
img->pixes[0] = twin_tvg_to_pixmap_scale(tvg_files[0], TWIN_ARGB32,
APP_WIDTH, APP_HEIGHT);
twin_button_t *button =
twin_button_create(parent, "Next Image", 0xFF482722, D(10),
TwinStyleBold | TwinStyleOblique);
twin_widget_set(&button->label.widget, 0xFFFEE4CE);
button->signal = _apps_image_button_signal;
button->closure = img;
button->label.widget.shape = TwinShapeRectangle;
}

static apps_image_t *apps_image_create(twin_box_t *parent)
{
apps_image_t *img = malloc(sizeof(apps_image_t));

_apps_image_init(img, parent, _apps_image_dispatch);
return img;
}

void apps_image_start(twin_screen_t *screen, const char *name, int x, int y)
{
twin_toplevel_t *toplevel =
twin_toplevel_create(screen, TWIN_ARGB32, TwinWindowApplication, x, y,
APP_WIDTH, APP_HEIGHT, name);
apps_image_t *img = apps_image_create(&toplevel->box);
(void) img;
twin_toplevel_show(toplevel);
}
4 changes: 4 additions & 0 deletions apps/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "apps_calc.h"
#include "apps_clock.h"
#include "apps_hello.h"
#include "apps_image.h"
#include "apps_line.h"
#include "apps_multi.h"
#include "apps_spline.h"
Expand Down Expand Up @@ -127,6 +128,9 @@ int main(void)
apps_animation_start(tx->screen, "Viewer", ASSET_PATH "nyancat.gif", 20,
20);
#endif
#if defined(CONFIG_DEMO_IMAGE)
apps_image_start(tx->screen, "Viewer", 20, 20);
#endif

twin_dispatch(tx);

Expand Down
Binary file added assets/chart.tvg
Binary file not shown.
Binary file added assets/comic.tvg
Binary file not shown.
Binary file added assets/flowchart.tvg
Binary file not shown.
Binary file added assets/folder.tvg
Binary file not shown.
Binary file added assets/shield.tvg
Binary file not shown.
Binary file added assets/tiger.tvg
Binary file not shown.
10 changes: 10 additions & 0 deletions configs/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ config LOADER_GIF
bool "Enable GIF loader"
default y

config LOADER_TVG
bool "Enable TinyVG (TVG) loader"
default y

endmenu

menu "Demo Applications"
Expand Down Expand Up @@ -113,4 +117,10 @@ config DEMO_ANIMATION
bool "Build animation demo"
default y
depends on DEMO_APPLICATIONS

config DEMO_IMAGE
bool "Build scalable image demo"
select LOADER_TVG
default y
depends on DEMO_APPLICATIONS
endmenu
9 changes: 9 additions & 0 deletions include/twin.h
Original file line number Diff line number Diff line change
Expand Up @@ -1187,6 +1187,15 @@ twin_work_t *twin_set_work(twin_work_proc_t work_proc,

void twin_clear_work(twin_work_t *work);

/*
* image-tvg.c
*/

twin_pixmap_t *twin_tvg_to_pixmap_scale(const char *filepath,
twin_format_t fmt,
twin_coord_t w,
twin_coord_t h);

/*
* backend
*/
Expand Down
Loading

0 comments on commit 3bee378

Please sign in to comment.