Skip to content

Commit

Permalink
Merge branch 'sysprog21:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
jouae authored Aug 2, 2024
2 parents 06fa29a + db1162e commit cdc9f32
Show file tree
Hide file tree
Showing 11 changed files with 267 additions and 27 deletions.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,16 @@ libtwin.a_files-y = \
src/icon.c \
src/pixmap.c \
src/timeout.c \
src/image.c \
src/api.c

libtwin.a_includes-y := \
include \
src

# Features
libtwin.a_files-$(CONFIG_CURSOR) += src/cursor.c

# Image loaders

ifeq ($(CONFIG_LOADER_JPEG), y)
Expand Down
17 changes: 11 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,17 @@ software by allowing anti-aliased drawing to generate nearly invisible errors
instead of visibly incorrect results. Smooth color gradations eliminate the need
for dithering or other color-approximating schemes.

Respectable CPU performance is expected, reducing the need to cache intermediate
rendering results, such as glyph images for text. Supporting only one general
performance class of drawing operations, `Mado` focuses on anti-aliased drawing,
as supported CPUs are fast enough to make non-anti-aliased drawing irrelevant.
Additionally, `Mado` does not rely on an FPU or heavy FPU emulations, using its
own fixed-point arithmetic instead.
`Mado` is designed to ensure respectable CPU performance, which mitigates the
need for caching intermediate rendering results like glyph images for text. It
supports only a single, general performance class of drawing operations,
focusing exclusively on anti-aliased drawing. This focus is practical because
the CPUs that `Mado` supports are sufficiently fast, rendering non-anti-aliased
drawing obsolete. Moreover, `Mado` avoids reliance on a floating point unit (FPU)
or extensive FPU emulation by employing its own fixed-point arithmetic for all
necessary computations. This approach extends to nearly all of `Mado`'s optional
components as well. For specific tasks such as subpixel font layout and alpha
blending, `Mado` utilizes fixed-point math, ensuring that it remains efficient
even on CPUs without an FPU.

These environmental limitations enable `Mado` to provide significant
functionality with minimal wasted code. Unlike window systems designed for
Expand Down
22 changes: 11 additions & 11 deletions apps/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,13 @@

#define ASSET_PATH "assets/"

