ttf support

git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@473 b9cfdab3-6d41-4d17-bbe4-086880011989
This commit is contained in:
Nishi 2025-10-23 07:33:54 +00:00
commit 705e68408a
14 changed files with 21167 additions and 20948 deletions

View file

@ -23,6 +23,40 @@ MWDECL MwFont MwFontData[];
*/
MWDECL MwFont MwBoldFontData[];
/*!
* %brief Default TTF font data
*/
MWDECL unsigned char MwTTFData[];
/*!
* %brief Default TTF font size
*/
MWDECL unsigned int MwTTFDataSize;
/*!
* %brief Default bold TTF font data
*/
MWDECL unsigned char MwBoldTTFData[];
/*!
* %brief Default bold TTF font size
*/
MWDECL unsigned int MwBoldTTFDataSize;
/*!
* %brief Loads a TTF Font
* %param data Data
* %param size Data size
* %return Font handle
*/
MWDECL void* MwFontLoad(unsigned char* data, unsigned int size);
/*!
* %brieff Frees a font handle
* %param handle Handle
*/
MWDECL void MwFontFree(void* handle);
#ifdef __cplusplus
}
#endif

View file

@ -34,6 +34,8 @@
#define MwNpixmap "Vpixmap"
#define MwNiconPixmap "ViconPixmap"
#define MwNsizeHints "VsizeHints"
#define MwNfont "Vfont"
#define MwNboldFont "VboldFont"
#define MwNactivateHandler "Cactivate" /* NULL/int* (MwListBox) */
#define MwNresizeHandler "Cresize" /* NULL */

View file

@ -70,6 +70,8 @@
<pixmap name="pixmap" />
<pixmap name="iconPixmap" />
<struct defname="MwSizeHints" pointer="yes" name="sizeHints" />
<pointer name="font" />
<pointer name="boldFont" />
<handler name="activate" />
<handler name="resize" />

View file

