ttf support
git-svn-id: http://svn2.nishi.boats/svn/milsko/trunk@473 b9cfdab3-6d41-4d17-bbe4-086880011989
This commit is contained in:
parent
9686e69abf
commit
705e68408a
14 changed files with 21167 additions and 20948 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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" />
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
38
src/core.c
38
src/core.c
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
40
src/draw.c
40
src/draw.c
|
|
@ -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);
|
||||
|
|
|
|||
21579
src/text/boldttf.c
21579
src/text/boldttf.c
File diff suppressed because it is too large
Load diff
167
src/text/draw.c
167
src/text/draw.c
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
20219
src/text/ttf.c
20219
src/text/ttf.c
File diff suppressed because it is too large
Load diff
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue