// draw editing string to given region, with cursor highlight void render_edit_string(region* reg, char* str, u8 len, u8 cursor) { u8 i; u8* dst = (u8*)reg->data; u32 off = 0; // const u32 squarePx = (FONT_CHARW+2) * FONT_CHARH; u32 dif; region_fill(reg, 0x0); for(i=0; i<len; ++i) { if(str[i] == 0) { break; } if(i == cursor) { /// fixme: net art // region_fill_part(reg, off, squarePx, 0xf); // hack a column fill with a space character font_glyph(' ', dst, reg->w, 0x0, 0xf); dst += 2; off += 2; font_glyph_fixed(str[i], dst, reg->w, 0x0, 0xf); dif = FONT_CHARW + 2; dst += dif; off += dif; } else { dif = font_glyph(str[i], dst, reg->w, 0xf, 0x0) + 1; dst += dif; off += dif; } } reg->dirty = 1; }
static const struct dfont_rect * gen_char(int unicode, const char * utf8, int size, int edge) { // todo : use large size when size is large struct font_context ctx; font_create(FONT_SIZE, &ctx); if (ctx.font == NULL) { return NULL; } font_size(utf8, unicode, &ctx); const struct dfont_rect * rect = dfont_insert(Dfont, unicode, FONT_SIZE, ctx.w+1, ctx.h+1, edge); if (rect == NULL) { dfont_flush(Dfont); rect = dfont_insert(Dfont, unicode, FONT_SIZE, ctx.w+1, ctx.h+1, edge); if (rect == NULL) { font_release(&ctx); return NULL; } } ctx.w = rect->w ; ctx.h = rect->h ; int buffer_sz = ctx.w * ctx.h; ARRAY(uint8_t, buffer, buffer_sz); #ifdef FONT_EDGE_HASH if (edge) { ARRAY(uint8_t, tmp, buffer_sz); memset(tmp,0,buffer_sz); font_glyph(utf8, unicode, tmp, &ctx); gen_outline(ctx.w, ctx.h, tmp, buffer); } else { memset(buffer,0,buffer_sz); font_glyph(utf8, unicode, buffer, &ctx); } #else ARRAY(uint8_t, tmp, buffer_sz); memset(tmp,0,buffer_sz); font_glyph(utf8, unicode, tmp, &ctx); gen_outline(ctx.w, ctx.h, tmp, buffer); #endif // write_pgm(unicode, ctx.w, ctx.h, buffer); font_release(&ctx); render_texture_subupdate(R, Tex, buffer, rect->x, rect->y, rect->w, rect->h); return rect; }
static const struct dfont_rect * gen_char(int unicode, const char * utf8, int size) { // todo : use large size when size is large struct font_context ctx; font_create(FONT_SIZE, &ctx); if (ctx.font == NULL) { return NULL; } font_size(utf8, unicode, &ctx); const struct dfont_rect * rect = dfont_insert(Dfont, unicode, FONT_SIZE, ctx.w+1, ctx.h+1); if (rect == NULL) { font_release(&ctx); return NULL; } ctx.w = rect->w ; ctx.h = rect->h ; int buffer_sz = ctx.w * ctx.h; ARRAY(uint8_t, buffer, buffer_sz); ARRAY(uint8_t, tmp, buffer_sz); memset(tmp,0,buffer_sz); font_glyph(utf8, unicode, tmp, &ctx); gen_outline(ctx.w, ctx.h, tmp, buffer); // write_pgm(unicode, ctx.w, ctx.h, buffer); font_release(&ctx); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexSubImage2D(GL_TEXTURE_2D, 0, rect->x, rect->y, rect->w, rect->h, TEX_FMT, GL_UNSIGNED_BYTE, buffer); return rect; }
// render a string of packed glyphs to a buffer u8* font_string(const char* str, u8* buf, u32 size, u8 w, u8 a, u8 b) { // u32 x = 0; // columns processed // u32 off = 0; // offset u8* max = buf + size; while (buf < max) { if (*str == 0) { // end of string break; } /* if (*str == '\n') { */ /* // newline... ??? */ /* } */ /* if (*str == '\r') { */ /* // carriage return ... ??? */ /* if(pix > 0) { */ /* // ... ??? */ /* } */ /* } */ buf = font_glyph(*str, buf, w, a, b); // 1-column space between chars buf++; str++; } return buf; }
// clipping variant void font_string_region_clip(region* reg, const char* str, u8 xoff, u8 yoff, u8 fg, u8 bg) { u8* buf = reg->data + xoff + (u32)(reg->w) * (u32)yoff; u8* max = reg->data + reg->len; u32 xmax = reg->w - 7; // padding u8 dx = 0; while(buf < max) { // break on end of string if(*str == 0) { break; } dx = font_glyph(*str, buf, reg->w, fg, bg) + 1; buf += dx; xoff += dx; ++str; // wrap lines if(xoff > xmax) { return; } } }
void font_string_region_clip_right(region* reg, const char* str, u8 xoff, u8 yoff, u8 fg, u8 bg) { int8_t x = xoff - font_string_pixels(str); if(x < 0) x = 0; u8* buf = reg->data + x + (u32)(reg->w) * (u32)yoff; u8* max = reg->data + reg->len; u32 xmax = reg->w - 6; // padding changed from 7 to 6 (only using 4 wide nums anyway) u8 dx = 0; while(buf < max) { // break on end of string if(*str == 0) { break; } dx = font_glyph(*str, buf, reg->w, fg, bg) + 1; buf += dx; x += dx; ++str; // wrap lines if(x > xmax) { return; } } }
// render a string of packed glyphs to a buffer u8* font_string(const char* str, u8* buf, u32 size, u8 w, u8 a, u8 b) { u8* max = buf + size - 8; // pad 1 character width on right edge // u32 x = 0; // u8 dx = 0; while(buf < max) { // while (x < w) { if (*str == 0) { // end of string break; } // dx = font_glyph(*str, buf, w, a, b); // buf = +=dx; buf += font_glyph(*str, buf, w, a, b); // x += dx; // 1-column space between chars ++buf; // ++x; ++str; } return buf; }
int main(int argc, char** argv) { /* Window manager data structures. */ struct wm_device* dev = NULL; struct wm_window* win = NULL; const struct wm_window_desc win_desc = { 800, 600, 0 }; /* Renderer data structure. */ struct rdr_glyph_desc glyph_desc_list[NB_CHARS]; struct rdr_font* font = NULL; struct rdr_frame* frame = NULL; struct rdr_system* sys = NULL; struct rdr_term* term = NULL; /* Resources data structure. */ struct rsrc_context* ctxt = NULL; struct rsrc_font* rfont = NULL; /* Miscellaneous data. */ const char* driver_name = NULL; const char* font_name = NULL; size_t line_space = 0; size_t i = 0; bool b = false; if(argc != 3) { printf("usage: %s RB_DRIVER FONT\n", argv[0]); return -1; } driver_name = argv[1]; font_name = argv[2]; /* Setup the render font. */ RSRC(create_context(NULL, &ctxt)); RSRC(create_font(ctxt, font_name, &rfont)); if(RSRC(is_font_scalable(rfont, &b)), b) RSRC(font_size(rfont, 18, 18)); for(i = 0; i < NB_CHARS; ++i) { struct rsrc_glyph* glyph = NULL; struct rsrc_glyph_desc glyph_desc; size_t width = 0; size_t height = 0; size_t Bpp = 0; size_t size = 0; RSRC(font_glyph(rfont, (wchar_t)(i + FIRST_CHAR), &glyph)); /* Get glyph desc. */ RSRC(glyph_desc(glyph, &glyph_desc)); glyph_desc_list[i].width = glyph_desc.width; glyph_desc_list[i].character = glyph_desc.character; glyph_desc_list[i].bitmap_left = glyph_desc.bbox.x_min; glyph_desc_list[i].bitmap_top = glyph_desc.bbox.y_min; /* Get glyph bitmap. */ RSRC(glyph_bitmap(glyph, true, &width, &height, &Bpp, NULL)); glyph_desc_list[i].bitmap.width = width; glyph_desc_list[i].bitmap.height = height; glyph_desc_list[i].bitmap.bytes_per_pixel = Bpp; glyph_desc_list[i].bitmap.buffer = NULL; size = width * height * Bpp; if(0 != size) { unsigned char* buffer = MEM_CALLOC(&mem_default_allocator, 1, size); RSRC(glyph_bitmap(glyph, true, NULL, NULL, NULL, buffer)); glyph_desc_list[i].bitmap.buffer = buffer; } RSRC(glyph_ref_put(glyph)); } RSRC(font_line_space(rfont, &line_space)); RSRC(font_ref_put(rfont)); RSRC(context_ref_put(ctxt)); WM(create_device(NULL, &dev)); WM(create_window(dev, &win_desc, &win)); RDR(create_system(driver_name, NULL, &sys)); RDR(create_frame (sys, (struct rdr_frame_desc[]){{win_desc.width,win_desc.height}}, &frame));