@ -12,11 +12,6 @@
#include <X11/Xcursor/Xcursor.h>
#include <X11/extensions/Xrender.h>
#ifdef HAS_FREETYPE
#include <ft2build.h>
#include FT_FREETYPE_H
#endif
struct _MwLL {
Display* display;
Window window;
@ -47,13 +42,6 @@ struct _MwLL {
unsigned long blue_mask;
unsigned long blue_max;
unsigned long blue_shift;
#ifdef HAS_FREETYPE
void* ftLib;
FT_Library ftHandle;
MwBool ftOwns;
FT_Face ftFace;
#endif
};
struct _MwLLColor {

View file

@ -421,8 +421,8 @@ static void inherit_text(MwWidget handle, const char* key, const char* default_v
}
static void inherit_integer(MwWidget handle, const char* key, int default_value) {
int n;
MwWidget h = handle;
int n;
MwWidget h = handle;
while(h != NULL) {
if((n = MwGetInteger(h, key)) != -1) {
MwSetInteger(handle, key, n);
@ -433,6 +433,36 @@ static void inherit_integer(MwWidget handle, const char* key, int default_value)
MwSetInteger(handle, key, default_value);
}
#ifdef USE_STB_TRUETYPE
static void set_font(MwWidget handle) {
void* f;
MwWidget h = handle;
while(h != NULL) {
if((f = MwGetVoid(h, MwNfont)) != NULL) {
MwSetVoid(handle, MwNfont, f);
return;
}
h = h->parent;
}
f = MwFontLoad(MwTTFData, MwTTFDataSize);
MwSetVoid(handle, MwNfont, f);
}
static void set_boldfont(MwWidget handle) {
void* f;
MwWidget h = handle;
while(h != NULL) {
if((f = MwGetVoid(h, MwNboldFont)) != NULL) {
MwSetVoid(handle, MwNboldFont, f);
return;
}
h = h->parent;
}
f = MwFontLoad(MwBoldTTFData, MwBoldTTFDataSize);
MwSetVoid(handle, MwNboldFont, f);
}
#endif
void MwSetDefault(MwWidget handle) {
MwLLSetCursor(handle->lowlevel, &MwCursorDefault, &MwCursorDefaultMask);
@ -443,6 +473,10 @@ void MwSetDefault(MwWidget handle) {
#else
inherit_integer(handle, MwNmodernLook, 1);
#endif
#ifdef USE_STB_TRUETYPE
set_font(handle);
set_boldfont(handle);
#endif
}
void MwHideCursor(MwWidget handle) {

View file

@ -1,6 +1,6 @@
/* $Id$ */
#include <Mw/Milsko.h>
const int MwDefaultBorderWidth = 2;
const char* MwDefaultBackground = "#ddd";
const char* MwDefaultForeground = "#000";
const int MwDefaultBorderWidth = 2;
const char* MwDefaultBackground = "#ddd";
const char* MwDefaultForeground = "#000";

View file

@ -11,10 +11,10 @@
#include "../external/stb_ds.h"
static int get_color_diff(MwWidget handle){
if(MwGetInteger(handle, MwNmodernLook)){
static int get_color_diff(MwWidget handle) {
if(MwGetInteger(handle, MwNmodernLook)) {
return 48;
}else{
} else {
return 128;
}
}
@ -95,14 +95,14 @@ void MwDrawRect(MwWidget handle, MwRect* rect, MwLLColor color) {
MwLLPolygon(handle->lowlevel, p, 4, color);
}
void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color) {
MwLLPixmap pixmap;
int y;
int x;
double darken = 0.;
int ColorDiff = get_color_diff(handle);
double darkenStep = (ColorDiff / 2.) / rect->height;
unsigned long sz = rect->width * rect->height * 4;
unsigned char* data = malloc(sz);
MwLLPixmap pixmap;
int y;
int x;
double darken = 0.;
int ColorDiff = get_color_diff(handle);
double darkenStep = (ColorDiff / 2.) / rect->height;
unsigned long sz = rect->width * rect->height * 4;
unsigned char* data = malloc(sz);
memset(data, 0, sz);
for(y = 0; y < rect->height; y++) {
@ -131,18 +131,18 @@ void MwDrawWidgetBack(MwWidget handle, MwRect* rect, MwLLColor color, int invert
if(border) {
MwDrawFrame(handle, rect, color, invert);
}
if(MwGetInteger(handle, MwNmodernLook)){
if(MwGetInteger(handle, MwNmodernLook)) {
MwDrawRectFading(handle, rect, color);
}else{
} else {
MwDrawRect(handle, rect, color);
}
}
void MwDrawFrameEx(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border) {
MwPoint p[6];
int ColorDiff = get_color_diff(handle);
MwLLColor darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff);
MwLLColor lighter = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff);
int ColorDiff = get_color_diff(handle);
MwLLColor darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff);
MwLLColor lighter = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff);
p[0].x = rect->x;
p[0].y = rect->y;
@ -195,10 +195,10 @@ void MwDrawFrameEx(MwWidget handle, MwRect* rect, MwLLColor color, int invert, i
void MwDrawTriangle(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int direction) {
MwPoint p1[4], p2[4], p3[4], p4[3];
const int border = MwGetInteger(handle, MwNmodernLook) ? 1 : MwDefaultBorderWidth;
int ColorDiff = get_color_diff(handle);
MwLLColor darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff);
MwLLColor lighter = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff);
const int border = MwGetInteger(handle, MwNmodernLook) ? 1 : MwDefaultBorderWidth;
int ColorDiff = get_color_diff(handle);
MwLLColor darker = MwLightenColor(handle, color, -ColorDiff, -ColorDiff, -ColorDiff);
MwLLColor lighter = MwLightenColor(handle, color, ColorDiff, ColorDiff, ColorDiff);
double deg = 30 + ((direction == MwEAST || direction == MwWEST) ? 30 : 0);
double c = cos(deg / 180 * M_PI);

File diff suppressed because it is too large Load diff

View file

@ -1,13 +1,24 @@
/* $Id$ */
#include <Mw/Milsko.h>
#ifdef USE_STB_TRUETYPE
#include "../../external/stb_truetype.h"
typedef struct ttf {
stbtt_fontinfo font;
void* data;
float scale;
int ascent;
int descent;
} ttf_t;
#endif
#define FontWidth 7
#define FontHeight 14
static void bitmap_MwDrawText(MwWidget handle, MwPoint* point, const char* text, int bold, int align, MwLLColor color) {
int i = 0, x, y, sx, sy;
int tw;
int th;
int tw, th;
unsigned char* px;
MwRect r;
MwLLPixmap p;
@ -69,20 +80,138 @@ static void bitmap_MwDrawText(MwWidget handle, MwPoint* point, const char* text,
free(px);
}
#ifdef USE_STB_TRUETYPE
static int ttf_MwDrawText(MwWidget handle, MwPoint* point, const char* text, int bold, int align, MwLLColor color) {
ttf_t* ttf = MwGetVoid(handle, MwNfont);
MwLLColor base;
unsigned char* px;
int tw, th;
MwRect r;
MwLLPixmap p;
int i;
int ax, lsb;
int x = 0;
if(ttf == NULL) return 1;
base = MwParseColor(handle, MwGetText(handle, MwNbackground));
tw = MwTextWidth(handle, text);
th = MwTextHeight(handle, text);
px = malloc(tw * th * 4);
memset(px, 0, tw * th * 4);
while(text[0] != 0) {
int c;
int x0, y0, x1, y1, cx, cy;
int ow, oh;
unsigned char* out;
text += MwUTF8ToUTF32(text, &c);
stbtt_GetCodepointHMetrics(&ttf->font, c, &ax, &lsb);
stbtt_GetCodepointBitmapBox(&ttf->font, c, ttf->scale, ttf->scale, &x0, &y0, &x1, &y1);
ow = x1 - x0;
oh = y1 - y0;
out = malloc(ow * oh);
stbtt_MakeCodepointBitmap(&ttf->font, out, ow, oh, ow, ttf->scale, ttf->scale, c);
for(cy = 0; cy < oh; cy++) {
for(cx = 0; cx < ow; cx++) {
int ox = x + (lsb * ttf->scale) + cx;
int oy = (ttf->ascent * ttf->scale) + y0 + cy;
unsigned char* opx = &px[(oy * tw + ox) * 4];
double a = out[cy * ow + cx];
if(a != 0) {
a /= 255;
a = 1 - a;
opx[0] = base->red * a;
opx[1] = base->green * a;
opx[2] = base->blue * a;
opx[3] = 255;
}
}
}
x += ax * ttf->scale;
free(out);
}
p = MwLoadRaw(handle, px, tw, th);
r.x = point->x;
r.y = point->y - th / 2;
r.width = tw;
r.height = th;
if(align == MwALIGNMENT_CENTER) {
r.x -= tw / 2;
} else if(align == MwALIGNMENT_END) {
r.x -= tw;
}
MwLLDrawPixmap(handle->lowlevel, &r, p);
MwLLDestroyPixmap(p);
free(px);
MwLLFreeColor(base);
return 0;
}
int ttf_MwTextWidth(MwWidget handle, const char* text) {
ttf_t* ttf = MwGetVoid(handle, MwNfont);
int ax, lsb;
int tw = 0;
if(ttf == NULL) return -1;
while(text[0] != 0) {
int c;
text += MwUTF8ToUTF32(text, &c);
stbtt_GetCodepointHMetrics(&ttf->font, c, &ax, &lsb);
tw += ax * ttf->scale;
}
return tw;
}
int ttf_MwTextHeight(MwWidget handle, int count) {
ttf_t* ttf = MwGetVoid(handle, MwNfont);
if(ttf == NULL) return -1;
return (ttf->ascent - ttf->descent) * ttf->scale * count;
}
#endif
void MwDrawText(MwWidget handle, MwPoint* point, const char* text, int bold, int align, MwLLColor color) {
bitmap_MwDrawText(handle, point, text, bold, align, color);
#ifdef USE_STB_TRUETYPE
if(ttf_MwDrawText(handle, point, text, bold, align, color))
#endif
bitmap_MwDrawText(handle, point, text, bold, align, color);
}
int MwTextWidth(MwWidget handle, const char* text) {
(void)handle;
int st;
/* TODO: check newline */
#ifdef USE_STB_TRUETYPE
if((st = ttf_MwTextWidth(handle, text)) != -1) return st;
#else
(void)handle;
#endif
return strlen(text) * FontWidth;
}
int MwTextHeight(MwWidget handle, const char* text) {
int c = 1;
int i = 0;
int st;
(void)handle;
(void)text;
@ -93,5 +222,35 @@ int MwTextHeight(MwWidget handle, const char* text) {
if(out == '\n') c++;
}
#ifdef USE_STB_TRUETYPE
if((st = ttf_MwTextHeight(handle, c)) != -1) return st;
#endif
return FontHeight * c;
}
void* MwFontLoad(unsigned char* data, unsigned int size) {
#ifdef USE_STB_TRUETYPE
ttf_t* ttf = malloc(sizeof(*ttf));
ttf->data = malloc(size);
memcpy(ttf->data, data, size);
stbtt_InitFont(&ttf->font, ttf->data, 0);
ttf->scale = stbtt_ScaleForPixelHeight(&ttf->font, 16);
stbtt_GetFontVMetrics(&ttf->font, &ttf->ascent, &ttf->descent, 0);
return ttf;
#else
return NULL;
#endif
}
void MwFontFree(void* handle) {
#ifdef USE_STB_TRUETYPE
ttf_t* ttf = handle;
free(ttf->data);
free(ttf);
#else
(void)font;
#endif
}

File diff suppressed because it is too large Load diff

View file

@ -106,8 +106,10 @@ static void draw(MwWidget handle) {
BEGIN_MENU_LOOP;
if(m->sub[i]->wsub != NULL) {
MwDrawFrame(handle, &r, base, MwFALSE);
MwDrawWidgetBack(handle, &r, base, 0, MwFALSE);
} else if(in_area && handle->pressed) {
MwDrawFrame(handle, &r, base, MwFALSE);
MwDrawWidgetBack(handle, &r, base, 0, MwFALSE);
}

View file

@ -130,7 +130,7 @@ static void draw(MwWidget handle) {
}
static void mouse_move(MwWidget handle) {
int or = MwGetInteger(handle, MwNorientation);
int or = MwGetInteger(handle, MwNorientation);
scrollbar_t* scr = handle->internal;
if(!handle->pressed) return;
@ -158,9 +158,9 @@ static void mouse_move(MwWidget handle) {
}
static void mouse_down(MwWidget handle, void* ptr) {
int ww = MwGetInteger(handle, MwNwidth);
int wh = MwGetInteger(handle, MwNheight);
int or = MwGetInteger(handle, MwNorientation);
int ww = MwGetInteger(handle, MwNwidth);
int wh = MwGetInteger(handle, MwNheight);
int or = MwGetInteger(handle, MwNorientation);
scrollbar_t* scr = handle->internal;
MwLLMouse* m = ptr;

View file

@ -96,7 +96,7 @@ sub generate {
print(OUT "LD = $link\n");
print(OUT "\n");
print(OUT
"CFLAGS = ${inc}include ${def}_MILSKO ${def}USE_GDI ${def}USE_STB_IMAGE ${def}STBI_NO_SIMD\n"
"CFLAGS = ${inc}include ${def}_MILSKO ${def}USE_GDI ${def}USE_STB_TRUETYPE ${def}USE_STB_IMAGE ${def}STBI_NO_SIMD\n"
);
print(OUT "LDFLAGS = $dll");
print(OUT "\n");

View file

@ -7,8 +7,8 @@ for out in src/text/ttf.c src/text/boldttf.c; do
echo '' >> $out
echo '#ifdef USE_STB_TRUETYPE' >> $out
done
xxd -n MwBoldTTFData -i resource/mononoki.ttf >> src/text/ttf.c
xxd -n MwTTFData -i resource/mononoki-Bold.ttf >> src/text/boldttf.c
xxd -n MwBoldTTFData -i resource/mononoki.ttf | sed s/_len/Size/ >> src/text/ttf.c
xxd -n MwTTFData -i resource/mononoki-Bold.ttf | sed s/_len/Size/ >> src/text/boldttf.c
for out in src/text/ttf.c src/text/boldttf.c; do
echo '#endif' >> $out
done