diff --git a/contrib/sdk/samples/freetype/txview/tview.c b/contrib/sdk/samples/freetype/txview/tview.c new file mode 100644 index 0000000000..241b516825 --- /dev/null +++ b/contrib/sdk/samples/freetype/txview/tview.c @@ -0,0 +1,282 @@ +#include +#include +#include +#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); +int get_font_height(font_t *font); +int get_font_width(font_t *font); + +int draw_text_ext(ctx_t *ctx, font_t *font, char *text, int len, rect_t *rc, color_t color); + +typedef struct +{ + ctx_t *ctx; + font_t *font; + + char *text; + char **line; + int lines; + + int startline; + int endline; + int pagesize; + int tail; + + rect_t margins; + int leading; + int line_height; + int w; + int h; + +}tview_t; + + + +tview_t *create_tview(ctx_t *ctx, int width, int height) +{ + tview_t *txv; + + txv = malloc(sizeof(*txv)); + if(txv == NULL) + { + return NULL; + }; + + memset(txv, 0, sizeof(*txv)); + + txv->ctx = ctx; + txv->w = width; + txv->h = height; + txv->font = create_font(NULL, 18); + txv->leading = 4; + txv->line_height = txv->leading + get_font_height(txv->font); + return txv; +}; + +void txv_get_margins(const tview_t *txv, rect_t *margins) +{ + *margins = txv->margins; +}; + +void txv_set_margins(tview_t *txv, const rect_t *margins) +{ + txv->margins = *margins; +}; + +static void txv_recalc(tview_t *txv) +{ + int full_height; + int endline; + + full_height = txv->h - (txv->margins.t + txv->margins.b); + txv->pagesize = full_height / txv->line_height; + txv->tail = full_height % txv->line_height; + endline = txv->startline + txv->pagesize; + txv->endline = endline < txv->lines ? endline : txv->lines; + +// printf("pagesize %d visible %d endline %d\n",txv->pagesize, txv->pagesize+!!txv->tail, txv->endline ); +}; + +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 = txv->margins.l; + rc.t = txv->margins.t; + rc.r = txv->w - txv->margins.r; + rc.b = rc.t + txv->line_height; + + for(i = txv->startline; i < txv->endline; i++) + { + draw_text_ext(txv->ctx, txv->font, txv->line[i], txv->line[i+1]-txv->line[i], &rc, 0xFF000000); + rc.t+= txv->line_height; + rc.b+= txv->line_height; + } + if(txv->tail && ( i < txv->lines)) + draw_text_ext(txv->ctx, txv->font, txv->line[i], txv->line[i+1]-txv->line[i], &rc, 0xFF000000); +}; + +void txv_set_text(tview_t *txv, char *text, int size) +{ + int i = 0; + char *p, *t; + + p = text; + + while(i < size) + { + switch(*p++) + { + case '\n': + txv->lines++; + break; + case '\r': + break; + } + i++; + }; + + txv->line = user_alloc((txv->lines+1)*sizeof(char*)); + txv->text = text; + { + int l=0; + + i = 0; + txv->line[0] = txv->text; + + while(i < size) + { + switch(*text++) + { + case '\n': + l++; + txv->line[l] = text; + break; + case '\r': + txv->line[l] = text; + break; + } + i++; + }; + } + + txv_recalc(txv); + txv_redraw(txv); +}; + +int txv_scroll_down(tview_t *txv) +{ + int dst, src, rows; + rect_t rc; + + if(txv->endline < txv->lines) + { + dst = txv->margins.t; + src = dst + txv->line_height; + rows = txv->line_height * (txv->pagesize-1); + scroll_ctx(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); + + draw_text_ext(txv->ctx, txv->font, txv->line[txv->endline], + txv->line[txv->endline+1]-txv->line[txv->endline], &rc, 0xFF000000); + + txv->startline++; + txv->endline++; + + if( txv->tail && (txv->endline < txv->lines)) + { + 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); + draw_text_ext(txv->ctx, txv->font, txv->line[txv->endline], + txv->line[txv->endline+1]-txv->line[txv->endline], &rc, 0xFF000000); + } + return 1; + }; + + return 0; +}; + +int txv_scroll_up(tview_t *txv) +{ + int dst, src, rows; + rect_t rc; + + if(txv->startline > 0) + { + rows = txv->tail + txv->line_height * (txv->pagesize-1); + src = txv->margins.t; + dst = src + txv->line_height; + + scroll_ctx(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); + + txv->startline--; + txv->endline--; + + draw_text_ext(txv->ctx, txv->font, txv->line[txv->startline], + txv->line[txv->startline+1]-txv->line[txv->startline], &rc, 0xFF000000); + return 1; + }; + + return 0; +}; + +int txv_page_up(tview_t *txv) +{ + int startline, endline; + + startline = txv->startline - txv->pagesize; + txv->startline = startline >= 0 ? startline : 0; + + endline = txv->startline + txv->pagesize; + txv->endline = endline < txv->lines ? endline : txv->lines; + txv_redraw(txv); + return 1; +}; + +int txv_page_down(tview_t *txv) +{ + int startline, endline; + + endline = txv->endline + txv->pagesize; + txv->endline = endline < txv->lines ? endline : txv->lines; + startline = txv->endline - txv->pagesize; + txv->startline = startline >= 0 ? startline : 0; + txv_redraw(txv); + return 1; +}; + +void txv_set_size(tview_t *txv, int txw, int txh) +{ + txv->w = txw; + txv->h = txh; + + txv_recalc(txv); + txv_redraw(txv); +}; + +void txv_set_font_size(tview_t *txv, int size) +{ + + if(size > 72) + size = 72; + else if(size < 6) + size = 6; + + txv->font = create_font(NULL, size); + if ( txv->font == NULL ) + { + printf("cannot create font\n"); + return; + } + + txv->line_height = txv->leading + get_font_height(txv->font); + txv_recalc(txv); + txv_redraw(txv); +} + +int txv_get_font_size(tview_t *txv) +{ + return get_font_height(txv->font); +}