Skip to content

Commit

Permalink
Add install target for mingw, more favicon implementations
Browse files Browse the repository at this point in the history
  • Loading branch information
petabyt committed Jan 6, 2024
1 parent 086ed00 commit 6bbc303
Show file tree
Hide file tree
Showing 9 changed files with 282 additions and 20 deletions.
21 changes: 15 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,25 @@ LIBUI_COMMON:=$(filter-out %OLD_table.o,$(LIBUI_COMMON))

CFLAGS=-I$(LIBUI)

all:
echo "see Makefile"

ide/demo.h: ide/test.lua
cd ide && xxd -i test.lua > demo.h
ide/test.c: ide/demo.h

ifeq ($(TARGET),w) # ---------------------------
LIBUI_COMMON+=extras/favicon-win.o
LIBUI_COMMON+=extras/favicon/win.o
include win.mk
endif # ------------------------------

ifeq ($(TARGET),l) # ------------------------------
LIBUI_COMMON+=extras/favicon.o
LIBUI_COMMON+=extras/favicon/linux.o extras/label.o

LIBUI_UNIX:=$(patsubst %.c,%.o,$(wildcard $(LIBUI)/unix/*.c))
LIBUI_UNIX:=$(filter-out %OLD_table.o,$(LIBUI_UNIX))
LIBUI_UNIX:=$(filter-out %image.o,$(LIBUI_UNIX))
LIBUI_UNIX+=extras/image/image.o

O_FILES:=$(LIBUI_COMMON) $(LIBUI_UNIX)
O_FILES:=$(O_FILES:.o=.$(TARGET).o)
Expand All @@ -33,8 +38,8 @@ install: libui.so
sudo rm -rf /usr/local/lib/x86_64-linux-gnu/libui.so
sudo cp libui.so /usr/local/lib/x86_64-linux-gnu/libui.so

ex.out: example/main.c
$(CC) $(CFLAGS) example/main.c -lui -o ex.out
ex.out: example/main.c libui.so
$(CC) $(CFLAGS) example/main.c -L. -Wl,-rpath,. -lui -o ex.out

ide.out: ide/libuilua.c ide/test.c
$(CC) ide/libuilua.c ide/test.c -lui -ldl $(shell pkg-config --libs --cflags lua-5.3) -o ide.out
Expand All @@ -46,7 +51,7 @@ ide.AppImage:
endif # ------------------------------------

ifeq ($(TARGET),m) # ------------------
LIBUI_COMMON+=extras/favicon.o
LIBUI_COMMON+=extras/favicon/darwin.o

LIBUI_DARWIN:=$(patsubst %.m,%.o,$(wildcard $(LIBUI)/darwin/*.m))
LIBUI_DARWIN:=$(filter-out %OLD_table.o,$(LIBUI_DARWIN))
Expand All @@ -59,9 +64,13 @@ LDFLAGS=-framework Foundation -framework Appkit
libui.dylib: $(O_FILES)
$(CC) -shared $(O_FILES) $(LDFLAGS) -o libui.dylib

ex-mac:
ex.out:
$(CC) $(CFLAGS) example/main.c -L. -lui -o ex.out

install: libui.dylib
cp libui.dylib /usr/local/lib
cp libui-ng/ui.h /usr/local/include

endif # ---------------------

%.$(TARGET).o: %.m
Expand Down
18 changes: 15 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
# libui-cross
Prebuilt binaries for cross-compiling software using libui.
Builds will contain a few experimental extensions.

- [x] X86_64 Linux
- [x] X86_64 Windows
- [ ] X86_64 MacOS
```
# Compile for MinGW from Linux
make TARGET=w libui_win64.a install
# Compile for linux from linux
make TARGET=l libui.so install
# Compile for Mac from Darling/Mac
make TARGET=m libui.dylib
```

- [x] X86_64 Linux (.so, .AppImage)
- [x] X86_64 Windows (.a, .exe)
- [ ] X86_64 MacOS (.dylib, .app)
- [ ] ARM64 Linux
- [ ] ARM64 MacOS
29 changes: 18 additions & 11 deletions example/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include <string.h>
#include <ui.h>

_UI_EXTERN void uiLabelSetAttribute(uiLabel *label, uiAttribute *attr);

static int onClosing(uiWindow *w, void *data)
{
uiQuit();
Expand Down Expand Up @@ -37,8 +39,23 @@ static uiControl *makeBasicControlsPage(void)
uiControl(uiNewCheckbox("Checkbox")),
0);

//char *data = malloc(64 * 64 * 4);
//memset(data, 0x111111ff, 64 * 64 * 4);
//uiImageAppend(img, data, 64, 64, 4);

uiImage *img = uiNewImage(64, 64);
extern void uiImageFromFile(uiImage *i, char *file);
uiImageFromFile(img, "ide/libui.png");

uiBoxAppend(vbox, uiControl(img), 0);

uiLabel *label = uiNewLabel("This is a label.\nLabels can span multiple lines.");

uiLabelSetAttribute(label, uiNewSizeAttribute(20));
uiLabelSetAttribute(label, uiNewItalicAttribute(uiTextItalicOblique));

uiBoxAppend(vbox,
uiControl(uiNewLabel("This is a label.\nLabels can span multiple lines.")),
uiControl(label),
0);

uiBoxAppend(vbox,
Expand Down Expand Up @@ -425,16 +442,6 @@ int main(void)
return 1;
}

uiBox *box = uiNewVerticalBox();

uiButton *btn = uiNewButton("Hello");
uiBoxAppend(box, uiControl(btn), 0);
uiButtonOnClicked(btn, clickevent, 0);

btn = uiNewButton("fart");
uiBoxAppend(box, uiControl(btn), 0);


uiControlShow(uiControl(mainwin));
uiMain();
uiUninit();
Expand Down
6 changes: 6 additions & 0 deletions extras/favicon/darwin.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include <stdint.h>
#include <ui.h>

_UI_EXTERN void uiWindowSetIcon(uiWindow *w, const void *data, size_t length) {
// ...
}
File renamed without changes.
File renamed without changes.
153 changes: 153 additions & 0 deletions extras/image/image.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
// 27 june 2016
#include "unix/uipriv_unix.h"

struct uiImage {
uiUnixControl c;
GtkWidget *widget;

double width;
double height;
GPtrArray *images;
};

#define uiImageSignature 123

#define uiImage(this) ((uiImage *) (this))

uiUnixControlAllDefaults(uiImage)

static void freeImageRep(gpointer item)
{
cairo_surface_t *cs = (cairo_surface_t *) item;

cairo_surface_destroy(cs);
}

uiImage *uiNewImage(double width, double height)
{
uiImage *i;

uiUnixNewControl(uiImage, i);

i->widget = gtk_image_new();

i->width = width;
i->height = height;
i->images = g_ptr_array_new_with_free_func(freeImageRep);
return i;
}

void uiFreeImage(uiImage *i)
{
g_ptr_array_free(i->images, TRUE);
uiprivFree(i);
}

void uiImageFromFile(uiImage *i, char *file) {
i->widget = gtk_image_new_from_file(file);
}

void uiImageAppend(uiImage *i, void *pixels, int pixelWidth, int pixelHeight, int byteStride)
{
cairo_surface_t *cs;
uint8_t *data, *pix;
int realStride;
int x, y;

// note that this is native-endian
cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
pixelWidth, pixelHeight);
if (cairo_surface_status(cs) != CAIRO_STATUS_SUCCESS) {
/* TODO */
}
cairo_surface_flush(cs);

pix = (uint8_t *) pixels;
data = (uint8_t *) cairo_image_surface_get_data(cs);
realStride = cairo_image_surface_get_stride(cs);
for (y = 0; y < pixelHeight; y++) {
for (x = 0; x < pixelWidth * 4; x += 4) {
union {
uint32_t v32;
uint8_t v8[4];
} v;

v.v32 = ((uint32_t) (pix[x + 3])) << 24;
v.v32 |= ((uint32_t) (pix[x])) << 16;
v.v32 |= ((uint32_t) (pix[x + 1])) << 8;
v.v32 |= ((uint32_t) (pix[x + 2]));
data[x] = v.v8[0];
data[x + 1] = v.v8[1];
data[x + 2] = v.v8[2];
data[x + 3] = v.v8[3];
}
pix += byteStride;
data += realStride;
}

gtk_image_set_from_surface(i->widget, cs);

cairo_surface_mark_dirty(cs);
g_ptr_array_add(i->images, cs);
}