/**
/*
* Load the background pixmap from storage.
* @filename: File name of a PNG background.
*
* Return a default pattern if the load of @filename fails.
* Return a default pattern if the load of @path or image loader fails.
*/
static twin_pixmap_t *load_background(twin_screen_t *screen,
const char *filename)
static twin_pixmap_t *load_background(twin_screen_t *screen, const char *path)
{
#if defined(CONFIG_LOADER_PNG)
twin_pixmap_t *raw_background = twin_png_to_pixmap(filename, TWIN_ARGB32);
twin_pixmap_t *raw_background = twin_pixmap_from_file(path, TWIN_ARGB32);
if (!raw_background) /* Fallback to a default pattern */
return twin_make_pattern();

Expand Down Expand Up @@ -67,9 +63,6 @@ static twin_pixmap_t *load_background(twin_screen_t *screen,
twin_pixmap_destroy(raw_background);

return scaled_background;
#else
return twin_make_pattern();
#endif
}

static twin_context_t *tx = NULL;
Expand Down Expand Up @@ -101,6 +94,13 @@ int main(void)
atexit(cleanup);
signal(SIGINT, sigint_handler);

#if defined(CONFIG_CURSOR)
int hx, hy;
twin_pixmap_t *cursor = twin_make_cursor(&hx, &hy);
if (cursor)
twin_screen_set_cursor(tx->screen, cursor, hx, hy);
#endif

twin_screen_set_background(
tx->screen, load_background(tx->screen, ASSET_PATH "/tux.png"));

Expand Down
8 changes: 8 additions & 0 deletions configs/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ config BACKEND_SDL

endchoice

menu "Features"

config CURSOR
bool "Manipulate cursor"
default n

endmenu

menu "Image Loaders"

config LOADER_PNG
Expand Down
16 changes: 8 additions & 8 deletions include/twin.h
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,12 @@ void twin_path_convolve(twin_path_t *dest,
twin_path_t *stroke,
twin_path_t *pen);

/*
* cursor.c
*/

twin_pixmap_t *twin_make_cursor(int *hx, int *hy);

/*
* dispatch.c
*/
Expand Down Expand Up @@ -681,16 +687,10 @@ void twin_icon_draw(twin_pixmap_t *pixmap,
twin_matrix_t matrix);

/*
* image-jpeg.c
*/

twin_pixmap_t *twin_jpeg_to_pixmap(const char *filepath, twin_format_t fmt);

/*
* image-png.c
* image.c
*/

twin_pixmap_t *twin_png_to_pixmap(const char *filepath, twin_format_t fmt);
twin_pixmap_t *twin_pixmap_from_file(const char *path, twin_format_t fmt);

/*
* label.c
Expand Down
16 changes: 16 additions & 0 deletions include/twin_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -544,4 +544,20 @@ static inline int twin_clz(uint32_t v)
}
#endif

/* Pattern Matching for C macros.
* https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms
*/

/* In Visual Studio, __VA_ARGS__ is treated as a separate parameter. */
#define FIX_VC_BUG(x) x

/* catenate */
#define PRIMITIVE_CAT(a, ...) FIX_VC_BUG(a##__VA_ARGS__)

#define IIF(c) PRIMITIVE_CAT(IIF_, c)
/* run the 2nd parameter */
#define IIF_0(t, ...) __VA_ARGS__
/* run the 1st parameter */
#define IIF_1(t, ...) t

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

/* Manipulating cursor images */

#include <stddef.h>
#include <twin.h>

static const uint8_t _twin_cursor_default[] = {
0x19, 0x19, 0x19, 0xb8, 0x1e, 0x1e, 0x1e, 0xc8, 0x00, 0x00, 0x00, 0x13,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x48, 0x48, 0xcc,
0xb2, 0xb2, 0xb2, 0xff, 0x3a, 0x3a, 0x3a, 0xcc, 0x00, 0x00, 0x00, 0x24,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3b, 0x3b, 0x3b, 0xc8, 0xf6, 0xf6, 0xf6, 0xff,
0xdc, 0xdc, 0xdc, 0xff, 0x43, 0x43, 0x43, 0xe0, 0x00, 0x00, 0x00, 0x3b,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3b, 0x3b, 0x3b, 0xcb, 0xe6, 0xe6, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xfc,
0xe5, 0xe5, 0xe5, 0xff, 0x59, 0x59, 0x59, 0xf3, 0x00, 0x00, 0x00, 0x4f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0xcb,
0xe9, 0xe9, 0xe9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xf5, 0xf5, 0xf5, 0xff, 0x72, 0x72, 0x72, 0xff, 0x00, 0x00, 0x00, 0x73,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3d, 0x3d, 0x3d, 0xcb, 0xe9, 0xe9, 0xe9, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x8a, 0x8a, 0x8a, 0xff, 0x00, 0x00, 0x00, 0x90,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x99, 0x99, 0x00,
0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x3e, 0x3e, 0x3e, 0xcb, 0xe9, 0xe9, 0xe9, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xa2, 0xa2, 0xa2, 0xff, 0x13, 0x13, 0x13, 0xab,
0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x3f, 0xcb,
0xe9, 0xe9, 0xe9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xb7, 0xb7, 0xb7, 0xff, 0x1f, 0x1f, 0x1f, 0xbb,
0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x41, 0x41, 0x41, 0xcc, 0xea, 0xea, 0xea, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xca, 0xca, 0xca, 0xff, 0x3d, 0x3d, 0x3d, 0xd8,
0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x41, 0x41, 0x41, 0xcc, 0xea, 0xea, 0xea, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xde, 0xde, 0xde, 0xff, 0x56, 0x56, 0x56, 0xef,
0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0xcc,
0xea, 0xea, 0xea, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xf3, 0xf3, 0xf3, 0xff, 0x76, 0x76, 0x76, 0xff,
0x00, 0x00, 0x00, 0x6b, 0x43, 0x43, 0x43, 0xcc, 0xea, 0xea, 0xea, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xce, 0xce, 0xce, 0xff,
0x80, 0x80, 0x80, 0xf7, 0x74, 0x74, 0x74, 0xf8, 0x6d, 0x6d, 0x6d, 0xfb,
0x72, 0x72, 0x72, 0xf8, 0x57, 0x57, 0x57, 0xff, 0x0c, 0x0c, 0x0c, 0xb3,
0x44, 0x44, 0x44, 0xcc, 0xeb, 0xeb, 0xeb, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xfc, 0xfb, 0xfb, 0xfb, 0xff, 0xfe, 0xfe, 0xfe, 0xff,
0xff, 0xff, 0xff, 0xff, 0xc9, 0xc9, 0xc9, 0xff, 0x13, 0x13, 0x13, 0xb7,
0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x13,
0x00, 0x00, 0x00, 0x0c, 0x29, 0x29, 0x29, 0x07, 0x45, 0x45, 0x45, 0xcc,
0xe8, 0xe8, 0xe8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xd9, 0xd9, 0xd9, 0xff,
0x5e, 0x5e, 0x5e, 0xff, 0xe2, 0xe2, 0xe2, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0x62, 0x62, 0x62, 0xf0, 0x00, 0x00, 0x00, 0x13,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x45, 0x45, 0x45, 0xcc, 0xf9, 0xf9, 0xf9, 0xff,
0xec, 0xec, 0xec, 0xff, 0x4a, 0x4a, 0x4a, 0xd8, 0x00, 0x00, 0x00, 0x78,
0x8a, 0x8a, 0x8a, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xc3, 0xc3, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x58, 0x58, 0x58, 0xd3, 0xd9, 0xd9, 0xd9, 0xff, 0x5e, 0x5e, 0x5e, 0xef,
0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x3b, 0x3b, 0xc7,
0xe9, 0xe9, 0xe9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf4, 0xf4, 0xf4, 0xff,
0x54, 0x54, 0x54, 0xdc, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x3e, 0x3e, 0xe0,
0x54, 0x54, 0x54, 0xff, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x8e, 0x8e, 0x8e, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb0, 0xb0, 0xb0, 0xff,
0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x04,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x4f,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x10, 0x4c, 0x4c, 0x4c, 0xd0, 0xec, 0xec, 0xec, 0xff,
0xff, 0xff, 0xff, 0xfc, 0xf4, 0xf4, 0xf4, 0xff, 0x53, 0x53, 0x53, 0xd8,
0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x1e, 0x1e, 0x00,
0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x6f, 0xab, 0xab, 0xab, 0xff, 0xf6, 0xf6, 0xf6, 0xff,
0x80, 0x80, 0x80, 0xff, 0x31, 0x31, 0x31, 0xac, 0x00, 0x00, 0x00, 0x17,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09, 0x09, 0x03,
0x02, 0x02, 0x02, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
0x2e, 0x2e, 0x2e, 0xd7, 0x38, 0x38, 0x38, 0xc7, 0x00, 0x00, 0x00, 0x47,
0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
};

twin_pixmap_t *twin_make_cursor(int *hx, int *hy)
{
twin_pointer_t pixels = {.v = (void *) _twin_cursor_default};

twin_pixmap_t *cur =
twin_pixmap_create_const(TWIN_ARGB32, 14, 20, 14 * 4, pixels);
if (!cur)
return NULL;
*hx = 14;
*hy = 20;
return cur;
}
2 changes: 1 addition & 1 deletion src/image-jpeg.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ static void twin_jpeg_error_exit(j_common_ptr cinfo)
longjmp(jerr->jbuf, 1);
}

twin_pixmap_t *twin_jpeg_to_pixmap(const char *filepath, twin_format_t fmt)
twin_pixmap_t *_twin_jpeg_to_pixmap(const char *filepath, twin_format_t fmt)
{
twin_pixmap_t *pix = NULL;

Expand Down
2 changes: 1 addition & 1 deletion src/image-png.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ static void _convertBGRtoARGB(uint8_t *data, int width, int height)
}
#endif

twin_pixmap_t *twin_png_to_pixmap(const char *filepath, twin_format_t fmt)
twin_pixmap_t *_twin_png_to_pixmap(const char *filepath, twin_format_t fmt)
{
uint8_t signature[8];
int rb = 0;
Expand Down
81 changes: 81 additions & 0 deletions src/image.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#include <string.h>
#include <strings.h>

#include "twin_private.h"

#if !defined(CONFIG_LOADER_PNG)
#define CONFIG_LOADER_PNG 0
#endif

#if !defined(CONFIG_LOADER_JPEG)
#define CONFIG_LOADER_JPEG 0
#endif

/* Feature test macro */
#define LOADER_HAS(x) CONFIG_LOADER_##x

/* clang-format off */
#define SUPPORTED_FORMATS \
IIF(LOADER_HAS(PNG))( \
_(png) \
) \
IIF(LOADER_HAS(JPEG))( \
_(jpeg) \
)
/* clang-format on */

typedef enum {
IMAGE_TYPE_unknown,
#define _(x) IMAGE_TYPE_##x,
SUPPORTED_FORMATS
#undef _
} twin_image_format_t;

/* FIXME: Check the header of the given images to determine the supported image
* formats instead of parsing the filename without checking its content.
*/
static twin_image_format_t image_type_from_name(const char *path)
{
twin_image_format_t type = IMAGE_TYPE_unknown;
const char *extname = strrchr(path, '.');
if (!extname)
return IMAGE_TYPE_unknown;
#if LOADER_HAS(PNG)
else if (!strcasecmp(extname, ".png")) {
type = IMAGE_TYPE_png;
}
#endif
#if LOADER_HAS(JPEG)
else if (!strcasecmp(extname, ".jpg") || !strcasecmp(extname, ".jpeg")) {
type = IMAGE_TYPE_jpeg;
}
#endif
/* otherwise, unsupported format */

return type;
}

#define _(x) \
twin_pixmap_t *_twin_##x##_to_pixmap(const char *filepath, \
twin_format_t fmt);
SUPPORTED_FORMATS
#undef _

typedef twin_pixmap_t *(*loader_func_t)(const char *, twin_format_t);

/* clang-format off */
static loader_func_t image_loaders[] = {
[IMAGE_TYPE_unknown] = NULL,
#define _(x) [IMAGE_TYPE_##x] = _twin_##x##_to_pixmap,
SUPPORTED_FORMATS
#undef _
};
/* clang-format on */

twin_pixmap_t *twin_pixmap_from_file(const char *path, twin_format_t fmt)
{
loader_func_t loader = image_loaders[image_type_from_name(path)];
if (!loader)
return NULL;
return loader(path, fmt);
}
Loading

0 comments on commit cdc9f32

Please sign in to comment.