forked from KolibriOS/kolibrios
freetype sample: update
git-svn-id: svn://kolibrios.org@6865 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
98f098c030
commit
ddda916673
@ -1,29 +1,49 @@
|
||||
|
||||
CC = kos32-gcc
|
||||
LD = kos32-ld
|
||||
AR = kos32-ar
|
||||
|
||||
SDK_DIR:= $(abspath ../../..)
|
||||
CONTRIB_DIR:= $(abspath ../../../..)
|
||||
|
||||
LDFLAGS = -static -S -nostdlib -T $(SDK_DIR)/sources/newlib/app.lds -Map txview.map --image-base 0
|
||||
LDFLAGS = -static --subsystem native -Tapp-dynamic.lds -Map txview.map --image-base 0
|
||||
|
||||
CFLAGS = -c -fno-ident -O2 -fomit-frame-pointer -U__WIN32__ -U_Win32 -U_WIN32 -U__MINGW32__ -UWIN32
|
||||
CFLAGS = -c -O2 -msse2 -fno-ident -U__WIN32__ -U_Win32 -U_WIN32 -U__MINGW32__ -UWIN32
|
||||
|
||||
INCLUDES= -I $(SDK_DIR)/sources/newlib/libc/include -I $(SDK_DIR)/sources/freetype/include
|
||||
LIBPATH:= -L $(SDK_DIR)/lib -L /home/autobuild/tools/win32/mingw32/lib
|
||||
INCLUDES= -I./winlib -I./pxdraw -I $(SDK_DIR)/sources/newlib/libc/include -I $(SDK_DIR)/sources/freetype/include
|
||||
INCLUDES+= -I $(CONTRIB_DIR)/toolchain/binutils/bfd -I $(CONTRIB_DIR)/toolchain/binutils/include
|
||||
LIBPATH:= -L./ -L $(SDK_DIR)/lib
|
||||
|
||||
LIB_SRCS= \
|
||||
pxdraw/context.c \
|
||||
pxdraw/dutils.c \
|
||||
pxdraw/region.c \
|
||||
winlib/button.c \
|
||||
winlib/winlib.c \
|
||||
$(NULL)
|
||||
|
||||
SOURCES = main.c \
|
||||
fontlib.c \
|
||||
tview.c
|
||||
fontlib.c \
|
||||
tview.c \
|
||||
$(NULL)
|
||||
|
||||
LIB_OBJS = $(patsubst %.c, %.o, $(LIB_SRCS))
|
||||
|
||||
OBJECTS = $(patsubst %.c, %.o, $(SOURCES))
|
||||
|
||||
|
||||
default: txview
|
||||
|
||||
txview: $(OBJECTS) Makefile
|
||||
$(LD) $(LDFLAGS) $(LIBPATH) -o txview $(OBJECTS) -lfreetype.dll -lpixlib.dll -lgcc -lc.dll -lapp
|
||||
objcopy txview -O binary
|
||||
libwin.a: $(LIB_OBJS) Makefile
|
||||
$(AR) crs $@ $(LIB_OBJS)
|
||||
|
||||
txview: $(OBJECTS) libwin.a Makefile
|
||||
$(LD) $(LDFLAGS) $(LIBPATH) -o txview.dll $(OBJECTS) -lfreetype.dll -lpixlib3 -lwin -lgcc -lc.dll
|
||||
# objdump -d txview.dll > txview.lst
|
||||
objcopy txview.dll txview -O binary
|
||||
|
||||
clean:
|
||||
/bin/rm -rf *.o txview
|
||||
|
||||
%.o : %.c Makefile $(SOURCES)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -o $@ $<
|
||||
|
@ -6,19 +6,12 @@
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_GLYPH_H
|
||||
#include <pixlib2.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int l;
|
||||
int t;
|
||||
int r;
|
||||
int b;
|
||||
}rect_t;
|
||||
#include <pxdraw.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FT_Face face;
|
||||
int fontsize;
|
||||
int height;
|
||||
int base;
|
||||
|
||||
@ -27,6 +20,9 @@ typedef struct
|
||||
}font_t;
|
||||
|
||||
static FT_Face def_face;
|
||||
static FT_Face sym_face;
|
||||
|
||||
font_t *sym_font;
|
||||
|
||||
typedef unsigned int color_t;
|
||||
|
||||
@ -34,63 +30,37 @@ unsigned int ansi2utf32(unsigned char ch);
|
||||
|
||||
font_t *create_font(FT_Face face, int size);
|
||||
|
||||
void my_draw_bitmap(bitmap_t *win, FT_Bitmap *bitmap, int dstx, int dsty, int col)
|
||||
void draw_glyph(ctx_t *ctx, void *buffer, int pitch, rect_t *rc, color_t color);
|
||||
|
||||
unsigned int ansi2utf32(unsigned char ch)
|
||||
{
|
||||
uint8_t *dst;
|
||||
uint8_t *src, *tmpsrc;
|
||||
if(ch < 0x80)
|
||||
return ch;
|
||||
|
||||
uint32_t *tmpdst;
|
||||
int i, j;
|
||||
if(ch < 0xB0)
|
||||
return 0x410-0x80 + ch;
|
||||
|
||||
dst = win->data + dsty * win->pitch + dstx*4;
|
||||
src = bitmap->buffer;
|
||||
if(ch < 0xE0)
|
||||
return 0;
|
||||
|
||||
// printf("buffer %x width %d rows %d\n",
|
||||
// bitmap->buffer, bitmap->width, bitmap->rows);
|
||||
if(ch < 0xF0)
|
||||
return 0x440-0xE0 + ch;
|
||||
|
||||
if(ch == 0xF0)
|
||||
return 0x401;
|
||||
else if(ch==0xF1)
|
||||
return 0x451;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
for( i = 0; i < bitmap->rows; i++ )
|
||||
{
|
||||
tmpdst = (uint32_t*)dst;
|
||||
tmpsrc = src;
|
||||
|
||||
dst+= win->pitch;
|
||||
src+= bitmap->pitch;
|
||||
|
||||
for( j = 0; j < bitmap->width; j++)
|
||||
{
|
||||
int a = *tmpsrc++;
|
||||
int sr, sg, sb;
|
||||
int dr, dg, db;
|
||||
|
||||
if( a != 0) a++;
|
||||
|
||||
db = *tmpdst & 0xFF;
|
||||
dg = (*tmpdst >> 8) & 0xFF;
|
||||
dr = (*tmpdst >> 16) & 0xFF;
|
||||
|
||||
sb = col & 0xFF;
|
||||
sg = (col >> 8) & 0xFF;
|
||||
sr = (col >> 16) &0xFF;
|
||||
|
||||
db = (a*sb + db*(256-a))/256;
|
||||
dg = (a*sg + dg*(256-a))/256;
|
||||
dr = (a*sr + dr*(256-a))/256;
|
||||
|
||||
*tmpdst++ = 0xFF000000|(dr<<16)|(dg<<8)|db;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int draw_text_ext(bitmap_t *winbitmap, font_t *font, char *text, int len, rect_t *rc, int color)
|
||||
int draw_text_ext(ctx_t *ctx, font_t *font, char *text, int len, rect_t *rc, color_t color)
|
||||
{
|
||||
FT_UInt glyph_index;
|
||||
FT_Bool use_kerning = 0;
|
||||
FT_BitmapGlyph glyph;
|
||||
FT_UInt previous;
|
||||
|
||||
int x, y, w;
|
||||
int x, y, xend;
|
||||
int col, ncol;
|
||||
unsigned char ch;
|
||||
int err = 0;
|
||||
@ -100,9 +70,8 @@ int draw_text_ext(bitmap_t *winbitmap, font_t *font, char *text, int len, rect_t
|
||||
col = 0;
|
||||
|
||||
x = rc->l << 6;
|
||||
y = rc->b;
|
||||
|
||||
w = (rc->r - rc->l) << 6;
|
||||
xend = rc->r << 6;
|
||||
y = rc->t + font->base;
|
||||
|
||||
while( len-- )
|
||||
{
|
||||
@ -113,7 +82,7 @@ int draw_text_ext(bitmap_t *winbitmap, font_t *font, char *text, int len, rect_t
|
||||
|
||||
if(ch == '\t')
|
||||
{
|
||||
ncol = (col+4) & ~3;
|
||||
ncol = (col+3) & ~4;
|
||||
if( col < ncol)
|
||||
{
|
||||
glyph_index = FT_Get_Char_Index( font->face, ansi2utf32(' ') );
|
||||
@ -127,7 +96,7 @@ int draw_text_ext(bitmap_t *winbitmap, font_t *font, char *text, int len, rect_t
|
||||
x += delta.x ;
|
||||
}
|
||||
|
||||
if( x + (font->glyph[ch]->advance.x >> 10) > w)
|
||||
if( x + (font->glyph[ch]->advance.x >> 10) >= xend)
|
||||
break;
|
||||
|
||||
x += font->glyph[ch]->advance.x >> 10;
|
||||
@ -147,15 +116,30 @@ int draw_text_ext(bitmap_t *winbitmap, font_t *font, char *text, int len, rect_t
|
||||
x += delta.x ;
|
||||
}
|
||||
|
||||
if( x + (font->glyph[ch]->advance.x >> 10) > w)
|
||||
// if( x + (font->glyph[ch]->advance.x >> 10) >= xend)
|
||||
// break;
|
||||
|
||||
if( x >= xend)
|
||||
break;
|
||||
|
||||
glyph = (FT_BitmapGlyph)font->glyph[ch];
|
||||
|
||||
my_draw_bitmap(winbitmap, &glyph->bitmap, (x >> 6) + glyph->left,
|
||||
y - glyph->top, color);
|
||||
if(glyph != NULL)
|
||||
{
|
||||
rect_t rc_dst;
|
||||
|
||||
x += font->glyph[ch]->advance.x >> 10;
|
||||
rc_dst.l = (x >> 6) + glyph->left;
|
||||
rc_dst.t = y - glyph->top;
|
||||
rc_dst.r = rc_dst.l + glyph->bitmap.width;
|
||||
if(rc_dst.r > (xend >> 6))
|
||||
rc_dst.r = xend >> 6;
|
||||
rc_dst.b = rc_dst.t + glyph->bitmap.rows;
|
||||
|
||||
// printf("char: %c ", ch);
|
||||
px_draw_glyph(ctx, glyph->bitmap.buffer, glyph->bitmap.pitch, &rc_dst, color);
|
||||
|
||||
x += font->glyph[ch]->advance.x >> 10;
|
||||
};
|
||||
previous = glyph_index;
|
||||
};
|
||||
|
||||
@ -180,7 +164,6 @@ int init_fontlib()
|
||||
// err = FT_New_Face( library, "/kolibrios/Fonts/lucon.ttf", 0, &face );
|
||||
|
||||
err = FT_New_Face( library, "/kolibrios/Fonts/DroidSansMono.ttf", 0, &face );
|
||||
|
||||
if ( err == FT_Err_Unknown_File_Format )
|
||||
{
|
||||
printf("font format is unsupported\n");
|
||||
@ -191,37 +174,33 @@ int init_fontlib()
|
||||
{
|
||||
printf("font file could not be read or broken\n");
|
||||
goto done;
|
||||
|
||||
}
|
||||
|
||||
def_face = face;
|
||||
|
||||
err = FT_New_Face( library, "/kolibrios/Fonts/Symbols.ttf", 0, &face );
|
||||
if ( err == FT_Err_Unknown_File_Format )
|
||||
{
|
||||
printf("font format is unsupported\n");
|
||||
goto done;
|
||||
|
||||
}
|
||||
else if ( err )
|
||||
{
|
||||
printf("font file could not be read or broken\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
sym_face = face;
|
||||
|
||||
sym_font = create_font(sym_face, 14);
|
||||
|
||||
done:
|
||||
|
||||
return err;
|
||||
};
|
||||
|
||||
|
||||
unsigned int ansi2utf32(unsigned char ch)
|
||||
{
|
||||
if(ch < 0x80)
|
||||
return ch;
|
||||
|
||||
if(ch < 0xB0)
|
||||
return 0x410-0x80 + ch;
|
||||
|
||||
if(ch < 0xE0)
|
||||
return 0;
|
||||
|
||||
if(ch < 0xF0)
|
||||
return 0x440-0xE0 + ch;
|
||||
|
||||
if(ch == 0xF0)
|
||||
return 0x401;
|
||||
else if(ch==0xF1)
|
||||
return 0x451;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
|
||||
font_t *create_font(FT_Face xface, int size)
|
||||
@ -236,7 +215,7 @@ font_t *create_font(FT_Face xface, int size)
|
||||
memset(font, 0, sizeof(*font));
|
||||
|
||||
font->face = (xface == NULL) ? def_face : xface;
|
||||
font->height = size+1;
|
||||
font->height = size;
|
||||
|
||||
err = FT_Set_Pixel_Sizes( font->face, 0, size );
|
||||
|
||||
@ -276,3 +255,9 @@ font_t *create_font(FT_Face xface, int size)
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
int get_font_height(font_t *font)
|
||||
{
|
||||
return font->height;
|
||||
}
|
||||
|
||||
|
@ -1,53 +1,36 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_GLYPH_H
|
||||
#include <kos32sys.h>
|
||||
#include <pixlib2.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int l;
|
||||
int t;
|
||||
int r;
|
||||
int b;
|
||||
}rect_t;
|
||||
#include "winlib.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
FT_Face face;
|
||||
int height;
|
||||
int base;
|
||||
|
||||
FT_Glyph glyph[256];
|
||||
typedef struct tview *tview_t;
|
||||
|
||||
}font_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bitmap_t bitmap;
|
||||
font_t *font;
|
||||
|
||||
char *text;
|
||||
char **line;
|
||||
int lines;
|
||||
int txlines;
|
||||
int startline;
|
||||
int endline;
|
||||
int w;
|
||||
int h;
|
||||
}tview_t;
|
||||
|
||||
int init_tview(tview_t *txv, int width, int height, char *text, int size);
|
||||
tview_t *create_tview(ctx_t *ctx, int width, int height);
|
||||
void txv_get_margins(const tview_t *txv, rect_t *margins);
|
||||
void txv_set_margins(tview_t *txv, const rect_t *margins);
|
||||
void txv_set_size(tview_t *txv, int txw, int txh);
|
||||
void txv_set_font_size(tview_t *txv, int size);
|
||||
|
||||
int txv_get_font_size(tview_t *txv);
|
||||
void txv_set_text(tview_t *txv, char *text, int size);
|
||||
int txv_scroll_up(tview_t *txv);
|
||||
int txv_scroll_down(tview_t *txv);
|
||||
int txv_page_up(tview_t *txv);
|
||||
int txv_page_down(tview_t *txv);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
volatile int lock;
|
||||
unsigned int handle;
|
||||
}mutex_t;
|
||||
|
||||
|
||||
void* init_fontlib();
|
||||
int draw_text_ext(bitmap_t *winbitmap, FT_Face face, char *text, int len, rect_t *rc, int color);
|
||||
|
||||
void draw_window(void)
|
||||
{
|
||||
@ -56,15 +39,21 @@ void draw_window(void)
|
||||
EndDraw();
|
||||
}
|
||||
|
||||
tview_t txv;
|
||||
tview_t *txv;
|
||||
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
ufile_t uf;
|
||||
oskey_t key;
|
||||
ufile_t uf;
|
||||
oskey_t key;
|
||||
ctx_t *ctx;
|
||||
rect_t margins = {4,2,20,0};
|
||||
|
||||
int clw = 640;
|
||||
int clh = 480;
|
||||
|
||||
|
||||
__asm__ __volatile__(
|
||||
"int $0x40"
|
||||
::"a"(40), "b"(0xc0000027));
|
||||
@ -74,19 +63,21 @@ int main(int argc, char *argv[])
|
||||
else uf = load_file(argv[1]);
|
||||
|
||||
if(uf.data == NULL ||
|
||||
uf.size == 0)
|
||||
return 0;
|
||||
uf.size == 0)
|
||||
return 0;
|
||||
|
||||
ctx = create_context(TYPE_3_BORDER_WIDTH, get_skin_height(), clw, clh);
|
||||
|
||||
init_pixlib(0);
|
||||
init_fontlib();
|
||||
|
||||
init_tview(&txv, clw, clh, uf.data, uf.size);
|
||||
txv = create_tview(ctx, clw, clh);
|
||||
txv_set_margins(txv, &margins);
|
||||
txv_set_text(txv, uf.data, uf.size);
|
||||
|
||||
BeginDraw();
|
||||
DrawWindow(10, 40, clw+TYPE_3_BORDER_WIDTH*2,
|
||||
clh+TYPE_3_BORDER_WIDTH+get_skin_height(), "Text example", 0x000000, 0x73);
|
||||
blit_bitmap(&txv.bitmap, TYPE_3_BORDER_WIDTH, get_skin_height(), txv.w, txv.h, 0, 0);
|
||||
|
||||
show_context(ctx);
|
||||
EndDraw();
|
||||
|
||||
for (;;)
|
||||
@ -102,8 +93,14 @@ int main(int argc, char *argv[])
|
||||
char proc_info[1024];
|
||||
int winx, winy, winw, winh;
|
||||
int txw, txh;
|
||||
char state;
|
||||
|
||||
draw_window();
|
||||
|
||||
get_proc_info(proc_info);
|
||||
state = *(char*)(proc_info+70);
|
||||
if(state & (WIN_STATE_MINIMIZED|WIN_STATE_ROLLED))
|
||||
continue;
|
||||
|
||||
winx = *(uint32_t*)(proc_info+34);
|
||||
winy = *(uint32_t*)(proc_info+38);
|
||||
@ -116,47 +113,56 @@ int main(int argc, char *argv[])
|
||||
if( (txw != clw) ||
|
||||
(txh != clh) )
|
||||
{
|
||||
txv_set_size(&txv, txw, txh);
|
||||
resize_context(ctx, txw, txh);
|
||||
txv_set_size(txv, txw, txh);
|
||||
clw = txw;
|
||||
clh = txh;
|
||||
};
|
||||
|
||||
draw_window();
|
||||
blit_bitmap(&txv.bitmap, TYPE_3_BORDER_WIDTH, get_skin_height(), txv.w, txv.h, 0, 0);
|
||||
show_context(ctx);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
key = get_key();
|
||||
printf("key %d\n", key.code);
|
||||
// printf("key %d\n", key.code);
|
||||
switch(key.code)
|
||||
{
|
||||
case 27:
|
||||
return;
|
||||
return 0;
|
||||
|
||||
case 45:
|
||||
txv_set_font_size(&txv, txv.font->height-3);
|
||||
blit_bitmap(&txv.bitmap, TYPE_3_BORDER_WIDTH, get_skin_height(), txv.w, txv.h, 0, 0);
|
||||
txv_set_font_size(txv, txv_get_font_size(txv) - 2);
|
||||
show_context(ctx);
|
||||
break;
|
||||
|
||||
case 61:
|
||||
txv_set_font_size(&txv, txv.font->height+1);
|
||||
blit_bitmap(&txv.bitmap, TYPE_3_BORDER_WIDTH, get_skin_height(), txv.w, txv.h, 0, 0);
|
||||
txv_set_font_size(txv, txv_get_font_size(txv) + 2);
|
||||
show_context(ctx);
|
||||
break;
|
||||
|
||||
case 177:
|
||||
if( txv_scroll_up(&txv) )
|
||||
blit_bitmap(&txv.bitmap, TYPE_3_BORDER_WIDTH, get_skin_height(), txv.w, txv.h, 0, 0);
|
||||
if( txv_scroll_down(txv) )
|
||||
show_context(ctx);
|
||||
break;
|
||||
|
||||
case 178:
|
||||
if( txv_scroll_down(&txv) )
|
||||
blit_bitmap(&txv.bitmap, TYPE_3_BORDER_WIDTH, get_skin_height(), txv.w, txv.h, 0, 0);
|
||||
if( txv_scroll_up(txv) )
|
||||
show_context(ctx);
|
||||
break;
|
||||
case 183:
|
||||
if( txv_page_down(txv) )
|
||||
show_context(ctx);
|
||||
break;
|
||||
case 184:
|
||||
if( txv_page_up(txv) )
|
||||
show_context(ctx);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// button pressed; we have only one button, close
|
||||
return;
|
||||
return 0;
|
||||
|
||||
case 6:
|
||||
// pos = get_mouse_pos();
|
||||
@ -165,15 +171,15 @@ int main(int argc, char *argv[])
|
||||
|
||||
if( wheels & 0xFFFF)
|
||||
{
|
||||
int r;
|
||||
int r = 0;
|
||||
|
||||
if((short)wheels > 0)
|
||||
r = txv_scroll_up(&txv);
|
||||
else
|
||||
r = txv_scroll_down(&txv);
|
||||
r = txv_scroll_down(txv);
|
||||
else if((short)wheels < 0)
|
||||
r = txv_scroll_up(txv);
|
||||
|
||||
if( r )
|
||||
blit_bitmap(&txv.bitmap, TYPE_3_BORDER_WIDTH, get_skin_height(), txv.w, txv.h, 0, 0);
|
||||
show_context(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
339
contrib/sdk/samples/freetype/txview/pxdraw/context.c
Normal file
339
contrib/sdk/samples/freetype/txview/pxdraw/context.c
Normal file
@ -0,0 +1,339 @@
|
||||
#include <stdlib.h>
|
||||
#include <kos32sys.h>
|
||||
#include "pxdraw.h"
|
||||
#include "internal.h"
|
||||
|
||||
ctx_t* create_context(int x, int y, int width, int height)
|
||||
{
|
||||
ctx_t *ctx;
|
||||
|
||||
ctx = malloc(sizeof(ctx_t));
|
||||
if (ctx == NULL)
|
||||
goto err_0;
|
||||
|
||||
ctx->pitch = ALIGN(width * sizeof(color_t), 16);
|
||||
ctx->size = ALIGN(ctx->pitch * height, 4096);
|
||||
|
||||
ctx->buffer = user_alloc(ctx->size+4096);
|
||||
if (ctx->buffer == NULL)
|
||||
goto err_1;
|
||||
|
||||
ctx->x = x;
|
||||
ctx->y = y;
|
||||
ctx->width = width;
|
||||
ctx->height = height;
|
||||
|
||||
ctx->rc.l = 0;
|
||||
ctx->rc.t = 0;
|
||||
ctx->rc.r = width;
|
||||
ctx->rc.b = height;
|
||||
|
||||
ctx->rcu.l = 0;
|
||||
ctx->rcu.t = 0;
|
||||
ctx->rcu.r = ctx->width;
|
||||
ctx->rcu.b = ctx->height;
|
||||
ctx->dirty = 1;
|
||||
|
||||
__builtin_cpu_init ();
|
||||
if (__builtin_cpu_supports ("sse2"))
|
||||
ctx->px_rect_simd = px_rect_xmm;
|
||||
else if (__builtin_cpu_supports ("mmx"))
|
||||
ctx->px_rect_simd = px_rect_mmx;
|
||||
else
|
||||
ctx->px_rect_simd = px_rect_alu;
|
||||
|
||||
if (__builtin_cpu_supports ("sse2"))
|
||||
ctx->px_glyph = px_glyph_sse;
|
||||
else
|
||||
ctx->px_glyph = px_glyph_alu;
|
||||
|
||||
return ctx;
|
||||
|
||||
err_1:
|
||||
free(ctx);
|
||||
err_0:
|
||||
return NULL;
|
||||
};
|
||||
|
||||
int resize_context(ctx_t *ctx, int width, int height)
|
||||
{
|
||||
int size;
|
||||
int pitch;
|
||||
|
||||
pitch = ALIGN(width * sizeof(color_t), 16);
|
||||
size = ALIGN(pitch * height, 4096);
|
||||
|
||||
if (size > ctx->size)
|
||||
{
|
||||
ctx->buffer = user_realloc(ctx->buffer, size); /* grow buffer */
|
||||
if (ctx->buffer == NULL)
|
||||
return -1;
|
||||
|
||||
ctx->size = size;
|
||||
}
|
||||
else if (size < ctx->size)
|
||||
user_unmap(ctx->buffer, size, ctx->size - size); /* unmap unused pages */
|
||||
|
||||
ctx->width = width;
|
||||
ctx->height = height;
|
||||
ctx->pitch = pitch;
|
||||
|
||||
ctx->rc.l = 0;
|
||||
ctx->rc.t = 0;
|
||||
ctx->rc.r = width;
|
||||
ctx->rc.b = height;
|
||||
|
||||
ctx->rcu.l = ctx->rcu.t = 0;
|
||||
ctx->rcu.r = ctx->rcu.b = 0;
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
void clear_context(ctx_t *ctx, color_t color)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
size = ctx->pitch * ctx->height;
|
||||
|
||||
if (size >= 1024)
|
||||
ctx->px_rect_simd(ctx->buffer, ctx->pitch, ctx->width, ctx->height, color);
|
||||
else
|
||||
px_rect_alu(ctx->buffer, ctx->pitch, ctx->width, ctx->height, color);
|
||||
|
||||
ctx->rcu.l = 0;
|
||||
ctx->rcu.t = 0;
|
||||
ctx->rcu.r = ctx->width;
|
||||
ctx->rcu.b = ctx->height;
|
||||
ctx->dirty = 1;
|
||||
};
|
||||
|
||||
void show_context(ctx_t *ctx)
|
||||
{
|
||||
struct blit_call bc;
|
||||
int ret;
|
||||
|
||||
bc.dstx = ctx->x;
|
||||
bc.dsty = ctx->y;
|
||||
bc.w = ctx->width;
|
||||
bc.h = ctx->height;
|
||||
bc.srcx = 0;
|
||||
bc.srcy = 0;
|
||||
bc.srcw = ctx->width;
|
||||
bc.srch = ctx->height;
|
||||
bc.stride = ctx->pitch;
|
||||
bc.bitmap = ctx->buffer;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"int $0x40":"=a"(ret):"a"(73), "b"(0x00),
|
||||
"c"(&bc):"memory");
|
||||
|
||||
ctx->dirty = 0;
|
||||
};
|
||||
|
||||
void scroll_context(ctx_t *ctx, int dst_y, int src_y, int rows)
|
||||
{
|
||||
char *dst;
|
||||
char *src;
|
||||
|
||||
dst = ctx->buffer + dst_y * ctx->pitch;
|
||||
src = ctx->buffer + src_y * ctx->pitch;
|
||||
|
||||
__builtin_memmove(dst, src, rows * ctx->pitch);
|
||||
ctx->dirty = 1;
|
||||
}
|
||||
|
||||
static int clip_rect(const rect_t *clip, rect_t *rc)
|
||||
{
|
||||
if (rc->l > rc->r)
|
||||
return 1;
|
||||
if (rc->t > rc->b)
|
||||
return 1;
|
||||
|
||||
if (rc->l < clip->l)
|
||||
rc->l = clip->l;
|
||||
else if (rc->l >= clip->r)
|
||||
return 1;
|
||||
|
||||
if (rc->t < clip->t)
|
||||
rc->t = clip->t;
|
||||
else if (rc->t >= clip->b)
|
||||
return 1;
|
||||
|
||||
if (rc->r < clip->l)
|
||||
return 1;
|
||||
else if (rc->r > clip->r)
|
||||
rc->r = clip->r;
|
||||
|
||||
if (rc->b < clip->t)
|
||||
return 1;
|
||||
else if (rc->b > clip->b)
|
||||
rc->b = clip->b;
|
||||
|
||||
if ((rc->l == rc->r) ||
|
||||
(rc->t == rc->b))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int px_hline(ctx_t*ctx, int x, int y, int width, color_t color)
|
||||
{
|
||||
char *dst_addr;
|
||||
|
||||
int xr = x + width;
|
||||
|
||||
if(y < ctx->rc.t)
|
||||
return 0;
|
||||
else if(y >= ctx->rc.b)
|
||||
return 0;
|
||||
|
||||
if(x < ctx->rc.l)
|
||||
x = ctx->rc.l;
|
||||
else if(x >= ctx->rc.r)
|
||||
return 0;
|
||||
|
||||
if(xr <= ctx->rc.l)
|
||||
return 0;
|
||||
else if(xr > ctx->rc.r)
|
||||
xr = ctx->rc.r;
|
||||
|
||||
dst_addr = ctx->buffer;
|
||||
dst_addr+= ctx->pitch * y + x * sizeof(color_t);
|
||||
|
||||
__asm__ __volatile__
|
||||
(" cld; rep stosl\n\t"
|
||||
:: "D" (dst_addr),"c" (xr-x), "a" (color)
|
||||
: "flags");
|
||||
};
|
||||
|
||||
void px_vline(ctx_t*ctx, int x, int y, int height, color_t color)
|
||||
{
|
||||
char *dst_addr;
|
||||
|
||||
int yb = y + height;
|
||||
|
||||
if(x < ctx->rc.l)
|
||||
return;
|
||||
else if(x >= ctx->rc.r)
|
||||
return;
|
||||
|
||||
if(y < ctx->rc.t)
|
||||
y = ctx->rc.t;
|
||||
else if(y >= ctx->rc.b)
|
||||
return;
|
||||
|
||||
if(yb <= ctx->rc.t)
|
||||
return;
|
||||
else if(yb > ctx->rc.b)
|
||||
yb = ctx->rc.b;
|
||||
|
||||
dst_addr = ctx->buffer;
|
||||
dst_addr+= ctx->pitch * y + x * sizeof(color_t);
|
||||
|
||||
while(y < yb)
|
||||
{
|
||||
color_t *t = (color_t*)dst_addr;
|
||||
*t = color;
|
||||
y++;
|
||||
dst_addr+= ctx->pitch;
|
||||
};
|
||||
};
|
||||
|
||||
static int do_fill_rect(ctx_t *ctx, rect_t *rc, color_t color)
|
||||
{
|
||||
if (!clip_rect(&ctx->rc, rc))
|
||||
{
|
||||
int w, h;
|
||||
char *dst_addr;
|
||||
|
||||
w = rc->r - rc->l;
|
||||
h = rc->b - rc->t;
|
||||
|
||||
dst_addr = ctx->buffer;
|
||||
dst_addr += ctx->pitch * rc->t + rc->l * sizeof(color_t);
|
||||
if (w * h >= 256)
|
||||
ctx->px_rect_simd(dst_addr, ctx->pitch, w, h, color);
|
||||
else
|
||||
px_rect_alu(dst_addr, ctx->pitch, w, h, color);
|
||||
return 1;
|
||||
};
|
||||
return 0;
|
||||
};
|
||||
|
||||
void px_fill_rect(ctx_t *ctx, const rect_t *src, color_t color)
|
||||
{
|
||||
rect_t rc = *src;
|
||||
int update;
|
||||
|
||||
update = do_fill_rect(ctx, &rc, color);
|
||||
|
||||
if(update)
|
||||
{
|
||||
if (rc.l < ctx->rcu.l)
|
||||
ctx->rcu.l = rc.l;
|
||||
if (rc.t < ctx->rcu.t)
|
||||
ctx->rcu.t = rc.t;
|
||||
if (rc.r > ctx->rcu.r)
|
||||
ctx->rcu.r = rc.r;
|
||||
if (rc.b > ctx->rcu.b)
|
||||
ctx->rcu.b = rc.b;
|
||||
ctx->dirty = 1;
|
||||
};
|
||||
}
|
||||
|
||||
void px_fill_region(ctx_t *ctx, const rgn_t *rgn, color_t color)
|
||||
{
|
||||
int update = 0;
|
||||
|
||||
for (int i = 0; i < rgn->num_rects; i++)
|
||||
{
|
||||
rect_t rc = rgn->rects[i];
|
||||
update |= do_fill_rect(ctx, &rc, color);
|
||||
}
|
||||
|
||||
if (update)
|
||||
{
|
||||
if (rgn->extents.l < ctx->rcu.l)
|
||||
ctx->rcu.l = rgn->extents.l;
|
||||
if (rgn->extents.t < ctx->rcu.t)
|
||||
ctx->rcu.t = rgn->extents.t;
|
||||
if (rgn->extents.r > ctx->rcu.r)
|
||||
ctx->rcu.r = rgn->extents.r;
|
||||
if (rgn->extents.b > ctx->rcu.b)
|
||||
ctx->rcu.b = rgn->extents.b;
|
||||
ctx->dirty = 1;
|
||||
};
|
||||
}
|
||||
|
||||
void px_draw_glyph(ctx_t *ctx, const void *buffer, int pitch, const rect_t *rc, color_t color)
|
||||
{
|
||||
rect_t rc_dst = *rc;
|
||||
int srcx, srcy;
|
||||
|
||||
if (!clip_rect(&ctx->rc, &rc_dst))
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
unsigned char *dst = ctx->buffer;
|
||||
const unsigned char *src = buffer;
|
||||
|
||||
width = rc_dst.r - rc_dst.l;
|
||||
height = rc_dst.b - rc_dst.t;
|
||||
|
||||
srcx = rc_dst.l - rc->l;
|
||||
srcy = rc_dst.t - rc->t;
|
||||
dst += ctx->pitch * rc_dst.t + rc_dst.l * sizeof(color_t);
|
||||
src += pitch * srcy + srcx;
|
||||
ctx->px_glyph(dst, ctx->pitch, src, pitch, width, height, color);
|
||||
|
||||
if (rc_dst.l < ctx->rcu.l)
|
||||
ctx->rcu.l = rc_dst.l;
|
||||
if (rc_dst.t < ctx->rcu.t)
|
||||
ctx->rcu.t = rc_dst.t;
|
||||
if (rc_dst.r > ctx->rcu.r)
|
||||
ctx->rcu.r = rc_dst.r;
|
||||
if (rc_dst.b > ctx->rcu.b)
|
||||
ctx->rcu.b = rc_dst.b;
|
||||
|
||||
ctx->dirty = 1;
|
||||
};
|
||||
};
|
226
contrib/sdk/samples/freetype/txview/pxdraw/dutils.c
Normal file
226
contrib/sdk/samples/freetype/txview/pxdraw/dutils.c
Normal file
@ -0,0 +1,226 @@
|
||||
#include <mmintrin.h>
|
||||
#include <xmmintrin.h>
|
||||
#include <emmintrin.h>
|
||||
|
||||
typedef unsigned int color_t;
|
||||
|
||||
void px_rect_alu(void *dst_addr, int pitch, int w, int h, color_t src_color)
|
||||
{
|
||||
while (h--)
|
||||
{
|
||||
char *tmp = dst_addr;
|
||||
dst_addr = tmp + pitch;
|
||||
__asm__ __volatile__(
|
||||
"cld; rep stosl\n\t"
|
||||
:: "D"(tmp), "a"(src_color), "c"(w)
|
||||
: "flags");
|
||||
};
|
||||
};
|
||||
|
||||
void px_rect_mmx(void *dst_addr, int pitch, int w, int h, color_t src_color)
|
||||
{
|
||||
register __m64 color;
|
||||
|
||||
color = _mm_cvtsi32_si64(src_color);
|
||||
color = _mm_unpacklo_pi32(color, color);
|
||||
|
||||
while (h--)
|
||||
{
|
||||
char *tmp = dst_addr;
|
||||
char *end = tmp + w * sizeof(color_t);
|
||||
dst_addr = tmp + pitch;
|
||||
|
||||
int t = (int)tmp;
|
||||
if (t & 4)
|
||||
{
|
||||
*(color_t*)tmp = src_color;
|
||||
tmp += 4;
|
||||
};
|
||||
|
||||
while (tmp + 64 <= end)
|
||||
{
|
||||
__m64 *_tmp = (__m64*)tmp;
|
||||
_tmp[0] = color;
|
||||
_tmp[1] = color;
|
||||
_tmp[2] = color;
|
||||
_tmp[3] = color;
|
||||
_tmp[4] = color;
|
||||
_tmp[5] = color;
|
||||
_tmp[6] = color;
|
||||
_tmp[7] = color;
|
||||
tmp += 64;
|
||||
};
|
||||
if (tmp + 32 <= end)
|
||||
{
|
||||
__m64 *_tmp = (__m64*)tmp;
|
||||
_tmp[0] = color;
|
||||
_tmp[1] = color;
|
||||
_tmp[2] = color;
|
||||
_tmp[3] = color;
|
||||
tmp += 32;
|
||||
};
|
||||
if (tmp + 16 <= end)
|
||||
{
|
||||
__m64 *_tmp = (__m64*)tmp;
|
||||
_tmp[0] = color;
|
||||
_tmp[1] = color;
|
||||
tmp += 16;
|
||||
};
|
||||
if (tmp + 8 <= end)
|
||||
{
|
||||
__m64 *_tmp = (__m64*)tmp;
|
||||
_tmp[0] = color;
|
||||
tmp += 8;
|
||||
};
|
||||
if (tmp < end)
|
||||
*(color_t*)tmp = src_color;
|
||||
};
|
||||
_mm_empty();
|
||||
};
|
||||
|
||||
void px_rect_xmm(void *dst_addr, int pitch, int w, int h, color_t dst_color)
|
||||
{
|
||||
__m128i color;
|
||||
|
||||
color = _mm_set_epi32(dst_color, dst_color, dst_color, dst_color);
|
||||
|
||||
while (h--)
|
||||
{
|
||||
char *tmp = dst_addr;
|
||||
char *end = tmp + w * sizeof(color_t);
|
||||
dst_addr = tmp + pitch;
|
||||
|
||||
if ((int)tmp & 4)
|
||||
{
|
||||
*(color_t*)tmp = dst_color;
|
||||
tmp += 4;
|
||||
};
|
||||
if ((int)tmp & 8)
|
||||
{
|
||||
__m128i *_tmp = (__m128i*)tmp;
|
||||
_mm_storel_epi64(_tmp, color);
|
||||
tmp += 8;
|
||||
};
|
||||
|
||||
while (tmp + 128 <= end)
|
||||
{
|
||||
__m128i *_tmp = (__m128i*)tmp;
|
||||
_mm_store_si128(&_tmp[0], color);
|
||||
_mm_store_si128(&_tmp[1], color);
|
||||
_mm_store_si128(&_tmp[2], color);
|
||||
_mm_store_si128(&_tmp[3], color);
|
||||
_mm_store_si128(&_tmp[4], color);
|
||||
_mm_store_si128(&_tmp[5], color);
|
||||
_mm_store_si128(&_tmp[6], color);
|
||||
_mm_store_si128(&_tmp[7], color);
|
||||
tmp += 128;
|
||||
};
|
||||
if (tmp + 64 <= end)
|
||||
{
|
||||
__m128i *_tmp = (__m128i*)tmp;
|
||||
_mm_store_si128(&_tmp[0], color);
|
||||
_mm_store_si128(&_tmp[1], color);
|
||||
_mm_store_si128(&_tmp[2], color);
|
||||
_mm_store_si128(&_tmp[3], color);
|
||||
tmp += 64;
|
||||
};
|
||||
if (tmp + 32 <= end)
|
||||
{
|
||||
__m128i *_tmp = (__m128i*)tmp;
|
||||
_mm_store_si128(&_tmp[0], color);
|
||||
_mm_store_si128(&_tmp[1], color);
|
||||
tmp += 32;
|
||||
};
|
||||
if (tmp + 16 <= end)
|
||||
{
|
||||
__m128i *_tmp = (__m128i*)tmp;
|
||||
_mm_store_si128(&_tmp[0], color);
|
||||
tmp += 16;
|
||||
};
|
||||
if (tmp + 8 <= end)
|
||||
{
|
||||
__m128i *_tmp = (__m128i*)tmp;
|
||||
_mm_storel_epi64(_tmp, color);
|
||||
tmp += 8;
|
||||
};
|
||||
if (tmp < end)
|
||||
*(color_t*)tmp = dst_color;
|
||||
};
|
||||
}
|
||||
|
||||
void px_glyph_alu(void *dst_addr, int dst_pitch,const void *src_addr, int src_pitch,
|
||||
int width, int height, color_t src_color)
|
||||
{
|
||||
while (height-- > 0)
|
||||
{
|
||||
int w = width;
|
||||
const unsigned char *src = src_addr;
|
||||
color_t *dst = dst_addr;
|
||||
|
||||
dst_addr = (char*)dst + dst_pitch;
|
||||
src_addr = src + src_pitch;
|
||||
|
||||
while (w-- > 0)
|
||||
{
|
||||
unsigned char a = *src++;
|
||||
color_t dst_color = *(color_t*)dst;
|
||||
unsigned int rb = dst_color & 0xff00ff;
|
||||
unsigned int g = dst_color & 0x00ff00;
|
||||
|
||||
rb += ((src_color & 0xff00ff) - rb) * a >> 8;
|
||||
g += ((src_color & 0x00ff00) - g) * a >> 8;
|
||||
|
||||
*dst++ = (src_color & 0xFF000000) | (rb & 0xff00ff) | (g & 0xff00);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
__m64 m_4x0080 = { 0x00800080, 0x00800080 };
|
||||
__m64 m_4x0101 = { 0x01010101, 0x01010101 };
|
||||
__m64 m_4x00FF = { 0x00FF00FF, 0x00FF00FF };
|
||||
__m64 m_zero = { 0 };
|
||||
|
||||
void px_glyph_sse(void *dst_addr, int dst_pitch, const void *src_addr, int src_pitch,
|
||||
int width, int height, color_t src_color)
|
||||
{
|
||||
static __m64 m_4x0080 = { 0x00800080, 0x00800080 };
|
||||
static __m64 m_4x0101 = { 0x01010101, 0x01010101 };
|
||||
static __m64 m_4x00FF = { 0x00FF00FF, 0x00FF00FF };
|
||||
static __m64 m_zero = { 0 };
|
||||
|
||||
__m64 color;
|
||||
|
||||
color = _mm_cvtsi32_si64(src_color);
|
||||
color = _m_punpcklbw(color, m_zero);
|
||||
while (height-- > 0)
|
||||
{
|
||||
int w = width;
|
||||
const unsigned char *tmpsrc = src_addr;
|
||||
color_t *tmpdst = dst_addr;
|
||||
|
||||
dst_addr = (char*)tmpdst + dst_pitch;
|
||||
src_addr = tmpsrc + src_pitch;
|
||||
|
||||
while (w-- > 0)
|
||||
{
|
||||
__m64 m_alpha, m_1_minus_alpha;
|
||||
__m64 src_alpha, dst_color;
|
||||
|
||||
unsigned int alpha = *tmpsrc++;
|
||||
m_alpha = _mm_cvtsi32_si64((alpha << 16) | alpha);
|
||||
dst_color = _mm_cvtsi32_si64(*(int*)tmpdst);
|
||||
|
||||
m_alpha = _mm_unpacklo_pi32(m_alpha, m_alpha);
|
||||
m_1_minus_alpha = _m_psubb(m_4x00FF, m_alpha);
|
||||
dst_color = _m_punpcklbw(dst_color, m_zero);
|
||||
src_alpha = _m_pmullw(color, m_alpha);
|
||||
dst_color = _m_pmullw(dst_color, m_1_minus_alpha);
|
||||
dst_color = _m_paddw(src_alpha, dst_color);
|
||||
dst_color = _m_paddw(dst_color, m_4x0080);
|
||||
dst_color = _mm_mulhi_pu16(dst_color, m_4x0101);
|
||||
dst_color = _mm_packs_pu16(dst_color, dst_color);
|
||||
*tmpdst++ = _mm_cvtsi64_si32(dst_color);
|
||||
};
|
||||
}
|
||||
_mm_empty();
|
||||
};
|
31
contrib/sdk/samples/freetype/txview/pxdraw/internal.h
Normal file
31
contrib/sdk/samples/freetype/txview/pxdraw/internal.h
Normal file
@ -0,0 +1,31 @@
|
||||
|
||||
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
|
||||
#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
|
||||
|
||||
struct context
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
rect_t rc;
|
||||
rect_t rcu;
|
||||
void *buffer;
|
||||
size_t pitch;
|
||||
size_t size;
|
||||
int dirty;
|
||||
void (*px_rect_simd)(void *dst_addr, int pitch, int w, int h, color_t dst_color);
|
||||
void (*px_glyph)(void *dst_addr, int dst_pitch, const void *src_addr, int src_pitch,
|
||||
int width, int height, color_t src_color);
|
||||
};
|
||||
|
||||
|
||||
void px_rect_alu(void *dst_addr, int pitch, int w, int h, color_t src_color);
|
||||
void px_rect_mmx(void *dst_addr, int pitch, int w, int h, color_t src_color);
|
||||
void px_rect_xmm(void *dst_addr, int pitch, int w, int h, color_t dst_color);
|
||||
void px_glyph_alu(void *dst_addr, int dst_pitch,const void *src_addr,
|
||||
int src_pitch, int width, int height, color_t src_color);
|
||||
|
||||
void px_glyph_sse(void *dst_addr, int dst_pitch, const void *src_addr,
|
||||
int src_pitch, int width, int height, color_t src_color);
|
||||
|
46
contrib/sdk/samples/freetype/txview/pxdraw/pxdraw.h
Normal file
46
contrib/sdk/samples/freetype/txview/pxdraw/pxdraw.h
Normal file
@ -0,0 +1,46 @@
|
||||
#ifndef __PXDRAW_H__
|
||||
#define __PXDRAW_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef unsigned int color_t;
|
||||
typedef struct context ctx_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int l;
|
||||
int t;
|
||||
int r;
|
||||
int b;
|
||||
}rect_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int num_rects;
|
||||
rect_t *rects;
|
||||
rect_t extents;
|
||||
}rgn_t;
|
||||
|
||||
rgn_t* create_round_rect_rgn(int left, int top, int right, int bottom,
|
||||
int ellipse_width, int ellipse_height);
|
||||
void destroy_region(rgn_t *rgn);
|
||||
|
||||
ctx_t* create_context(int x, int y, int width, int height);
|
||||
int resize_context(ctx_t *ctx, int width, int height);
|
||||
void clear_context(ctx_t *ctx, color_t color);
|
||||
void show_context(ctx_t *ctx);
|
||||
void scroll_context(ctx_t *ctx, int dst_y, int src_y, int rows);
|
||||
|
||||
int px_hline(ctx_t*ctx, int x, int y, int width, color_t color);
|
||||
void px_vline(ctx_t*ctx, int x, int y, int height, color_t color);
|
||||
void px_fill_rect(ctx_t *ctx, const rect_t *src, color_t color);
|
||||
void px_draw_glyph(ctx_t *ctx, const void *buffer, int pitch, const rect_t *rc, color_t color);
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __PXDRAW_H__ */
|
93
contrib/sdk/samples/freetype/txview/pxdraw/region.c
Normal file
93
contrib/sdk/samples/freetype/txview/pxdraw/region.c
Normal file
@ -0,0 +1,93 @@
|
||||
#include <stdlib.h>
|
||||
#include "pxdraw.h"
|
||||
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
rgn_t* create_round_rect_rgn(int left, int top, int right, int bottom,
|
||||
int ellipse_width, int ellipse_height)
|
||||
{
|
||||
rgn_t *obj;
|
||||
rect_t *rects;
|
||||
int a, b, i, x, y;
|
||||
int64_t asq, bsq, dx, dy, err;
|
||||
|
||||
right--;
|
||||
bottom--;
|
||||
|
||||
ellipse_width = min(right - left, abs(ellipse_width));
|
||||
ellipse_height = min(bottom - top, abs(ellipse_height));
|
||||
|
||||
obj = malloc(sizeof(rgn_t));
|
||||
if (obj == NULL)
|
||||
return NULL;
|
||||
|
||||
obj->num_rects = ellipse_height;
|
||||
obj->extents.l = left;
|
||||
obj->extents.t = top;
|
||||
obj->extents.r = right;
|
||||
obj->extents.b = bottom;
|
||||
|
||||
obj->rects = rects = malloc(obj->num_rects * sizeof(rect_t));
|
||||
if (rects == NULL)
|
||||
{
|
||||
free(obj);
|
||||
return NULL;
|
||||
};
|
||||
|
||||
/* based on an algorithm by Alois Zingl */
|
||||
|
||||
a = ellipse_width - 1;
|
||||
b = ellipse_height - 1;
|
||||
asq = (int64_t)8 * a * a;
|
||||
bsq = (int64_t)8 * b * b;
|
||||
dx = (int64_t)4 * b * b * (1 - a);
|
||||
dy = (int64_t)4 * a * a * (1 + (b % 2));
|
||||
err = dx + dy + a * a * (b % 2);
|
||||
|
||||
x = 0;
|
||||
y = ellipse_height / 2;
|
||||
|
||||
rects[y].l = left;
|
||||
rects[y].r = right;
|
||||
|
||||
while (x <= ellipse_width / 2)
|
||||
{
|
||||
int64_t e2 = 2 * err;
|
||||
if (e2 >= dx)
|
||||
{
|
||||
x++;
|
||||
err += dx += bsq;
|
||||
}
|
||||
if (e2 <= dy)
|
||||
{
|
||||
y++;
|
||||
err += dy += asq;
|
||||
rects[y].l = left + x;
|
||||
rects[y].r = right - x;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ellipse_height / 2; i++)
|
||||
{
|
||||
rects[i].l = rects[b - i].l;
|
||||
rects[i].r = rects[b - i].r;
|
||||
rects[i].t = top + i;
|
||||
rects[i].b = rects[i].t + 1;
|
||||
}
|
||||
for (; i < ellipse_height; i++)
|
||||
{
|
||||
rects[i].t = bottom - ellipse_height + i;
|
||||
rects[i].b = rects[i].t + 1;
|
||||
}
|
||||
rects[ellipse_height / 2].t = top + ellipse_height / 2; /* extend to top of rectangle */
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
void destroy_region(rgn_t *rgn)
|
||||
{
|
||||
free(rgn->rects);
|
||||
free(rgn);
|
||||
};
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_GLYPH_H
|
||||
#include "winlib.h"
|
||||
#include "draw2.h"
|
||||
|
||||
int init_fontlib();
|
||||
font_t *create_font(FT_Face face, int size);
|
||||
@ -87,7 +86,12 @@ static void txv_redraw(tview_t *txv)
|
||||
rect_t rc;
|
||||
int i;
|
||||
|
||||
draw_rect(txv->ctx, 0, 0, txv->w, txv->h, 0xFFFFFFFF);
|
||||
rc.l = 0;
|
||||
rc.t = 0;
|
||||
rc.r = txv->w;
|
||||
rc.b = txv->h;
|
||||
|
||||
px_fill_rect(txv->ctx, &rc, 0xFFFFFFFF);
|
||||
|
||||
rc.l = txv->margins.l;
|
||||
rc.t = txv->margins.t;
|
||||
@ -162,14 +166,14 @@ int txv_scroll_down(tview_t *txv)
|
||||
dst = txv->margins.t;
|
||||
src = dst + txv->line_height;
|
||||
rows = txv->line_height * (txv->pagesize-1);
|
||||
scroll_ctx(txv->ctx, dst, src, rows );
|
||||
scroll_context(txv->ctx, dst, src, rows );
|
||||
|
||||
rc.l = txv->margins.l;
|
||||
rc.t = txv->margins.t + rows;
|
||||
rc.r = txv->w - txv->margins.r;
|
||||
rc.b = rc.t + txv->line_height;
|
||||
|
||||
draw_rect(txv->ctx, rc.l, rc.t, rc.r - rc.l, txv->line_height, 0xFFFFFFFF);
|
||||
px_fill_rect(txv->ctx, &rc, 0xFFFFFFFF);
|
||||
|
||||
draw_text_ext(txv->ctx, txv->font, txv->line[txv->endline],
|
||||
txv->line[txv->endline+1]-txv->line[txv->endline], &rc, 0xFF000000);
|
||||
@ -181,7 +185,7 @@ int txv_scroll_down(tview_t *txv)
|
||||
{
|
||||
rc.t+= txv->line_height;
|
||||
rc.b+= txv->line_height;
|
||||
draw_rect(txv->ctx, rc.l, rc.t, rc.r - rc.l, txv->line_height, 0xFFFFFFFF);
|
||||
px_fill_rect(txv->ctx, &rc, 0xFFFFFFFF);
|
||||
draw_text_ext(txv->ctx, txv->font, txv->line[txv->endline],
|
||||
txv->line[txv->endline+1]-txv->line[txv->endline], &rc, 0xFF000000);
|
||||
}
|
||||
@ -202,14 +206,14 @@ int txv_scroll_up(tview_t *txv)
|
||||
src = txv->margins.t;
|
||||
dst = src + txv->line_height;
|
||||
|
||||
scroll_ctx(txv->ctx, dst, src, rows);
|
||||
scroll_context(txv->ctx, dst, src, rows);
|
||||
|
||||
rc.l = txv->margins.l;
|
||||
rc.t = txv->margins.t;
|
||||
rc.r = txv->w - txv->margins.r;
|
||||
rc.b = rc.t + txv->line_height;
|
||||
|
||||
draw_rect(txv->ctx, rc.l, rc.t, rc.r - rc.l, txv->line_height, 0xFFFFFFFF);
|
||||
px_fill_rect(txv->ctx, &rc, 0xFFFFFFFF);
|
||||
|
||||
txv->startline--;
|
||||
txv->endline--;
|
||||
|
158
contrib/sdk/samples/freetype/txview/winlib/button.c
Normal file
158
contrib/sdk/samples/freetype/txview/winlib/button.c
Normal file
@ -0,0 +1,158 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "winlib.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ctrl_t ctrl;
|
||||
|
||||
uint32_t state;
|
||||
|
||||
char *caption;
|
||||
int capt_len;
|
||||
}button_t;
|
||||
|
||||
static void button_on_draw(button_t *btn)
|
||||
{
|
||||
color_t color = 0xFFD7D7D7;
|
||||
char t = (char)btn->ctrl.id;
|
||||
rect_t rc, rci;
|
||||
|
||||
if(btn->ctrl.style & 1)
|
||||
{
|
||||
send_message(btn->ctrl.parent, MSG_OWNERDRAW, btn, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if(btn->state & bPressed)
|
||||
color = 0xFFB0B0B0;
|
||||
else if(btn->state & bHighlight)
|
||||
color = 0xFFE7E7E7;
|
||||
|
||||
rc = rci = btn->ctrl.rc;
|
||||
rci.l++;
|
||||
rci.t++;
|
||||
|
||||
px_hline(btn->ctrl.ctx, rc.l, rc.t, btn->ctrl.w, 0xFF646464);
|
||||
px_fill_rect(btn->ctrl.ctx, &rci, color);
|
||||
px_hline(btn->ctrl.ctx, rc.l, rc.b-1, btn->ctrl.w, 0xFF646464);
|
||||
px_vline(btn->ctrl.ctx, rc.l, rc.t+1, btn->ctrl.h-2, 0xFF646464);
|
||||
px_vline(btn->ctrl.ctx, rc.r-1, rc.t+1, btn->ctrl.h-2, 0xFF646464);
|
||||
|
||||
rc.l+= 4;
|
||||
rc.t+= 6;
|
||||
|
||||
draw_text_ext(btn->ctrl.ctx, btn->ctrl.font, btn->caption, btn->capt_len, &rc, 0xFF000000);
|
||||
};
|
||||
|
||||
static void button_on_mouseenter(button_t *btn)
|
||||
{
|
||||
btn->state|= bHighlight;
|
||||
send_message(&btn->ctrl, MSG_DRAW, 0, 0);
|
||||
}
|
||||
|
||||
static void button_on_mouseleave(button_t *btn)
|
||||
{
|
||||
if( (ctrl_t*)btn != mouse_capture) {
|
||||
btn->state &= ~bHighlight;
|
||||
send_message(&btn->ctrl, MSG_DRAW, 0, 0);
|
||||
};
|
||||
}
|
||||
|
||||
static void button_on_lbuttondown(button_t *btn, int x, int y)
|
||||
{
|
||||
capture_mouse((ctrl_t*)btn);
|
||||
btn->state|= bPressed;
|
||||
send_message(&btn->ctrl, MSG_DRAW, 0, 0);
|
||||
};
|
||||
|
||||
static void button_on_lbuttonup(button_t *btn, int x, int y)
|
||||
{
|
||||
int action;
|
||||
|
||||
action = (btn->state & bPressed) ? MSG_COMMAND : 0;
|
||||
|
||||
release_mouse();
|
||||
|
||||
if( pt_in_rect( &btn->ctrl.rc, x, y) )
|
||||
btn->state = bHighlight;
|
||||
else
|
||||
btn->state = 0;
|
||||
|
||||
send_message(&btn->ctrl, MSG_DRAW, 0, 0);
|
||||
|
||||
if(action)
|
||||
send_message(btn->ctrl.parent,MSG_COMMAND,btn->ctrl.id,(int)btn);
|
||||
};
|
||||
|
||||
static void button_on_mousemove(button_t *btn, int x, int y)
|
||||
{
|
||||
int old_state;
|
||||
|
||||
if( !(btn->state & bHighlight))
|
||||
{
|
||||
btn->state|= bHighlight;
|
||||
send_message(&btn->ctrl, MSG_DRAW, 0, 0);
|
||||
};
|
||||
|
||||
if( (ctrl_t*)btn != mouse_capture)
|
||||
return;
|
||||
|
||||
old_state = btn->state;
|
||||
|
||||
if( pt_in_rect(&btn->ctrl.rc, x, y) )
|
||||
btn->state |= bPressed;
|
||||
else
|
||||
btn->state &= ~bPressed;
|
||||
|
||||
if( old_state ^ btn->state)
|
||||
send_message(&btn->ctrl, MSG_DRAW, 0, 0);
|
||||
}
|
||||
|
||||
int button_proc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2)
|
||||
{
|
||||
button_t *btn = (button_t*)ctrl;
|
||||
|
||||
switch( msg )
|
||||
{
|
||||
HANDLE_MSG(btn, MSG_DRAW, button_on_draw);
|
||||
HANDLE_MSG(btn, MSG_MOUSEENTER, button_on_mouseenter);
|
||||
HANDLE_MSG(btn, MSG_MOUSELEAVE, button_on_mouseleave);
|
||||
HANDLE_MSG(btn, MSG_LBTNDOWN, button_on_lbuttondown);
|
||||
HANDLE_MSG(btn, MSG_LBTNDBLCLK, button_on_lbuttondown);
|
||||
HANDLE_MSG(btn, MSG_LBTNUP, button_on_lbuttonup);
|
||||
HANDLE_MSG(btn, MSG_MOUSEMOVE, button_on_mousemove);
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
||||
ctrl_t *create_button(char *caption, uint32_t style, int id, int x, int y,
|
||||
int w, int h, ctrl_t *parent)
|
||||
{
|
||||
button_t *btn;
|
||||
int len;
|
||||
|
||||
if( !parent )
|
||||
return NULL;
|
||||
|
||||
btn = create_control(sizeof(button_t), id, x, y, w, h, parent);
|
||||
btn->ctrl.style = style;
|
||||
btn->ctrl.handler = button_proc;
|
||||
btn->state = 0;
|
||||
btn->caption = caption;
|
||||
|
||||
if( !caption )
|
||||
btn->capt_len = 0;
|
||||
else
|
||||
{
|
||||
len = strlen(caption);
|
||||
btn->capt_len = len;
|
||||
if( len )
|
||||
btn->caption = strdup(caption);
|
||||
else
|
||||
btn->caption = NULL;
|
||||
}
|
||||
|
||||
return &btn->ctrl;
|
||||
};
|
||||
|
109
contrib/sdk/samples/freetype/txview/winlib/control.h
Normal file
109
contrib/sdk/samples/freetype/txview/winlib/control.h
Normal file
@ -0,0 +1,109 @@
|
||||
#ifndef __CONTROL_H__
|
||||
#define __CONTROL_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <pxdraw.h>
|
||||
#include "link.h"
|
||||
|
||||
typedef struct font font_t;
|
||||
|
||||
typedef struct control ctrl_t;
|
||||
|
||||
typedef int (handler_t)(ctrl_t*, uint32_t, uint32_t, uint32_t);
|
||||
|
||||
struct control
|
||||
{
|
||||
link_t link;
|
||||
link_t child;
|
||||
|
||||
handler_t *handler;
|
||||
ctrl_t *parent;
|
||||
|
||||
ctx_t *ctx;
|
||||
font_t *font;
|
||||
uint32_t id;
|
||||
uint32_t style;
|
||||
|
||||
rect_t rc;
|
||||
int w;
|
||||
int h;
|
||||
};
|
||||
|
||||
void *create_control(size_t size, int id, int x, int y,
|
||||
int w, int h, ctrl_t *parent);
|
||||
|
||||
#define bPressed 2
|
||||
#define bHighlight 1
|
||||
|
||||
|
||||
ctrl_t *create_button(char *caption, uint32_t style, int id, int x, int y,
|
||||
int w, int h, ctrl_t *parent);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ctrl_t ctrl;
|
||||
|
||||
uint32_t state;
|
||||
|
||||
int pix_range;
|
||||
int min_range;
|
||||
int max_range;
|
||||
int page_size;
|
||||
int thumb_pos;
|
||||
|
||||
rect_t tl_rect;
|
||||
rect_t br_rect;
|
||||
|
||||
ctrl_t *btn_up;
|
||||
ctrl_t *btn_down;
|
||||
ctrl_t *thumb;
|
||||
}scroller_t;
|
||||
|
||||
|
||||
#define MSG_SYS_PAINT 0x001
|
||||
#define MSG_SYS_KEY 0x002
|
||||
#define MSG_SYS_BUTTON 0x003
|
||||
#define MSG_SYS_MOUSE 0x006
|
||||
|
||||
#define MSG_LBTNDOWN 0x010
|
||||
#define MSG_LBTNUP 0x011
|
||||
#define MSG_RBTNDOWN 0x012
|
||||
#define MSG_RBTNUP 0x013
|
||||
#define MSG_MBTNDOWN 0x014
|
||||
#define MSG_MBTNUP 0x015
|
||||
#define MSG_WHEELDOWN 0x016
|
||||
#define MSG_WHEELUP 0x017
|
||||
|
||||
#define MSG_LBTNDBLCLK 0x018
|
||||
|
||||
#define MSG_MOUSEMOVE 0x019
|
||||
#define MSG_MOUSEENTER 0x01A
|
||||
#define MSG_MOUSELEAVE 0x01B
|
||||
|
||||
#define MSG_CREATE 0x020
|
||||
#define MSG_SIZE 0x021
|
||||
#define MSG_DRAW 0x022
|
||||
#define MSG_OWNERDRAW 0x023
|
||||
#define MSG_POSCHANGING 0x024
|
||||
#define MSG_POSCHANGE 0x025
|
||||
|
||||
#define MSG_COMMAND 0x030
|
||||
|
||||
static inline int pt_in_rect(rect_t *rc, int x, int y)
|
||||
{
|
||||
if( (x >= rc->l) && (x < rc->r) &&
|
||||
(y >= rc->t) && (y < rc->b) )
|
||||
return 1;
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
#define send_message( ctrl, msg, arg1, arg2) \
|
||||
(ctrl)->handler( (ctrl_t*)(ctrl), \
|
||||
(uint32_t)(msg), (uint32_t)(arg1), (uint32_t)(arg2))
|
||||
|
||||
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
|
||||
#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
|
||||
|
||||
|
||||
#endif /* __CONTROL_H_ */
|
64
contrib/sdk/samples/freetype/txview/winlib/link.h
Normal file
64
contrib/sdk/samples/freetype/txview/winlib/link.h
Normal file
@ -0,0 +1,64 @@
|
||||
#ifndef __LINK_H__
|
||||
#define __LINK_H__
|
||||
|
||||
typedef struct link
|
||||
{
|
||||
struct link *prev;
|
||||
struct link *next;
|
||||
}link_t;
|
||||
|
||||
#define LIST_INITIALIZE(name) \
|
||||
link_t name = { .prev = &name, .next = &name }
|
||||
|
||||
#define list_get_instance(link, type, member) \
|
||||
((type *)(((u8_t *)(link)) - ((u8_t *)&(((type *)NULL)->member))))
|
||||
|
||||
static inline void link_initialize(link_t *link)
|
||||
{
|
||||
link->prev = NULL;
|
||||
link->next = NULL;
|
||||
}
|
||||
|
||||
static inline void list_initialize(link_t *head)
|
||||
{
|
||||
head->prev = head;
|
||||
head->next = head;
|
||||
}
|
||||
|
||||
static inline void list_append(link_t *link, link_t *head)
|
||||
{
|
||||
link->prev = head->prev;
|
||||
link->next = head;
|
||||
head->prev->next = link;
|
||||
head->prev = link;
|
||||
}
|
||||
|
||||
static inline void list_remove(link_t *link)
|
||||
{
|
||||
link->next->prev = link->prev;
|
||||
link->prev->next = link->next;
|
||||
link_initialize(link);
|
||||
}
|
||||
|
||||
static inline int list_empty(link_t *head)
|
||||
{
|
||||
return head->next == head ? 1 : 0;
|
||||
}
|
||||
|
||||
static inline void list_prepend(link_t *link, link_t *head)
|
||||
{
|
||||
link->next = head->next;
|
||||
link->prev = head;
|
||||
head->next->prev = link;
|
||||
head->next = link;
|
||||
}
|
||||
|
||||
static inline void list_insert(link_t *new, link_t *old)
|
||||
{
|
||||
new->prev = old->prev;
|
||||
new->next = old;
|
||||
new->prev->next = new;
|
||||
old->prev = new;
|
||||
}
|
||||
|
||||
#endif /* __LINK_H__ */
|
615
contrib/sdk/samples/freetype/txview/winlib/winlib.c
Normal file
615
contrib/sdk/samples/freetype/txview/winlib/winlib.c
Normal file
@ -0,0 +1,615 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "winlib.h"
|
||||
|
||||
#define ID_SCROLLER_UP 0x30
|
||||
#define ID_SCROLLER_DOWN 0x31
|
||||
#define ID_SCROLLER_THUMB 0x32
|
||||
|
||||
typedef int v2si __attribute__ ((vector_size (8)));
|
||||
|
||||
font_t *create_font(void *face, int size);
|
||||
|
||||
static pos_t old_pos;
|
||||
ctrl_t *mouse_capture = NULL;
|
||||
|
||||
|
||||
|
||||
void show_window(window_t *win)
|
||||
{
|
||||
BeginDraw();
|
||||
DrawWindow(0,0,0,0,NULL,0,0x73);
|
||||
if( (win->win_state != MINIMIZED) &&
|
||||
(win->win_state != ROLLED) )
|
||||
show_context(win->ctx);
|
||||
EndDraw();
|
||||
}
|
||||
|
||||
window_t *create_window(char *caption, int style, int x, int y,
|
||||
int w, int h, handler_t handler)
|
||||
{
|
||||
char proc_info[1024];
|
||||
window_t *win;
|
||||
|
||||
if(handler==NULL)
|
||||
return NULL;
|
||||
|
||||
win = malloc(sizeof(*win));
|
||||
if(win == NULL)
|
||||
return NULL;
|
||||
|
||||
BeginDraw();
|
||||
DrawWindow(x, y, w+TYPE_3_BORDER_WIDTH*2,
|
||||
h+TYPE_3_BORDER_WIDTH+get_skin_height(), caption, 0x000000, 0x73);
|
||||
EndDraw();
|
||||
|
||||
GetProcInfo(proc_info);
|
||||
|
||||
x = *(uint32_t*)(proc_info+34);
|
||||
y = *(uint32_t*)(proc_info+38);
|
||||
w = *(uint32_t*)(proc_info+42)+1;
|
||||
h = *(uint32_t*)(proc_info+46)+1;
|
||||
|
||||
win->handler = handler;
|
||||
|
||||
list_initialize(&win->link);
|
||||
list_initialize(&win->child);
|
||||
|
||||
win->rc.l = x;
|
||||
win->rc.t = y;
|
||||
win->rc.r = x + w;
|
||||
win->rc.b = y + h;
|
||||
|
||||
win->w = w;
|
||||
win->h = h;
|
||||
|
||||
win->client.l = TYPE_3_BORDER_WIDTH;
|
||||
win->client.t = get_skin_height();
|
||||
win->client.r = w - TYPE_3_BORDER_WIDTH;
|
||||
win->client.b = h - TYPE_3_BORDER_WIDTH;
|
||||
win->clw = win->client.r - win->client.l;
|
||||
win->clh = win->client.b - win->client.t;
|
||||
|
||||
win->caption_txt = caption;
|
||||
win->style = style;
|
||||
|
||||
win->child_over = NULL;
|
||||
win->child_focus = NULL;
|
||||
|
||||
win->ctx = create_context(win->client.l, win->client.t, win->clw, win->clh);
|
||||
clear_context(win->ctx, 0xFFFFFFFF);
|
||||
|
||||
win->font = create_font(NULL, 14);
|
||||
|
||||
send_message((ctrl_t*)win, MSG_CREATE, 0, 0);
|
||||
send_message((ctrl_t*)win, MSG_DRAW, 0, 0);
|
||||
|
||||
ctrl_t *child;
|
||||
|
||||
child = (ctrl_t*)win->child.next;
|
||||
|
||||
while( &child->link != &win->child)
|
||||
{
|
||||
send_message(child, MSG_DRAW, 0, 0);
|
||||
child = (ctrl_t*)child->link.next;
|
||||
};
|
||||
|
||||
show_window(win);
|
||||
|
||||
return win;
|
||||
};
|
||||
|
||||
|
||||
void handle_sys_paint(window_t *win)
|
||||
{
|
||||
char proc_info[1024];
|
||||
int winx, winy, winw, winh;
|
||||
uint8_t state;
|
||||
|
||||
GetProcInfo(proc_info);
|
||||
|
||||
winx = *(uint32_t*)(proc_info+34);
|
||||
winy = *(uint32_t*)(proc_info+38);
|
||||
winw = *(uint32_t*)(proc_info+42)+1;
|
||||
winh = *(uint32_t*)(proc_info+46)+1;
|
||||
|
||||
state = *(uint8_t*)(proc_info+70);
|
||||
|
||||
if(state & 2)
|
||||
{
|
||||
win->win_state = MINIMIZED;
|
||||
return;
|
||||
}
|
||||
else if(state & 4)
|
||||
{
|
||||
win->win_state = ROLLED;
|
||||
show_window(win);
|
||||
return;
|
||||
};
|
||||
|
||||
if(state & 1)
|
||||
state = MAXIMIZED;
|
||||
else
|
||||
state = NORMAL;
|
||||
|
||||
if( (win->w != winw) ||
|
||||
(win->h != winh) )
|
||||
{
|
||||
ctrl_t *child;
|
||||
|
||||
win->client.l = TYPE_3_BORDER_WIDTH;
|
||||
win->client.t = get_skin_height();
|
||||
win->client.r = winw - TYPE_3_BORDER_WIDTH;
|
||||
win->client.b = winh - TYPE_3_BORDER_WIDTH;
|
||||
win->clw = win->client.r - win->client.l;
|
||||
win->clh = win->client.b - win->client.t;
|
||||
|
||||
resize_context(win->ctx, win->clw, win->clh);
|
||||
|
||||
clear_context(win->ctx, 0xFFFFFFFF);
|
||||
|
||||
send_message((ctrl_t*)win, MSG_SIZE, 0, 0);
|
||||
send_message((ctrl_t*)win, MSG_DRAW, 0, 0);
|
||||
|
||||
child = (ctrl_t*)win->child.next;
|
||||
|
||||
while( &child->link != &win->child)
|
||||
{
|
||||
send_message(child, MSG_DRAW, 0, 0);
|
||||
child = (ctrl_t*)child->link.next;
|
||||
};
|
||||
}
|
||||
|
||||
win->rc.l = winx;
|
||||
win->rc.t = winy;
|
||||
win->rc.r = winx + winw;
|
||||
win->rc.b = winy + winh;
|
||||
win->w = winw;
|
||||
win->h = winh;
|
||||
win->win_state = state;
|
||||
|
||||
show_window(win);
|
||||
};
|
||||
|
||||
|
||||
ctrl_t *get_child(ctrl_t *ctrl, int x, int y)
|
||||
{
|
||||
ctrl_t *child = NULL;
|
||||
|
||||
ctrl_t *tmp = (ctrl_t*)ctrl->child.next;
|
||||
|
||||
while( &tmp->link != &ctrl->child )
|
||||
{
|
||||
if(pt_in_rect(&tmp->rc, x, y))
|
||||
{
|
||||
child = get_child(tmp, x, y);
|
||||
return child == NULL ? tmp : child;
|
||||
};
|
||||
tmp = (ctrl_t*)tmp->link.next;
|
||||
};
|
||||
return child;
|
||||
};
|
||||
|
||||
|
||||
int send_mouse_message(window_t *win, uint32_t msg)
|
||||
{
|
||||
ctrl_t *child;
|
||||
|
||||
if(mouse_capture)
|
||||
return send_message(mouse_capture, msg, 0, old_pos.val);
|
||||
|
||||
child = get_child((ctrl_t*)win, old_pos.x, old_pos.y);
|
||||
|
||||
if(msg == MSG_MOUSEMOVE)
|
||||
{
|
||||
if( win->child_over )
|
||||
{
|
||||
if(child == win->child_over)
|
||||
send_message(child, MSG_MOUSEMOVE, 0, old_pos.val);
|
||||
else
|
||||
send_message(win->child_over, MSG_MOUSELEAVE, 0, old_pos.val);
|
||||
}
|
||||
else if( child )
|
||||
send_message(child, MSG_MOUSEENTER, 0, old_pos.val);
|
||||
|
||||
win->child_over = child;
|
||||
};
|
||||
|
||||
if( child )
|
||||
return send_message(child, msg, 0, old_pos.val);
|
||||
|
||||
if(pt_in_rect(&win->client, old_pos.x, old_pos.y))
|
||||
return send_message((ctrl_t*)win, msg, 0, old_pos.val);
|
||||
|
||||
};
|
||||
|
||||
#define DBG(x)
|
||||
|
||||
static void handle_sys_mouse(window_t *win)
|
||||
{
|
||||
static uint32_t mouse_click_time;
|
||||
static int mouse_action;
|
||||
static int old_buttons;
|
||||
int buttons;
|
||||
uint32_t wheels;
|
||||
uint32_t click_time;
|
||||
int action;
|
||||
|
||||
pos_t pos;
|
||||
|
||||
mouse_action = 0;
|
||||
pos = get_mouse_pos(POS_WINDOW);
|
||||
|
||||
if(pos.val != old_pos.val)
|
||||
{
|
||||
mouse_action = 0x80000000;
|
||||
old_pos = pos;
|
||||
};
|
||||
// printf("pos x%d y%d\n", pos.x, pos.y);
|
||||
|
||||
buttons = get_mouse_buttons();
|
||||
wheels = get_mouse_wheels();
|
||||
|
||||
// if( wheels & 0xFFFF){
|
||||
// wheels = (short)wheels>0 ? MSG_WHEELDOWN : MSG_WHEELUP;
|
||||
// send_mouse_message(win, wheels);
|
||||
// }
|
||||
|
||||
if((action = (buttons ^ old_buttons))!=0)
|
||||
{
|
||||
mouse_action|= action<<3;
|
||||
mouse_action|= buttons & ~old_buttons;
|
||||
}
|
||||
old_buttons = buttons;
|
||||
|
||||
if(mouse_action & 0x80000000) {
|
||||
DBG("mouse move \n\r");
|
||||
send_mouse_message(win, MSG_MOUSEMOVE);
|
||||
};
|
||||
|
||||
if(mouse_action & 0x09)
|
||||
{
|
||||
if((mouse_action & 0x09)==0x09)
|
||||
{
|
||||
// printf("left button down x= %d y= %d\n\r", old_x.x, old_x.y);
|
||||
click_time = get_tick_count();
|
||||
if(click_time < mouse_click_time+35) {
|
||||
mouse_click_time = click_time;
|
||||
send_mouse_message(win,MSG_LBTNDBLCLK);
|
||||
}
|
||||
else {
|
||||
mouse_click_time = click_time;
|
||||
send_mouse_message(win,MSG_LBTNDOWN);
|
||||
};
|
||||
}
|
||||
else {
|
||||
// printf("left button up \n\r");
|
||||
send_mouse_message(win,MSG_LBTNUP);
|
||||
}
|
||||
};
|
||||
|
||||
if(mouse_action & 0x12)
|
||||
{
|
||||
if((mouse_action & 0x12)==0x12) {
|
||||
DBG("right button down \n\r");
|
||||
send_mouse_message(win,MSG_RBTNDOWN);
|
||||
}
|
||||
else {
|
||||
DBG("right button up \n\r");
|
||||
send_mouse_message(win,MSG_RBTNUP);
|
||||
};
|
||||
};
|
||||
if(mouse_action & 0x24)
|
||||
{
|
||||
if((mouse_action & 0x24)==0x24){
|
||||
DBG("middle button down \n\r");
|
||||
send_mouse_message(win,MSG_MBTNDOWN);
|
||||
}
|
||||
else {
|
||||
DBG("middle button up \n\r");
|
||||
send_mouse_message(win,MSG_MBTNUP);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
int handle_system_events(window_t *win)
|
||||
{
|
||||
oskey_t key;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
switch (get_os_event())
|
||||
{
|
||||
case MSG_SYS_PAINT:
|
||||
handle_sys_paint(win);
|
||||
break;
|
||||
|
||||
case MSG_SYS_KEY:
|
||||
key = get_key();
|
||||
printf("key %d\n", key.code);
|
||||
break;
|
||||
|
||||
case MSG_SYS_BUTTON:
|
||||
// button pressed; we have only one button, close
|
||||
return 0;
|
||||
|
||||
case MSG_SYS_MOUSE:
|
||||
handle_sys_mouse(win);
|
||||
break;
|
||||
};
|
||||
|
||||
if( (win->win_state != MINIMIZED) &&
|
||||
(win->win_state != ROLLED) )
|
||||
show_context(win->ctx);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *create_control(size_t size, int id, int x, int y,
|
||||
int w, int h, ctrl_t *parent)
|
||||
{
|
||||
|
||||
ctrl_t *ctrl;
|
||||
|
||||
if( !parent )
|
||||
return NULL;
|
||||
|
||||
ctrl = (ctrl_t*)malloc(size);
|
||||
|
||||
link_initialize(&ctrl->link);
|
||||
list_initialize(&ctrl->child);
|
||||
|
||||
ctrl->parent = parent;
|
||||
|
||||
ctrl->ctx = parent->ctx;
|
||||
ctrl->font = parent->font;
|
||||
ctrl->id = id;
|
||||
|
||||
ctrl->rc.l = x;
|
||||
ctrl->rc.t = y ;
|
||||
|
||||
ctrl->rc.r = x + w;
|
||||
ctrl->rc.b = y + h;
|
||||
|
||||
ctrl->w = w;
|
||||
ctrl->h = h;
|
||||
|
||||
list_append(&ctrl->link, &parent->child);
|
||||
|
||||
return ctrl;
|
||||
};
|
||||
|
||||
|
||||
int move_ctrl(ctrl_t *ctrl, int x, int y, int w, int h)
|
||||
{
|
||||
rect_t rc;
|
||||
rc.l = x;
|
||||
rc.t = y;
|
||||
rc.r = w;
|
||||
rc.b = h;
|
||||
|
||||
send_message(ctrl, MSG_POSCHANGING, 0, &rc);
|
||||
|
||||
ctrl->rc.l = rc.l;
|
||||
ctrl->rc.t = rc.t;
|
||||
ctrl->rc.r = rc.l + rc.r;
|
||||
ctrl->rc.b = rc.t + rc.b;
|
||||
ctrl->w = rc.r;
|
||||
ctrl->h = rc.b;
|
||||
|
||||
send_message(ctrl, MSG_POSCHANGE, 0, &rc);
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
int def_ctrl_proc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2)
|
||||
{
|
||||
switch( msg )
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
static void scroller_on_draw(scroller_t *scrl)
|
||||
{
|
||||
if(scrl->btn_up)
|
||||
send_message((ctrl_t*)scrl->btn_up, MSG_DRAW, 0, 0);
|
||||
|
||||
if(scrl->btn_down)
|
||||
send_message((ctrl_t*)scrl->btn_down, MSG_DRAW, 0, 0);
|
||||
|
||||
if(scrl->thumb)
|
||||
send_message((ctrl_t*)scrl->thumb, MSG_DRAW, 0, 0);
|
||||
|
||||
if(scrl->tl_rect.t != scrl->tl_rect.b)
|
||||
px_fill_rect(scrl->ctrl.ctx, &scrl->tl_rect, 0xFFE1D8D0);
|
||||
|
||||
if(scrl->br_rect.t != scrl->br_rect.b)
|
||||
px_fill_rect(scrl->ctrl.ctx, &scrl->br_rect, 0xFFE1D8D0);
|
||||
}
|
||||
|
||||
static void scroller_on_ownerdraw(scroller_t *scrl, ctrl_t *child)
|
||||
{
|
||||
typedef struct
|
||||
{
|
||||
ctrl_t ctrl;
|
||||
|
||||
uint32_t state;
|
||||
|
||||
char *caption;
|
||||
int capt_len;
|
||||
}button_t;
|
||||
|
||||
button_t *btn;
|
||||
color_t color = 0xFFD7D7D7;
|
||||
char t = (char)child->id;
|
||||
rect_t rc;
|
||||
|
||||
switch(child->id)
|
||||
{
|
||||
case ID_SCROLLER_UP:
|
||||
case ID_SCROLLER_DOWN:
|
||||
btn = (button_t*)child;
|
||||
if(btn->state & bPressed)
|
||||
color = 0xFFB0B0B0;
|
||||
else if(btn->state & bHighlight)
|
||||
color = 0xFFE7E7E7;
|
||||
|
||||
rc = btn->ctrl.rc;
|
||||
px_fill_rect(btn->ctrl.ctx, &rc, color);
|
||||
rc.l+= 3;
|
||||
rc.t+= 5;
|
||||
draw_text_ext(btn->ctrl.ctx, sym_font, &t, 1, &rc, 0xFF000000);
|
||||
break;
|
||||
|
||||
case ID_SCROLLER_THUMB:
|
||||
btn = (button_t*)child;
|
||||
color = 0xFFB0B0B0;
|
||||
if(btn->state & bPressed)
|
||||
color = 0xFF707070;
|
||||
else if(btn->state & bHighlight)
|
||||
color = 0xFF909090;
|
||||
|
||||
rc = btn->ctrl.rc;
|
||||
px_fill_rect(btn->ctrl.ctx, &rc, color);
|
||||
}
|
||||
};
|
||||
|
||||
static void scroller_update_layout(scroller_t *scrl)
|
||||
{
|
||||
|
||||
// th_size = scrl->pix_range*scrl->page_size/
|
||||
// (scrl->max_range-scrl->min_range);
|
||||
|
||||
// if(th_size > scrl->pix_range)
|
||||
// th_size = scrl->pix_range;
|
||||
|
||||
scrl->tl_rect.l = scrl->ctrl.rc.l;
|
||||
scrl->br_rect.l = scrl->ctrl.rc.l;
|
||||
|
||||
scrl->tl_rect.r = scrl->ctrl.rc.r;
|
||||
scrl->br_rect.r = scrl->ctrl.rc.r;
|
||||
|
||||
scrl->tl_rect.t = scrl->btn_up->rc.b;
|
||||
scrl->tl_rect.b = scrl->thumb->rc.t;
|
||||
|
||||
scrl->br_rect.t = scrl->thumb->rc.b;
|
||||
scrl->br_rect.b = scrl->btn_down->rc.t;
|
||||
|
||||
scrl->pix_range = scrl->ctrl.h - 40 - 20;
|
||||
};
|
||||
|
||||
static void scroller_on_poschange(scroller_t *scrl, rect_t *pos)
|
||||
{
|
||||
move_ctrl(scrl->btn_up, pos->l, pos->t, pos->r, pos->r);
|
||||
move_ctrl(scrl->btn_down, pos->l, pos->t+pos->b-pos->r, pos->r, pos->r);
|
||||
move_ctrl(scrl->thumb, pos->l, pos->t+pos->r, pos->r, pos->r);
|
||||
|
||||
scroller_update_layout(scrl);
|
||||
scroller_on_draw(scrl);
|
||||
};
|
||||
|
||||
static void scroller_on_command(scroller_t *ctrl, int id, ctrl_t *child, int notify)
|
||||
{
|
||||
scroller_t *scrl = (scroller_t*)ctrl;
|
||||
int thumb_pos = scrl->thumb_pos;
|
||||
|
||||
switch(id)
|
||||
{
|
||||
case ID_SCROLLER_UP:
|
||||
if(scrl->thumb_pos > scrl->min_range)
|
||||
scrl->thumb_pos--;
|
||||
printf("scroll up\n");
|
||||
break;
|
||||
case ID_SCROLLER_DOWN:
|
||||
if(scrl->thumb_pos < scrl->max_range)
|
||||
scrl->thumb_pos++;
|
||||
printf("scroll down\n");
|
||||
break;
|
||||
};
|
||||
|
||||
if(thumb_pos != scrl->thumb_pos)
|
||||
{
|
||||
rect_t rc = scrl->thumb->rc;
|
||||
int offset = scrl->pix_range*scrl->thumb_pos;
|
||||
offset /= scrl->max_range - scrl->min_range;
|
||||
rc.t = scrl->ctrl.rc.t + scrl->btn_up->h + offset;
|
||||
rc.r = scrl->thumb->w;
|
||||
rc.b = scrl->thumb->h;
|
||||
move_ctrl(scrl->thumb, rc.l, rc.t, rc.r, rc.b);
|
||||
scroller_update_layout(scrl);
|
||||
scroller_on_draw(scrl);
|
||||
}
|
||||
}
|
||||
|
||||
int scroller_proc(ctrl_t *ctrl, uint32_t msg, uint32_t arg1, uint32_t arg2)
|
||||
{
|
||||
scroller_t *scrl = (scroller_t*)ctrl;
|
||||
|
||||
switch( msg )
|
||||
{
|
||||
HANDLE_MSG(scrl, MSG_DRAW, scroller_on_draw);
|
||||
HANDLE_MSG(scrl, MSG_COMMAND, scroller_on_command);
|
||||
HANDLE_MSG(scrl, MSG_OWNERDRAW, scroller_on_ownerdraw);
|
||||
HANDLE_MSG(scrl, MSG_POSCHANGE, scroller_on_poschange);
|
||||
};
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
scroller_t *create_scroller(uint32_t style, int id, int x, int y,
|
||||
int w, int h, ctrl_t *parent)
|
||||
{
|
||||
scroller_t *scrl;
|
||||
|
||||
if( !parent )
|
||||
return NULL;
|
||||
|
||||
scrl = create_control(sizeof(scroller_t), id, x, y, w, h, parent);
|
||||
scrl->ctrl.handler = scroller_proc;
|
||||
|
||||
scrl->min_range = 0;
|
||||
scrl->max_range = 100;
|
||||
scrl->thumb_pos = 0;
|
||||
scrl->page_size = 1;
|
||||
|
||||
scrl->btn_up = create_button(NULL, 1, ID_SCROLLER_UP, x, y, w, w, (ctrl_t*)scrl);
|
||||
scrl->btn_down = create_button(NULL, 1, ID_SCROLLER_DOWN, x, y+h-w, w, w, (ctrl_t*)scrl);
|
||||
scrl->thumb = create_button(NULL, 1, ID_SCROLLER_THUMB, x, w, w, w, (ctrl_t*)scrl);
|
||||
|
||||
scroller_update_layout(scrl);
|
||||
|
||||
return scrl;
|
||||
};
|
||||
|
||||
|
124
contrib/sdk/samples/freetype/txview/winlib/winlib.h
Normal file
124
contrib/sdk/samples/freetype/txview/winlib/winlib.h
Normal file
@ -0,0 +1,124 @@
|
||||
#ifndef __WINLIB_H__
|
||||
#define __WINLIB_H__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <kos32sys.h>
|
||||
#include "control.h"
|
||||
|
||||
enum win_state{
|
||||
NORMAL, MINIMIZED, ROLLED, MAXIMIZED, FULLSCREEN
|
||||
};
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
link_t link;
|
||||
link_t child;
|
||||
|
||||
handler_t *handler;
|
||||
ctrl_t *parent;
|
||||
|
||||
ctx_t *ctx;
|
||||
font_t *font;
|
||||
|
||||
uint32_t id;
|
||||
uint32_t style;
|
||||
|
||||
rect_t rc;
|
||||
int w;
|
||||
int h;
|
||||
|
||||
rect_t saved;
|
||||
rect_t client;
|
||||
int clw;
|
||||
int clh;
|
||||
|
||||
char *caption_txt;
|
||||
ctrl_t *child_over;
|
||||
ctrl_t *child_focus;
|
||||
|
||||
enum win_state win_state;
|
||||
enum win_state saved_state;
|
||||
|
||||
}window_t;
|
||||
|
||||
|
||||
#define HANDLE_MSG(ctrl, message, fn) \
|
||||
case (message): return HANDLE_##message((ctrl), (arg1), (arg2), (fn))
|
||||
|
||||
/* void ctrl_on_draw(ctrl_t *ctrl) */
|
||||
#define HANDLE_MSG_DRAW(ctrl, arg1, arg2, fn) \
|
||||
((fn)(ctrl),0)
|
||||
|
||||
/* void ctrl_on_ownerdraw(ctrl_t *ctrl, ctrl_t *child) */
|
||||
#define HANDLE_MSG_OWNERDRAW(ctrl, arg1, arg2, fn) \
|
||||
((fn)((ctrl),((ctrl_t*)arg1)),0)
|
||||
|
||||
/* void ctrl_on_poschanging(ctrl_t *ctrl, rect_t *pos) */
|
||||
#define HANDLE_MSG_POSCHANGING(ctrl, arg1, arg2, fn) \
|
||||
((fn)((ctrl),((rect_t*)arg2)),0)
|
||||
|
||||
/* void ctrl_on_poschange(ctrl_t *ctrl, rect_t *pos) */
|
||||
#define HANDLE_MSG_POSCHANGE(ctrl, arg1, arg2, fn) \
|
||||
((fn)((ctrl),((rect_t*)arg2)),0)
|
||||
|
||||
/* void ctrl_on_mouseenter(ctrl_t *ctrl) */
|
||||
#define HANDLE_MSG_MOUSEENTER(ctrl, arg1, arg2, fn) \
|
||||
((fn)(ctrl),0)
|
||||
|
||||
/* void ctrl_on_mouseleave(ctrl_t *ctrl) */
|
||||
#define HANDLE_MSG_MOUSELEAVE(ctrl, arg1, arg2, fn) \
|
||||
((fn)(ctrl),0)
|
||||
|
||||
/* void ctrl_on_lbuttondown(ctrl_t *ctrl, int x, int y) */
|
||||
#define HANDLE_MSG_LBTNDOWN(ctrl, arg1, arg2, fn) \
|
||||
((fn)((ctrl), ((pos_t)arg2).x, ((pos_t)arg2).y), 0L)
|
||||
|
||||
#define HANDLE_MSG_LBTNDBLCLK(ctrl, arg1, arg2, fn) \
|
||||
((fn)((ctrl), ((pos_t)arg2).x, ((pos_t)arg2).y), 0L)
|
||||
|
||||
/* void ctrl_on_lbuttonup(ctrl_t *ctrl, int x, int y) */
|
||||
#define HANDLE_MSG_LBTNUP(ctrl, arg1, arg2, fn) \
|
||||
((fn)((ctrl), ((pos_t)arg2).x, ((pos_t)arg2).y), 0L)
|
||||
|
||||
/* void ctrl_on_mousemove(ctrl_t *ctrl, int x, int y) */
|
||||
#define HANDLE_MSG_MOUSEMOVE(ctrl, arg1, arg2, fn) \
|
||||
((fn)((ctrl), ((pos_t)arg2).x, ((pos_t)arg2).y), 0L)
|
||||
|
||||
/* void ctrl_on_command(ctrl_t *ctrl, int id, ctrl_t *child, int notify) */
|
||||
#define HANDLE_MSG_COMMAND(ctrl,arg1,arg2,fn) \
|
||||
((fn)((ctrl),(int)(arg1 & 0xFFFF),(ctrl_t*)(arg2),(int)(arg1>>16)),0)
|
||||
|
||||
window_t *create_window(char *caption, int style, int x, int y,
|
||||
int w, int h, handler_t handler);
|
||||
int handle_system_events(window_t *win);
|
||||
void show_window(window_t *win);
|
||||
|
||||
extern ctrl_t *mouse_capture;
|
||||
|
||||
static inline ctrl_t *capture_mouse(ctrl_t *newm)
|
||||
{
|
||||
ctrl_t *old = mouse_capture;
|
||||
|
||||
mouse_capture = newm;
|
||||
|
||||
__asm__ __volatile__(
|
||||
"int $0x40"
|
||||
::"a"(40), "b"(0x80000027));
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
static void release_mouse(void)
|
||||
{
|
||||
mouse_capture = NULL;
|
||||
__asm__ __volatile__(
|
||||
"int $0x40"
|
||||
::"a"(40), "b"(0xC0000027));
|
||||
}
|
||||
|
||||
extern font_t *sym_font;
|
||||
|
||||
int draw_text_ext(ctx_t *ctx, font_t *font, char *text, int len, rect_t *rc, color_t color);
|
||||
|
||||
#endif /* __WINLIB_H__ */
|
Loading…
Reference in New Issue
Block a user