struct matcher {
cairo_surface_t *best;
int distX;
int distY;
int targetX;
int targetY;
gboolean foundLarger;
};

// TODO is this the right algorithm?
static void match(gpointer surface, gpointer data)
{
cairo_surface_t *cs = (cairo_surface_t *) surface;
struct matcher *m = (struct matcher *) data;
int x, y;
int x2, y2;

x = cairo_image_surface_get_width(cs);
y = cairo_image_surface_get_height(cs);
if (m->best == NULL)
goto writeMatch;

if (x < m->targetX && y < m->targetY)
if (m->foundLarger)
// always prefer larger ones
return;
if (x >= m->targetX && y >= m->targetY && !m->foundLarger)
// we set foundLarger below
goto writeMatch;

x2 = abs(m->targetX - x);
y2 = abs(m->targetY - y);
if (x2 < m->distX && y2 < m->distY)
goto writeMatch;

// TODO weight one dimension? threshhold?
return;

writeMatch:
// must set this here too; otherwise the first image will never have ths set
if (x >= m->targetX && y >= m->targetY && !m->foundLarger)
m->foundLarger = TRUE;
m->best = cs;
m->distX = abs(m->targetX - x);
m->distY = abs(m->targetY - y);
}

cairo_surface_t *uiprivImageAppropriateSurface(uiImage *i, GtkWidget *w)
{
struct matcher m;

m.best = NULL;
m.distX = G_MAXINT;
m.distY = G_MAXINT;
m.targetX = i->width * gtk_widget_get_scale_factor(w);
m.targetY = i->height * gtk_widget_get_scale_factor(w);
m.foundLarger = FALSE;
g_ptr_array_foreach(i->images, match, &m);
return m.best;
}
71 changes: 71 additions & 0 deletions extras/label.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include <stdint.h>
#include <ui.h>

