/contrib/sdk/samples/freetype/txview/Makefile |
---|
1,19 → 1,33 |
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 |
tview.c \ |
$(NULL) |
LIB_OBJS = $(patsubst %.c, %.o, $(LIB_SRCS)) |
OBJECTS = $(patsubst %.c, %.o, $(SOURCES)) |
20,10 → 34,16 |
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 $@ $< |
/contrib/sdk/samples/freetype/txview/fontlib.c |
---|
6,19 → 6,12 |
#include <ft2build.h> |
#include FT_FREETYPE_H |
#include FT_GLYPH_H |
#include <pixlib2.h> |
#include <pxdraw.h> |
typedef struct |
{ |
int l; |
int t; |
int r; |
int b; |
}rect_t; |
typedef struct |
{ |
FT_Face face; |
int fontsize; |
int height; |
int base; |
27,7 → 20,10 |
}font_t; |
static FT_Face def_face; |
static FT_Face sym_face; |
font_t *sym_font; |
typedef unsigned int color_t; |
unsigned int ansi2utf32(unsigned char ch); |
34,56 → 30,30 |
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) |
{ |
uint8_t *dst; |
uint8_t *src, *tmpsrc; |
void draw_glyph(ctx_t *ctx, void *buffer, int pitch, rect_t *rc, color_t color); |
uint32_t *tmpdst; |
int i, j; |
dst = win->data + dsty * win->pitch + dstx*4; |
src = bitmap->buffer; |
// printf("buffer %x width %d rows %d\n", |
// bitmap->buffer, bitmap->width, bitmap->rows); |
for( i = 0; i < bitmap->rows; i++ ) |
unsigned int ansi2utf32(unsigned char ch) |
{ |
tmpdst = (uint32_t*)dst; |
tmpsrc = src; |
if(ch < 0x80) |
return ch; |
dst+= win->pitch; |
src+= bitmap->pitch; |
if(ch < 0xB0) |
return 0x410-0x80 + ch; |
for( j = 0; j < bitmap->width; j++) |
{ |
int a = *tmpsrc++; |
int sr, sg, sb; |
int dr, dg, db; |
if(ch < 0xE0) |
return 0; |
if( a != 0) a++; |
if(ch < 0xF0) |
return 0x440-0xE0 + ch; |
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; |
}; |
if(ch == 0xF0) |
return 0x401; |
else if(ch==0xF1) |
return 0x451; |
else return 0; |
} |
}; |
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; |
90,7 → 60,7 |
FT_BitmapGlyph glyph; |
FT_UInt previous; |
int x, y, w; |
int x, y, xend; |
int col, ncol; |
unsigned char ch; |
int err = 0; |
100,10 → 70,9 |
col = 0; |
x = rc->l << 6; |
y = rc->b; |
xend = rc->r << 6; |
y = rc->t + font->base; |
w = (rc->r - rc->l) << 6; |
while( len-- ) |
{ |
ch = *text++; |
113,7 → 82,7 |
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 |
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 |
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; |
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 |
// 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 |
{ |
printf("font file could not be read or broken\n"); |
goto done; |
} |
def_face = face; |
done: |
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; |
return err; |
}; |
} |
else if ( err ) |
{ |
printf("font file could not be read or broken\n"); |
goto done; |
} |
sym_face = face; |
unsigned int ansi2utf32(unsigned char ch) |
{ |
if(ch < 0x80) |
return ch; |
sym_font = create_font(sym_face, 14); |
if(ch < 0xB0) |
return 0x410-0x80 + ch; |
done: |
if(ch < 0xE0) |
return 0; |
return err; |
}; |
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 |
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 |
return font; |
} |
int get_font_height(font_t *font) |
{ |
return font->height; |
} |
/contrib/sdk/samples/freetype/txview/main.c |
---|
1,3 → 1,4 |
#include <stdio.h> |
#include <string.h> |
#include <ft2build.h> |
4,50 → 5,32 |
#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; |
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 |
{ |
bitmap_t bitmap; |
font_t *font; |
volatile int lock; |
unsigned int handle; |
}mutex_t; |
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); |
void txv_set_size(tview_t *txv, int txw, int txh); |
void txv_set_font_size(tview_t *txv, int size); |
int txv_scroll_up(tview_t *txv); |
int txv_scroll_down(tview_t *txv); |
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 |
EndDraw(); |
} |
tview_t txv; |
tview_t *txv; |
int main(int argc, char *argv[]) |
{ |
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)); |
77,16 → 66,18 |
uf.size == 0) |
return 0; |
init_pixlib(0); |
ctx = create_context(TYPE_3_BORDER_WIDTH, get_skin_height(), clw, clh); |
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 |
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 |
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 |
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); |
} |
} |
} |
/contrib/sdk/samples/freetype/txview/pxdraw/context.c |
---|
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; |
}; |
}; |
/contrib/sdk/samples/freetype/txview/pxdraw/dutils.c |
---|
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(); |
}; |
/contrib/sdk/samples/freetype/txview/pxdraw/internal.h |
---|
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); |
/contrib/sdk/samples/freetype/txview/pxdraw/pxdraw.h |
---|
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__ */ |
/contrib/sdk/samples/freetype/txview/pxdraw/region.c |
---|
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); |
}; |
/contrib/sdk/samples/freetype/txview/tview.c |
---|
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,8 → 86,13 |
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; |
rc.r = txv->w - txv->margins.r; |
162,7 → 166,7 |
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; |
169,7 → 173,7 |
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 |
{ |
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,7 → 206,7 |
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; |
209,7 → 213,7 |
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--; |
/contrib/sdk/samples/freetype/txview/winlib/button.c |
---|
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; |
}; |
/contrib/sdk/samples/freetype/txview/winlib/control.h |
---|
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_ */ |
/contrib/sdk/samples/freetype/txview/winlib/link.h |
---|
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__ */ |
/contrib/sdk/samples/freetype/txview/winlib/winlib.c |
---|
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; |
}; |
/contrib/sdk/samples/freetype/txview/winlib/winlib.h |
---|
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__ */ |