#ifdef __unix__

#include <unix/uipriv_unix.h>
#include <unix/attrstr.h>
#include <gtk/gtk.h>

struct uiLabel {
uiUnixControl c;
GtkWidget *widget;
GtkMisc *misc;
GtkLabel *label;
};

PangoAttrList *uiprivAttributedStringToPangoAttrList(uiDrawTextLayoutParams *p);

struct attr {
uiAttribute *val;
size_t start;
size_t end;
struct attr *prev;
struct attr *next;
};

struct uiprivAttrList {
struct attr *first;
struct attr *last;
};

struct uiAttributedString {
char *s;
size_t len;

uiprivAttrList *attrs;

// indiscriminately keep a UTF-16 copy of the string on all platforms so we can hand this off to the grapheme calculator
// this ensures no one platform has a speed advantage (sorry GTK+)
uint16_t *u16;
size_t u16len;

size_t *u8tou16;
size_t *u16tou8;

// this is lazily created to keep things from getting *too* slow
uiprivGraphemes *graphemes;
};


_UI_EXTERN void uiLabelSetAttribute(uiLabel *label, uiAttribute *attr)
{
struct uiDrawTextLayoutParams params;
params.String = uiNewAttributedString("");

uiAttributedStringSetAttribute(params.String, attr, 0, -1);

PangoAttrList *pango_list = uiprivAttributedStringToPangoAttrList(&params);

PangoAttrList *old_list = gtk_label_get_attributes(GTK_LABEL(label->widget));

GSList *attr_list = pango_attr_list_get_attributes(old_list);

for (; attr_list != NULL; attr_list = attr_list->next) {
pango_attr_list_insert(pango_list, attr_list->data);
}

gtk_label_set_attributes(GTK_LABEL(label->widget), pango_list);
}

#endif
4 changes: 4 additions & 0 deletions win.mk
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ LDFLAGS=$(LIBS)
libui_win64.a: $(O_FILES)
x86_64-w64-mingw32-ar rsc libui_win64.a $(O_FILES)

install: libui_win64.a
cp libui_win64.a /usr/x86_64-w64-mingw32/lib/libui.a
cp $(LIBUI)/ui.h /usr/x86_64-w64-mingw32/include/

build: libui_win64.a
-mkdir build
cd $(LIBUI) && meson setup build && ninja -C build
Expand Down

0 comments on commit 6bbc303

Please sign in to comment.